entt.hpp 2.1 MB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529125301253112532125331253412535125361253712538125391254012541125421254312544125451254612547125481254912550125511255212553125541255512556125571255812559125601256112562125631256412565125661256712568125691257012571125721257312574125751257612577125781257912580125811258212583125841258512586125871258812589125901259112592125931259412595125961259712598125991260012601126021260312604126051260612607126081260912610126111261212613126141261512616126171261812619126201262112622126231262412625126261262712628126291263012631126321263312634126351263612637126381263912640126411264212643126441264512646126471264812649126501265112652126531265412655126561265712658126591266012661126621266312664126651266612667126681266912670126711267212673126741267512676126771267812679126801268112682126831268412685126861268712688126891269012691126921269312694126951269612697126981269912700127011270212703127041270512706127071270812709127101271112712127131271412715127161271712718127191272012721127221272312724127251272612727127281272912730127311273212733127341273512736127371273812739127401274112742127431274412745127461274712748127491275012751127521275312754127551275612757127581275912760127611276212763127641276512766127671276812769127701277112772127731277412775127761277712778127791278012781127821278312784127851278612787127881278912790127911279212793127941279512796127971279812799128001280112802128031280412805128061280712808128091281012811128121281312814128151281612817128181281912820128211282212823128241282512826128271282812829128301283112832128331283412835128361283712838128391284012841128421284312844128451284612847128481284912850128511285212853128541285512856128571285812859128601286112862128631286412865128661286712868128691287012871128721287312874128751287612877128781287912880128811288212883128841288512886128871288812889128901289112892128931289412895128961289712898128991290012901129021290312904129051290612907129081290912910129111291212913129141291512916129171291812919129201292112922129231292412925129261292712928129291293012931129321293312934129351293612937129381293912940129411294212943129441294512946129471294812949129501295112952129531295412955129561295712958129591296012961129621296312964129651296612967129681296912970129711297212973129741297512976129771297812979129801298112982129831298412985129861298712988129891299012991129921299312994129951299612997129981299913000130011300213003130041300513006130071300813009130101301113012130131301413015130161301713018130191302013021130221302313024130251302613027130281302913030130311303213033130341303513036130371303813039130401304113042130431304413045130461304713048130491305013051130521305313054130551305613057130581305913060130611306213063130641306513066130671306813069130701307113072130731307413075130761307713078130791308013081130821308313084130851308613087130881308913090130911309213093130941309513096130971309813099131001310113102131031310413105131061310713108131091311013111131121311313114131151311613117131181311913120131211312213123131241312513126131271312813129131301313113132131331313413135131361313713138131391314013141131421314313144131451314613147131481314913150131511315213153131541315513156131571315813159131601316113162131631316413165131661316713168131691317013171131721317313174131751317613177131781317913180131811318213183131841318513186131871318813189131901319113192131931319413195131961319713198131991320013201132021320313204132051320613207132081320913210132111321213213132141321513216132171321813219132201322113222132231322413225132261322713228132291323013231132321323313234132351323613237132381323913240132411324213243132441324513246132471324813249132501325113252132531325413255132561325713258132591326013261132621326313264132651326613267132681326913270132711327213273132741327513276132771327813279132801328113282132831328413285132861328713288132891329013291132921329313294132951329613297132981329913300133011330213303133041330513306133071330813309133101331113312133131331413315133161331713318133191332013321133221332313324133251332613327133281332913330133311333213333133341333513336133371333813339133401334113342133431334413345133461334713348133491335013351133521335313354133551335613357133581335913360133611336213363133641336513366133671336813369133701337113372133731337413375133761337713378133791338013381133821338313384133851338613387133881338913390133911339213393133941339513396133971339813399134001340113402134031340413405134061340713408134091341013411134121341313414134151341613417134181341913420134211342213423134241342513426134271342813429134301343113432134331343413435134361343713438134391344013441134421344313444134451344613447134481344913450134511345213453134541345513456134571345813459134601346113462134631346413465134661346713468134691347013471134721347313474134751347613477134781347913480134811348213483134841348513486134871348813489134901349113492134931349413495134961349713498134991350013501135021350313504135051350613507135081350913510135111351213513135141351513516135171351813519135201352113522135231352413525135261352713528135291353013531135321353313534135351353613537135381353913540135411354213543135441354513546135471354813549135501355113552135531355413555135561355713558135591356013561135621356313564135651356613567135681356913570135711357213573135741357513576135771357813579135801358113582135831358413585135861358713588135891359013591135921359313594135951359613597135981359913600136011360213603136041360513606136071360813609136101361113612136131361413615136161361713618136191362013621136221362313624136251362613627136281362913630136311363213633136341363513636136371363813639136401364113642136431364413645136461364713648136491365013651136521365313654136551365613657136581365913660136611366213663136641366513666136671366813669136701367113672136731367413675136761367713678136791368013681136821368313684136851368613687136881368913690136911369213693136941369513696136971369813699137001370113702137031370413705137061370713708137091371013711137121371313714137151371613717137181371913720137211372213723137241372513726137271372813729137301373113732137331373413735137361373713738137391374013741137421374313744137451374613747137481374913750137511375213753137541375513756137571375813759137601376113762137631376413765137661376713768137691377013771137721377313774137751377613777137781377913780137811378213783137841378513786137871378813789137901379113792137931379413795137961379713798137991380013801138021380313804138051380613807138081380913810138111381213813138141381513816138171381813819138201382113822138231382413825138261382713828138291383013831138321383313834138351383613837138381383913840138411384213843138441384513846138471384813849138501385113852138531385413855138561385713858138591386013861138621386313864138651386613867138681386913870138711387213873138741387513876138771387813879138801388113882138831388413885138861388713888138891389013891138921389313894138951389613897138981389913900139011390213903139041390513906139071390813909139101391113912139131391413915139161391713918139191392013921139221392313924139251392613927139281392913930139311393213933139341393513936139371393813939139401394113942139431394413945139461394713948139491395013951139521395313954139551395613957139581395913960139611396213963139641396513966139671396813969139701397113972139731397413975139761397713978139791398013981139821398313984139851398613987139881398913990139911399213993139941399513996139971399813999140001400114002140031400414005140061400714008140091401014011140121401314014140151401614017140181401914020140211402214023140241402514026140271402814029140301403114032140331403414035140361403714038140391404014041140421404314044140451404614047140481404914050140511405214053140541405514056140571405814059140601406114062140631406414065140661406714068140691407014071140721407314074140751407614077140781407914080140811408214083140841408514086140871408814089140901409114092140931409414095140961409714098140991410014101141021410314104141051410614107141081410914110141111411214113141141411514116141171411814119141201412114122141231412414125141261412714128141291413014131141321413314134141351413614137141381413914140141411414214143141441414514146141471414814149141501415114152141531415414155141561415714158141591416014161141621416314164141651416614167141681416914170141711417214173141741417514176141771417814179141801418114182141831418414185141861418714188141891419014191141921419314194141951419614197141981419914200142011420214203142041420514206142071420814209142101421114212142131421414215142161421714218142191422014221142221422314224142251422614227142281422914230142311423214233142341423514236142371423814239142401424114242142431424414245142461424714248142491425014251142521425314254142551425614257142581425914260142611426214263142641426514266142671426814269142701427114272142731427414275142761427714278142791428014281142821428314284142851428614287142881428914290142911429214293142941429514296142971429814299143001430114302143031430414305143061430714308143091431014311143121431314314143151431614317143181431914320143211432214323143241432514326143271432814329143301433114332143331433414335143361433714338143391434014341143421434314344143451434614347143481434914350143511435214353143541435514356143571435814359143601436114362143631436414365143661436714368143691437014371143721437314374143751437614377143781437914380143811438214383143841438514386143871438814389143901439114392143931439414395143961439714398143991440014401144021440314404144051440614407144081440914410144111441214413144141441514416144171441814419144201442114422144231442414425144261442714428144291443014431144321443314434144351443614437144381443914440144411444214443144441444514446144471444814449144501445114452144531445414455144561445714458144591446014461144621446314464144651446614467144681446914470144711447214473144741447514476144771447814479144801448114482144831448414485144861448714488144891449014491144921449314494144951449614497144981449914500145011450214503145041450514506145071450814509145101451114512145131451414515145161451714518145191452014521145221452314524145251452614527145281452914530145311453214533145341453514536145371453814539145401454114542145431454414545145461454714548145491455014551145521455314554145551455614557145581455914560145611456214563145641456514566145671456814569145701457114572145731457414575145761457714578145791458014581145821458314584145851458614587145881458914590145911459214593145941459514596145971459814599146001460114602146031460414605146061460714608146091461014611146121461314614146151461614617146181461914620146211462214623146241462514626146271462814629146301463114632146331463414635146361463714638146391464014641146421464314644146451464614647146481464914650146511465214653146541465514656146571465814659146601466114662146631466414665146661466714668146691467014671146721467314674146751467614677146781467914680146811468214683146841468514686146871468814689146901469114692146931469414695146961469714698146991470014701147021470314704147051470614707147081470914710147111471214713147141471514716147171471814719147201472114722147231472414725147261472714728147291473014731147321473314734147351473614737147381473914740147411474214743147441474514746147471474814749147501475114752147531475414755147561475714758147591476014761147621476314764147651476614767147681476914770147711477214773147741477514776147771477814779147801478114782147831478414785147861478714788147891479014791147921479314794147951479614797147981479914800148011480214803148041480514806148071480814809148101481114812148131481414815148161481714818148191482014821148221482314824148251482614827148281482914830148311483214833148341483514836148371483814839148401484114842148431484414845148461484714848148491485014851148521485314854148551485614857148581485914860148611486214863148641486514866148671486814869148701487114872148731487414875148761487714878148791488014881148821488314884148851488614887148881488914890148911489214893148941489514896148971489814899149001490114902149031490414905149061490714908149091491014911149121491314914149151491614917149181491914920149211492214923149241492514926149271492814929149301493114932149331493414935149361493714938149391494014941149421494314944149451494614947149481494914950149511495214953149541495514956149571495814959149601496114962149631496414965149661496714968149691497014971149721497314974149751497614977149781497914980149811498214983149841498514986149871498814989149901499114992149931499414995149961499714998149991500015001150021500315004150051500615007150081500915010150111501215013150141501515016150171501815019150201502115022150231502415025150261502715028150291503015031150321503315034150351503615037150381503915040150411504215043150441504515046150471504815049150501505115052150531505415055150561505715058150591506015061150621506315064150651506615067150681506915070150711507215073150741507515076150771507815079150801508115082150831508415085150861508715088150891509015091150921509315094150951509615097150981509915100151011510215103151041510515106151071510815109151101511115112151131511415115151161511715118151191512015121151221512315124151251512615127151281512915130151311513215133151341513515136151371513815139151401514115142151431514415145151461514715148151491515015151151521515315154151551515615157151581515915160151611516215163151641516515166151671516815169151701517115172151731517415175151761517715178151791518015181151821518315184151851518615187151881518915190151911519215193151941519515196151971519815199152001520115202152031520415205152061520715208152091521015211152121521315214152151521615217152181521915220152211522215223152241522515226152271522815229152301523115232152331523415235152361523715238152391524015241152421524315244152451524615247152481524915250152511525215253152541525515256152571525815259152601526115262152631526415265152661526715268152691527015271152721527315274152751527615277152781527915280152811528215283152841528515286152871528815289152901529115292152931529415295152961529715298152991530015301153021530315304153051530615307153081530915310153111531215313153141531515316153171531815319153201532115322153231532415325153261532715328153291533015331153321533315334153351533615337153381533915340153411534215343153441534515346153471534815349153501535115352153531535415355153561535715358153591536015361153621536315364153651536615367153681536915370153711537215373153741537515376153771537815379153801538115382153831538415385153861538715388153891539015391153921539315394153951539615397153981539915400154011540215403154041540515406154071540815409154101541115412154131541415415154161541715418154191542015421154221542315424154251542615427154281542915430154311543215433154341543515436154371543815439154401544115442154431544415445154461544715448154491545015451154521545315454154551545615457154581545915460154611546215463154641546515466154671546815469154701547115472154731547415475154761547715478154791548015481154821548315484154851548615487154881548915490154911549215493154941549515496154971549815499155001550115502155031550415505155061550715508155091551015511155121551315514155151551615517155181551915520155211552215523155241552515526155271552815529155301553115532155331553415535155361553715538155391554015541155421554315544155451554615547155481554915550155511555215553155541555515556155571555815559155601556115562155631556415565155661556715568155691557015571155721557315574155751557615577155781557915580155811558215583155841558515586155871558815589155901559115592155931559415595155961559715598155991560015601156021560315604156051560615607156081560915610156111561215613156141561515616156171561815619156201562115622156231562415625156261562715628156291563015631156321563315634156351563615637156381563915640156411564215643156441564515646156471564815649156501565115652156531565415655156561565715658156591566015661156621566315664156651566615667156681566915670156711567215673156741567515676156771567815679156801568115682156831568415685156861568715688156891569015691156921569315694156951569615697156981569915700157011570215703157041570515706157071570815709157101571115712157131571415715157161571715718157191572015721157221572315724157251572615727157281572915730157311573215733157341573515736157371573815739157401574115742157431574415745157461574715748157491575015751157521575315754157551575615757157581575915760157611576215763157641576515766157671576815769157701577115772157731577415775157761577715778157791578015781157821578315784157851578615787157881578915790157911579215793157941579515796157971579815799158001580115802158031580415805158061580715808158091581015811158121581315814158151581615817158181581915820158211582215823158241582515826158271582815829158301583115832158331583415835158361583715838158391584015841158421584315844158451584615847158481584915850158511585215853158541585515856158571585815859158601586115862158631586415865158661586715868158691587015871158721587315874158751587615877158781587915880158811588215883158841588515886158871588815889158901589115892158931589415895158961589715898158991590015901159021590315904159051590615907159081590915910159111591215913159141591515916159171591815919159201592115922159231592415925159261592715928159291593015931159321593315934159351593615937159381593915940159411594215943159441594515946159471594815949159501595115952159531595415955159561595715958159591596015961159621596315964159651596615967159681596915970159711597215973159741597515976159771597815979159801598115982159831598415985159861598715988159891599015991159921599315994159951599615997159981599916000160011600216003160041600516006160071600816009160101601116012160131601416015160161601716018160191602016021160221602316024160251602616027160281602916030160311603216033160341603516036160371603816039160401604116042160431604416045160461604716048160491605016051160521605316054160551605616057160581605916060160611606216063160641606516066160671606816069160701607116072160731607416075160761607716078160791608016081160821608316084160851608616087160881608916090160911609216093160941609516096160971609816099161001610116102161031610416105161061610716108161091611016111161121611316114161151611616117161181611916120161211612216123161241612516126161271612816129161301613116132161331613416135161361613716138161391614016141161421614316144161451614616147161481614916150161511615216153161541615516156161571615816159161601616116162161631616416165161661616716168161691617016171161721617316174161751617616177161781617916180161811618216183161841618516186161871618816189161901619116192161931619416195161961619716198161991620016201162021620316204162051620616207162081620916210162111621216213162141621516216162171621816219162201622116222162231622416225162261622716228162291623016231162321623316234162351623616237162381623916240162411624216243162441624516246162471624816249162501625116252162531625416255162561625716258162591626016261162621626316264162651626616267162681626916270162711627216273162741627516276162771627816279162801628116282162831628416285162861628716288162891629016291162921629316294162951629616297162981629916300163011630216303163041630516306163071630816309163101631116312163131631416315163161631716318163191632016321163221632316324163251632616327163281632916330163311633216333163341633516336163371633816339163401634116342163431634416345163461634716348163491635016351163521635316354163551635616357163581635916360163611636216363163641636516366163671636816369163701637116372163731637416375163761637716378163791638016381163821638316384163851638616387163881638916390163911639216393163941639516396163971639816399164001640116402164031640416405164061640716408164091641016411164121641316414164151641616417164181641916420164211642216423164241642516426164271642816429164301643116432164331643416435164361643716438164391644016441164421644316444164451644616447164481644916450164511645216453164541645516456164571645816459164601646116462164631646416465164661646716468164691647016471164721647316474164751647616477164781647916480164811648216483164841648516486164871648816489164901649116492164931649416495164961649716498164991650016501165021650316504165051650616507165081650916510165111651216513165141651516516165171651816519165201652116522165231652416525165261652716528165291653016531165321653316534165351653616537165381653916540165411654216543165441654516546165471654816549165501655116552165531655416555165561655716558165591656016561165621656316564165651656616567165681656916570165711657216573165741657516576165771657816579165801658116582165831658416585165861658716588165891659016591165921659316594165951659616597165981659916600166011660216603166041660516606166071660816609166101661116612166131661416615166161661716618166191662016621166221662316624166251662616627166281662916630166311663216633166341663516636166371663816639166401664116642166431664416645166461664716648166491665016651166521665316654166551665616657166581665916660166611666216663166641666516666166671666816669166701667116672166731667416675166761667716678166791668016681166821668316684166851668616687166881668916690166911669216693166941669516696166971669816699167001670116702167031670416705167061670716708167091671016711167121671316714167151671616717167181671916720167211672216723167241672516726167271672816729167301673116732167331673416735167361673716738167391674016741167421674316744167451674616747167481674916750167511675216753167541675516756167571675816759167601676116762167631676416765167661676716768167691677016771167721677316774167751677616777167781677916780167811678216783167841678516786167871678816789167901679116792167931679416795167961679716798167991680016801168021680316804168051680616807168081680916810168111681216813168141681516816168171681816819168201682116822168231682416825168261682716828168291683016831168321683316834168351683616837168381683916840168411684216843168441684516846168471684816849168501685116852168531685416855168561685716858168591686016861168621686316864168651686616867168681686916870168711687216873168741687516876168771687816879168801688116882168831688416885168861688716888168891689016891168921689316894168951689616897168981689916900169011690216903169041690516906169071690816909169101691116912169131691416915169161691716918169191692016921169221692316924169251692616927169281692916930169311693216933169341693516936169371693816939169401694116942169431694416945169461694716948169491695016951169521695316954169551695616957169581695916960169611696216963169641696516966169671696816969169701697116972169731697416975169761697716978169791698016981169821698316984169851698616987169881698916990169911699216993169941699516996169971699816999170001700117002170031700417005170061700717008170091701017011170121701317014170151701617017170181701917020170211702217023170241702517026170271702817029170301703117032170331703417035170361703717038170391704017041170421704317044170451704617047170481704917050170511705217053170541705517056170571705817059170601706117062170631706417065170661706717068170691707017071170721707317074170751707617077170781707917080170811708217083170841708517086170871708817089170901709117092170931709417095170961709717098170991710017101171021710317104171051710617107171081710917110171111711217113171141711517116171171711817119171201712117122171231712417125171261712717128171291713017131171321713317134171351713617137171381713917140171411714217143171441714517146171471714817149171501715117152171531715417155171561715717158171591716017161171621716317164171651716617167171681716917170171711717217173171741717517176171771717817179171801718117182171831718417185171861718717188171891719017191171921719317194171951719617197171981719917200172011720217203172041720517206172071720817209172101721117212172131721417215172161721717218172191722017221172221722317224172251722617227172281722917230172311723217233172341723517236172371723817239172401724117242172431724417245172461724717248172491725017251172521725317254172551725617257172581725917260172611726217263172641726517266172671726817269172701727117272172731727417275172761727717278172791728017281172821728317284172851728617287172881728917290172911729217293172941729517296172971729817299173001730117302173031730417305173061730717308173091731017311173121731317314173151731617317173181731917320173211732217323173241732517326173271732817329173301733117332173331733417335173361733717338173391734017341173421734317344173451734617347173481734917350173511735217353173541735517356173571735817359173601736117362173631736417365173661736717368173691737017371173721737317374173751737617377173781737917380173811738217383173841738517386173871738817389173901739117392173931739417395173961739717398173991740017401174021740317404174051740617407174081740917410174111741217413174141741517416174171741817419174201742117422174231742417425174261742717428174291743017431174321743317434174351743617437174381743917440174411744217443174441744517446174471744817449174501745117452174531745417455174561745717458174591746017461174621746317464174651746617467174681746917470174711747217473174741747517476174771747817479174801748117482174831748417485174861748717488174891749017491174921749317494174951749617497174981749917500175011750217503175041750517506175071750817509175101751117512175131751417515175161751717518175191752017521175221752317524175251752617527175281752917530175311753217533175341753517536175371753817539175401754117542175431754417545175461754717548175491755017551175521755317554175551755617557175581755917560175611756217563175641756517566175671756817569175701757117572175731757417575175761757717578175791758017581175821758317584175851758617587175881758917590175911759217593175941759517596175971759817599176001760117602176031760417605176061760717608176091761017611176121761317614176151761617617176181761917620176211762217623176241762517626176271762817629176301763117632176331763417635176361763717638176391764017641176421764317644176451764617647176481764917650176511765217653176541765517656176571765817659176601766117662176631766417665176661766717668176691767017671176721767317674176751767617677176781767917680176811768217683176841768517686176871768817689176901769117692176931769417695176961769717698176991770017701177021770317704177051770617707177081770917710177111771217713177141771517716177171771817719177201772117722177231772417725177261772717728177291773017731177321773317734177351773617737177381773917740177411774217743177441774517746177471774817749177501775117752177531775417755177561775717758177591776017761177621776317764177651776617767177681776917770177711777217773177741777517776177771777817779177801778117782177831778417785177861778717788177891779017791177921779317794177951779617797177981779917800178011780217803178041780517806178071780817809178101781117812178131781417815178161781717818178191782017821178221782317824178251782617827178281782917830178311783217833178341783517836178371783817839178401784117842178431784417845178461784717848178491785017851178521785317854178551785617857178581785917860178611786217863178641786517866178671786817869178701787117872178731787417875178761787717878178791788017881178821788317884178851788617887178881788917890178911789217893178941789517896178971789817899179001790117902179031790417905179061790717908179091791017911179121791317914179151791617917179181791917920179211792217923179241792517926179271792817929179301793117932179331793417935179361793717938179391794017941179421794317944179451794617947179481794917950179511795217953179541795517956179571795817959179601796117962179631796417965179661796717968179691797017971179721797317974179751797617977179781797917980179811798217983179841798517986179871798817989179901799117992179931799417995179961799717998179991800018001180021800318004180051800618007180081800918010180111801218013180141801518016180171801818019180201802118022180231802418025180261802718028180291803018031180321803318034180351803618037180381803918040180411804218043180441804518046180471804818049180501805118052180531805418055180561805718058180591806018061180621806318064180651806618067180681806918070180711807218073180741807518076180771807818079180801808118082180831808418085180861808718088180891809018091180921809318094180951809618097180981809918100181011810218103181041810518106181071810818109181101811118112181131811418115181161811718118181191812018121181221812318124181251812618127181281812918130181311813218133181341813518136181371813818139181401814118142181431814418145181461814718148181491815018151181521815318154181551815618157181581815918160181611816218163181641816518166181671816818169181701817118172181731817418175181761817718178181791818018181181821818318184181851818618187181881818918190181911819218193181941819518196181971819818199182001820118202182031820418205182061820718208182091821018211182121821318214182151821618217182181821918220182211822218223182241822518226182271822818229182301823118232182331823418235182361823718238182391824018241182421824318244182451824618247182481824918250182511825218253182541825518256182571825818259182601826118262182631826418265182661826718268182691827018271182721827318274182751827618277182781827918280182811828218283182841828518286182871828818289182901829118292182931829418295182961829718298182991830018301183021830318304183051830618307183081830918310183111831218313183141831518316183171831818319183201832118322183231832418325183261832718328183291833018331183321833318334183351833618337183381833918340183411834218343183441834518346183471834818349183501835118352183531835418355183561835718358183591836018361183621836318364183651836618367183681836918370183711837218373183741837518376183771837818379183801838118382183831838418385183861838718388183891839018391183921839318394183951839618397183981839918400184011840218403184041840518406184071840818409184101841118412184131841418415184161841718418184191842018421184221842318424184251842618427184281842918430184311843218433184341843518436184371843818439184401844118442184431844418445184461844718448184491845018451184521845318454184551845618457184581845918460184611846218463184641846518466184671846818469184701847118472184731847418475184761847718478184791848018481184821848318484184851848618487184881848918490184911849218493184941849518496184971849818499185001850118502185031850418505185061850718508185091851018511185121851318514185151851618517185181851918520185211852218523185241852518526185271852818529185301853118532185331853418535185361853718538185391854018541185421854318544185451854618547185481854918550185511855218553185541855518556185571855818559185601856118562185631856418565185661856718568185691857018571185721857318574185751857618577185781857918580185811858218583185841858518586185871858818589185901859118592185931859418595185961859718598185991860018601186021860318604186051860618607186081860918610186111861218613186141861518616186171861818619186201862118622186231862418625186261862718628186291863018631186321863318634186351863618637186381863918640186411864218643186441864518646186471864818649186501865118652186531865418655186561865718658186591866018661186621866318664186651866618667186681866918670186711867218673186741867518676186771867818679186801868118682186831868418685186861868718688186891869018691186921869318694186951869618697186981869918700187011870218703187041870518706187071870818709187101871118712187131871418715187161871718718187191872018721187221872318724187251872618727187281872918730187311873218733187341873518736187371873818739187401874118742187431874418745187461874718748187491875018751187521875318754187551875618757187581875918760187611876218763187641876518766187671876818769187701877118772187731877418775187761877718778187791878018781187821878318784187851878618787187881878918790187911879218793187941879518796187971879818799188001880118802188031880418805188061880718808188091881018811188121881318814188151881618817188181881918820188211882218823188241882518826188271882818829188301883118832188331883418835188361883718838188391884018841188421884318844188451884618847188481884918850188511885218853188541885518856188571885818859188601886118862188631886418865188661886718868188691887018871188721887318874188751887618877188781887918880188811888218883188841888518886188871888818889188901889118892188931889418895188961889718898188991890018901189021890318904189051890618907189081890918910189111891218913189141891518916189171891818919189201892118922189231892418925189261892718928189291893018931189321893318934189351893618937189381893918940189411894218943189441894518946189471894818949189501895118952189531895418955189561895718958189591896018961189621896318964189651896618967189681896918970189711897218973189741897518976189771897818979189801898118982189831898418985189861898718988189891899018991189921899318994189951899618997189981899919000190011900219003190041900519006190071900819009190101901119012190131901419015190161901719018190191902019021190221902319024190251902619027190281902919030190311903219033190341903519036190371903819039190401904119042190431904419045190461904719048190491905019051190521905319054190551905619057190581905919060190611906219063190641906519066190671906819069190701907119072190731907419075190761907719078190791908019081190821908319084190851908619087190881908919090190911909219093190941909519096190971909819099191001910119102191031910419105191061910719108191091911019111191121911319114191151911619117191181911919120191211912219123191241912519126191271912819129191301913119132191331913419135191361913719138191391914019141191421914319144191451914619147191481914919150191511915219153191541915519156191571915819159191601916119162191631916419165191661916719168191691917019171191721917319174191751917619177191781917919180191811918219183191841918519186191871918819189191901919119192191931919419195191961919719198191991920019201192021920319204192051920619207192081920919210192111921219213192141921519216192171921819219192201922119222192231922419225192261922719228192291923019231192321923319234192351923619237192381923919240192411924219243192441924519246192471924819249192501925119252192531925419255192561925719258192591926019261192621926319264192651926619267192681926919270192711927219273192741927519276192771927819279192801928119282192831928419285192861928719288192891929019291192921929319294192951929619297192981929919300193011930219303193041930519306193071930819309193101931119312193131931419315193161931719318193191932019321193221932319324193251932619327193281932919330193311933219333193341933519336193371933819339193401934119342193431934419345193461934719348193491935019351193521935319354193551935619357193581935919360193611936219363193641936519366193671936819369193701937119372193731937419375193761937719378193791938019381193821938319384193851938619387193881938919390193911939219393193941939519396193971939819399194001940119402194031940419405194061940719408194091941019411194121941319414194151941619417194181941919420194211942219423194241942519426194271942819429194301943119432194331943419435194361943719438194391944019441194421944319444194451944619447194481944919450194511945219453194541945519456194571945819459194601946119462194631946419465194661946719468194691947019471194721947319474194751947619477194781947919480194811948219483194841948519486194871948819489194901949119492194931949419495194961949719498194991950019501195021950319504195051950619507195081950919510195111951219513195141951519516195171951819519195201952119522195231952419525195261952719528195291953019531195321953319534195351953619537195381953919540195411954219543195441954519546195471954819549195501955119552195531955419555195561955719558195591956019561195621956319564195651956619567195681956919570195711957219573195741957519576195771957819579195801958119582195831958419585195861958719588195891959019591195921959319594195951959619597195981959919600196011960219603196041960519606196071960819609196101961119612196131961419615196161961719618196191962019621196221962319624196251962619627196281962919630196311963219633196341963519636196371963819639196401964119642196431964419645196461964719648196491965019651196521965319654196551965619657196581965919660196611966219663196641966519666196671966819669196701967119672196731967419675196761967719678196791968019681196821968319684196851968619687196881968919690196911969219693196941969519696196971969819699197001970119702197031970419705197061970719708197091971019711197121971319714197151971619717197181971919720197211972219723197241972519726197271972819729197301973119732197331973419735197361973719738197391974019741197421974319744197451974619747197481974919750197511975219753197541975519756197571975819759197601976119762197631976419765197661976719768197691977019771197721977319774197751977619777197781977919780197811978219783197841978519786197871978819789197901979119792197931979419795197961979719798197991980019801198021980319804198051980619807198081980919810198111981219813198141981519816198171981819819198201982119822198231982419825198261982719828198291983019831198321983319834198351983619837198381983919840198411984219843198441984519846198471984819849198501985119852198531985419855198561985719858198591986019861198621986319864198651986619867198681986919870198711987219873198741987519876198771987819879198801988119882198831988419885198861988719888198891989019891198921989319894198951989619897198981989919900199011990219903199041990519906199071990819909199101991119912199131991419915199161991719918199191992019921199221992319924199251992619927199281992919930199311993219933199341993519936199371993819939199401994119942199431994419945199461994719948199491995019951199521995319954199551995619957199581995919960199611996219963199641996519966199671996819969199701997119972199731997419975199761997719978199791998019981199821998319984199851998619987199881998919990199911999219993199941999519996199971999819999200002000120002200032000420005200062000720008200092001020011200122001320014200152001620017200182001920020200212002220023200242002520026200272002820029200302003120032200332003420035200362003720038200392004020041200422004320044200452004620047200482004920050200512005220053200542005520056200572005820059200602006120062200632006420065200662006720068200692007020071200722007320074200752007620077200782007920080200812008220083200842008520086200872008820089200902009120092200932009420095200962009720098200992010020101201022010320104201052010620107201082010920110201112011220113201142011520116201172011820119201202012120122201232012420125201262012720128201292013020131201322013320134201352013620137201382013920140201412014220143201442014520146201472014820149201502015120152201532015420155201562015720158201592016020161201622016320164201652016620167201682016920170201712017220173201742017520176201772017820179201802018120182201832018420185201862018720188201892019020191201922019320194201952019620197201982019920200202012020220203202042020520206202072020820209202102021120212202132021420215202162021720218202192022020221202222022320224202252022620227202282022920230202312023220233202342023520236202372023820239202402024120242202432024420245202462024720248202492025020251202522025320254202552025620257202582025920260202612026220263202642026520266202672026820269202702027120272202732027420275202762027720278202792028020281202822028320284202852028620287202882028920290202912029220293202942029520296202972029820299203002030120302203032030420305203062030720308203092031020311203122031320314203152031620317203182031920320203212032220323203242032520326203272032820329203302033120332203332033420335203362033720338203392034020341203422034320344203452034620347203482034920350203512035220353203542035520356203572035820359203602036120362203632036420365203662036720368203692037020371203722037320374203752037620377203782037920380203812038220383203842038520386203872038820389203902039120392203932039420395203962039720398203992040020401204022040320404204052040620407204082040920410204112041220413204142041520416204172041820419204202042120422204232042420425204262042720428204292043020431204322043320434204352043620437204382043920440204412044220443204442044520446204472044820449204502045120452204532045420455204562045720458204592046020461204622046320464204652046620467204682046920470204712047220473204742047520476204772047820479204802048120482204832048420485204862048720488204892049020491204922049320494204952049620497204982049920500205012050220503205042050520506205072050820509205102051120512205132051420515205162051720518205192052020521205222052320524205252052620527205282052920530205312053220533205342053520536205372053820539205402054120542205432054420545205462054720548205492055020551205522055320554205552055620557205582055920560205612056220563205642056520566205672056820569205702057120572205732057420575205762057720578205792058020581205822058320584205852058620587205882058920590205912059220593205942059520596205972059820599206002060120602206032060420605206062060720608206092061020611206122061320614206152061620617206182061920620206212062220623206242062520626206272062820629206302063120632206332063420635206362063720638206392064020641206422064320644206452064620647206482064920650206512065220653206542065520656206572065820659206602066120662206632066420665206662066720668206692067020671206722067320674206752067620677206782067920680206812068220683206842068520686206872068820689206902069120692206932069420695206962069720698206992070020701207022070320704207052070620707207082070920710207112071220713207142071520716207172071820719207202072120722207232072420725207262072720728207292073020731207322073320734207352073620737207382073920740207412074220743207442074520746207472074820749207502075120752207532075420755207562075720758207592076020761207622076320764207652076620767207682076920770207712077220773207742077520776207772077820779207802078120782207832078420785207862078720788207892079020791207922079320794207952079620797207982079920800208012080220803208042080520806208072080820809208102081120812208132081420815208162081720818208192082020821208222082320824208252082620827208282082920830208312083220833208342083520836208372083820839208402084120842208432084420845208462084720848208492085020851208522085320854208552085620857208582085920860208612086220863208642086520866208672086820869208702087120872208732087420875208762087720878208792088020881208822088320884208852088620887208882088920890208912089220893208942089520896208972089820899209002090120902209032090420905209062090720908209092091020911209122091320914209152091620917209182091920920209212092220923209242092520926209272092820929209302093120932209332093420935209362093720938209392094020941209422094320944209452094620947209482094920950209512095220953209542095520956209572095820959209602096120962209632096420965209662096720968209692097020971209722097320974209752097620977209782097920980209812098220983209842098520986209872098820989209902099120992209932099420995209962099720998209992100021001210022100321004210052100621007210082100921010210112101221013210142101521016210172101821019210202102121022210232102421025210262102721028210292103021031210322103321034210352103621037210382103921040210412104221043210442104521046210472104821049210502105121052210532105421055210562105721058210592106021061210622106321064210652106621067210682106921070210712107221073210742107521076210772107821079210802108121082210832108421085210862108721088210892109021091210922109321094210952109621097210982109921100211012110221103211042110521106211072110821109211102111121112211132111421115211162111721118211192112021121211222112321124211252112621127211282112921130211312113221133211342113521136211372113821139211402114121142211432114421145211462114721148211492115021151211522115321154211552115621157211582115921160211612116221163211642116521166211672116821169211702117121172211732117421175211762117721178211792118021181211822118321184211852118621187211882118921190211912119221193211942119521196211972119821199212002120121202212032120421205212062120721208212092121021211212122121321214212152121621217212182121921220212212122221223212242122521226212272122821229212302123121232212332123421235212362123721238212392124021241212422124321244212452124621247212482124921250212512125221253212542125521256212572125821259212602126121262212632126421265212662126721268212692127021271212722127321274212752127621277212782127921280212812128221283212842128521286212872128821289212902129121292212932129421295212962129721298212992130021301213022130321304213052130621307213082130921310213112131221313213142131521316213172131821319213202132121322213232132421325213262132721328213292133021331213322133321334213352133621337213382133921340213412134221343213442134521346213472134821349213502135121352213532135421355213562135721358213592136021361213622136321364213652136621367213682136921370213712137221373213742137521376213772137821379213802138121382213832138421385213862138721388213892139021391213922139321394213952139621397213982139921400214012140221403214042140521406214072140821409214102141121412214132141421415214162141721418214192142021421214222142321424214252142621427214282142921430214312143221433214342143521436214372143821439214402144121442214432144421445214462144721448214492145021451214522145321454214552145621457214582145921460214612146221463214642146521466214672146821469214702147121472214732147421475214762147721478214792148021481214822148321484214852148621487214882148921490214912149221493214942149521496214972149821499215002150121502215032150421505215062150721508215092151021511215122151321514215152151621517215182151921520215212152221523215242152521526215272152821529215302153121532215332153421535215362153721538215392154021541215422154321544215452154621547215482154921550215512155221553215542155521556215572155821559215602156121562215632156421565215662156721568215692157021571215722157321574215752157621577215782157921580215812158221583215842158521586215872158821589215902159121592215932159421595215962159721598215992160021601216022160321604216052160621607216082160921610216112161221613216142161521616216172161821619216202162121622216232162421625216262162721628216292163021631216322163321634216352163621637216382163921640216412164221643216442164521646216472164821649216502165121652216532165421655216562165721658216592166021661216622166321664216652166621667216682166921670216712167221673216742167521676216772167821679216802168121682216832168421685216862168721688216892169021691216922169321694216952169621697216982169921700217012170221703217042170521706217072170821709217102171121712217132171421715217162171721718217192172021721217222172321724217252172621727217282172921730217312173221733217342173521736217372173821739217402174121742217432174421745217462174721748217492175021751217522175321754217552175621757217582175921760217612176221763217642176521766217672176821769217702177121772217732177421775217762177721778217792178021781217822178321784217852178621787217882178921790217912179221793217942179521796217972179821799218002180121802218032180421805218062180721808218092181021811218122181321814218152181621817218182181921820218212182221823218242182521826218272182821829218302183121832218332183421835218362183721838218392184021841218422184321844218452184621847218482184921850218512185221853218542185521856218572185821859218602186121862218632186421865218662186721868218692187021871218722187321874218752187621877218782187921880218812188221883218842188521886218872188821889218902189121892218932189421895218962189721898218992190021901219022190321904219052190621907219082190921910219112191221913219142191521916219172191821919219202192121922219232192421925219262192721928219292193021931219322193321934219352193621937219382193921940219412194221943219442194521946219472194821949219502195121952219532195421955219562195721958219592196021961219622196321964219652196621967219682196921970219712197221973219742197521976219772197821979219802198121982219832198421985219862198721988219892199021991219922199321994219952199621997219982199922000220012200222003220042200522006220072200822009220102201122012220132201422015220162201722018220192202022021220222202322024220252202622027220282202922030220312203222033220342203522036220372203822039220402204122042220432204422045220462204722048220492205022051220522205322054220552205622057220582205922060220612206222063220642206522066220672206822069220702207122072220732207422075220762207722078220792208022081220822208322084220852208622087220882208922090220912209222093220942209522096220972209822099221002210122102221032210422105221062210722108221092211022111221122211322114221152211622117221182211922120221212212222123221242212522126221272212822129221302213122132221332213422135221362213722138221392214022141221422214322144221452214622147221482214922150221512215222153221542215522156221572215822159221602216122162221632216422165221662216722168221692217022171221722217322174221752217622177221782217922180221812218222183221842218522186221872218822189221902219122192221932219422195221962219722198221992220022201222022220322204222052220622207222082220922210222112221222213222142221522216222172221822219222202222122222222232222422225222262222722228222292223022231222322223322234222352223622237222382223922240222412224222243222442224522246222472224822249222502225122252222532225422255222562225722258222592226022261222622226322264222652226622267222682226922270222712227222273222742227522276222772227822279222802228122282222832228422285222862228722288222892229022291222922229322294222952229622297222982229922300223012230222303223042230522306223072230822309223102231122312223132231422315223162231722318223192232022321223222232322324223252232622327223282232922330223312233222333223342233522336223372233822339223402234122342223432234422345223462234722348223492235022351223522235322354223552235622357223582235922360223612236222363223642236522366223672236822369223702237122372223732237422375223762237722378223792238022381223822238322384223852238622387223882238922390223912239222393223942239522396223972239822399224002240122402224032240422405224062240722408224092241022411224122241322414224152241622417224182241922420224212242222423224242242522426224272242822429224302243122432224332243422435224362243722438224392244022441224422244322444224452244622447224482244922450224512245222453224542245522456224572245822459224602246122462224632246422465224662246722468224692247022471224722247322474224752247622477224782247922480224812248222483224842248522486224872248822489224902249122492224932249422495224962249722498224992250022501225022250322504225052250622507225082250922510225112251222513225142251522516225172251822519225202252122522225232252422525225262252722528225292253022531225322253322534225352253622537225382253922540225412254222543225442254522546225472254822549225502255122552225532255422555225562255722558225592256022561225622256322564225652256622567225682256922570225712257222573225742257522576225772257822579225802258122582225832258422585225862258722588225892259022591225922259322594225952259622597225982259922600226012260222603226042260522606226072260822609226102261122612226132261422615226162261722618226192262022621226222262322624226252262622627226282262922630226312263222633226342263522636226372263822639226402264122642226432264422645226462264722648226492265022651226522265322654226552265622657226582265922660226612266222663226642266522666226672266822669226702267122672226732267422675226762267722678226792268022681226822268322684226852268622687226882268922690226912269222693226942269522696226972269822699227002270122702227032270422705227062270722708227092271022711227122271322714227152271622717227182271922720227212272222723227242272522726227272272822729227302273122732227332273422735227362273722738227392274022741227422274322744227452274622747227482274922750227512275222753227542275522756227572275822759227602276122762227632276422765227662276722768227692277022771227722277322774227752277622777227782277922780227812278222783227842278522786227872278822789227902279122792227932279422795227962279722798227992280022801228022280322804228052280622807228082280922810228112281222813228142281522816228172281822819228202282122822228232282422825228262282722828228292283022831228322283322834228352283622837228382283922840228412284222843228442284522846228472284822849228502285122852228532285422855228562285722858228592286022861228622286322864228652286622867228682286922870228712287222873228742287522876228772287822879228802288122882228832288422885228862288722888228892289022891228922289322894228952289622897228982289922900229012290222903229042290522906229072290822909229102291122912229132291422915229162291722918229192292022921229222292322924229252292622927229282292922930229312293222933229342293522936229372293822939229402294122942229432294422945229462294722948229492295022951229522295322954229552295622957229582295922960229612296222963229642296522966229672296822969229702297122972229732297422975229762297722978229792298022981229822298322984229852298622987229882298922990229912299222993229942299522996229972299822999230002300123002230032300423005230062300723008230092301023011230122301323014230152301623017230182301923020230212302223023230242302523026230272302823029230302303123032230332303423035230362303723038230392304023041230422304323044230452304623047230482304923050230512305223053230542305523056230572305823059230602306123062230632306423065230662306723068230692307023071230722307323074230752307623077230782307923080230812308223083230842308523086230872308823089230902309123092230932309423095230962309723098230992310023101231022310323104231052310623107231082310923110231112311223113231142311523116231172311823119231202312123122231232312423125231262312723128231292313023131231322313323134231352313623137231382313923140231412314223143231442314523146231472314823149231502315123152231532315423155231562315723158231592316023161231622316323164231652316623167231682316923170231712317223173231742317523176231772317823179231802318123182231832318423185231862318723188231892319023191231922319323194231952319623197231982319923200232012320223203232042320523206232072320823209232102321123212232132321423215232162321723218232192322023221232222322323224232252322623227232282322923230232312323223233232342323523236232372323823239232402324123242232432324423245232462324723248232492325023251232522325323254232552325623257232582325923260232612326223263232642326523266232672326823269232702327123272232732327423275232762327723278232792328023281232822328323284232852328623287232882328923290232912329223293232942329523296232972329823299233002330123302233032330423305233062330723308233092331023311233122331323314233152331623317233182331923320233212332223323233242332523326233272332823329233302333123332233332333423335233362333723338233392334023341233422334323344233452334623347233482334923350233512335223353233542335523356233572335823359233602336123362233632336423365233662336723368233692337023371233722337323374233752337623377233782337923380233812338223383233842338523386233872338823389233902339123392233932339423395233962339723398233992340023401234022340323404234052340623407234082340923410234112341223413234142341523416234172341823419234202342123422234232342423425234262342723428234292343023431234322343323434234352343623437234382343923440234412344223443234442344523446234472344823449234502345123452234532345423455234562345723458234592346023461234622346323464234652346623467234682346923470234712347223473234742347523476234772347823479234802348123482234832348423485234862348723488234892349023491234922349323494234952349623497234982349923500235012350223503235042350523506235072350823509235102351123512235132351423515235162351723518235192352023521235222352323524235252352623527235282352923530235312353223533235342353523536235372353823539235402354123542235432354423545235462354723548235492355023551235522355323554235552355623557235582355923560235612356223563235642356523566235672356823569235702357123572235732357423575235762357723578235792358023581235822358323584235852358623587235882358923590235912359223593235942359523596235972359823599236002360123602236032360423605236062360723608236092361023611236122361323614236152361623617236182361923620236212362223623236242362523626236272362823629236302363123632236332363423635236362363723638236392364023641236422364323644236452364623647236482364923650236512365223653236542365523656236572365823659236602366123662236632366423665236662366723668236692367023671236722367323674236752367623677236782367923680236812368223683236842368523686236872368823689236902369123692236932369423695236962369723698236992370023701237022370323704237052370623707237082370923710237112371223713237142371523716237172371823719237202372123722237232372423725237262372723728237292373023731237322373323734237352373623737237382373923740237412374223743237442374523746237472374823749237502375123752237532375423755237562375723758237592376023761237622376323764237652376623767237682376923770237712377223773237742377523776237772377823779237802378123782237832378423785237862378723788237892379023791237922379323794237952379623797237982379923800238012380223803238042380523806238072380823809238102381123812238132381423815238162381723818238192382023821238222382323824238252382623827238282382923830238312383223833238342383523836238372383823839238402384123842238432384423845238462384723848238492385023851238522385323854238552385623857238582385923860238612386223863238642386523866238672386823869238702387123872238732387423875238762387723878238792388023881238822388323884238852388623887238882388923890238912389223893238942389523896238972389823899239002390123902239032390423905239062390723908239092391023911239122391323914239152391623917239182391923920239212392223923239242392523926239272392823929239302393123932239332393423935239362393723938239392394023941239422394323944239452394623947239482394923950239512395223953239542395523956239572395823959239602396123962239632396423965239662396723968239692397023971239722397323974239752397623977239782397923980239812398223983239842398523986239872398823989239902399123992239932399423995239962399723998239992400024001240022400324004240052400624007240082400924010240112401224013240142401524016240172401824019240202402124022240232402424025240262402724028240292403024031240322403324034240352403624037240382403924040240412404224043240442404524046240472404824049240502405124052240532405424055240562405724058240592406024061240622406324064240652406624067240682406924070240712407224073240742407524076240772407824079240802408124082240832408424085240862408724088240892409024091240922409324094240952409624097240982409924100241012410224103241042410524106241072410824109241102411124112241132411424115241162411724118241192412024121241222412324124241252412624127241282412924130241312413224133241342413524136241372413824139241402414124142241432414424145241462414724148241492415024151241522415324154241552415624157241582415924160241612416224163241642416524166241672416824169241702417124172241732417424175241762417724178241792418024181241822418324184241852418624187241882418924190241912419224193241942419524196241972419824199242002420124202242032420424205242062420724208242092421024211242122421324214242152421624217242182421924220242212422224223242242422524226242272422824229242302423124232242332423424235242362423724238242392424024241242422424324244242452424624247242482424924250242512425224253242542425524256242572425824259242602426124262242632426424265242662426724268242692427024271242722427324274242752427624277242782427924280242812428224283242842428524286242872428824289242902429124292242932429424295242962429724298242992430024301243022430324304243052430624307243082430924310243112431224313243142431524316243172431824319243202432124322243232432424325243262432724328243292433024331243322433324334243352433624337243382433924340243412434224343243442434524346243472434824349243502435124352243532435424355243562435724358243592436024361243622436324364243652436624367243682436924370243712437224373243742437524376243772437824379243802438124382243832438424385243862438724388243892439024391243922439324394243952439624397243982439924400244012440224403244042440524406244072440824409244102441124412244132441424415244162441724418244192442024421244222442324424244252442624427244282442924430244312443224433244342443524436244372443824439244402444124442244432444424445244462444724448244492445024451244522445324454244552445624457244582445924460244612446224463244642446524466244672446824469244702447124472244732447424475244762447724478244792448024481244822448324484244852448624487244882448924490244912449224493244942449524496244972449824499245002450124502245032450424505245062450724508245092451024511245122451324514245152451624517245182451924520245212452224523245242452524526245272452824529245302453124532245332453424535245362453724538245392454024541245422454324544245452454624547245482454924550245512455224553245542455524556245572455824559245602456124562245632456424565245662456724568245692457024571245722457324574245752457624577245782457924580245812458224583245842458524586245872458824589245902459124592245932459424595245962459724598245992460024601246022460324604246052460624607246082460924610246112461224613246142461524616246172461824619246202462124622246232462424625246262462724628246292463024631246322463324634246352463624637246382463924640246412464224643246442464524646246472464824649246502465124652246532465424655246562465724658246592466024661246622466324664246652466624667246682466924670246712467224673246742467524676246772467824679246802468124682246832468424685246862468724688246892469024691246922469324694246952469624697246982469924700247012470224703247042470524706247072470824709247102471124712247132471424715247162471724718247192472024721247222472324724247252472624727247282472924730247312473224733247342473524736247372473824739247402474124742247432474424745247462474724748247492475024751247522475324754247552475624757247582475924760247612476224763247642476524766247672476824769247702477124772247732477424775247762477724778247792478024781247822478324784247852478624787247882478924790247912479224793247942479524796247972479824799248002480124802248032480424805248062480724808248092481024811248122481324814248152481624817248182481924820248212482224823248242482524826248272482824829248302483124832248332483424835248362483724838248392484024841248422484324844248452484624847248482484924850248512485224853248542485524856248572485824859248602486124862248632486424865248662486724868248692487024871248722487324874248752487624877248782487924880248812488224883248842488524886248872488824889248902489124892248932489424895248962489724898248992490024901249022490324904249052490624907249082490924910249112491224913249142491524916249172491824919249202492124922249232492424925249262492724928249292493024931249322493324934249352493624937249382493924940249412494224943249442494524946249472494824949249502495124952249532495424955249562495724958249592496024961249622496324964249652496624967249682496924970249712497224973249742497524976249772497824979249802498124982249832498424985249862498724988249892499024991249922499324994249952499624997249982499925000250012500225003250042500525006250072500825009250102501125012250132501425015250162501725018250192502025021250222502325024250252502625027250282502925030250312503225033250342503525036250372503825039250402504125042250432504425045250462504725048250492505025051250522505325054250552505625057250582505925060250612506225063250642506525066250672506825069250702507125072250732507425075250762507725078250792508025081250822508325084250852508625087250882508925090250912509225093250942509525096250972509825099251002510125102251032510425105251062510725108251092511025111251122511325114251152511625117251182511925120251212512225123251242512525126251272512825129251302513125132251332513425135251362513725138251392514025141251422514325144251452514625147251482514925150251512515225153251542515525156251572515825159251602516125162251632516425165251662516725168251692517025171251722517325174251752517625177251782517925180251812518225183251842518525186251872518825189251902519125192251932519425195251962519725198251992520025201252022520325204252052520625207252082520925210252112521225213252142521525216252172521825219252202522125222252232522425225252262522725228252292523025231252322523325234252352523625237252382523925240252412524225243252442524525246252472524825249252502525125252252532525425255252562525725258252592526025261252622526325264252652526625267252682526925270252712527225273252742527525276252772527825279252802528125282252832528425285252862528725288252892529025291252922529325294252952529625297252982529925300253012530225303253042530525306253072530825309253102531125312253132531425315253162531725318253192532025321253222532325324253252532625327253282532925330253312533225333253342533525336253372533825339253402534125342253432534425345253462534725348253492535025351253522535325354253552535625357253582535925360253612536225363253642536525366253672536825369253702537125372253732537425375253762537725378253792538025381253822538325384253852538625387253882538925390253912539225393253942539525396253972539825399254002540125402254032540425405254062540725408254092541025411254122541325414254152541625417254182541925420254212542225423254242542525426254272542825429254302543125432254332543425435254362543725438254392544025441254422544325444254452544625447254482544925450254512545225453254542545525456254572545825459254602546125462254632546425465254662546725468254692547025471254722547325474254752547625477254782547925480254812548225483254842548525486254872548825489254902549125492254932549425495254962549725498254992550025501255022550325504255052550625507255082550925510255112551225513255142551525516255172551825519255202552125522255232552425525255262552725528255292553025531255322553325534255352553625537255382553925540255412554225543255442554525546255472554825549255502555125552255532555425555255562555725558255592556025561255622556325564255652556625567255682556925570255712557225573255742557525576255772557825579255802558125582255832558425585255862558725588255892559025591255922559325594255952559625597255982559925600256012560225603256042560525606256072560825609256102561125612256132561425615256162561725618256192562025621256222562325624256252562625627256282562925630256312563225633256342563525636256372563825639256402564125642256432564425645256462564725648256492565025651256522565325654256552565625657256582565925660256612566225663256642566525666256672566825669256702567125672256732567425675256762567725678256792568025681256822568325684256852568625687256882568925690256912569225693256942569525696256972569825699257002570125702257032570425705257062570725708257092571025711257122571325714257152571625717257182571925720257212572225723257242572525726257272572825729257302573125732257332573425735257362573725738257392574025741257422574325744257452574625747257482574925750257512575225753257542575525756257572575825759257602576125762257632576425765257662576725768257692577025771257722577325774257752577625777257782577925780257812578225783257842578525786257872578825789257902579125792257932579425795257962579725798257992580025801258022580325804258052580625807258082580925810258112581225813258142581525816258172581825819258202582125822258232582425825258262582725828258292583025831258322583325834258352583625837258382583925840258412584225843258442584525846258472584825849258502585125852258532585425855258562585725858258592586025861258622586325864258652586625867258682586925870258712587225873258742587525876258772587825879258802588125882258832588425885258862588725888258892589025891258922589325894258952589625897258982589925900259012590225903259042590525906259072590825909259102591125912259132591425915259162591725918259192592025921259222592325924259252592625927259282592925930259312593225933259342593525936259372593825939259402594125942259432594425945259462594725948259492595025951259522595325954259552595625957259582595925960259612596225963259642596525966259672596825969259702597125972259732597425975259762597725978259792598025981259822598325984259852598625987259882598925990259912599225993259942599525996259972599825999260002600126002260032600426005260062600726008260092601026011260122601326014260152601626017260182601926020260212602226023260242602526026260272602826029260302603126032260332603426035260362603726038260392604026041260422604326044260452604626047260482604926050260512605226053260542605526056260572605826059260602606126062260632606426065260662606726068260692607026071260722607326074260752607626077260782607926080260812608226083260842608526086260872608826089260902609126092260932609426095260962609726098260992610026101261022610326104261052610626107261082610926110261112611226113261142611526116261172611826119261202612126122261232612426125261262612726128261292613026131261322613326134261352613626137261382613926140261412614226143261442614526146261472614826149261502615126152261532615426155261562615726158261592616026161261622616326164261652616626167261682616926170261712617226173261742617526176261772617826179261802618126182261832618426185261862618726188261892619026191261922619326194261952619626197261982619926200262012620226203262042620526206262072620826209262102621126212262132621426215262162621726218262192622026221262222622326224262252622626227262282622926230262312623226233262342623526236262372623826239262402624126242262432624426245262462624726248262492625026251262522625326254262552625626257262582625926260262612626226263262642626526266262672626826269262702627126272262732627426275262762627726278262792628026281262822628326284262852628626287262882628926290262912629226293262942629526296262972629826299263002630126302263032630426305263062630726308263092631026311263122631326314263152631626317263182631926320263212632226323263242632526326263272632826329263302633126332263332633426335263362633726338263392634026341263422634326344263452634626347263482634926350263512635226353263542635526356263572635826359263602636126362263632636426365263662636726368263692637026371263722637326374263752637626377263782637926380263812638226383263842638526386263872638826389263902639126392263932639426395263962639726398263992640026401264022640326404264052640626407264082640926410264112641226413264142641526416264172641826419264202642126422264232642426425264262642726428264292643026431264322643326434264352643626437264382643926440264412644226443264442644526446264472644826449264502645126452264532645426455264562645726458264592646026461264622646326464264652646626467264682646926470264712647226473264742647526476264772647826479264802648126482264832648426485264862648726488264892649026491264922649326494264952649626497264982649926500265012650226503265042650526506265072650826509265102651126512265132651426515265162651726518265192652026521265222652326524265252652626527265282652926530265312653226533265342653526536265372653826539265402654126542265432654426545265462654726548265492655026551265522655326554265552655626557265582655926560265612656226563265642656526566265672656826569265702657126572265732657426575265762657726578265792658026581265822658326584265852658626587265882658926590265912659226593265942659526596265972659826599266002660126602266032660426605266062660726608266092661026611266122661326614266152661626617266182661926620266212662226623266242662526626266272662826629266302663126632266332663426635266362663726638266392664026641266422664326644266452664626647266482664926650266512665226653266542665526656266572665826659266602666126662266632666426665266662666726668266692667026671266722667326674266752667626677266782667926680266812668226683266842668526686266872668826689266902669126692266932669426695266962669726698266992670026701267022670326704267052670626707267082670926710267112671226713267142671526716267172671826719267202672126722267232672426725267262672726728267292673026731267322673326734267352673626737267382673926740267412674226743267442674526746267472674826749267502675126752267532675426755267562675726758267592676026761267622676326764267652676626767267682676926770267712677226773267742677526776267772677826779267802678126782267832678426785267862678726788267892679026791267922679326794267952679626797267982679926800268012680226803268042680526806268072680826809268102681126812268132681426815268162681726818268192682026821268222682326824268252682626827268282682926830268312683226833268342683526836268372683826839268402684126842268432684426845268462684726848268492685026851268522685326854268552685626857268582685926860268612686226863268642686526866268672686826869268702687126872268732687426875268762687726878268792688026881268822688326884268852688626887268882688926890268912689226893268942689526896268972689826899269002690126902269032690426905269062690726908269092691026911269122691326914269152691626917269182691926920269212692226923269242692526926269272692826929269302693126932269332693426935269362693726938269392694026941269422694326944269452694626947269482694926950269512695226953269542695526956269572695826959269602696126962269632696426965269662696726968269692697026971269722697326974269752697626977269782697926980269812698226983269842698526986269872698826989269902699126992269932699426995269962699726998269992700027001270022700327004270052700627007270082700927010270112701227013270142701527016270172701827019270202702127022270232702427025270262702727028270292703027031270322703327034270352703627037270382703927040270412704227043270442704527046270472704827049270502705127052270532705427055270562705727058270592706027061270622706327064270652706627067270682706927070270712707227073270742707527076270772707827079270802708127082270832708427085270862708727088270892709027091270922709327094270952709627097270982709927100271012710227103271042710527106271072710827109271102711127112271132711427115271162711727118271192712027121271222712327124271252712627127271282712927130271312713227133271342713527136271372713827139271402714127142271432714427145271462714727148271492715027151271522715327154271552715627157271582715927160271612716227163271642716527166271672716827169271702717127172271732717427175271762717727178271792718027181271822718327184271852718627187271882718927190271912719227193271942719527196271972719827199272002720127202272032720427205272062720727208272092721027211272122721327214272152721627217272182721927220272212722227223272242722527226272272722827229272302723127232272332723427235272362723727238272392724027241272422724327244272452724627247272482724927250272512725227253272542725527256272572725827259272602726127262272632726427265272662726727268272692727027271272722727327274272752727627277272782727927280272812728227283272842728527286272872728827289272902729127292272932729427295272962729727298272992730027301273022730327304273052730627307273082730927310273112731227313273142731527316273172731827319273202732127322273232732427325273262732727328273292733027331273322733327334273352733627337273382733927340273412734227343273442734527346273472734827349273502735127352273532735427355273562735727358273592736027361273622736327364273652736627367273682736927370273712737227373273742737527376273772737827379273802738127382273832738427385273862738727388273892739027391273922739327394273952739627397273982739927400274012740227403274042740527406274072740827409274102741127412274132741427415274162741727418274192742027421274222742327424274252742627427274282742927430274312743227433274342743527436274372743827439274402744127442274432744427445274462744727448274492745027451274522745327454274552745627457274582745927460274612746227463274642746527466274672746827469274702747127472274732747427475274762747727478274792748027481274822748327484274852748627487274882748927490274912749227493274942749527496274972749827499275002750127502275032750427505275062750727508275092751027511275122751327514275152751627517275182751927520275212752227523275242752527526275272752827529275302753127532275332753427535275362753727538275392754027541275422754327544275452754627547275482754927550275512755227553275542755527556275572755827559275602756127562275632756427565275662756727568275692757027571275722757327574275752757627577275782757927580275812758227583275842758527586275872758827589275902759127592275932759427595275962759727598275992760027601276022760327604276052760627607276082760927610276112761227613276142761527616276172761827619276202762127622276232762427625276262762727628276292763027631276322763327634276352763627637276382763927640276412764227643276442764527646276472764827649276502765127652276532765427655276562765727658276592766027661276622766327664276652766627667276682766927670276712767227673276742767527676276772767827679276802768127682276832768427685276862768727688276892769027691276922769327694276952769627697276982769927700277012770227703277042770527706277072770827709277102771127712277132771427715277162771727718277192772027721277222772327724277252772627727277282772927730277312773227733277342773527736277372773827739277402774127742277432774427745277462774727748277492775027751277522775327754277552775627757277582775927760277612776227763277642776527766277672776827769277702777127772277732777427775277762777727778277792778027781277822778327784277852778627787277882778927790277912779227793277942779527796277972779827799278002780127802278032780427805278062780727808278092781027811278122781327814278152781627817278182781927820278212782227823278242782527826278272782827829278302783127832278332783427835278362783727838278392784027841278422784327844278452784627847278482784927850278512785227853278542785527856278572785827859278602786127862278632786427865278662786727868278692787027871278722787327874278752787627877278782787927880278812788227883278842788527886278872788827889278902789127892278932789427895278962789727898278992790027901279022790327904279052790627907279082790927910279112791227913279142791527916279172791827919279202792127922279232792427925279262792727928279292793027931279322793327934279352793627937279382793927940279412794227943279442794527946279472794827949279502795127952279532795427955279562795727958279592796027961279622796327964279652796627967279682796927970279712797227973279742797527976279772797827979279802798127982279832798427985279862798727988279892799027991279922799327994279952799627997279982799928000280012800228003280042800528006280072800828009280102801128012280132801428015280162801728018280192802028021280222802328024280252802628027280282802928030280312803228033280342803528036280372803828039280402804128042280432804428045280462804728048280492805028051280522805328054280552805628057280582805928060280612806228063280642806528066280672806828069280702807128072280732807428075280762807728078280792808028081280822808328084280852808628087280882808928090280912809228093280942809528096280972809828099281002810128102281032810428105281062810728108281092811028111281122811328114281152811628117281182811928120281212812228123281242812528126281272812828129281302813128132281332813428135281362813728138281392814028141281422814328144281452814628147281482814928150281512815228153281542815528156281572815828159281602816128162281632816428165281662816728168281692817028171281722817328174281752817628177281782817928180281812818228183281842818528186281872818828189281902819128192281932819428195281962819728198281992820028201282022820328204282052820628207282082820928210282112821228213282142821528216282172821828219282202822128222282232822428225282262822728228282292823028231282322823328234282352823628237282382823928240282412824228243282442824528246282472824828249282502825128252282532825428255282562825728258282592826028261282622826328264282652826628267282682826928270282712827228273282742827528276282772827828279282802828128282282832828428285282862828728288282892829028291282922829328294282952829628297282982829928300283012830228303283042830528306283072830828309283102831128312283132831428315283162831728318283192832028321283222832328324283252832628327283282832928330283312833228333283342833528336283372833828339283402834128342283432834428345283462834728348283492835028351283522835328354283552835628357283582835928360283612836228363283642836528366283672836828369283702837128372283732837428375283762837728378283792838028381283822838328384283852838628387283882838928390283912839228393283942839528396283972839828399284002840128402284032840428405284062840728408284092841028411284122841328414284152841628417284182841928420284212842228423284242842528426284272842828429284302843128432284332843428435284362843728438284392844028441284422844328444284452844628447284482844928450284512845228453284542845528456284572845828459284602846128462284632846428465284662846728468284692847028471284722847328474284752847628477284782847928480284812848228483284842848528486284872848828489284902849128492284932849428495284962849728498284992850028501285022850328504285052850628507285082850928510285112851228513285142851528516285172851828519285202852128522285232852428525285262852728528285292853028531285322853328534285352853628537285382853928540285412854228543285442854528546285472854828549285502855128552285532855428555285562855728558285592856028561285622856328564285652856628567285682856928570285712857228573285742857528576285772857828579285802858128582285832858428585285862858728588285892859028591285922859328594285952859628597285982859928600286012860228603286042860528606286072860828609286102861128612286132861428615286162861728618286192862028621286222862328624286252862628627286282862928630286312863228633286342863528636286372863828639286402864128642286432864428645286462864728648286492865028651286522865328654286552865628657286582865928660286612866228663286642866528666286672866828669286702867128672286732867428675286762867728678286792868028681286822868328684286852868628687286882868928690286912869228693286942869528696286972869828699287002870128702287032870428705287062870728708287092871028711287122871328714287152871628717287182871928720287212872228723287242872528726287272872828729287302873128732287332873428735287362873728738287392874028741287422874328744287452874628747287482874928750287512875228753287542875528756287572875828759287602876128762287632876428765287662876728768287692877028771287722877328774287752877628777287782877928780287812878228783287842878528786287872878828789287902879128792287932879428795287962879728798287992880028801288022880328804288052880628807288082880928810288112881228813288142881528816288172881828819288202882128822288232882428825288262882728828288292883028831288322883328834288352883628837288382883928840288412884228843288442884528846288472884828849288502885128852288532885428855288562885728858288592886028861288622886328864288652886628867288682886928870288712887228873288742887528876288772887828879288802888128882288832888428885288862888728888288892889028891288922889328894288952889628897288982889928900289012890228903289042890528906289072890828909289102891128912289132891428915289162891728918289192892028921289222892328924289252892628927289282892928930289312893228933289342893528936289372893828939289402894128942289432894428945289462894728948289492895028951289522895328954289552895628957289582895928960289612896228963289642896528966289672896828969289702897128972289732897428975289762897728978289792898028981289822898328984289852898628987289882898928990289912899228993289942899528996289972899828999290002900129002290032900429005290062900729008290092901029011290122901329014290152901629017290182901929020290212902229023290242902529026290272902829029290302903129032290332903429035290362903729038290392904029041290422904329044290452904629047290482904929050290512905229053290542905529056290572905829059290602906129062290632906429065290662906729068290692907029071290722907329074290752907629077290782907929080290812908229083290842908529086290872908829089290902909129092290932909429095290962909729098290992910029101291022910329104291052910629107291082910929110291112911229113291142911529116291172911829119291202912129122291232912429125291262912729128291292913029131291322913329134291352913629137291382913929140291412914229143291442914529146291472914829149291502915129152291532915429155291562915729158291592916029161291622916329164291652916629167291682916929170291712917229173291742917529176291772917829179291802918129182291832918429185291862918729188291892919029191291922919329194291952919629197291982919929200292012920229203292042920529206292072920829209292102921129212292132921429215292162921729218292192922029221292222922329224292252922629227292282922929230292312923229233292342923529236292372923829239292402924129242292432924429245292462924729248292492925029251292522925329254292552925629257292582925929260292612926229263292642926529266292672926829269292702927129272292732927429275292762927729278292792928029281292822928329284292852928629287292882928929290292912929229293292942929529296292972929829299293002930129302293032930429305293062930729308293092931029311293122931329314293152931629317293182931929320293212932229323293242932529326293272932829329293302933129332293332933429335293362933729338293392934029341293422934329344293452934629347293482934929350293512935229353293542935529356293572935829359293602936129362293632936429365293662936729368293692937029371293722937329374293752937629377293782937929380293812938229383293842938529386293872938829389293902939129392293932939429395293962939729398293992940029401294022940329404294052940629407294082940929410294112941229413294142941529416294172941829419294202942129422294232942429425294262942729428294292943029431294322943329434294352943629437294382943929440294412944229443294442944529446294472944829449294502945129452294532945429455294562945729458294592946029461294622946329464294652946629467294682946929470294712947229473294742947529476294772947829479294802948129482294832948429485294862948729488294892949029491294922949329494294952949629497294982949929500295012950229503295042950529506295072950829509295102951129512295132951429515295162951729518295192952029521295222952329524295252952629527295282952929530295312953229533295342953529536295372953829539295402954129542295432954429545295462954729548295492955029551295522955329554295552955629557295582955929560295612956229563295642956529566295672956829569295702957129572295732957429575295762957729578295792958029581295822958329584295852958629587295882958929590295912959229593295942959529596295972959829599296002960129602296032960429605296062960729608296092961029611296122961329614296152961629617296182961929620296212962229623296242962529626296272962829629296302963129632296332963429635296362963729638296392964029641296422964329644296452964629647296482964929650296512965229653296542965529656296572965829659296602966129662296632966429665296662966729668296692967029671296722967329674296752967629677296782967929680296812968229683296842968529686296872968829689296902969129692296932969429695296962969729698296992970029701297022970329704297052970629707297082970929710297112971229713297142971529716297172971829719297202972129722297232972429725297262972729728297292973029731297322973329734297352973629737297382973929740297412974229743297442974529746297472974829749297502975129752297532975429755297562975729758297592976029761297622976329764297652976629767297682976929770297712977229773297742977529776297772977829779297802978129782297832978429785297862978729788297892979029791297922979329794297952979629797297982979929800298012980229803298042980529806298072980829809298102981129812298132981429815298162981729818298192982029821298222982329824298252982629827298282982929830298312983229833298342983529836298372983829839298402984129842298432984429845298462984729848298492985029851298522985329854298552985629857298582985929860298612986229863298642986529866298672986829869298702987129872298732987429875298762987729878298792988029881298822988329884298852988629887298882988929890298912989229893298942989529896298972989829899299002990129902299032990429905299062990729908299092991029911299122991329914299152991629917299182991929920299212992229923299242992529926299272992829929299302993129932299332993429935299362993729938299392994029941299422994329944299452994629947299482994929950299512995229953299542995529956299572995829959299602996129962299632996429965299662996729968299692997029971299722997329974299752997629977299782997929980299812998229983299842998529986299872998829989299902999129992299932999429995299962999729998299993000030001300023000330004300053000630007300083000930010300113001230013300143001530016300173001830019300203002130022300233002430025300263002730028300293003030031300323003330034300353003630037300383003930040300413004230043300443004530046300473004830049300503005130052300533005430055300563005730058300593006030061300623006330064300653006630067300683006930070300713007230073300743007530076300773007830079300803008130082300833008430085300863008730088300893009030091300923009330094300953009630097300983009930100301013010230103301043010530106301073010830109301103011130112301133011430115301163011730118301193012030121301223012330124301253012630127301283012930130301313013230133301343013530136301373013830139301403014130142301433014430145301463014730148301493015030151301523015330154301553015630157301583015930160301613016230163301643016530166301673016830169301703017130172301733017430175301763017730178301793018030181301823018330184301853018630187301883018930190301913019230193301943019530196301973019830199302003020130202302033020430205302063020730208302093021030211302123021330214302153021630217302183021930220302213022230223302243022530226302273022830229302303023130232302333023430235302363023730238302393024030241302423024330244302453024630247302483024930250302513025230253302543025530256302573025830259302603026130262302633026430265302663026730268302693027030271302723027330274302753027630277302783027930280302813028230283302843028530286302873028830289302903029130292302933029430295302963029730298302993030030301303023030330304303053030630307303083030930310303113031230313303143031530316303173031830319303203032130322303233032430325303263032730328303293033030331303323033330334303353033630337303383033930340303413034230343303443034530346303473034830349303503035130352303533035430355303563035730358303593036030361303623036330364303653036630367303683036930370303713037230373303743037530376303773037830379303803038130382303833038430385303863038730388303893039030391303923039330394303953039630397303983039930400304013040230403304043040530406304073040830409304103041130412304133041430415304163041730418304193042030421304223042330424304253042630427304283042930430304313043230433304343043530436304373043830439304403044130442304433044430445304463044730448304493045030451304523045330454304553045630457304583045930460304613046230463304643046530466304673046830469304703047130472304733047430475304763047730478304793048030481304823048330484304853048630487304883048930490304913049230493304943049530496304973049830499305003050130502305033050430505305063050730508305093051030511305123051330514305153051630517305183051930520305213052230523305243052530526305273052830529305303053130532305333053430535305363053730538305393054030541305423054330544305453054630547305483054930550305513055230553305543055530556305573055830559305603056130562305633056430565305663056730568305693057030571305723057330574305753057630577305783057930580305813058230583305843058530586305873058830589305903059130592305933059430595305963059730598305993060030601306023060330604306053060630607306083060930610306113061230613306143061530616306173061830619306203062130622306233062430625306263062730628306293063030631306323063330634306353063630637306383063930640306413064230643306443064530646306473064830649306503065130652306533065430655306563065730658306593066030661306623066330664306653066630667306683066930670306713067230673306743067530676306773067830679306803068130682306833068430685306863068730688306893069030691306923069330694306953069630697306983069930700307013070230703307043070530706307073070830709307103071130712307133071430715307163071730718307193072030721307223072330724307253072630727307283072930730307313073230733307343073530736307373073830739307403074130742307433074430745307463074730748307493075030751307523075330754307553075630757307583075930760307613076230763307643076530766307673076830769307703077130772307733077430775307763077730778307793078030781307823078330784307853078630787307883078930790307913079230793307943079530796307973079830799308003080130802308033080430805308063080730808308093081030811308123081330814308153081630817308183081930820308213082230823308243082530826308273082830829308303083130832308333083430835308363083730838308393084030841308423084330844308453084630847308483084930850308513085230853308543085530856308573085830859308603086130862308633086430865308663086730868308693087030871308723087330874308753087630877308783087930880308813088230883308843088530886308873088830889308903089130892308933089430895308963089730898308993090030901309023090330904309053090630907309083090930910309113091230913309143091530916309173091830919309203092130922309233092430925309263092730928309293093030931309323093330934309353093630937309383093930940309413094230943309443094530946309473094830949309503095130952309533095430955309563095730958309593096030961309623096330964309653096630967309683096930970309713097230973309743097530976309773097830979309803098130982309833098430985309863098730988309893099030991309923099330994309953099630997309983099931000310013100231003310043100531006310073100831009310103101131012310133101431015310163101731018310193102031021310223102331024310253102631027310283102931030310313103231033310343103531036310373103831039310403104131042310433104431045310463104731048310493105031051310523105331054310553105631057310583105931060310613106231063310643106531066310673106831069310703107131072310733107431075310763107731078310793108031081310823108331084310853108631087310883108931090310913109231093310943109531096310973109831099311003110131102311033110431105311063110731108311093111031111311123111331114311153111631117311183111931120311213112231123311243112531126311273112831129311303113131132311333113431135311363113731138311393114031141311423114331144311453114631147311483114931150311513115231153311543115531156311573115831159311603116131162311633116431165311663116731168311693117031171311723117331174311753117631177311783117931180311813118231183311843118531186311873118831189311903119131192311933119431195311963119731198311993120031201312023120331204312053120631207312083120931210312113121231213312143121531216312173121831219312203122131222312233122431225312263122731228312293123031231312323123331234312353123631237312383123931240312413124231243312443124531246312473124831249312503125131252312533125431255312563125731258312593126031261312623126331264312653126631267312683126931270312713127231273312743127531276312773127831279312803128131282312833128431285312863128731288312893129031291312923129331294312953129631297312983129931300313013130231303313043130531306313073130831309313103131131312313133131431315313163131731318313193132031321313223132331324313253132631327313283132931330313313133231333313343133531336313373133831339313403134131342313433134431345313463134731348313493135031351313523135331354313553135631357313583135931360313613136231363313643136531366313673136831369313703137131372313733137431375313763137731378313793138031381313823138331384313853138631387313883138931390313913139231393313943139531396313973139831399314003140131402314033140431405314063140731408314093141031411314123141331414314153141631417314183141931420314213142231423314243142531426314273142831429314303143131432314333143431435314363143731438314393144031441314423144331444314453144631447314483144931450314513145231453314543145531456314573145831459314603146131462314633146431465314663146731468314693147031471314723147331474314753147631477314783147931480314813148231483314843148531486314873148831489314903149131492314933149431495314963149731498314993150031501315023150331504315053150631507315083150931510315113151231513315143151531516315173151831519315203152131522315233152431525315263152731528315293153031531315323153331534315353153631537315383153931540315413154231543315443154531546315473154831549315503155131552315533155431555315563155731558315593156031561315623156331564315653156631567315683156931570315713157231573315743157531576315773157831579315803158131582315833158431585315863158731588315893159031591315923159331594315953159631597315983159931600316013160231603316043160531606316073160831609316103161131612316133161431615316163161731618316193162031621316223162331624316253162631627316283162931630316313163231633316343163531636316373163831639316403164131642316433164431645316463164731648316493165031651316523165331654316553165631657316583165931660316613166231663316643166531666316673166831669316703167131672316733167431675316763167731678316793168031681316823168331684316853168631687316883168931690316913169231693316943169531696316973169831699317003170131702317033170431705317063170731708317093171031711317123171331714317153171631717317183171931720317213172231723317243172531726317273172831729317303173131732317333173431735317363173731738317393174031741317423174331744317453174631747317483174931750317513175231753317543175531756317573175831759317603176131762317633176431765317663176731768317693177031771317723177331774317753177631777317783177931780317813178231783317843178531786317873178831789317903179131792317933179431795317963179731798317993180031801318023180331804318053180631807318083180931810318113181231813318143181531816318173181831819318203182131822318233182431825318263182731828318293183031831318323183331834318353183631837318383183931840318413184231843318443184531846318473184831849318503185131852318533185431855318563185731858318593186031861318623186331864318653186631867318683186931870318713187231873318743187531876318773187831879318803188131882318833188431885318863188731888318893189031891318923189331894318953189631897318983189931900319013190231903319043190531906319073190831909319103191131912319133191431915319163191731918319193192031921319223192331924319253192631927319283192931930319313193231933319343193531936319373193831939319403194131942319433194431945319463194731948319493195031951319523195331954319553195631957319583195931960319613196231963319643196531966319673196831969319703197131972319733197431975319763197731978319793198031981319823198331984319853198631987319883198931990319913199231993319943199531996319973199831999320003200132002320033200432005320063200732008320093201032011320123201332014320153201632017320183201932020320213202232023320243202532026320273202832029320303203132032320333203432035320363203732038320393204032041320423204332044320453204632047320483204932050320513205232053320543205532056320573205832059320603206132062320633206432065320663206732068320693207032071320723207332074320753207632077320783207932080320813208232083320843208532086320873208832089320903209132092320933209432095320963209732098320993210032101321023210332104321053210632107321083210932110321113211232113321143211532116321173211832119321203212132122321233212432125321263212732128321293213032131321323213332134321353213632137321383213932140321413214232143321443214532146321473214832149321503215132152321533215432155321563215732158321593216032161321623216332164321653216632167321683216932170321713217232173321743217532176321773217832179321803218132182321833218432185321863218732188321893219032191321923219332194321953219632197321983219932200322013220232203322043220532206322073220832209322103221132212322133221432215322163221732218322193222032221322223222332224322253222632227322283222932230322313223232233322343223532236322373223832239322403224132242322433224432245322463224732248322493225032251322523225332254322553225632257322583225932260322613226232263322643226532266322673226832269322703227132272322733227432275322763227732278322793228032281322823228332284322853228632287322883228932290322913229232293322943229532296322973229832299323003230132302323033230432305323063230732308323093231032311323123231332314323153231632317323183231932320323213232232323323243232532326323273232832329323303233132332323333233432335323363233732338323393234032341323423234332344323453234632347323483234932350323513235232353323543235532356323573235832359323603236132362323633236432365323663236732368323693237032371323723237332374323753237632377323783237932380323813238232383323843238532386323873238832389323903239132392323933239432395323963239732398323993240032401324023240332404324053240632407324083240932410324113241232413324143241532416324173241832419324203242132422324233242432425324263242732428324293243032431324323243332434324353243632437324383243932440324413244232443324443244532446324473244832449324503245132452324533245432455324563245732458324593246032461324623246332464324653246632467324683246932470324713247232473324743247532476324773247832479324803248132482324833248432485324863248732488324893249032491324923249332494324953249632497324983249932500325013250232503325043250532506325073250832509325103251132512325133251432515325163251732518325193252032521325223252332524325253252632527325283252932530325313253232533325343253532536325373253832539325403254132542325433254432545325463254732548325493255032551325523255332554325553255632557325583255932560325613256232563325643256532566325673256832569325703257132572325733257432575325763257732578325793258032581325823258332584325853258632587325883258932590325913259232593325943259532596325973259832599326003260132602326033260432605326063260732608326093261032611326123261332614326153261632617326183261932620326213262232623326243262532626326273262832629326303263132632326333263432635326363263732638326393264032641326423264332644326453264632647326483264932650326513265232653326543265532656326573265832659326603266132662326633266432665326663266732668326693267032671326723267332674326753267632677326783267932680326813268232683326843268532686326873268832689326903269132692326933269432695326963269732698326993270032701327023270332704327053270632707327083270932710327113271232713327143271532716327173271832719327203272132722327233272432725327263272732728327293273032731327323273332734327353273632737327383273932740327413274232743327443274532746327473274832749327503275132752327533275432755327563275732758327593276032761327623276332764327653276632767327683276932770327713277232773327743277532776327773277832779327803278132782327833278432785327863278732788327893279032791327923279332794327953279632797327983279932800328013280232803328043280532806328073280832809328103281132812328133281432815328163281732818328193282032821328223282332824328253282632827328283282932830328313283232833328343283532836328373283832839328403284132842328433284432845328463284732848328493285032851328523285332854328553285632857328583285932860328613286232863328643286532866328673286832869328703287132872328733287432875328763287732878328793288032881328823288332884328853288632887328883288932890328913289232893328943289532896328973289832899329003290132902329033290432905329063290732908329093291032911329123291332914329153291632917329183291932920329213292232923329243292532926329273292832929329303293132932329333293432935329363293732938329393294032941329423294332944329453294632947329483294932950329513295232953329543295532956329573295832959329603296132962329633296432965329663296732968329693297032971329723297332974329753297632977329783297932980329813298232983329843298532986329873298832989329903299132992329933299432995329963299732998329993300033001330023300333004330053300633007330083300933010330113301233013330143301533016330173301833019330203302133022330233302433025330263302733028330293303033031330323303333034330353303633037330383303933040330413304233043330443304533046330473304833049330503305133052330533305433055330563305733058330593306033061330623306333064330653306633067330683306933070330713307233073330743307533076330773307833079330803308133082330833308433085330863308733088330893309033091330923309333094330953309633097330983309933100331013310233103331043310533106331073310833109331103311133112331133311433115331163311733118331193312033121331223312333124331253312633127331283312933130331313313233133331343313533136331373313833139331403314133142331433314433145331463314733148331493315033151331523315333154331553315633157331583315933160331613316233163331643316533166331673316833169331703317133172331733317433175331763317733178331793318033181331823318333184331853318633187331883318933190331913319233193331943319533196331973319833199332003320133202332033320433205332063320733208332093321033211332123321333214332153321633217332183321933220332213322233223332243322533226332273322833229332303323133232332333323433235332363323733238332393324033241332423324333244332453324633247332483324933250332513325233253332543325533256332573325833259332603326133262332633326433265332663326733268332693327033271332723327333274332753327633277332783327933280332813328233283332843328533286332873328833289332903329133292332933329433295332963329733298332993330033301333023330333304333053330633307333083330933310333113331233313333143331533316333173331833319333203332133322333233332433325333263332733328333293333033331333323333333334333353333633337333383333933340333413334233343333443334533346333473334833349333503335133352333533335433355333563335733358333593336033361333623336333364333653336633367333683336933370333713337233373333743337533376333773337833379333803338133382333833338433385333863338733388333893339033391333923339333394333953339633397333983339933400334013340233403334043340533406334073340833409334103341133412334133341433415334163341733418334193342033421334223342333424334253342633427334283342933430334313343233433334343343533436334373343833439334403344133442334433344433445334463344733448334493345033451334523345333454334553345633457334583345933460334613346233463334643346533466334673346833469334703347133472334733347433475334763347733478334793348033481334823348333484334853348633487334883348933490334913349233493334943349533496334973349833499335003350133502335033350433505335063350733508335093351033511335123351333514335153351633517335183351933520335213352233523335243352533526335273352833529335303353133532335333353433535335363353733538335393354033541335423354333544335453354633547335483354933550335513355233553335543355533556335573355833559335603356133562335633356433565335663356733568335693357033571335723357333574335753357633577335783357933580335813358233583335843358533586335873358833589335903359133592335933359433595335963359733598335993360033601336023360333604336053360633607336083360933610336113361233613336143361533616336173361833619336203362133622336233362433625336263362733628336293363033631336323363333634336353363633637336383363933640336413364233643336443364533646336473364833649336503365133652336533365433655336563365733658336593366033661336623366333664336653366633667336683366933670336713367233673336743367533676336773367833679336803368133682336833368433685336863368733688336893369033691336923369333694336953369633697336983369933700337013370233703337043370533706337073370833709337103371133712337133371433715337163371733718337193372033721337223372333724337253372633727337283372933730337313373233733337343373533736337373373833739337403374133742337433374433745337463374733748337493375033751337523375333754337553375633757337583375933760337613376233763337643376533766337673376833769337703377133772337733377433775337763377733778337793378033781337823378333784337853378633787337883378933790337913379233793337943379533796337973379833799338003380133802338033380433805338063380733808338093381033811338123381333814338153381633817338183381933820338213382233823338243382533826338273382833829338303383133832338333383433835338363383733838338393384033841338423384333844338453384633847338483384933850338513385233853338543385533856338573385833859338603386133862338633386433865338663386733868338693387033871338723387333874338753387633877338783387933880338813388233883338843388533886338873388833889338903389133892338933389433895338963389733898338993390033901339023390333904339053390633907339083390933910339113391233913339143391533916339173391833919339203392133922339233392433925339263392733928339293393033931339323393333934339353393633937339383393933940339413394233943339443394533946339473394833949339503395133952339533395433955339563395733958339593396033961339623396333964339653396633967339683396933970339713397233973339743397533976339773397833979339803398133982339833398433985339863398733988339893399033991339923399333994339953399633997339983399934000340013400234003340043400534006340073400834009340103401134012340133401434015340163401734018340193402034021340223402334024340253402634027340283402934030340313403234033340343403534036340373403834039340403404134042340433404434045340463404734048340493405034051340523405334054340553405634057340583405934060340613406234063340643406534066340673406834069340703407134072340733407434075340763407734078340793408034081340823408334084340853408634087340883408934090340913409234093340943409534096340973409834099341003410134102341033410434105341063410734108341093411034111341123411334114341153411634117341183411934120341213412234123341243412534126341273412834129341303413134132341333413434135341363413734138341393414034141341423414334144341453414634147341483414934150341513415234153341543415534156341573415834159341603416134162341633416434165341663416734168341693417034171341723417334174341753417634177341783417934180341813418234183341843418534186341873418834189341903419134192341933419434195341963419734198341993420034201342023420334204342053420634207342083420934210342113421234213342143421534216342173421834219342203422134222342233422434225342263422734228342293423034231342323423334234342353423634237342383423934240342413424234243342443424534246342473424834249342503425134252342533425434255342563425734258342593426034261342623426334264342653426634267342683426934270342713427234273342743427534276342773427834279342803428134282342833428434285342863428734288342893429034291342923429334294342953429634297342983429934300343013430234303343043430534306343073430834309343103431134312343133431434315343163431734318343193432034321343223432334324343253432634327343283432934330343313433234333343343433534336343373433834339343403434134342343433434434345343463434734348343493435034351343523435334354343553435634357343583435934360343613436234363343643436534366343673436834369343703437134372343733437434375343763437734378343793438034381343823438334384343853438634387343883438934390343913439234393343943439534396343973439834399344003440134402344033440434405344063440734408344093441034411344123441334414344153441634417344183441934420344213442234423344243442534426344273442834429344303443134432344333443434435344363443734438344393444034441344423444334444344453444634447344483444934450344513445234453344543445534456344573445834459344603446134462344633446434465344663446734468344693447034471344723447334474344753447634477344783447934480344813448234483344843448534486344873448834489344903449134492344933449434495344963449734498344993450034501345023450334504345053450634507345083450934510345113451234513345143451534516345173451834519345203452134522345233452434525345263452734528345293453034531345323453334534345353453634537345383453934540345413454234543345443454534546345473454834549345503455134552345533455434555345563455734558345593456034561345623456334564345653456634567345683456934570345713457234573345743457534576345773457834579345803458134582345833458434585345863458734588345893459034591345923459334594345953459634597345983459934600346013460234603346043460534606346073460834609346103461134612346133461434615346163461734618346193462034621346223462334624346253462634627346283462934630346313463234633346343463534636346373463834639346403464134642346433464434645346463464734648346493465034651346523465334654346553465634657346583465934660346613466234663346643466534666346673466834669346703467134672346733467434675346763467734678346793468034681346823468334684346853468634687346883468934690346913469234693346943469534696346973469834699347003470134702347033470434705347063470734708347093471034711347123471334714347153471634717347183471934720347213472234723347243472534726347273472834729347303473134732347333473434735347363473734738347393474034741347423474334744347453474634747347483474934750347513475234753347543475534756347573475834759347603476134762347633476434765347663476734768347693477034771347723477334774347753477634777347783477934780347813478234783347843478534786347873478834789347903479134792347933479434795347963479734798347993480034801348023480334804348053480634807348083480934810348113481234813348143481534816348173481834819348203482134822348233482434825348263482734828348293483034831348323483334834348353483634837348383483934840348413484234843348443484534846348473484834849348503485134852348533485434855348563485734858348593486034861348623486334864348653486634867348683486934870348713487234873348743487534876348773487834879348803488134882348833488434885348863488734888348893489034891348923489334894348953489634897348983489934900349013490234903349043490534906349073490834909349103491134912349133491434915349163491734918349193492034921349223492334924349253492634927349283492934930349313493234933349343493534936349373493834939349403494134942349433494434945349463494734948349493495034951349523495334954349553495634957349583495934960349613496234963349643496534966349673496834969349703497134972349733497434975349763497734978349793498034981349823498334984349853498634987349883498934990349913499234993349943499534996349973499834999350003500135002350033500435005350063500735008350093501035011350123501335014350153501635017350183501935020350213502235023350243502535026350273502835029350303503135032350333503435035350363503735038350393504035041350423504335044350453504635047350483504935050350513505235053350543505535056350573505835059350603506135062350633506435065350663506735068350693507035071350723507335074350753507635077350783507935080350813508235083350843508535086350873508835089350903509135092350933509435095350963509735098350993510035101351023510335104351053510635107351083510935110351113511235113351143511535116351173511835119351203512135122351233512435125351263512735128351293513035131351323513335134351353513635137351383513935140351413514235143351443514535146351473514835149351503515135152351533515435155351563515735158351593516035161351623516335164351653516635167351683516935170351713517235173351743517535176351773517835179351803518135182351833518435185351863518735188351893519035191351923519335194351953519635197351983519935200352013520235203352043520535206352073520835209352103521135212352133521435215352163521735218352193522035221352223522335224352253522635227352283522935230352313523235233352343523535236352373523835239352403524135242352433524435245352463524735248352493525035251352523525335254352553525635257352583525935260352613526235263352643526535266352673526835269352703527135272352733527435275352763527735278352793528035281352823528335284352853528635287352883528935290352913529235293352943529535296352973529835299353003530135302353033530435305353063530735308353093531035311353123531335314353153531635317353183531935320353213532235323353243532535326353273532835329353303533135332353333533435335353363533735338353393534035341353423534335344353453534635347353483534935350353513535235353353543535535356353573535835359353603536135362353633536435365353663536735368353693537035371353723537335374353753537635377353783537935380353813538235383353843538535386353873538835389353903539135392353933539435395353963539735398353993540035401354023540335404354053540635407354083540935410354113541235413354143541535416354173541835419354203542135422354233542435425354263542735428354293543035431354323543335434354353543635437354383543935440354413544235443354443544535446354473544835449354503545135452354533545435455354563545735458354593546035461354623546335464354653546635467354683546935470354713547235473354743547535476354773547835479354803548135482354833548435485354863548735488354893549035491354923549335494354953549635497354983549935500355013550235503355043550535506355073550835509355103551135512355133551435515355163551735518355193552035521355223552335524355253552635527355283552935530355313553235533355343553535536355373553835539355403554135542355433554435545355463554735548355493555035551355523555335554355553555635557355583555935560355613556235563355643556535566355673556835569355703557135572355733557435575355763557735578355793558035581355823558335584355853558635587355883558935590355913559235593355943559535596355973559835599356003560135602356033560435605356063560735608356093561035611356123561335614356153561635617356183561935620356213562235623356243562535626356273562835629356303563135632356333563435635356363563735638356393564035641356423564335644356453564635647356483564935650356513565235653356543565535656356573565835659356603566135662356633566435665356663566735668356693567035671356723567335674356753567635677356783567935680356813568235683356843568535686356873568835689356903569135692356933569435695356963569735698356993570035701357023570335704357053570635707357083570935710357113571235713357143571535716357173571835719357203572135722357233572435725357263572735728357293573035731357323573335734357353573635737357383573935740357413574235743357443574535746357473574835749357503575135752357533575435755357563575735758357593576035761357623576335764357653576635767357683576935770357713577235773357743577535776357773577835779357803578135782357833578435785357863578735788357893579035791357923579335794357953579635797357983579935800358013580235803358043580535806358073580835809358103581135812358133581435815358163581735818358193582035821358223582335824358253582635827358283582935830358313583235833358343583535836358373583835839358403584135842358433584435845358463584735848358493585035851358523585335854358553585635857358583585935860358613586235863358643586535866358673586835869358703587135872358733587435875358763587735878358793588035881358823588335884358853588635887358883588935890358913589235893358943589535896358973589835899359003590135902359033590435905359063590735908359093591035911359123591335914359153591635917359183591935920359213592235923359243592535926359273592835929359303593135932359333593435935359363593735938359393594035941359423594335944359453594635947359483594935950359513595235953359543595535956359573595835959359603596135962359633596435965359663596735968359693597035971359723597335974359753597635977359783597935980359813598235983359843598535986359873598835989359903599135992359933599435995359963599735998359993600036001360023600336004360053600636007360083600936010360113601236013360143601536016360173601836019360203602136022360233602436025360263602736028360293603036031360323603336034360353603636037360383603936040360413604236043360443604536046360473604836049360503605136052360533605436055360563605736058360593606036061360623606336064360653606636067360683606936070360713607236073360743607536076360773607836079360803608136082360833608436085360863608736088360893609036091360923609336094360953609636097360983609936100361013610236103361043610536106361073610836109361103611136112361133611436115361163611736118361193612036121361223612336124361253612636127361283612936130361313613236133361343613536136361373613836139361403614136142361433614436145361463614736148361493615036151361523615336154361553615636157361583615936160361613616236163361643616536166361673616836169361703617136172361733617436175361763617736178361793618036181361823618336184361853618636187361883618936190361913619236193361943619536196361973619836199362003620136202362033620436205362063620736208362093621036211362123621336214362153621636217362183621936220362213622236223362243622536226362273622836229362303623136232362333623436235362363623736238362393624036241362423624336244362453624636247362483624936250362513625236253362543625536256362573625836259362603626136262362633626436265362663626736268362693627036271362723627336274362753627636277362783627936280362813628236283362843628536286362873628836289362903629136292362933629436295362963629736298362993630036301363023630336304363053630636307363083630936310363113631236313363143631536316363173631836319363203632136322363233632436325363263632736328363293633036331363323633336334363353633636337363383633936340363413634236343363443634536346363473634836349363503635136352363533635436355363563635736358363593636036361363623636336364363653636636367363683636936370363713637236373363743637536376363773637836379363803638136382363833638436385363863638736388363893639036391363923639336394363953639636397363983639936400364013640236403364043640536406364073640836409364103641136412364133641436415364163641736418364193642036421364223642336424364253642636427364283642936430364313643236433364343643536436364373643836439364403644136442364433644436445364463644736448364493645036451364523645336454364553645636457364583645936460364613646236463364643646536466364673646836469364703647136472364733647436475364763647736478364793648036481364823648336484364853648636487364883648936490364913649236493364943649536496364973649836499365003650136502365033650436505365063650736508365093651036511365123651336514365153651636517365183651936520365213652236523365243652536526365273652836529365303653136532365333653436535365363653736538365393654036541365423654336544365453654636547365483654936550365513655236553365543655536556365573655836559365603656136562365633656436565365663656736568365693657036571365723657336574365753657636577365783657936580365813658236583365843658536586365873658836589365903659136592365933659436595365963659736598365993660036601366023660336604366053660636607366083660936610366113661236613366143661536616366173661836619366203662136622366233662436625366263662736628366293663036631366323663336634366353663636637366383663936640366413664236643366443664536646366473664836649366503665136652366533665436655366563665736658366593666036661366623666336664366653666636667366683666936670366713667236673366743667536676366773667836679366803668136682366833668436685366863668736688366893669036691366923669336694366953669636697366983669936700367013670236703367043670536706367073670836709367103671136712367133671436715367163671736718367193672036721367223672336724367253672636727367283672936730367313673236733367343673536736367373673836739367403674136742367433674436745367463674736748367493675036751367523675336754367553675636757367583675936760367613676236763367643676536766367673676836769367703677136772367733677436775367763677736778367793678036781367823678336784367853678636787367883678936790367913679236793367943679536796367973679836799368003680136802368033680436805368063680736808368093681036811368123681336814368153681636817368183681936820368213682236823368243682536826368273682836829368303683136832368333683436835368363683736838368393684036841368423684336844368453684636847368483684936850368513685236853368543685536856368573685836859368603686136862368633686436865368663686736868368693687036871368723687336874368753687636877368783687936880368813688236883368843688536886368873688836889368903689136892368933689436895368963689736898368993690036901369023690336904369053690636907369083690936910369113691236913369143691536916369173691836919369203692136922369233692436925369263692736928369293693036931369323693336934369353693636937369383693936940369413694236943369443694536946369473694836949369503695136952369533695436955369563695736958369593696036961369623696336964369653696636967369683696936970369713697236973369743697536976369773697836979369803698136982369833698436985369863698736988369893699036991369923699336994369953699636997369983699937000370013700237003370043700537006370073700837009370103701137012370133701437015370163701737018370193702037021370223702337024370253702637027370283702937030370313703237033370343703537036370373703837039370403704137042370433704437045370463704737048370493705037051370523705337054370553705637057370583705937060370613706237063370643706537066370673706837069370703707137072370733707437075370763707737078370793708037081370823708337084370853708637087370883708937090370913709237093370943709537096370973709837099371003710137102371033710437105371063710737108371093711037111371123711337114371153711637117371183711937120371213712237123371243712537126371273712837129371303713137132371333713437135371363713737138371393714037141371423714337144371453714637147371483714937150371513715237153371543715537156371573715837159371603716137162371633716437165371663716737168371693717037171371723717337174371753717637177371783717937180371813718237183371843718537186371873718837189371903719137192371933719437195371963719737198371993720037201372023720337204372053720637207372083720937210372113721237213372143721537216372173721837219372203722137222372233722437225372263722737228372293723037231372323723337234372353723637237372383723937240372413724237243372443724537246372473724837249372503725137252372533725437255372563725737258372593726037261372623726337264372653726637267372683726937270372713727237273372743727537276372773727837279372803728137282372833728437285372863728737288372893729037291372923729337294372953729637297372983729937300373013730237303373043730537306373073730837309373103731137312373133731437315373163731737318373193732037321373223732337324373253732637327373283732937330373313733237333373343733537336373373733837339373403734137342373433734437345373463734737348373493735037351373523735337354373553735637357373583735937360373613736237363373643736537366373673736837369373703737137372373733737437375373763737737378373793738037381373823738337384373853738637387373883738937390373913739237393373943739537396373973739837399374003740137402374033740437405374063740737408374093741037411374123741337414374153741637417374183741937420374213742237423374243742537426374273742837429374303743137432374333743437435374363743737438374393744037441374423744337444374453744637447374483744937450374513745237453374543745537456374573745837459374603746137462374633746437465374663746737468374693747037471374723747337474374753747637477374783747937480374813748237483374843748537486374873748837489374903749137492374933749437495374963749737498374993750037501375023750337504375053750637507375083750937510375113751237513375143751537516375173751837519375203752137522375233752437525375263752737528375293753037531375323753337534375353753637537375383753937540375413754237543375443754537546375473754837549375503755137552375533755437555375563755737558375593756037561375623756337564375653756637567375683756937570375713757237573375743757537576375773757837579375803758137582375833758437585375863758737588375893759037591375923759337594375953759637597375983759937600376013760237603376043760537606376073760837609376103761137612376133761437615376163761737618376193762037621376223762337624376253762637627376283762937630376313763237633376343763537636376373763837639376403764137642376433764437645376463764737648376493765037651376523765337654376553765637657376583765937660376613766237663376643766537666376673766837669376703767137672376733767437675376763767737678376793768037681376823768337684376853768637687376883768937690376913769237693376943769537696376973769837699377003770137702377033770437705377063770737708377093771037711377123771337714377153771637717377183771937720377213772237723377243772537726377273772837729377303773137732377333773437735377363773737738377393774037741377423774337744377453774637747377483774937750377513775237753377543775537756377573775837759377603776137762377633776437765377663776737768377693777037771377723777337774377753777637777377783777937780377813778237783377843778537786377873778837789377903779137792377933779437795377963779737798377993780037801378023780337804378053780637807378083780937810378113781237813378143781537816378173781837819378203782137822378233782437825378263782737828378293783037831378323783337834378353783637837378383783937840378413784237843378443784537846378473784837849378503785137852378533785437855378563785737858378593786037861378623786337864378653786637867378683786937870378713787237873378743787537876378773787837879378803788137882378833788437885378863788737888378893789037891378923789337894378953789637897378983789937900379013790237903379043790537906379073790837909379103791137912379133791437915379163791737918379193792037921379223792337924379253792637927379283792937930379313793237933379343793537936379373793837939379403794137942379433794437945379463794737948379493795037951379523795337954379553795637957379583795937960379613796237963379643796537966379673796837969379703797137972379733797437975379763797737978379793798037981379823798337984379853798637987379883798937990379913799237993379943799537996379973799837999380003800138002380033800438005380063800738008380093801038011380123801338014380153801638017380183801938020380213802238023380243802538026380273802838029380303803138032380333803438035380363803738038380393804038041380423804338044380453804638047380483804938050380513805238053380543805538056380573805838059380603806138062380633806438065380663806738068380693807038071380723807338074380753807638077380783807938080380813808238083380843808538086380873808838089380903809138092380933809438095380963809738098380993810038101381023810338104381053810638107381083810938110381113811238113381143811538116381173811838119381203812138122381233812438125381263812738128381293813038131381323813338134381353813638137381383813938140381413814238143381443814538146381473814838149381503815138152381533815438155381563815738158381593816038161381623816338164381653816638167381683816938170381713817238173381743817538176381773817838179381803818138182381833818438185381863818738188381893819038191381923819338194381953819638197381983819938200382013820238203382043820538206382073820838209382103821138212382133821438215382163821738218382193822038221382223822338224382253822638227382283822938230382313823238233382343823538236382373823838239382403824138242382433824438245382463824738248382493825038251382523825338254382553825638257382583825938260382613826238263382643826538266382673826838269382703827138272382733827438275382763827738278382793828038281382823828338284382853828638287382883828938290382913829238293382943829538296382973829838299383003830138302383033830438305383063830738308383093831038311383123831338314383153831638317383183831938320383213832238323383243832538326383273832838329383303833138332383333833438335383363833738338383393834038341383423834338344383453834638347383483834938350383513835238353383543835538356383573835838359383603836138362383633836438365383663836738368383693837038371383723837338374383753837638377383783837938380383813838238383383843838538386383873838838389383903839138392383933839438395383963839738398383993840038401384023840338404384053840638407384083840938410384113841238413384143841538416384173841838419384203842138422384233842438425384263842738428384293843038431384323843338434384353843638437384383843938440384413844238443384443844538446384473844838449384503845138452384533845438455384563845738458384593846038461384623846338464384653846638467384683846938470384713847238473384743847538476384773847838479384803848138482384833848438485384863848738488384893849038491384923849338494384953849638497384983849938500385013850238503385043850538506385073850838509385103851138512385133851438515385163851738518385193852038521385223852338524385253852638527385283852938530385313853238533385343853538536385373853838539385403854138542385433854438545385463854738548385493855038551385523855338554385553855638557385583855938560385613856238563385643856538566385673856838569385703857138572385733857438575385763857738578385793858038581385823858338584385853858638587385883858938590385913859238593385943859538596385973859838599386003860138602386033860438605386063860738608386093861038611386123861338614386153861638617386183861938620386213862238623386243862538626386273862838629386303863138632386333863438635386363863738638386393864038641386423864338644386453864638647386483864938650386513865238653386543865538656386573865838659386603866138662386633866438665386663866738668386693867038671386723867338674386753867638677386783867938680386813868238683386843868538686386873868838689386903869138692386933869438695386963869738698386993870038701387023870338704387053870638707387083870938710387113871238713387143871538716387173871838719387203872138722387233872438725387263872738728387293873038731387323873338734387353873638737387383873938740387413874238743387443874538746387473874838749387503875138752387533875438755387563875738758387593876038761387623876338764387653876638767387683876938770387713877238773387743877538776387773877838779387803878138782387833878438785387863878738788387893879038791387923879338794387953879638797387983879938800388013880238803388043880538806388073880838809388103881138812388133881438815388163881738818388193882038821388223882338824388253882638827388283882938830388313883238833388343883538836388373883838839388403884138842388433884438845388463884738848388493885038851388523885338854388553885638857388583885938860388613886238863388643886538866388673886838869388703887138872388733887438875388763887738878388793888038881388823888338884388853888638887388883888938890388913889238893388943889538896388973889838899389003890138902389033890438905389063890738908389093891038911389123891338914389153891638917389183891938920389213892238923389243892538926389273892838929389303893138932389333893438935389363893738938389393894038941389423894338944389453894638947389483894938950389513895238953389543895538956389573895838959389603896138962389633896438965389663896738968389693897038971389723897338974389753897638977389783897938980389813898238983389843898538986389873898838989389903899138992389933899438995389963899738998389993900039001390023900339004390053900639007390083900939010390113901239013390143901539016390173901839019390203902139022390233902439025390263902739028390293903039031390323903339034390353903639037390383903939040390413904239043390443904539046390473904839049390503905139052390533905439055390563905739058390593906039061390623906339064390653906639067390683906939070390713907239073390743907539076390773907839079390803908139082390833908439085390863908739088390893909039091390923909339094390953909639097390983909939100391013910239103391043910539106391073910839109391103911139112391133911439115391163911739118391193912039121391223912339124391253912639127391283912939130391313913239133391343913539136391373913839139391403914139142391433914439145391463914739148391493915039151391523915339154391553915639157391583915939160391613916239163391643916539166391673916839169391703917139172391733917439175391763917739178391793918039181391823918339184391853918639187391883918939190391913919239193391943919539196391973919839199392003920139202392033920439205392063920739208392093921039211392123921339214392153921639217392183921939220392213922239223392243922539226392273922839229392303923139232392333923439235392363923739238392393924039241392423924339244392453924639247392483924939250392513925239253392543925539256392573925839259392603926139262392633926439265392663926739268392693927039271392723927339274392753927639277392783927939280392813928239283392843928539286392873928839289392903929139292392933929439295392963929739298392993930039301393023930339304393053930639307393083930939310393113931239313393143931539316393173931839319393203932139322393233932439325393263932739328393293933039331393323933339334393353933639337393383933939340393413934239343393443934539346393473934839349393503935139352393533935439355393563935739358393593936039361393623936339364393653936639367393683936939370393713937239373393743937539376393773937839379393803938139382393833938439385393863938739388393893939039391393923939339394393953939639397393983939939400394013940239403394043940539406394073940839409394103941139412394133941439415394163941739418394193942039421394223942339424394253942639427394283942939430394313943239433394343943539436394373943839439394403944139442394433944439445394463944739448394493945039451394523945339454394553945639457394583945939460394613946239463394643946539466394673946839469394703947139472394733947439475394763947739478394793948039481394823948339484394853948639487394883948939490394913949239493394943949539496394973949839499395003950139502395033950439505395063950739508395093951039511395123951339514395153951639517395183951939520395213952239523395243952539526395273952839529395303953139532395333953439535395363953739538395393954039541395423954339544395453954639547395483954939550395513955239553395543955539556395573955839559395603956139562395633956439565395663956739568395693957039571395723957339574395753957639577395783957939580395813958239583395843958539586395873958839589395903959139592395933959439595395963959739598395993960039601396023960339604396053960639607396083960939610396113961239613396143961539616396173961839619396203962139622396233962439625396263962739628396293963039631396323963339634396353963639637396383963939640396413964239643396443964539646396473964839649396503965139652396533965439655396563965739658396593966039661396623966339664396653966639667396683966939670396713967239673396743967539676396773967839679396803968139682396833968439685396863968739688396893969039691396923969339694396953969639697396983969939700397013970239703397043970539706397073970839709397103971139712397133971439715397163971739718397193972039721397223972339724397253972639727397283972939730397313973239733397343973539736397373973839739397403974139742397433974439745397463974739748397493975039751397523975339754397553975639757397583975939760397613976239763397643976539766397673976839769397703977139772397733977439775397763977739778397793978039781397823978339784397853978639787397883978939790397913979239793397943979539796397973979839799398003980139802398033980439805398063980739808398093981039811398123981339814398153981639817398183981939820398213982239823398243982539826398273982839829398303983139832398333983439835398363983739838398393984039841398423984339844398453984639847398483984939850398513985239853398543985539856398573985839859398603986139862398633986439865398663986739868398693987039871398723987339874398753987639877398783987939880398813988239883398843988539886398873988839889398903989139892398933989439895398963989739898398993990039901399023990339904399053990639907399083990939910399113991239913399143991539916399173991839919399203992139922399233992439925399263992739928399293993039931399323993339934399353993639937399383993939940399413994239943399443994539946399473994839949399503995139952399533995439955399563995739958399593996039961399623996339964399653996639967399683996939970399713997239973399743997539976399773997839979399803998139982399833998439985399863998739988399893999039991399923999339994399953999639997399983999940000400014000240003400044000540006400074000840009400104001140012400134001440015400164001740018400194002040021400224002340024400254002640027400284002940030400314003240033400344003540036400374003840039400404004140042400434004440045400464004740048400494005040051400524005340054400554005640057400584005940060400614006240063400644006540066400674006840069400704007140072400734007440075400764007740078400794008040081400824008340084400854008640087400884008940090400914009240093400944009540096400974009840099401004010140102401034010440105401064010740108401094011040111401124011340114401154011640117401184011940120401214012240123401244012540126401274012840129401304013140132401334013440135401364013740138401394014040141401424014340144401454014640147401484014940150401514015240153401544015540156401574015840159401604016140162401634016440165401664016740168401694017040171401724017340174401754017640177401784017940180401814018240183401844018540186401874018840189401904019140192401934019440195401964019740198401994020040201402024020340204402054020640207402084020940210402114021240213402144021540216402174021840219402204022140222402234022440225402264022740228402294023040231402324023340234402354023640237402384023940240402414024240243402444024540246402474024840249402504025140252402534025440255402564025740258402594026040261402624026340264402654026640267402684026940270402714027240273402744027540276402774027840279402804028140282402834028440285402864028740288402894029040291402924029340294402954029640297402984029940300403014030240303403044030540306403074030840309403104031140312403134031440315403164031740318403194032040321403224032340324403254032640327403284032940330403314033240333403344033540336403374033840339403404034140342403434034440345403464034740348403494035040351403524035340354403554035640357403584035940360403614036240363403644036540366403674036840369403704037140372403734037440375403764037740378403794038040381403824038340384403854038640387403884038940390403914039240393403944039540396403974039840399404004040140402404034040440405404064040740408404094041040411404124041340414404154041640417404184041940420404214042240423404244042540426404274042840429404304043140432404334043440435404364043740438404394044040441404424044340444404454044640447404484044940450404514045240453404544045540456404574045840459404604046140462404634046440465404664046740468404694047040471404724047340474404754047640477404784047940480404814048240483404844048540486404874048840489404904049140492404934049440495404964049740498404994050040501405024050340504405054050640507405084050940510405114051240513405144051540516405174051840519405204052140522405234052440525405264052740528405294053040531405324053340534405354053640537405384053940540405414054240543405444054540546405474054840549405504055140552405534055440555405564055740558405594056040561405624056340564405654056640567405684056940570405714057240573405744057540576405774057840579405804058140582405834058440585405864058740588405894059040591405924059340594405954059640597405984059940600406014060240603406044060540606406074060840609406104061140612406134061440615406164061740618406194062040621406224062340624406254062640627406284062940630406314063240633406344063540636406374063840639406404064140642406434064440645406464064740648406494065040651406524065340654406554065640657406584065940660406614066240663406644066540666406674066840669406704067140672406734067440675406764067740678406794068040681406824068340684406854068640687406884068940690406914069240693406944069540696406974069840699407004070140702407034070440705407064070740708407094071040711407124071340714407154071640717407184071940720407214072240723407244072540726407274072840729407304073140732407334073440735407364073740738407394074040741407424074340744407454074640747407484074940750407514075240753407544075540756407574075840759407604076140762407634076440765407664076740768407694077040771407724077340774407754077640777407784077940780407814078240783407844078540786407874078840789407904079140792407934079440795407964079740798407994080040801408024080340804408054080640807408084080940810408114081240813408144081540816408174081840819408204082140822408234082440825408264082740828408294083040831408324083340834408354083640837408384083940840408414084240843408444084540846408474084840849408504085140852408534085440855408564085740858408594086040861408624086340864408654086640867408684086940870408714087240873408744087540876408774087840879408804088140882408834088440885408864088740888408894089040891408924089340894408954089640897408984089940900409014090240903409044090540906409074090840909409104091140912409134091440915409164091740918409194092040921409224092340924409254092640927409284092940930409314093240933409344093540936409374093840939409404094140942409434094440945409464094740948409494095040951409524095340954409554095640957409584095940960409614096240963409644096540966409674096840969409704097140972409734097440975409764097740978409794098040981409824098340984409854098640987409884098940990409914099240993409944099540996409974099840999410004100141002410034100441005410064100741008410094101041011410124101341014410154101641017410184101941020410214102241023410244102541026410274102841029410304103141032410334103441035410364103741038410394104041041410424104341044410454104641047410484104941050410514105241053410544105541056410574105841059410604106141062410634106441065410664106741068410694107041071410724107341074410754107641077410784107941080410814108241083410844108541086410874108841089410904109141092410934109441095410964109741098410994110041101411024110341104411054110641107411084110941110411114111241113411144111541116411174111841119411204112141122411234112441125411264112741128411294113041131411324113341134411354113641137411384113941140411414114241143411444114541146411474114841149411504115141152411534115441155411564115741158411594116041161411624116341164411654116641167411684116941170411714117241173411744117541176411774117841179411804118141182411834118441185411864118741188411894119041191411924119341194411954119641197411984119941200412014120241203412044120541206412074120841209412104121141212412134121441215412164121741218412194122041221412224122341224412254122641227412284122941230412314123241233412344123541236412374123841239412404124141242412434124441245412464124741248412494125041251412524125341254412554125641257412584125941260412614126241263412644126541266412674126841269412704127141272412734127441275412764127741278412794128041281412824128341284412854128641287412884128941290412914129241293412944129541296412974129841299413004130141302413034130441305413064130741308413094131041311413124131341314413154131641317413184131941320413214132241323413244132541326413274132841329413304133141332413334133441335413364133741338413394134041341413424134341344413454134641347413484134941350413514135241353413544135541356413574135841359413604136141362413634136441365413664136741368413694137041371413724137341374413754137641377413784137941380413814138241383413844138541386413874138841389413904139141392413934139441395413964139741398413994140041401414024140341404414054140641407414084140941410414114141241413414144141541416414174141841419414204142141422414234142441425414264142741428414294143041431414324143341434414354143641437414384143941440414414144241443414444144541446414474144841449414504145141452414534145441455414564145741458414594146041461414624146341464414654146641467414684146941470414714147241473414744147541476414774147841479414804148141482414834148441485414864148741488414894149041491414924149341494414954149641497414984149941500415014150241503415044150541506415074150841509415104151141512415134151441515415164151741518415194152041521415224152341524415254152641527415284152941530415314153241533415344153541536415374153841539415404154141542415434154441545415464154741548415494155041551415524155341554415554155641557415584155941560415614156241563415644156541566415674156841569415704157141572415734157441575415764157741578415794158041581415824158341584415854158641587415884158941590415914159241593415944159541596415974159841599416004160141602416034160441605416064160741608416094161041611416124161341614416154161641617416184161941620416214162241623416244162541626416274162841629416304163141632416334163441635416364163741638416394164041641416424164341644416454164641647416484164941650416514165241653416544165541656416574165841659416604166141662416634166441665416664166741668416694167041671416724167341674416754167641677416784167941680416814168241683416844168541686416874168841689416904169141692416934169441695416964169741698416994170041701417024170341704417054170641707417084170941710417114171241713417144171541716417174171841719417204172141722417234172441725417264172741728417294173041731417324173341734417354173641737417384173941740417414174241743417444174541746417474174841749417504175141752417534175441755417564175741758417594176041761417624176341764417654176641767417684176941770417714177241773417744177541776417774177841779417804178141782417834178441785417864178741788417894179041791417924179341794417954179641797417984179941800418014180241803418044180541806418074180841809418104181141812418134181441815418164181741818418194182041821418224182341824418254182641827418284182941830418314183241833418344183541836418374183841839418404184141842418434184441845418464184741848418494185041851418524185341854418554185641857418584185941860418614186241863418644186541866418674186841869418704187141872418734187441875418764187741878418794188041881418824188341884418854188641887418884188941890418914189241893418944189541896418974189841899419004190141902419034190441905419064190741908419094191041911419124191341914419154191641917419184191941920419214192241923419244192541926419274192841929419304193141932419334193441935419364193741938419394194041941419424194341944419454194641947419484194941950419514195241953419544195541956419574195841959419604196141962419634196441965419664196741968419694197041971419724197341974419754197641977419784197941980419814198241983419844198541986419874198841989419904199141992419934199441995419964199741998419994200042001420024200342004420054200642007420084200942010420114201242013420144201542016420174201842019420204202142022420234202442025420264202742028420294203042031420324203342034420354203642037420384203942040420414204242043420444204542046420474204842049420504205142052420534205442055420564205742058420594206042061420624206342064420654206642067420684206942070420714207242073420744207542076420774207842079420804208142082420834208442085420864208742088420894209042091420924209342094420954209642097420984209942100421014210242103421044210542106421074210842109421104211142112421134211442115421164211742118421194212042121421224212342124421254212642127421284212942130421314213242133421344213542136421374213842139421404214142142421434214442145421464214742148421494215042151421524215342154421554215642157421584215942160421614216242163421644216542166421674216842169421704217142172421734217442175421764217742178421794218042181421824218342184421854218642187421884218942190421914219242193421944219542196421974219842199422004220142202422034220442205422064220742208422094221042211422124221342214422154221642217422184221942220422214222242223422244222542226422274222842229422304223142232422334223442235422364223742238422394224042241422424224342244422454224642247422484224942250422514225242253422544225542256422574225842259422604226142262422634226442265422664226742268422694227042271422724227342274422754227642277422784227942280422814228242283422844228542286422874228842289422904229142292422934229442295422964229742298422994230042301423024230342304423054230642307423084230942310423114231242313423144231542316423174231842319423204232142322423234232442325423264232742328423294233042331423324233342334423354233642337423384233942340423414234242343423444234542346423474234842349423504235142352423534235442355423564235742358423594236042361423624236342364423654236642367423684236942370423714237242373423744237542376423774237842379423804238142382423834238442385423864238742388423894239042391423924239342394423954239642397423984239942400424014240242403424044240542406424074240842409424104241142412424134241442415424164241742418424194242042421424224242342424424254242642427424284242942430424314243242433424344243542436424374243842439424404244142442424434244442445424464244742448424494245042451424524245342454424554245642457424584245942460424614246242463424644246542466424674246842469424704247142472424734247442475424764247742478424794248042481424824248342484424854248642487424884248942490424914249242493424944249542496424974249842499425004250142502425034250442505425064250742508425094251042511425124251342514425154251642517425184251942520425214252242523425244252542526425274252842529425304253142532425334253442535425364253742538425394254042541425424254342544425454254642547425484254942550425514255242553425544255542556425574255842559425604256142562425634256442565425664256742568425694257042571425724257342574425754257642577425784257942580425814258242583425844258542586425874258842589425904259142592425934259442595425964259742598425994260042601426024260342604426054260642607426084260942610426114261242613426144261542616426174261842619426204262142622426234262442625426264262742628426294263042631426324263342634426354263642637426384263942640426414264242643426444264542646426474264842649426504265142652426534265442655426564265742658426594266042661426624266342664426654266642667426684266942670426714267242673426744267542676426774267842679426804268142682426834268442685426864268742688426894269042691426924269342694426954269642697426984269942700427014270242703427044270542706427074270842709427104271142712427134271442715427164271742718427194272042721427224272342724427254272642727427284272942730427314273242733427344273542736427374273842739427404274142742427434274442745427464274742748427494275042751427524275342754427554275642757427584275942760427614276242763427644276542766427674276842769427704277142772427734277442775427764277742778427794278042781427824278342784427854278642787427884278942790427914279242793427944279542796427974279842799428004280142802428034280442805428064280742808428094281042811428124281342814428154281642817428184281942820428214282242823428244282542826428274282842829428304283142832428334283442835428364283742838428394284042841428424284342844428454284642847428484284942850428514285242853428544285542856428574285842859428604286142862428634286442865428664286742868428694287042871428724287342874428754287642877428784287942880428814288242883428844288542886428874288842889428904289142892428934289442895428964289742898428994290042901429024290342904429054290642907429084290942910429114291242913429144291542916429174291842919429204292142922429234292442925429264292742928429294293042931429324293342934429354293642937429384293942940429414294242943429444294542946429474294842949429504295142952429534295442955429564295742958429594296042961429624296342964429654296642967429684296942970429714297242973429744297542976429774297842979429804298142982429834298442985429864298742988429894299042991429924299342994429954299642997429984299943000430014300243003430044300543006430074300843009430104301143012430134301443015430164301743018430194302043021430224302343024430254302643027430284302943030430314303243033430344303543036430374303843039430404304143042430434304443045430464304743048430494305043051430524305343054430554305643057430584305943060430614306243063430644306543066430674306843069430704307143072430734307443075430764307743078430794308043081430824308343084430854308643087430884308943090430914309243093430944309543096430974309843099431004310143102431034310443105431064310743108431094311043111431124311343114431154311643117431184311943120431214312243123431244312543126431274312843129431304313143132431334313443135431364313743138431394314043141431424314343144431454314643147431484314943150431514315243153431544315543156431574315843159431604316143162431634316443165431664316743168431694317043171431724317343174431754317643177431784317943180431814318243183431844318543186431874318843189431904319143192431934319443195431964319743198431994320043201432024320343204432054320643207432084320943210432114321243213432144321543216432174321843219432204322143222432234322443225432264322743228432294323043231432324323343234432354323643237432384323943240432414324243243432444324543246432474324843249432504325143252432534325443255432564325743258432594326043261432624326343264432654326643267432684326943270432714327243273432744327543276432774327843279432804328143282432834328443285432864328743288432894329043291432924329343294432954329643297432984329943300433014330243303433044330543306433074330843309433104331143312433134331443315433164331743318433194332043321433224332343324433254332643327433284332943330433314333243333433344333543336433374333843339433404334143342433434334443345433464334743348433494335043351433524335343354433554335643357433584335943360433614336243363433644336543366433674336843369433704337143372433734337443375433764337743378433794338043381433824338343384433854338643387433884338943390433914339243393433944339543396433974339843399434004340143402434034340443405434064340743408434094341043411434124341343414434154341643417434184341943420434214342243423434244342543426434274342843429434304343143432434334343443435434364343743438434394344043441434424344343444434454344643447434484344943450434514345243453434544345543456434574345843459434604346143462434634346443465434664346743468434694347043471434724347343474434754347643477434784347943480434814348243483434844348543486434874348843489434904349143492434934349443495434964349743498434994350043501435024350343504435054350643507435084350943510435114351243513435144351543516435174351843519435204352143522435234352443525435264352743528435294353043531435324353343534435354353643537435384353943540435414354243543435444354543546435474354843549435504355143552435534355443555435564355743558435594356043561435624356343564435654356643567435684356943570435714357243573435744357543576435774357843579435804358143582435834358443585435864358743588435894359043591435924359343594435954359643597435984359943600436014360243603436044360543606436074360843609436104361143612436134361443615436164361743618436194362043621436224362343624436254362643627436284362943630436314363243633436344363543636436374363843639436404364143642436434364443645436464364743648436494365043651436524365343654436554365643657436584365943660436614366243663436644366543666436674366843669436704367143672436734367443675436764367743678436794368043681436824368343684436854368643687436884368943690436914369243693436944369543696436974369843699437004370143702437034370443705437064370743708437094371043711437124371343714437154371643717437184371943720437214372243723437244372543726437274372843729437304373143732437334373443735437364373743738437394374043741437424374343744437454374643747437484374943750437514375243753437544375543756437574375843759437604376143762437634376443765437664376743768437694377043771437724377343774437754377643777437784377943780437814378243783437844378543786437874378843789437904379143792437934379443795437964379743798437994380043801438024380343804438054380643807438084380943810438114381243813438144381543816438174381843819438204382143822438234382443825438264382743828438294383043831438324383343834438354383643837438384383943840438414384243843438444384543846438474384843849438504385143852438534385443855438564385743858438594386043861438624386343864438654386643867438684386943870438714387243873438744387543876438774387843879438804388143882438834388443885438864388743888438894389043891438924389343894438954389643897438984389943900439014390243903439044390543906439074390843909439104391143912439134391443915439164391743918439194392043921439224392343924439254392643927439284392943930439314393243933439344393543936439374393843939439404394143942439434394443945439464394743948439494395043951439524395343954439554395643957439584395943960439614396243963439644396543966439674396843969439704397143972439734397443975439764397743978439794398043981439824398343984439854398643987439884398943990439914399243993439944399543996439974399843999440004400144002440034400444005440064400744008440094401044011440124401344014440154401644017440184401944020440214402244023440244402544026440274402844029440304403144032440334403444035440364403744038440394404044041440424404344044440454404644047440484404944050440514405244053440544405544056440574405844059440604406144062440634406444065440664406744068440694407044071440724407344074440754407644077440784407944080440814408244083440844408544086440874408844089440904409144092440934409444095440964409744098440994410044101441024410344104441054410644107441084410944110441114411244113441144411544116441174411844119441204412144122441234412444125441264412744128441294413044131441324413344134441354413644137441384413944140441414414244143441444414544146441474414844149441504415144152441534415444155441564415744158441594416044161441624416344164441654416644167441684416944170441714417244173441744417544176441774417844179441804418144182441834418444185441864418744188441894419044191441924419344194441954419644197441984419944200442014420244203442044420544206442074420844209442104421144212442134421444215442164421744218442194422044221442224422344224442254422644227442284422944230442314423244233442344423544236442374423844239442404424144242442434424444245442464424744248442494425044251442524425344254442554425644257442584425944260442614426244263442644426544266442674426844269442704427144272442734427444275442764427744278442794428044281442824428344284442854428644287442884428944290442914429244293442944429544296442974429844299443004430144302443034430444305443064430744308443094431044311443124431344314443154431644317443184431944320443214432244323443244432544326443274432844329443304433144332443334433444335443364433744338443394434044341443424434344344443454434644347443484434944350443514435244353443544435544356443574435844359443604436144362443634436444365443664436744368443694437044371443724437344374443754437644377443784437944380443814438244383443844438544386443874438844389443904439144392443934439444395443964439744398443994440044401444024440344404444054440644407444084440944410444114441244413444144441544416444174441844419444204442144422444234442444425444264442744428444294443044431444324443344434444354443644437444384443944440444414444244443444444444544446444474444844449444504445144452444534445444455444564445744458444594446044461444624446344464444654446644467444684446944470444714447244473444744447544476444774447844479444804448144482444834448444485444864448744488444894449044491444924449344494444954449644497444984449944500445014450244503445044450544506445074450844509445104451144512445134451444515445164451744518445194452044521445224452344524445254452644527445284452944530445314453244533445344453544536445374453844539445404454144542445434454444545445464454744548445494455044551445524455344554445554455644557445584455944560445614456244563445644456544566445674456844569445704457144572445734457444575445764457744578445794458044581445824458344584445854458644587445884458944590445914459244593445944459544596445974459844599446004460144602446034460444605446064460744608446094461044611446124461344614446154461644617446184461944620446214462244623446244462544626446274462844629446304463144632446334463444635446364463744638446394464044641446424464344644446454464644647446484464944650446514465244653446544465544656446574465844659446604466144662446634466444665446664466744668446694467044671446724467344674446754467644677446784467944680446814468244683446844468544686446874468844689446904469144692446934469444695446964469744698446994470044701447024470344704447054470644707447084470944710447114471244713447144471544716447174471844719447204472144722447234472444725447264472744728447294473044731447324473344734447354473644737447384473944740447414474244743447444474544746447474474844749447504475144752447534475444755447564475744758447594476044761447624476344764447654476644767447684476944770447714477244773447744477544776447774477844779447804478144782447834478444785447864478744788447894479044791447924479344794447954479644797447984479944800448014480244803448044480544806448074480844809448104481144812448134481444815448164481744818448194482044821448224482344824448254482644827448284482944830448314483244833448344483544836448374483844839448404484144842448434484444845448464484744848448494485044851448524485344854448554485644857448584485944860448614486244863448644486544866448674486844869448704487144872448734487444875448764487744878448794488044881448824488344884448854488644887448884488944890448914489244893448944489544896448974489844899449004490144902449034490444905449064490744908449094491044911449124491344914449154491644917449184491944920449214492244923449244492544926449274492844929449304493144932449334493444935449364493744938449394494044941449424494344944449454494644947449484494944950449514495244953449544495544956449574495844959449604496144962449634496444965449664496744968449694497044971449724497344974449754497644977449784497944980449814498244983449844498544986449874498844989449904499144992449934499444995449964499744998449994500045001450024500345004450054500645007450084500945010450114501245013450144501545016450174501845019450204502145022450234502445025450264502745028450294503045031450324503345034450354503645037450384503945040450414504245043450444504545046450474504845049450504505145052450534505445055450564505745058450594506045061450624506345064450654506645067450684506945070450714507245073450744507545076450774507845079450804508145082450834508445085450864508745088450894509045091450924509345094450954509645097450984509945100451014510245103451044510545106451074510845109451104511145112451134511445115451164511745118451194512045121451224512345124451254512645127451284512945130451314513245133451344513545136451374513845139451404514145142451434514445145451464514745148451494515045151451524515345154451554515645157451584515945160451614516245163451644516545166451674516845169451704517145172451734517445175451764517745178451794518045181451824518345184451854518645187451884518945190451914519245193451944519545196451974519845199452004520145202452034520445205452064520745208452094521045211452124521345214452154521645217452184521945220452214522245223452244522545226452274522845229452304523145232452334523445235452364523745238452394524045241452424524345244452454524645247452484524945250452514525245253452544525545256452574525845259452604526145262452634526445265452664526745268452694527045271452724527345274452754527645277452784527945280452814528245283452844528545286452874528845289452904529145292452934529445295452964529745298452994530045301453024530345304453054530645307453084530945310453114531245313453144531545316453174531845319453204532145322453234532445325453264532745328453294533045331453324533345334453354533645337453384533945340453414534245343453444534545346453474534845349453504535145352453534535445355453564535745358453594536045361453624536345364453654536645367453684536945370453714537245373453744537545376453774537845379453804538145382453834538445385453864538745388453894539045391453924539345394453954539645397453984539945400454014540245403454044540545406454074540845409454104541145412454134541445415454164541745418454194542045421454224542345424454254542645427454284542945430454314543245433454344543545436454374543845439454404544145442454434544445445454464544745448454494545045451454524545345454454554545645457454584545945460454614546245463454644546545466454674546845469454704547145472454734547445475454764547745478454794548045481454824548345484454854548645487454884548945490454914549245493454944549545496454974549845499455004550145502455034550445505455064550745508455094551045511455124551345514455154551645517455184551945520455214552245523455244552545526455274552845529455304553145532455334553445535455364553745538455394554045541455424554345544455454554645547455484554945550455514555245553455544555545556455574555845559455604556145562455634556445565455664556745568455694557045571455724557345574455754557645577455784557945580455814558245583455844558545586455874558845589455904559145592455934559445595455964559745598455994560045601456024560345604456054560645607456084560945610456114561245613456144561545616456174561845619456204562145622456234562445625456264562745628456294563045631456324563345634456354563645637456384563945640456414564245643456444564545646456474564845649456504565145652456534565445655456564565745658456594566045661456624566345664456654566645667456684566945670456714567245673456744567545676456774567845679456804568145682456834568445685456864568745688456894569045691456924569345694456954569645697456984569945700457014570245703457044570545706457074570845709457104571145712457134571445715457164571745718457194572045721457224572345724457254572645727457284572945730457314573245733457344573545736457374573845739457404574145742457434574445745457464574745748457494575045751457524575345754457554575645757457584575945760457614576245763457644576545766457674576845769457704577145772457734577445775457764577745778457794578045781457824578345784457854578645787457884578945790457914579245793457944579545796457974579845799458004580145802458034580445805458064580745808458094581045811458124581345814458154581645817458184581945820458214582245823458244582545826458274582845829458304583145832458334583445835458364583745838458394584045841458424584345844458454584645847458484584945850458514585245853458544585545856458574585845859458604586145862458634586445865458664586745868458694587045871458724587345874458754587645877458784587945880458814588245883458844588545886458874588845889458904589145892458934589445895458964589745898458994590045901459024590345904459054590645907459084590945910459114591245913459144591545916459174591845919459204592145922459234592445925459264592745928459294593045931459324593345934459354593645937459384593945940459414594245943459444594545946459474594845949459504595145952459534595445955459564595745958459594596045961459624596345964459654596645967459684596945970459714597245973459744597545976459774597845979459804598145982459834598445985459864598745988459894599045991459924599345994459954599645997459984599946000460014600246003460044600546006460074600846009460104601146012460134601446015460164601746018460194602046021460224602346024460254602646027460284602946030460314603246033460344603546036460374603846039460404604146042460434604446045460464604746048460494605046051460524605346054460554605646057460584605946060460614606246063460644606546066460674606846069460704607146072460734607446075460764607746078460794608046081460824608346084460854608646087460884608946090460914609246093460944609546096460974609846099461004610146102461034610446105461064610746108461094611046111461124611346114461154611646117461184611946120461214612246123461244612546126461274612846129461304613146132461334613446135461364613746138461394614046141461424614346144461454614646147461484614946150461514615246153461544615546156461574615846159461604616146162461634616446165461664616746168461694617046171461724617346174461754617646177461784617946180461814618246183461844618546186461874618846189461904619146192461934619446195461964619746198461994620046201462024620346204462054620646207462084620946210462114621246213462144621546216462174621846219462204622146222462234622446225462264622746228462294623046231462324623346234462354623646237462384623946240462414624246243462444624546246462474624846249462504625146252462534625446255462564625746258462594626046261462624626346264462654626646267462684626946270462714627246273462744627546276462774627846279462804628146282462834628446285462864628746288462894629046291462924629346294462954629646297462984629946300463014630246303463044630546306463074630846309463104631146312463134631446315463164631746318463194632046321463224632346324463254632646327463284632946330463314633246333463344633546336463374633846339463404634146342463434634446345463464634746348463494635046351463524635346354463554635646357463584635946360463614636246363463644636546366463674636846369463704637146372463734637446375463764637746378463794638046381463824638346384463854638646387463884638946390463914639246393463944639546396463974639846399464004640146402464034640446405464064640746408464094641046411464124641346414464154641646417464184641946420464214642246423464244642546426464274642846429464304643146432464334643446435464364643746438464394644046441464424644346444464454644646447464484644946450464514645246453464544645546456464574645846459464604646146462464634646446465464664646746468464694647046471464724647346474464754647646477464784647946480464814648246483464844648546486464874648846489464904649146492464934649446495464964649746498464994650046501465024650346504465054650646507465084650946510465114651246513465144651546516465174651846519465204652146522465234652446525465264652746528465294653046531465324653346534465354653646537465384653946540465414654246543465444654546546465474654846549465504655146552465534655446555465564655746558465594656046561465624656346564465654656646567465684656946570465714657246573465744657546576465774657846579465804658146582465834658446585465864658746588465894659046591465924659346594465954659646597465984659946600466014660246603466044660546606466074660846609466104661146612466134661446615466164661746618466194662046621466224662346624466254662646627466284662946630466314663246633466344663546636466374663846639466404664146642466434664446645466464664746648466494665046651466524665346654466554665646657466584665946660466614666246663466644666546666466674666846669466704667146672466734667446675466764667746678466794668046681466824668346684466854668646687466884668946690466914669246693466944669546696466974669846699467004670146702467034670446705467064670746708467094671046711467124671346714467154671646717467184671946720467214672246723467244672546726467274672846729467304673146732467334673446735467364673746738467394674046741467424674346744467454674646747467484674946750467514675246753467544675546756467574675846759467604676146762467634676446765467664676746768467694677046771467724677346774467754677646777467784677946780467814678246783467844678546786467874678846789467904679146792467934679446795467964679746798467994680046801468024680346804468054680646807468084680946810468114681246813468144681546816468174681846819468204682146822468234682446825468264682746828468294683046831468324683346834468354683646837468384683946840468414684246843468444684546846468474684846849468504685146852468534685446855468564685746858468594686046861468624686346864468654686646867468684686946870468714687246873468744687546876468774687846879468804688146882468834688446885468864688746888468894689046891468924689346894468954689646897468984689946900469014690246903469044690546906469074690846909469104691146912469134691446915469164691746918469194692046921469224692346924469254692646927469284692946930469314693246933469344693546936469374693846939469404694146942469434694446945469464694746948469494695046951469524695346954469554695646957469584695946960469614696246963469644696546966469674696846969469704697146972469734697446975469764697746978469794698046981469824698346984469854698646987469884698946990469914699246993469944699546996469974699846999470004700147002470034700447005470064700747008470094701047011470124701347014470154701647017470184701947020470214702247023470244702547026470274702847029470304703147032470334703447035470364703747038470394704047041470424704347044470454704647047470484704947050470514705247053470544705547056470574705847059470604706147062470634706447065470664706747068470694707047071470724707347074470754707647077470784707947080470814708247083470844708547086470874708847089470904709147092470934709447095470964709747098470994710047101471024710347104471054710647107471084710947110471114711247113471144711547116471174711847119471204712147122471234712447125471264712747128471294713047131471324713347134471354713647137471384713947140471414714247143471444714547146471474714847149471504715147152471534715447155471564715747158471594716047161471624716347164471654716647167471684716947170471714717247173471744717547176471774717847179471804718147182471834718447185471864718747188471894719047191471924719347194471954719647197471984719947200472014720247203472044720547206472074720847209472104721147212472134721447215472164721747218472194722047221472224722347224472254722647227472284722947230472314723247233472344723547236472374723847239472404724147242472434724447245472464724747248472494725047251472524725347254472554725647257472584725947260472614726247263472644726547266472674726847269472704727147272472734727447275472764727747278472794728047281472824728347284472854728647287472884728947290472914729247293472944729547296472974729847299473004730147302473034730447305473064730747308473094731047311473124731347314473154731647317473184731947320473214732247323473244732547326473274732847329473304733147332473334733447335473364733747338473394734047341473424734347344473454734647347473484734947350473514735247353473544735547356473574735847359473604736147362473634736447365473664736747368473694737047371473724737347374473754737647377473784737947380473814738247383473844738547386473874738847389473904739147392473934739447395473964739747398473994740047401474024740347404474054740647407474084740947410474114741247413474144741547416474174741847419474204742147422474234742447425474264742747428474294743047431474324743347434474354743647437474384743947440474414744247443474444744547446474474744847449474504745147452474534745447455474564745747458474594746047461474624746347464474654746647467474684746947470474714747247473474744747547476474774747847479474804748147482474834748447485474864748747488474894749047491474924749347494474954749647497474984749947500475014750247503475044750547506475074750847509475104751147512475134751447515475164751747518475194752047521475224752347524475254752647527475284752947530475314753247533475344753547536475374753847539475404754147542475434754447545475464754747548475494755047551475524755347554475554755647557475584755947560475614756247563475644756547566475674756847569475704757147572475734757447575475764757747578475794758047581475824758347584475854758647587475884758947590475914759247593475944759547596475974759847599476004760147602476034760447605476064760747608476094761047611476124761347614476154761647617476184761947620476214762247623476244762547626476274762847629476304763147632476334763447635476364763747638476394764047641476424764347644476454764647647476484764947650476514765247653476544765547656476574765847659476604766147662476634766447665476664766747668476694767047671476724767347674476754767647677476784767947680476814768247683476844768547686476874768847689476904769147692476934769447695476964769747698476994770047701477024770347704477054770647707477084770947710477114771247713477144771547716477174771847719477204772147722477234772447725477264772747728477294773047731477324773347734477354773647737477384773947740477414774247743477444774547746477474774847749477504775147752477534775447755477564775747758477594776047761477624776347764477654776647767477684776947770477714777247773477744777547776477774777847779477804778147782477834778447785477864778747788477894779047791477924779347794477954779647797477984779947800478014780247803478044780547806478074780847809478104781147812478134781447815478164781747818478194782047821478224782347824478254782647827478284782947830478314783247833478344783547836478374783847839478404784147842478434784447845478464784747848478494785047851478524785347854478554785647857478584785947860478614786247863478644786547866478674786847869478704787147872478734787447875478764787747878478794788047881478824788347884478854788647887478884788947890478914789247893478944789547896478974789847899479004790147902479034790447905479064790747908479094791047911479124791347914479154791647917479184791947920479214792247923479244792547926479274792847929479304793147932479334793447935479364793747938479394794047941479424794347944479454794647947479484794947950479514795247953479544795547956479574795847959479604796147962479634796447965479664796747968479694797047971479724797347974479754797647977479784797947980479814798247983479844798547986479874798847989479904799147992479934799447995479964799747998479994800048001480024800348004480054800648007480084800948010480114801248013480144801548016480174801848019480204802148022480234802448025480264802748028480294803048031480324803348034480354803648037480384803948040480414804248043480444804548046480474804848049480504805148052480534805448055480564805748058480594806048061480624806348064480654806648067480684806948070480714807248073480744807548076480774807848079480804808148082480834808448085480864808748088480894809048091480924809348094480954809648097480984809948100481014810248103481044810548106481074810848109481104811148112481134811448115481164811748118481194812048121481224812348124481254812648127481284812948130481314813248133481344813548136481374813848139481404814148142481434814448145481464814748148481494815048151481524815348154481554815648157481584815948160481614816248163481644816548166481674816848169481704817148172481734817448175481764817748178481794818048181481824818348184481854818648187481884818948190481914819248193481944819548196481974819848199482004820148202482034820448205482064820748208482094821048211482124821348214482154821648217482184821948220482214822248223482244822548226482274822848229482304823148232482334823448235482364823748238482394824048241482424824348244482454824648247482484824948250482514825248253482544825548256482574825848259482604826148262482634826448265482664826748268482694827048271482724827348274482754827648277482784827948280482814828248283482844828548286482874828848289482904829148292482934829448295482964829748298482994830048301483024830348304483054830648307483084830948310483114831248313483144831548316483174831848319483204832148322483234832448325483264832748328483294833048331483324833348334483354833648337483384833948340483414834248343483444834548346483474834848349483504835148352483534835448355483564835748358483594836048361483624836348364483654836648367483684836948370483714837248373483744837548376483774837848379483804838148382483834838448385483864838748388483894839048391483924839348394483954839648397483984839948400484014840248403484044840548406484074840848409484104841148412484134841448415484164841748418484194842048421484224842348424484254842648427484284842948430484314843248433484344843548436484374843848439484404844148442484434844448445484464844748448484494845048451484524845348454484554845648457484584845948460484614846248463484644846548466484674846848469484704847148472484734847448475484764847748478484794848048481484824848348484484854848648487484884848948490484914849248493484944849548496484974849848499485004850148502485034850448505485064850748508485094851048511485124851348514485154851648517485184851948520485214852248523485244852548526485274852848529485304853148532485334853448535485364853748538485394854048541485424854348544485454854648547485484854948550485514855248553485544855548556485574855848559485604856148562485634856448565485664856748568485694857048571485724857348574485754857648577485784857948580485814858248583485844858548586485874858848589485904859148592485934859448595485964859748598485994860048601486024860348604486054860648607486084860948610486114861248613486144861548616486174861848619486204862148622486234862448625486264862748628486294863048631486324863348634486354863648637486384863948640486414864248643486444864548646486474864848649486504865148652486534865448655486564865748658486594866048661486624866348664486654866648667486684866948670486714867248673486744867548676486774867848679486804868148682486834868448685486864868748688486894869048691486924869348694486954869648697486984869948700487014870248703487044870548706487074870848709487104871148712487134871448715487164871748718487194872048721487224872348724487254872648727487284872948730487314873248733487344873548736487374873848739487404874148742487434874448745487464874748748487494875048751487524875348754487554875648757487584875948760487614876248763487644876548766487674876848769487704877148772487734877448775487764877748778487794878048781487824878348784487854878648787487884878948790487914879248793487944879548796487974879848799488004880148802488034880448805488064880748808488094881048811488124881348814488154881648817488184881948820488214882248823488244882548826488274882848829488304883148832488334883448835488364883748838488394884048841488424884348844488454884648847488484884948850488514885248853488544885548856488574885848859488604886148862488634886448865488664886748868488694887048871488724887348874488754887648877488784887948880488814888248883488844888548886488874888848889488904889148892488934889448895488964889748898488994890048901489024890348904489054890648907489084890948910489114891248913489144891548916489174891848919489204892148922489234892448925489264892748928489294893048931489324893348934489354893648937489384893948940489414894248943489444894548946489474894848949489504895148952489534895448955489564895748958489594896048961489624896348964489654896648967489684896948970489714897248973489744897548976489774897848979489804898148982489834898448985489864898748988489894899048991489924899348994489954899648997489984899949000490014900249003490044900549006490074900849009490104901149012490134901449015490164901749018490194902049021490224902349024490254902649027490284902949030490314903249033490344903549036490374903849039490404904149042490434904449045490464904749048490494905049051490524905349054490554905649057490584905949060490614906249063490644906549066490674906849069490704907149072490734907449075490764907749078490794908049081490824908349084490854908649087490884908949090490914909249093490944909549096490974909849099491004910149102491034910449105491064910749108491094911049111491124911349114491154911649117491184911949120491214912249123491244912549126491274912849129491304913149132491334913449135491364913749138491394914049141491424914349144491454914649147491484914949150491514915249153491544915549156491574915849159491604916149162491634916449165491664916749168491694917049171491724917349174491754917649177491784917949180491814918249183491844918549186491874918849189491904919149192491934919449195491964919749198491994920049201492024920349204492054920649207492084920949210492114921249213492144921549216492174921849219492204922149222492234922449225492264922749228492294923049231492324923349234492354923649237492384923949240492414924249243492444924549246492474924849249492504925149252492534925449255492564925749258492594926049261492624926349264492654926649267492684926949270492714927249273492744927549276492774927849279492804928149282492834928449285492864928749288492894929049291492924929349294492954929649297492984929949300493014930249303493044930549306493074930849309493104931149312493134931449315493164931749318493194932049321493224932349324493254932649327493284932949330493314933249333493344933549336493374933849339493404934149342493434934449345493464934749348493494935049351493524935349354493554935649357493584935949360493614936249363493644936549366493674936849369493704937149372493734937449375493764937749378493794938049381493824938349384493854938649387493884938949390493914939249393493944939549396493974939849399494004940149402494034940449405494064940749408494094941049411494124941349414494154941649417494184941949420494214942249423494244942549426494274942849429494304943149432494334943449435494364943749438494394944049441494424944349444494454944649447494484944949450494514945249453494544945549456494574945849459494604946149462494634946449465494664946749468494694947049471494724947349474494754947649477494784947949480494814948249483494844948549486494874948849489494904949149492494934949449495494964949749498494994950049501495024950349504495054950649507495084950949510495114951249513495144951549516495174951849519495204952149522495234952449525495264952749528495294953049531495324953349534495354953649537495384953949540495414954249543495444954549546495474954849549495504955149552495534955449555495564955749558495594956049561495624956349564495654956649567495684956949570495714957249573495744957549576495774957849579495804958149582495834958449585495864958749588495894959049591495924959349594495954959649597495984959949600496014960249603496044960549606496074960849609496104961149612496134961449615496164961749618496194962049621496224962349624496254962649627496284962949630496314963249633496344963549636496374963849639496404964149642496434964449645496464964749648496494965049651496524965349654496554965649657496584965949660496614966249663496644966549666496674966849669496704967149672496734967449675496764967749678496794968049681496824968349684496854968649687496884968949690496914969249693496944969549696496974969849699497004970149702497034970449705497064970749708497094971049711497124971349714497154971649717497184971949720497214972249723497244972549726497274972849729497304973149732497334973449735497364973749738497394974049741497424974349744497454974649747497484974949750497514975249753497544975549756497574975849759497604976149762497634976449765497664976749768497694977049771497724977349774497754977649777497784977949780497814978249783497844978549786497874978849789497904979149792497934979449795497964979749798497994980049801498024980349804498054980649807498084980949810498114981249813498144981549816498174981849819498204982149822498234982449825498264982749828498294983049831498324983349834498354983649837498384983949840498414984249843498444984549846498474984849849498504985149852498534985449855498564985749858498594986049861498624986349864498654986649867498684986949870498714987249873498744987549876498774987849879498804988149882498834988449885498864988749888498894989049891498924989349894498954989649897498984989949900499014990249903499044990549906499074990849909499104991149912499134991449915499164991749918499194992049921499224992349924499254992649927499284992949930499314993249933499344993549936499374993849939499404994149942499434994449945499464994749948499494995049951499524995349954499554995649957499584995949960499614996249963499644996549966499674996849969499704997149972499734997449975499764997749978499794998049981499824998349984499854998649987499884998949990499914999249993499944999549996499974999849999500005000150002500035000450005500065000750008500095001050011500125001350014500155001650017500185001950020500215002250023500245002550026500275002850029500305003150032500335003450035500365003750038500395004050041500425004350044500455004650047500485004950050500515005250053500545005550056500575005850059500605006150062500635006450065500665006750068500695007050071500725007350074500755007650077500785007950080500815008250083500845008550086500875008850089500905009150092500935009450095500965009750098500995010050101501025010350104501055010650107501085010950110501115011250113501145011550116501175011850119501205012150122501235012450125501265012750128501295013050131501325013350134501355013650137501385013950140501415014250143501445014550146501475014850149501505015150152501535015450155501565015750158501595016050161501625016350164501655016650167501685016950170501715017250173501745017550176501775017850179501805018150182501835018450185501865018750188501895019050191501925019350194501955019650197501985019950200502015020250203502045020550206502075020850209502105021150212502135021450215502165021750218502195022050221502225022350224502255022650227502285022950230502315023250233502345023550236502375023850239502405024150242502435024450245502465024750248502495025050251502525025350254502555025650257502585025950260502615026250263502645026550266502675026850269502705027150272502735027450275502765027750278502795028050281502825028350284502855028650287502885028950290502915029250293502945029550296502975029850299503005030150302503035030450305503065030750308503095031050311503125031350314503155031650317503185031950320503215032250323503245032550326503275032850329503305033150332503335033450335503365033750338503395034050341503425034350344503455034650347503485034950350503515035250353503545035550356503575035850359503605036150362503635036450365503665036750368503695037050371503725037350374503755037650377503785037950380503815038250383503845038550386503875038850389503905039150392503935039450395503965039750398503995040050401504025040350404504055040650407504085040950410504115041250413504145041550416504175041850419504205042150422504235042450425504265042750428504295043050431504325043350434504355043650437504385043950440504415044250443504445044550446504475044850449504505045150452504535045450455504565045750458504595046050461504625046350464504655046650467504685046950470504715047250473504745047550476504775047850479504805048150482504835048450485504865048750488504895049050491504925049350494504955049650497504985049950500505015050250503505045050550506505075050850509505105051150512505135051450515505165051750518505195052050521505225052350524505255052650527505285052950530505315053250533505345053550536505375053850539505405054150542505435054450545505465054750548505495055050551505525055350554505555055650557505585055950560505615056250563505645056550566505675056850569505705057150572505735057450575505765057750578505795058050581505825058350584505855058650587505885058950590505915059250593505945059550596505975059850599506005060150602506035060450605506065060750608506095061050611506125061350614506155061650617506185061950620506215062250623506245062550626506275062850629506305063150632506335063450635506365063750638506395064050641506425064350644506455064650647506485064950650506515065250653506545065550656506575065850659506605066150662506635066450665506665066750668506695067050671506725067350674506755067650677506785067950680506815068250683506845068550686506875068850689506905069150692506935069450695506965069750698506995070050701507025070350704507055070650707507085070950710507115071250713507145071550716507175071850719507205072150722507235072450725507265072750728507295073050731507325073350734507355073650737507385073950740507415074250743507445074550746507475074850749507505075150752507535075450755507565075750758507595076050761507625076350764507655076650767507685076950770507715077250773507745077550776507775077850779507805078150782507835078450785507865078750788507895079050791507925079350794507955079650797507985079950800508015080250803508045080550806508075080850809508105081150812508135081450815508165081750818508195082050821508225082350824508255082650827508285082950830508315083250833508345083550836508375083850839508405084150842508435084450845508465084750848508495085050851508525085350854508555085650857508585085950860508615086250863508645086550866508675086850869508705087150872508735087450875508765087750878508795088050881508825088350884508855088650887508885088950890508915089250893508945089550896508975089850899509005090150902509035090450905509065090750908509095091050911509125091350914509155091650917509185091950920509215092250923509245092550926509275092850929509305093150932509335093450935509365093750938509395094050941509425094350944509455094650947509485094950950509515095250953509545095550956509575095850959509605096150962509635096450965509665096750968509695097050971509725097350974509755097650977509785097950980509815098250983509845098550986509875098850989509905099150992509935099450995509965099750998509995100051001510025100351004510055100651007510085100951010510115101251013510145101551016510175101851019510205102151022510235102451025510265102751028510295103051031510325103351034510355103651037510385103951040510415104251043510445104551046510475104851049510505105151052510535105451055510565105751058510595106051061510625106351064510655106651067510685106951070510715107251073510745107551076510775107851079510805108151082510835108451085510865108751088510895109051091510925109351094510955109651097510985109951100511015110251103511045110551106511075110851109511105111151112511135111451115511165111751118511195112051121511225112351124511255112651127511285112951130511315113251133511345113551136511375113851139511405114151142511435114451145511465114751148511495115051151511525115351154511555115651157511585115951160511615116251163511645116551166511675116851169511705117151172511735117451175511765117751178511795118051181511825118351184511855118651187511885118951190511915119251193511945119551196511975119851199512005120151202512035120451205512065120751208512095121051211512125121351214512155121651217512185121951220512215122251223512245122551226512275122851229512305123151232512335123451235512365123751238512395124051241512425124351244512455124651247512485124951250512515125251253512545125551256512575125851259512605126151262512635126451265512665126751268512695127051271512725127351274512755127651277512785127951280512815128251283512845128551286512875128851289512905129151292512935129451295512965129751298512995130051301513025130351304513055130651307513085130951310513115131251313513145131551316513175131851319513205132151322513235132451325513265132751328513295133051331513325133351334513355133651337513385133951340513415134251343513445134551346513475134851349513505135151352513535135451355513565135751358513595136051361513625136351364513655136651367513685136951370513715137251373513745137551376513775137851379513805138151382513835138451385513865138751388513895139051391513925139351394513955139651397513985139951400514015140251403514045140551406514075140851409514105141151412514135141451415514165141751418514195142051421514225142351424514255142651427514285142951430514315143251433514345143551436514375143851439514405144151442514435144451445514465144751448514495145051451514525145351454514555145651457514585145951460514615146251463514645146551466514675146851469514705147151472514735147451475514765147751478514795148051481514825148351484514855148651487514885148951490514915149251493514945149551496514975149851499515005150151502515035150451505515065150751508515095151051511515125151351514515155151651517515185151951520515215152251523515245152551526515275152851529515305153151532515335153451535515365153751538515395154051541515425154351544515455154651547515485154951550515515155251553515545155551556515575155851559515605156151562515635156451565515665156751568515695157051571515725157351574515755157651577515785157951580515815158251583515845158551586515875158851589515905159151592515935159451595515965159751598515995160051601516025160351604516055160651607516085160951610516115161251613516145161551616516175161851619516205162151622516235162451625516265162751628516295163051631516325163351634516355163651637516385163951640516415164251643516445164551646516475164851649516505165151652516535165451655516565165751658516595166051661516625166351664516655166651667516685166951670516715167251673516745167551676516775167851679516805168151682516835168451685516865168751688516895169051691516925169351694516955169651697516985169951700517015170251703517045170551706517075170851709517105171151712517135171451715517165171751718517195172051721517225172351724517255172651727517285172951730517315173251733517345173551736517375173851739517405174151742517435174451745517465174751748517495175051751517525175351754517555175651757517585175951760517615176251763517645176551766517675176851769517705177151772517735177451775517765177751778517795178051781517825178351784517855178651787517885178951790517915179251793517945179551796517975179851799518005180151802518035180451805518065180751808518095181051811518125181351814518155181651817518185181951820518215182251823518245182551826518275182851829518305183151832518335183451835518365183751838518395184051841518425184351844518455184651847518485184951850518515185251853518545185551856518575185851859518605186151862518635186451865518665186751868518695187051871518725187351874518755187651877518785187951880518815188251883518845188551886518875188851889518905189151892518935189451895518965189751898518995190051901519025190351904519055190651907519085190951910519115191251913519145191551916519175191851919519205192151922519235192451925519265192751928519295193051931519325193351934519355193651937519385193951940519415194251943519445194551946519475194851949519505195151952519535195451955519565195751958519595196051961519625196351964519655196651967519685196951970519715197251973519745197551976519775197851979519805198151982519835198451985519865198751988519895199051991519925199351994519955199651997519985199952000520015200252003520045200552006520075200852009520105201152012520135201452015520165201752018520195202052021520225202352024520255202652027520285202952030520315203252033520345203552036520375203852039520405204152042520435204452045520465204752048520495205052051520525205352054520555205652057520585205952060520615206252063520645206552066520675206852069520705207152072520735207452075520765207752078520795208052081520825208352084520855208652087520885208952090520915209252093520945209552096520975209852099521005210152102521035210452105521065210752108521095211052111521125211352114521155211652117521185211952120521215212252123521245212552126521275212852129521305213152132521335213452135521365213752138521395214052141521425214352144521455214652147521485214952150521515215252153521545215552156521575215852159521605216152162521635216452165521665216752168521695217052171521725217352174521755217652177521785217952180521815218252183521845218552186521875218852189521905219152192521935219452195521965219752198521995220052201522025220352204522055220652207522085220952210522115221252213522145221552216522175221852219522205222152222522235222452225522265222752228522295223052231522325223352234522355223652237522385223952240522415224252243522445224552246522475224852249522505225152252522535225452255522565225752258522595226052261522625226352264522655226652267522685226952270522715227252273522745227552276522775227852279522805228152282522835228452285522865228752288522895229052291522925229352294522955229652297522985229952300523015230252303523045230552306523075230852309523105231152312523135231452315523165231752318523195232052321523225232352324523255232652327523285232952330523315233252333523345233552336523375233852339523405234152342523435234452345523465234752348523495235052351523525235352354523555235652357523585235952360523615236252363523645236552366523675236852369523705237152372523735237452375523765237752378523795238052381523825238352384523855238652387523885238952390523915239252393523945239552396523975239852399524005240152402524035240452405524065240752408524095241052411524125241352414524155241652417524185241952420524215242252423524245242552426524275242852429524305243152432524335243452435524365243752438524395244052441524425244352444524455244652447524485244952450524515245252453524545245552456524575245852459524605246152462524635246452465524665246752468524695247052471524725247352474524755247652477524785247952480524815248252483524845248552486524875248852489524905249152492524935249452495524965249752498524995250052501525025250352504525055250652507525085250952510525115251252513525145251552516525175251852519525205252152522525235252452525525265252752528525295253052531525325253352534525355253652537525385253952540525415254252543525445254552546525475254852549525505255152552525535255452555525565255752558525595256052561525625256352564525655256652567525685256952570525715257252573525745257552576525775257852579525805258152582525835258452585525865258752588525895259052591525925259352594525955259652597525985259952600526015260252603526045260552606526075260852609526105261152612526135261452615526165261752618526195262052621526225262352624526255262652627526285262952630526315263252633526345263552636526375263852639526405264152642526435264452645526465264752648526495265052651526525265352654526555265652657526585265952660526615266252663526645266552666526675266852669526705267152672526735267452675526765267752678526795268052681526825268352684526855268652687526885268952690526915269252693526945269552696526975269852699527005270152702527035270452705527065270752708527095271052711527125271352714527155271652717527185271952720527215272252723527245272552726527275272852729527305273152732527335273452735527365273752738527395274052741527425274352744527455274652747527485274952750527515275252753527545275552756527575275852759527605276152762527635276452765527665276752768527695277052771527725277352774527755277652777527785277952780527815278252783527845278552786527875278852789527905279152792527935279452795527965279752798527995280052801528025280352804528055280652807528085280952810528115281252813528145281552816528175281852819528205282152822528235282452825528265282752828528295283052831528325283352834528355283652837528385283952840528415284252843528445284552846528475284852849528505285152852528535285452855528565285752858528595286052861528625286352864528655286652867528685286952870528715287252873528745287552876528775287852879528805288152882528835288452885528865288752888528895289052891528925289352894528955289652897528985289952900529015290252903529045290552906529075290852909529105291152912529135291452915529165291752918529195292052921529225292352924529255292652927529285292952930529315293252933529345293552936529375293852939529405294152942529435294452945529465294752948529495295052951529525295352954529555295652957529585295952960529615296252963529645296552966529675296852969529705297152972529735297452975529765297752978529795298052981529825298352984529855298652987529885298952990529915299252993529945299552996529975299852999530005300153002530035300453005530065300753008530095301053011530125301353014530155301653017530185301953020530215302253023530245302553026530275302853029530305303153032530335303453035530365303753038530395304053041530425304353044530455304653047530485304953050530515305253053530545305553056530575305853059530605306153062530635306453065530665306753068530695307053071530725307353074530755307653077530785307953080530815308253083530845308553086530875308853089530905309153092530935309453095530965309753098530995310053101531025310353104531055310653107531085310953110531115311253113531145311553116531175311853119531205312153122531235312453125531265312753128531295313053131531325313353134531355313653137531385313953140531415314253143531445314553146531475314853149531505315153152531535315453155531565315753158531595316053161531625316353164531655316653167531685316953170531715317253173531745317553176531775317853179531805318153182531835318453185531865318753188531895319053191531925319353194531955319653197531985319953200532015320253203532045320553206532075320853209532105321153212532135321453215532165321753218532195322053221532225322353224532255322653227532285322953230532315323253233532345323553236532375323853239532405324153242532435324453245532465324753248532495325053251532525325353254532555325653257532585325953260532615326253263532645326553266532675326853269532705327153272532735327453275532765327753278532795328053281532825328353284532855328653287532885328953290532915329253293532945329553296532975329853299533005330153302533035330453305533065330753308533095331053311533125331353314533155331653317533185331953320533215332253323533245332553326533275332853329533305333153332533335333453335533365333753338533395334053341533425334353344533455334653347533485334953350533515335253353533545335553356533575335853359533605336153362533635336453365533665336753368533695337053371533725337353374533755337653377533785337953380533815338253383533845338553386533875338853389533905339153392533935339453395533965339753398533995340053401534025340353404534055340653407534085340953410534115341253413534145341553416534175341853419534205342153422534235342453425534265342753428534295343053431534325343353434534355343653437534385343953440534415344253443534445344553446534475344853449534505345153452534535345453455534565345753458534595346053461534625346353464534655346653467534685346953470534715347253473534745347553476534775347853479534805348153482534835348453485534865348753488534895349053491534925349353494534955349653497534985349953500535015350253503535045350553506535075350853509535105351153512535135351453515535165351753518535195352053521535225352353524535255352653527535285352953530535315353253533535345353553536535375353853539535405354153542535435354453545535465354753548535495355053551535525355353554535555355653557535585355953560535615356253563535645356553566535675356853569535705357153572535735357453575535765357753578535795358053581535825358353584535855358653587535885358953590535915359253593535945359553596535975359853599536005360153602536035360453605536065360753608536095361053611536125361353614536155361653617536185361953620536215362253623536245362553626536275362853629536305363153632536335363453635536365363753638536395364053641536425364353644536455364653647536485364953650536515365253653536545365553656536575365853659536605366153662536635366453665536665366753668536695367053671536725367353674536755367653677536785367953680536815368253683536845368553686536875368853689536905369153692536935369453695536965369753698536995370053701537025370353704537055370653707537085370953710537115371253713537145371553716537175371853719537205372153722537235372453725537265372753728537295373053731537325373353734537355373653737537385373953740537415374253743537445374553746537475374853749537505375153752537535375453755537565375753758537595376053761537625376353764537655376653767537685376953770537715377253773537745377553776537775377853779537805378153782537835378453785537865378753788537895379053791537925379353794537955379653797537985379953800538015380253803538045380553806538075380853809538105381153812538135381453815538165381753818538195382053821538225382353824538255382653827538285382953830538315383253833538345383553836538375383853839538405384153842538435384453845538465384753848538495385053851538525385353854538555385653857538585385953860538615386253863538645386553866538675386853869538705387153872538735387453875538765387753878538795388053881538825388353884538855388653887538885388953890538915389253893538945389553896538975389853899539005390153902539035390453905539065390753908539095391053911539125391353914539155391653917539185391953920539215392253923539245392553926539275392853929539305393153932539335393453935539365393753938539395394053941539425394353944539455394653947539485394953950539515395253953539545395553956539575395853959539605396153962539635396453965539665396753968539695397053971539725397353974539755397653977539785397953980539815398253983539845398553986539875398853989539905399153992539935399453995539965399753998539995400054001540025400354004540055400654007540085400954010540115401254013540145401554016540175401854019540205402154022540235402454025540265402754028540295403054031540325403354034540355403654037540385403954040540415404254043540445404554046540475404854049540505405154052540535405454055540565405754058540595406054061540625406354064540655406654067540685406954070540715407254073540745407554076540775407854079540805408154082540835408454085540865408754088540895409054091540925409354094540955409654097540985409954100541015410254103541045410554106541075410854109541105411154112541135411454115541165411754118541195412054121541225412354124541255412654127541285412954130541315413254133541345413554136541375413854139541405414154142541435414454145541465414754148541495415054151541525415354154541555415654157541585415954160541615416254163541645416554166541675416854169541705417154172541735417454175541765417754178541795418054181541825418354184541855418654187541885418954190541915419254193541945419554196541975419854199542005420154202542035420454205542065420754208542095421054211542125421354214542155421654217542185421954220542215422254223542245422554226542275422854229542305423154232542335423454235542365423754238542395424054241542425424354244542455424654247542485424954250542515425254253542545425554256542575425854259542605426154262542635426454265542665426754268542695427054271542725427354274542755427654277542785427954280542815428254283542845428554286542875428854289542905429154292542935429454295542965429754298542995430054301543025430354304543055430654307543085430954310543115431254313543145431554316543175431854319543205432154322543235432454325543265432754328543295433054331543325433354334543355433654337543385433954340543415434254343543445434554346543475434854349543505435154352543535435454355543565435754358543595436054361543625436354364543655436654367543685436954370543715437254373543745437554376543775437854379543805438154382543835438454385543865438754388543895439054391543925439354394543955439654397543985439954400544015440254403544045440554406544075440854409544105441154412544135441454415544165441754418544195442054421544225442354424544255442654427544285442954430544315443254433544345443554436544375443854439544405444154442544435444454445544465444754448544495445054451544525445354454544555445654457544585445954460544615446254463544645446554466544675446854469544705447154472544735447454475544765447754478544795448054481544825448354484544855448654487544885448954490544915449254493544945449554496544975449854499545005450154502545035450454505545065450754508545095451054511545125451354514545155451654517545185451954520545215452254523545245452554526545275452854529545305453154532545335453454535545365453754538545395454054541545425454354544545455454654547545485454954550545515455254553545545455554556545575455854559545605456154562545635456454565545665456754568545695457054571545725457354574545755457654577545785457954580545815458254583545845458554586545875458854589545905459154592545935459454595545965459754598545995460054601546025460354604546055460654607546085460954610546115461254613546145461554616546175461854619546205462154622546235462454625546265462754628546295463054631546325463354634546355463654637546385463954640546415464254643546445464554646546475464854649546505465154652546535465454655546565465754658546595466054661546625466354664546655466654667546685466954670546715467254673546745467554676546775467854679546805468154682546835468454685546865468754688546895469054691546925469354694546955469654697546985469954700547015470254703547045470554706547075470854709547105471154712547135471454715547165471754718547195472054721547225472354724547255472654727547285472954730547315473254733547345473554736547375473854739547405474154742547435474454745547465474754748547495475054751547525475354754547555475654757547585475954760547615476254763547645476554766547675476854769547705477154772547735477454775547765477754778547795478054781547825478354784547855478654787547885478954790547915479254793547945479554796547975479854799548005480154802548035480454805548065480754808548095481054811548125481354814548155481654817548185481954820548215482254823548245482554826548275482854829548305483154832548335483454835548365483754838548395484054841548425484354844548455484654847548485484954850548515485254853548545485554856548575485854859548605486154862548635486454865548665486754868548695487054871548725487354874548755487654877548785487954880548815488254883548845488554886548875488854889548905489154892548935489454895548965489754898548995490054901549025490354904549055490654907549085490954910549115491254913549145491554916549175491854919549205492154922549235492454925549265492754928549295493054931549325493354934549355493654937549385493954940549415494254943549445494554946549475494854949549505495154952549535495454955549565495754958549595496054961549625496354964549655496654967549685496954970549715497254973549745497554976549775497854979549805498154982549835498454985549865498754988549895499054991549925499354994549955499654997549985499955000550015500255003550045500555006550075500855009550105501155012550135501455015550165501755018550195502055021550225502355024550255502655027550285502955030550315503255033550345503555036550375503855039550405504155042550435504455045550465504755048550495505055051550525505355054550555505655057550585505955060550615506255063550645506555066550675506855069550705507155072550735507455075550765507755078550795508055081550825508355084550855508655087550885508955090550915509255093550945509555096550975509855099551005510155102551035510455105551065510755108551095511055111551125511355114551155511655117551185511955120551215512255123551245512555126551275512855129551305513155132551335513455135551365513755138551395514055141551425514355144551455514655147551485514955150551515515255153551545515555156551575515855159551605516155162551635516455165551665516755168551695517055171551725517355174551755517655177551785517955180551815518255183551845518555186551875518855189551905519155192551935519455195551965519755198551995520055201552025520355204552055520655207552085520955210552115521255213552145521555216552175521855219552205522155222552235522455225552265522755228552295523055231552325523355234552355523655237552385523955240552415524255243552445524555246552475524855249552505525155252552535525455255552565525755258552595526055261552625526355264552655526655267552685526955270552715527255273552745527555276552775527855279552805528155282552835528455285552865528755288552895529055291552925529355294552955529655297552985529955300553015530255303553045530555306553075530855309553105531155312553135531455315553165531755318553195532055321553225532355324553255532655327553285532955330553315533255333553345533555336553375533855339553405534155342553435534455345553465534755348553495535055351553525535355354553555535655357553585535955360553615536255363553645536555366553675536855369553705537155372553735537455375553765537755378553795538055381553825538355384553855538655387553885538955390553915539255393553945539555396553975539855399554005540155402554035540455405554065540755408554095541055411554125541355414554155541655417554185541955420554215542255423554245542555426554275542855429554305543155432554335543455435554365543755438554395544055441554425544355444554455544655447554485544955450554515545255453554545545555456554575545855459554605546155462554635546455465554665546755468554695547055471554725547355474554755547655477554785547955480554815548255483554845548555486554875548855489554905549155492554935549455495554965549755498554995550055501555025550355504555055550655507555085550955510555115551255513555145551555516555175551855519555205552155522555235552455525555265552755528555295553055531555325553355534555355553655537555385553955540555415554255543555445554555546555475554855549555505555155552555535555455555555565555755558555595556055561555625556355564555655556655567555685556955570555715557255573555745557555576555775557855579555805558155582555835558455585555865558755588555895559055591555925559355594555955559655597555985559955600556015560255603556045560555606556075560855609556105561155612556135561455615556165561755618556195562055621556225562355624556255562655627556285562955630556315563255633556345563555636556375563855639556405564155642556435564455645556465564755648556495565055651556525565355654556555565655657556585565955660556615566255663556645566555666556675566855669556705567155672556735567455675556765567755678556795568055681556825568355684556855568655687556885568955690556915569255693556945569555696556975569855699557005570155702557035570455705557065570755708557095571055711557125571355714557155571655717557185571955720557215572255723557245572555726557275572855729557305573155732557335573455735557365573755738557395574055741557425574355744557455574655747557485574955750557515575255753557545575555756557575575855759557605576155762557635576455765557665576755768557695577055771557725577355774557755577655777557785577955780557815578255783557845578555786557875578855789557905579155792557935579455795557965579755798557995580055801558025580355804558055580655807558085580955810558115581255813558145581555816558175581855819558205582155822558235582455825558265582755828558295583055831558325583355834558355583655837558385583955840558415584255843558445584555846558475584855849558505585155852558535585455855558565585755858558595586055861558625586355864558655586655867558685586955870558715587255873558745587555876558775587855879558805588155882558835588455885558865588755888558895589055891558925589355894558955589655897558985589955900559015590255903559045590555906559075590855909559105591155912559135591455915559165591755918559195592055921559225592355924559255592655927559285592955930559315593255933559345593555936559375593855939559405594155942559435594455945559465594755948559495595055951559525595355954559555595655957559585595955960559615596255963559645596555966559675596855969559705597155972559735597455975559765597755978559795598055981559825598355984559855598655987559885598955990559915599255993559945599555996559975599855999560005600156002560035600456005560065600756008560095601056011560125601356014560155601656017560185601956020560215602256023560245602556026560275602856029560305603156032560335603456035560365603756038560395604056041560425604356044560455604656047560485604956050560515605256053560545605556056560575605856059560605606156062560635606456065560665606756068560695607056071560725607356074560755607656077560785607956080560815608256083560845608556086560875608856089560905609156092560935609456095560965609756098560995610056101561025610356104561055610656107561085610956110561115611256113561145611556116561175611856119561205612156122561235612456125561265612756128561295613056131561325613356134561355613656137561385613956140561415614256143561445614556146561475614856149561505615156152561535615456155561565615756158561595616056161561625616356164561655616656167561685616956170561715617256173561745617556176561775617856179561805618156182561835618456185561865618756188561895619056191561925619356194561955619656197561985619956200562015620256203562045620556206562075620856209562105621156212562135621456215562165621756218562195622056221562225622356224562255622656227562285622956230562315623256233562345623556236562375623856239562405624156242562435624456245562465624756248562495625056251562525625356254562555625656257562585625956260562615626256263562645626556266562675626856269562705627156272562735627456275562765627756278562795628056281562825628356284562855628656287562885628956290562915629256293562945629556296562975629856299563005630156302563035630456305563065630756308563095631056311563125631356314563155631656317563185631956320563215632256323563245632556326563275632856329563305633156332563335633456335563365633756338563395634056341563425634356344563455634656347563485634956350563515635256353563545635556356563575635856359563605636156362563635636456365563665636756368563695637056371563725637356374563755637656377563785637956380563815638256383563845638556386563875638856389563905639156392563935639456395563965639756398563995640056401564025640356404564055640656407564085640956410564115641256413564145641556416564175641856419564205642156422564235642456425564265642756428564295643056431564325643356434564355643656437564385643956440564415644256443564445644556446564475644856449564505645156452564535645456455564565645756458564595646056461564625646356464564655646656467564685646956470564715647256473564745647556476564775647856479564805648156482564835648456485564865648756488564895649056491564925649356494564955649656497564985649956500565015650256503565045650556506565075650856509565105651156512565135651456515565165651756518565195652056521565225652356524565255652656527565285652956530565315653256533565345653556536565375653856539565405654156542565435654456545565465654756548565495655056551565525655356554565555655656557565585655956560565615656256563565645656556566565675656856569565705657156572565735657456575565765657756578565795658056581565825658356584565855658656587565885658956590565915659256593565945659556596565975659856599566005660156602566035660456605566065660756608566095661056611566125661356614566155661656617566185661956620566215662256623566245662556626566275662856629566305663156632566335663456635566365663756638566395664056641566425664356644566455664656647566485664956650566515665256653566545665556656566575665856659566605666156662566635666456665566665666756668566695667056671566725667356674566755667656677566785667956680566815668256683566845668556686566875668856689566905669156692566935669456695566965669756698566995670056701567025670356704567055670656707567085670956710567115671256713567145671556716567175671856719567205672156722567235672456725567265672756728567295673056731567325673356734567355673656737567385673956740567415674256743567445674556746567475674856749567505675156752567535675456755567565675756758567595676056761567625676356764567655676656767567685676956770567715677256773567745677556776567775677856779567805678156782567835678456785567865678756788567895679056791567925679356794567955679656797567985679956800568015680256803568045680556806568075680856809568105681156812568135681456815568165681756818568195682056821568225682356824568255682656827568285682956830568315683256833568345683556836568375683856839568405684156842568435684456845568465684756848568495685056851568525685356854568555685656857568585685956860568615686256863568645686556866568675686856869568705687156872568735687456875568765687756878568795688056881568825688356884568855688656887568885688956890568915689256893568945689556896568975689856899569005690156902569035690456905569065690756908569095691056911569125691356914569155691656917569185691956920569215692256923569245692556926569275692856929569305693156932569335693456935569365693756938569395694056941569425694356944569455694656947569485694956950569515695256953569545695556956569575695856959569605696156962569635696456965569665696756968569695697056971569725697356974569755697656977569785697956980569815698256983569845698556986569875698856989569905699156992569935699456995569965699756998569995700057001570025700357004570055700657007570085700957010570115701257013570145701557016570175701857019570205702157022570235702457025570265702757028570295703057031570325703357034570355703657037570385703957040570415704257043570445704557046570475704857049570505705157052570535705457055570565705757058570595706057061570625706357064570655706657067570685706957070570715707257073570745707557076570775707857079570805708157082570835708457085570865708757088570895709057091570925709357094570955709657097570985709957100571015710257103571045710557106571075710857109571105711157112571135711457115571165711757118571195712057121571225712357124571255712657127571285712957130571315713257133571345713557136571375713857139571405714157142571435714457145571465714757148571495715057151571525715357154571555715657157571585715957160571615716257163571645716557166571675716857169571705717157172571735717457175571765717757178571795718057181571825718357184571855718657187571885718957190571915719257193571945719557196571975719857199572005720157202572035720457205572065720757208572095721057211572125721357214572155721657217572185721957220572215722257223572245722557226572275722857229572305723157232572335723457235572365723757238572395724057241572425724357244572455724657247572485724957250572515725257253572545725557256572575725857259572605726157262572635726457265572665726757268572695727057271572725727357274572755727657277572785727957280572815728257283572845728557286572875728857289572905729157292572935729457295572965729757298572995730057301573025730357304573055730657307573085730957310573115731257313573145731557316573175731857319573205732157322573235732457325573265732757328573295733057331573325733357334573355733657337573385733957340573415734257343573445734557346573475734857349573505735157352573535735457355573565735757358573595736057361573625736357364573655736657367573685736957370573715737257373573745737557376573775737857379573805738157382573835738457385573865738757388573895739057391573925739357394573955739657397573985739957400574015740257403574045740557406574075740857409574105741157412574135741457415574165741757418574195742057421574225742357424574255742657427574285742957430574315743257433574345743557436574375743857439574405744157442574435744457445574465744757448574495745057451574525745357454574555745657457574585745957460574615746257463574645746557466574675746857469574705747157472574735747457475574765747757478574795748057481574825748357484574855748657487574885748957490574915749257493574945749557496574975749857499575005750157502575035750457505575065750757508575095751057511575125751357514575155751657517575185751957520575215752257523575245752557526575275752857529575305753157532575335753457535575365753757538575395754057541575425754357544575455754657547575485754957550575515755257553575545755557556575575755857559575605756157562575635756457565575665756757568575695757057571575725757357574575755757657577575785757957580575815758257583575845758557586575875758857589575905759157592575935759457595575965759757598575995760057601576025760357604576055760657607576085760957610576115761257613576145761557616576175761857619576205762157622576235762457625576265762757628576295763057631576325763357634576355763657637576385763957640576415764257643576445764557646576475764857649576505765157652576535765457655576565765757658576595766057661576625766357664576655766657667576685766957670576715767257673576745767557676576775767857679576805768157682576835768457685576865768757688576895769057691576925769357694576955769657697576985769957700577015770257703577045770557706577075770857709577105771157712577135771457715577165771757718577195772057721577225772357724577255772657727577285772957730577315773257733577345773557736577375773857739577405774157742577435774457745577465774757748577495775057751577525775357754577555775657757577585775957760577615776257763577645776557766577675776857769577705777157772577735777457775577765777757778577795778057781577825778357784577855778657787577885778957790577915779257793577945779557796577975779857799578005780157802578035780457805578065780757808578095781057811578125781357814578155781657817578185781957820578215782257823578245782557826578275782857829578305783157832578335783457835578365783757838578395784057841578425784357844578455784657847578485784957850578515785257853578545785557856578575785857859578605786157862578635786457865578665786757868578695787057871578725787357874578755787657877578785787957880578815788257883578845788557886578875788857889578905789157892578935789457895578965789757898578995790057901579025790357904579055790657907579085790957910579115791257913579145791557916579175791857919579205792157922579235792457925579265792757928579295793057931579325793357934579355793657937579385793957940579415794257943579445794557946579475794857949579505795157952579535795457955579565795757958579595796057961579625796357964579655796657967579685796957970579715797257973579745797557976579775797857979579805798157982579835798457985579865798757988579895799057991579925799357994579955799657997579985799958000580015800258003580045800558006580075800858009580105801158012580135801458015580165801758018580195802058021580225802358024580255802658027580285802958030580315803258033580345803558036580375803858039580405804158042580435804458045580465804758048580495805058051580525805358054580555805658057580585805958060580615806258063580645806558066580675806858069580705807158072580735807458075580765807758078580795808058081580825808358084580855808658087580885808958090580915809258093580945809558096580975809858099581005810158102581035810458105581065810758108581095811058111581125811358114581155811658117581185811958120581215812258123581245812558126581275812858129581305813158132581335813458135581365813758138581395814058141581425814358144581455814658147581485814958150581515815258153581545815558156581575815858159581605816158162581635816458165581665816758168581695817058171581725817358174581755817658177581785817958180581815818258183581845818558186581875818858189581905819158192581935819458195581965819758198581995820058201582025820358204582055820658207582085820958210582115821258213582145821558216582175821858219582205822158222582235822458225582265822758228582295823058231582325823358234582355823658237582385823958240582415824258243582445824558246582475824858249582505825158252582535825458255582565825758258582595826058261582625826358264582655826658267582685826958270582715827258273582745827558276582775827858279582805828158282582835828458285582865828758288582895829058291582925829358294582955829658297582985829958300583015830258303583045830558306583075830858309583105831158312583135831458315583165831758318583195832058321583225832358324583255832658327583285832958330583315833258333583345833558336583375833858339583405834158342583435834458345583465834758348583495835058351583525835358354583555835658357583585835958360583615836258363583645836558366583675836858369583705837158372583735837458375583765837758378583795838058381583825838358384583855838658387583885838958390583915839258393583945839558396583975839858399584005840158402584035840458405584065840758408584095841058411584125841358414584155841658417584185841958420584215842258423584245842558426584275842858429584305843158432584335843458435584365843758438584395844058441584425844358444584455844658447584485844958450584515845258453584545845558456584575845858459584605846158462584635846458465584665846758468584695847058471584725847358474584755847658477584785847958480584815848258483584845848558486584875848858489584905849158492584935849458495584965849758498584995850058501585025850358504585055850658507585085850958510585115851258513585145851558516585175851858519585205852158522585235852458525585265852758528585295853058531585325853358534585355853658537585385853958540585415854258543585445854558546585475854858549585505855158552585535855458555585565855758558585595856058561585625856358564585655856658567585685856958570585715857258573585745857558576585775857858579585805858158582585835858458585585865858758588585895859058591585925859358594585955859658597585985859958600586015860258603586045860558606586075860858609586105861158612586135861458615586165861758618586195862058621586225862358624586255862658627586285862958630586315863258633586345863558636586375863858639586405864158642586435864458645586465864758648586495865058651586525865358654586555865658657586585865958660586615866258663586645866558666586675866858669586705867158672586735867458675586765867758678586795868058681586825868358684586855868658687586885868958690586915869258693586945869558696586975869858699587005870158702587035870458705587065870758708587095871058711587125871358714587155871658717587185871958720587215872258723587245872558726587275872858729587305873158732587335873458735587365873758738587395874058741587425874358744587455874658747587485874958750587515875258753587545875558756587575875858759587605876158762587635876458765587665876758768587695877058771587725877358774587755877658777587785877958780587815878258783587845878558786587875878858789587905879158792587935879458795587965879758798587995880058801588025880358804588055880658807588085880958810588115881258813588145881558816588175881858819588205882158822588235882458825588265882758828588295883058831588325883358834588355883658837588385883958840588415884258843588445884558846588475884858849588505885158852588535885458855588565885758858588595886058861588625886358864588655886658867588685886958870588715887258873588745887558876588775887858879588805888158882588835888458885588865888758888588895889058891588925889358894588955889658897588985889958900589015890258903589045890558906589075890858909589105891158912589135891458915589165891758918589195892058921589225892358924589255892658927589285892958930589315893258933589345893558936589375893858939589405894158942589435894458945589465894758948589495895058951589525895358954589555895658957589585895958960589615896258963589645896558966589675896858969589705897158972589735897458975589765897758978589795898058981589825898358984589855898658987589885898958990589915899258993589945899558996589975899858999590005900159002590035900459005590065900759008590095901059011590125901359014590155901659017590185901959020590215902259023590245902559026590275902859029590305903159032590335903459035590365903759038590395904059041590425904359044590455904659047590485904959050590515905259053590545905559056590575905859059590605906159062590635906459065590665906759068590695907059071590725907359074590755907659077590785907959080590815908259083590845908559086590875908859089590905909159092590935909459095590965909759098590995910059101591025910359104591055910659107591085910959110591115911259113591145911559116591175911859119591205912159122591235912459125591265912759128591295913059131591325913359134591355913659137591385913959140591415914259143591445914559146591475914859149591505915159152591535915459155591565915759158591595916059161591625916359164591655916659167591685916959170591715917259173591745917559176591775917859179591805918159182591835918459185591865918759188591895919059191591925919359194591955919659197591985919959200592015920259203592045920559206592075920859209592105921159212592135921459215592165921759218592195922059221592225922359224592255922659227592285922959230592315923259233592345923559236592375923859239592405924159242592435924459245592465924759248592495925059251592525925359254592555925659257592585925959260592615926259263592645926559266592675926859269592705927159272592735927459275592765927759278592795928059281592825928359284592855928659287592885928959290592915929259293592945929559296592975929859299593005930159302593035930459305593065930759308593095931059311593125931359314593155931659317593185931959320593215932259323593245932559326593275932859329593305933159332593335933459335593365933759338593395934059341593425934359344593455934659347593485934959350593515935259353593545935559356593575935859359593605936159362593635936459365593665936759368593695937059371593725937359374593755937659377593785937959380593815938259383593845938559386593875938859389593905939159392593935939459395593965939759398593995940059401594025940359404594055940659407594085940959410594115941259413594145941559416594175941859419594205942159422594235942459425594265942759428594295943059431594325943359434594355943659437594385943959440594415944259443594445944559446594475944859449594505945159452594535945459455594565945759458594595946059461594625946359464594655946659467594685946959470594715947259473594745947559476594775947859479594805948159482594835948459485594865948759488594895949059491594925949359494594955949659497594985949959500595015950259503595045950559506595075950859509595105951159512595135951459515595165951759518595195952059521595225952359524595255952659527595285952959530595315953259533595345953559536595375953859539595405954159542595435954459545595465954759548595495955059551595525955359554595555955659557595585955959560595615956259563595645956559566595675956859569595705957159572595735957459575595765957759578595795958059581595825958359584595855958659587595885958959590595915959259593595945959559596595975959859599596005960159602596035960459605596065960759608596095961059611596125961359614596155961659617596185961959620596215962259623596245962559626596275962859629596305963159632596335963459635596365963759638596395964059641596425964359644596455964659647596485964959650596515965259653596545965559656596575965859659596605966159662596635966459665596665966759668596695967059671596725967359674596755967659677596785967959680596815968259683596845968559686596875968859689596905969159692596935969459695596965969759698596995970059701597025970359704597055970659707597085970959710597115971259713597145971559716597175971859719597205972159722597235972459725597265972759728597295973059731597325973359734597355973659737597385973959740597415974259743597445974559746597475974859749597505975159752597535975459755597565975759758597595976059761597625976359764597655976659767597685976959770597715977259773597745977559776597775977859779597805978159782597835978459785597865978759788597895979059791597925979359794597955979659797597985979959800598015980259803598045980559806598075980859809598105981159812598135981459815598165981759818598195982059821598225982359824598255982659827598285982959830598315983259833598345983559836598375983859839598405984159842598435984459845598465984759848598495985059851598525985359854598555985659857598585985959860598615986259863598645986559866598675986859869598705987159872598735987459875598765987759878598795988059881598825988359884598855988659887598885988959890598915989259893598945989559896598975989859899599005990159902599035990459905599065990759908599095991059911599125991359914599155991659917599185991959920599215992259923599245992559926599275992859929599305993159932599335993459935599365993759938599395994059941599425994359944599455994659947599485994959950599515995259953599545995559956599575995859959599605996159962599635996459965599665996759968599695997059971599725997359974599755997659977599785997959980599815998259983599845998559986599875998859989599905999159992599935999459995599965999759998599996000060001600026000360004600056000660007600086000960010600116001260013600146001560016600176001860019600206002160022600236002460025600266002760028600296003060031600326003360034600356003660037600386003960040600416004260043600446004560046600476004860049600506005160052600536005460055600566005760058600596006060061600626006360064600656006660067600686006960070600716007260073600746007560076600776007860079600806008160082600836008460085600866008760088600896009060091600926009360094600956009660097600986009960100601016010260103601046010560106601076010860109601106011160112601136011460115601166011760118601196012060121601226012360124601256012660127601286012960130601316013260133601346013560136601376013860139601406014160142601436014460145601466014760148601496015060151601526015360154601556015660157601586015960160601616016260163601646016560166601676016860169601706017160172601736017460175601766017760178601796018060181601826018360184601856018660187601886018960190601916019260193601946019560196601976019860199602006020160202602036020460205602066020760208602096021060211602126021360214602156021660217602186021960220602216022260223602246022560226602276022860229602306023160232602336023460235602366023760238602396024060241602426024360244602456024660247602486024960250602516025260253602546025560256602576025860259602606026160262602636026460265602666026760268602696027060271602726027360274602756027660277602786027960280602816028260283602846028560286602876028860289602906029160292602936029460295602966029760298602996030060301603026030360304603056030660307603086030960310603116031260313603146031560316603176031860319603206032160322603236032460325603266032760328603296033060331603326033360334603356033660337603386033960340603416034260343603446034560346603476034860349603506035160352603536035460355603566035760358603596036060361603626036360364603656036660367603686036960370603716037260373603746037560376603776037860379603806038160382603836038460385603866038760388603896039060391603926039360394603956039660397603986039960400604016040260403604046040560406604076040860409604106041160412604136041460415604166041760418604196042060421604226042360424604256042660427604286042960430604316043260433604346043560436604376043860439604406044160442604436044460445604466044760448604496045060451604526045360454604556045660457604586045960460604616046260463604646046560466604676046860469604706047160472604736047460475604766047760478604796048060481604826048360484604856048660487604886048960490604916049260493604946049560496604976049860499605006050160502605036050460505605066050760508605096051060511605126051360514605156051660517605186051960520605216052260523605246052560526605276052860529605306053160532605336053460535605366053760538605396054060541605426054360544605456054660547605486054960550605516055260553605546055560556605576055860559605606056160562605636056460565605666056760568605696057060571605726057360574605756057660577605786057960580605816058260583605846058560586605876058860589605906059160592605936059460595605966059760598605996060060601606026060360604606056060660607606086060960610606116061260613606146061560616606176061860619606206062160622606236062460625606266062760628606296063060631606326063360634606356063660637606386063960640606416064260643606446064560646606476064860649606506065160652606536065460655606566065760658606596066060661606626066360664606656066660667606686066960670606716067260673606746067560676606776067860679606806068160682606836068460685606866068760688606896069060691606926069360694606956069660697606986069960700607016070260703607046070560706607076070860709607106071160712607136071460715607166071760718607196072060721607226072360724607256072660727607286072960730607316073260733607346073560736607376073860739607406074160742607436074460745607466074760748607496075060751607526075360754607556075660757607586075960760607616076260763607646076560766607676076860769607706077160772607736077460775607766077760778607796078060781607826078360784607856078660787607886078960790607916079260793607946079560796607976079860799608006080160802608036080460805608066080760808608096081060811608126081360814608156081660817608186081960820608216082260823608246082560826608276082860829608306083160832608336083460835608366083760838608396084060841608426084360844608456084660847608486084960850608516085260853608546085560856608576085860859608606086160862608636086460865608666086760868608696087060871608726087360874608756087660877608786087960880608816088260883608846088560886608876088860889608906089160892608936089460895608966089760898608996090060901609026090360904609056090660907609086090960910609116091260913609146091560916609176091860919609206092160922609236092460925609266092760928609296093060931609326093360934609356093660937609386093960940609416094260943609446094560946609476094860949609506095160952609536095460955609566095760958609596096060961609626096360964609656096660967609686096960970609716097260973609746097560976609776097860979609806098160982609836098460985609866098760988609896099060991609926099360994609956099660997609986099961000610016100261003610046100561006610076100861009610106101161012610136101461015610166101761018610196102061021610226102361024610256102661027610286102961030610316103261033610346103561036610376103861039610406104161042610436104461045610466104761048610496105061051610526105361054610556105661057610586105961060610616106261063610646106561066610676106861069610706107161072610736107461075610766107761078610796108061081610826108361084610856108661087610886108961090610916109261093610946109561096610976109861099611006110161102611036110461105611066110761108611096111061111611126111361114611156111661117611186111961120611216112261123611246112561126611276112861129611306113161132611336113461135611366113761138611396114061141611426114361144611456114661147611486114961150611516115261153611546115561156611576115861159611606116161162611636116461165611666116761168611696117061171611726117361174611756117661177611786117961180611816118261183611846118561186611876118861189611906119161192611936119461195611966119761198611996120061201612026120361204612056120661207612086120961210612116121261213612146121561216612176121861219612206122161222612236122461225612266122761228612296123061231612326123361234612356123661237612386123961240612416124261243612446124561246612476124861249612506125161252612536125461255612566125761258612596126061261612626126361264612656126661267612686126961270612716127261273612746127561276612776127861279612806128161282612836128461285612866128761288612896129061291612926129361294612956129661297612986129961300613016130261303613046130561306613076130861309613106131161312613136131461315613166131761318613196132061321613226132361324613256132661327613286132961330613316133261333613346133561336613376133861339613406134161342613436134461345613466134761348613496135061351613526135361354613556135661357613586135961360613616136261363613646136561366613676136861369613706137161372613736137461375613766137761378613796138061381613826138361384613856138661387613886138961390613916139261393613946139561396613976139861399614006140161402614036140461405614066140761408614096141061411614126141361414614156141661417614186141961420614216142261423614246142561426614276142861429614306143161432614336143461435614366143761438614396144061441614426144361444614456144661447614486144961450614516145261453614546145561456614576145861459614606146161462614636146461465614666146761468614696147061471614726147361474614756147661477614786147961480614816148261483614846148561486614876148861489614906149161492614936149461495614966149761498614996150061501615026150361504615056150661507615086150961510615116151261513615146151561516615176151861519615206152161522615236152461525615266152761528615296153061531615326153361534615356153661537615386153961540615416154261543615446154561546615476154861549615506155161552615536155461555615566155761558615596156061561615626156361564615656156661567615686156961570615716157261573615746157561576615776157861579615806158161582615836158461585615866158761588615896159061591615926159361594615956159661597615986159961600616016160261603616046160561606616076160861609616106161161612616136161461615616166161761618616196162061621616226162361624616256162661627616286162961630616316163261633616346163561636616376163861639616406164161642616436164461645616466164761648616496165061651616526165361654616556165661657616586165961660616616166261663616646166561666616676166861669616706167161672616736167461675616766167761678616796168061681616826168361684616856168661687616886168961690616916169261693616946169561696616976169861699617006170161702617036170461705617066170761708617096171061711617126171361714617156171661717617186171961720617216172261723617246172561726617276172861729617306173161732617336173461735617366173761738617396174061741617426174361744617456174661747617486174961750617516175261753617546175561756617576175861759617606176161762617636176461765617666176761768617696177061771617726177361774617756177661777617786177961780617816178261783617846178561786617876178861789617906179161792617936179461795617966179761798617996180061801618026180361804618056180661807618086180961810618116181261813618146181561816618176181861819618206182161822618236182461825618266182761828618296183061831618326183361834618356183661837618386183961840618416184261843618446184561846618476184861849618506185161852618536185461855618566185761858618596186061861618626186361864618656186661867618686186961870618716187261873618746187561876618776187861879618806188161882618836188461885618866188761888618896189061891618926189361894618956189661897618986189961900619016190261903619046190561906619076190861909619106191161912619136191461915619166191761918619196192061921619226192361924619256192661927619286192961930619316193261933619346193561936619376193861939619406194161942619436194461945619466194761948619496195061951619526195361954619556195661957619586195961960619616196261963619646196561966619676196861969619706197161972619736197461975619766197761978619796198061981619826198361984619856198661987619886198961990619916199261993619946199561996619976199861999620006200162002620036200462005620066200762008620096201062011620126201362014620156201662017620186201962020620216202262023620246202562026620276202862029620306203162032620336203462035620366203762038620396204062041620426204362044620456204662047620486204962050620516205262053620546205562056620576205862059620606206162062620636206462065620666206762068620696207062071620726207362074620756207662077620786207962080620816208262083620846208562086620876208862089620906209162092620936209462095620966209762098620996210062101621026210362104621056210662107621086210962110621116211262113621146211562116621176211862119621206212162122621236212462125621266212762128621296213062131621326213362134621356213662137621386213962140621416214262143621446214562146621476214862149621506215162152621536215462155621566215762158621596216062161621626216362164621656216662167621686216962170621716217262173621746217562176621776217862179621806218162182621836218462185621866218762188621896219062191621926219362194621956219662197621986219962200622016220262203622046220562206622076220862209622106221162212622136221462215622166221762218622196222062221622226222362224622256222662227622286222962230622316223262233622346223562236622376223862239622406224162242622436224462245622466224762248622496225062251622526225362254622556225662257622586225962260622616226262263622646226562266622676226862269622706227162272622736227462275622766227762278622796228062281622826228362284622856228662287622886228962290622916229262293622946229562296622976229862299623006230162302623036230462305623066230762308623096231062311623126231362314623156231662317623186231962320623216232262323623246232562326623276232862329623306233162332623336233462335623366233762338623396234062341623426234362344623456234662347623486234962350623516235262353623546235562356623576235862359623606236162362623636236462365623666236762368623696237062371623726237362374623756237662377623786237962380623816238262383623846238562386623876238862389623906239162392623936239462395623966239762398623996240062401624026240362404624056240662407624086240962410624116241262413624146241562416624176241862419624206242162422624236242462425624266242762428624296243062431624326243362434624356243662437624386243962440624416244262443624446244562446624476244862449624506245162452624536245462455624566245762458624596246062461624626246362464624656246662467624686246962470624716247262473624746247562476624776247862479624806248162482624836248462485624866248762488624896249062491624926249362494624956249662497624986249962500625016250262503625046250562506625076250862509625106251162512625136251462515625166251762518625196252062521625226252362524625256252662527625286252962530625316253262533625346253562536625376253862539625406254162542625436254462545625466254762548625496255062551625526255362554625556255662557625586255962560625616256262563625646256562566625676256862569625706257162572625736257462575625766257762578625796258062581625826258362584625856258662587625886258962590625916259262593625946259562596625976259862599626006260162602626036260462605626066260762608626096261062611626126261362614626156261662617626186261962620626216262262623626246262562626626276262862629626306263162632626336263462635626366263762638626396264062641626426264362644626456264662647626486264962650626516265262653626546265562656626576265862659626606266162662626636266462665626666266762668626696267062671626726267362674626756267662677626786267962680626816268262683626846268562686626876268862689626906269162692626936269462695626966269762698626996270062701627026270362704627056270662707627086270962710627116271262713627146271562716627176271862719627206272162722627236272462725627266272762728627296273062731627326273362734627356273662737627386273962740627416274262743627446274562746627476274862749627506275162752627536275462755627566275762758627596276062761627626276362764627656276662767627686276962770627716277262773627746277562776627776277862779627806278162782627836278462785627866278762788627896279062791627926279362794627956279662797627986279962800628016280262803628046280562806628076280862809628106281162812628136281462815628166281762818628196282062821628226282362824628256282662827628286282962830628316283262833628346283562836628376283862839628406284162842628436284462845628466284762848628496285062851628526285362854628556285662857628586285962860628616286262863628646286562866628676286862869628706287162872628736287462875628766287762878628796288062881628826288362884628856288662887628886288962890628916289262893628946289562896628976289862899629006290162902629036290462905629066290762908629096291062911629126291362914629156291662917629186291962920629216292262923629246292562926629276292862929629306293162932629336293462935629366293762938629396294062941629426294362944629456294662947629486294962950629516295262953629546295562956629576295862959629606296162962629636296462965629666296762968629696297062971629726297362974629756297662977629786297962980629816298262983629846298562986629876298862989629906299162992629936299462995629966299762998629996300063001630026300363004630056300663007630086300963010630116301263013630146301563016630176301863019630206302163022630236302463025630266302763028630296303063031630326303363034630356303663037630386303963040630416304263043630446304563046630476304863049630506305163052630536305463055630566305763058630596306063061630626306363064630656306663067630686306963070630716307263073630746307563076630776307863079630806308163082630836308463085630866308763088630896309063091630926309363094630956309663097630986309963100631016310263103631046310563106631076310863109631106311163112631136311463115631166311763118631196312063121631226312363124631256312663127631286312963130631316313263133631346313563136631376313863139631406314163142631436314463145631466314763148631496315063151631526315363154631556315663157631586315963160631616316263163631646316563166631676316863169631706317163172631736317463175631766317763178631796318063181631826318363184631856318663187631886318963190631916319263193631946319563196631976319863199632006320163202632036320463205632066320763208632096321063211632126321363214632156321663217632186321963220632216322263223632246322563226632276322863229632306323163232632336323463235632366323763238632396324063241632426324363244632456324663247632486324963250632516325263253632546325563256632576325863259632606326163262632636326463265632666326763268632696327063271632726327363274632756327663277632786327963280632816328263283632846328563286632876328863289632906329163292632936329463295632966329763298632996330063301633026330363304633056330663307633086330963310633116331263313633146331563316633176331863319633206332163322633236332463325633266332763328633296333063331633326333363334633356333663337633386333963340633416334263343633446334563346633476334863349633506335163352633536335463355633566335763358633596336063361633626336363364633656336663367633686336963370633716337263373633746337563376633776337863379633806338163382633836338463385633866338763388633896339063391633926339363394633956339663397633986339963400634016340263403634046340563406634076340863409634106341163412634136341463415634166341763418634196342063421634226342363424634256342663427634286342963430634316343263433634346343563436634376343863439634406344163442634436344463445634466344763448634496345063451634526345363454634556345663457634586345963460634616346263463634646346563466634676346863469634706347163472634736347463475634766347763478634796348063481634826348363484634856348663487634886348963490634916349263493634946349563496634976349863499635006350163502635036350463505635066350763508635096351063511635126351363514635156351663517635186351963520635216352263523635246352563526635276352863529635306353163532635336353463535635366353763538635396354063541635426354363544635456354663547635486354963550635516355263553635546355563556635576355863559635606356163562635636356463565635666356763568635696357063571635726357363574635756357663577635786357963580635816358263583635846358563586635876358863589635906359163592635936359463595635966359763598635996360063601636026360363604636056360663607636086360963610636116361263613636146361563616636176361863619636206362163622636236362463625636266362763628636296363063631636326363363634636356363663637636386363963640636416364263643636446364563646636476364863649636506365163652636536365463655636566365763658636596366063661636626366363664636656366663667636686366963670636716367263673636746367563676636776367863679636806368163682636836368463685636866368763688636896369063691636926369363694636956369663697636986369963700637016370263703637046370563706637076370863709637106371163712637136371463715637166371763718637196372063721637226372363724637256372663727637286372963730637316373263733637346373563736637376373863739637406374163742637436374463745637466374763748637496375063751637526375363754637556375663757637586375963760637616376263763637646376563766637676376863769637706377163772637736377463775637766377763778637796378063781637826378363784637856378663787637886378963790637916379263793637946379563796637976379863799638006380163802638036380463805638066380763808638096381063811638126381363814638156381663817638186381963820638216382263823638246382563826638276382863829638306383163832638336383463835638366383763838638396384063841638426384363844638456384663847638486384963850638516385263853638546385563856638576385863859638606386163862638636386463865638666386763868638696387063871638726387363874638756387663877638786387963880638816388263883638846388563886638876388863889638906389163892638936389463895638966389763898638996390063901639026390363904639056390663907639086390963910639116391263913639146391563916639176391863919639206392163922639236392463925639266392763928639296393063931639326393363934639356393663937639386393963940639416394263943639446394563946639476394863949639506395163952639536395463955639566395763958639596396063961639626396363964639656396663967639686396963970639716397263973639746397563976639776397863979639806398163982639836398463985639866398763988639896399063991639926399363994639956399663997639986399964000640016400264003640046400564006640076400864009640106401164012640136401464015640166401764018640196402064021640226402364024640256402664027640286402964030640316403264033640346403564036640376403864039640406404164042640436404464045640466404764048640496405064051640526405364054640556405664057640586405964060640616406264063640646406564066640676406864069640706407164072640736407464075640766407764078640796408064081640826408364084640856408664087640886408964090640916409264093640946409564096640976409864099641006410164102641036410464105641066410764108641096411064111641126411364114641156411664117641186411964120641216412264123641246412564126641276412864129641306413164132641336413464135641366413764138641396414064141641426414364144641456414664147641486414964150641516415264153641546415564156641576415864159641606416164162641636416464165641666416764168641696417064171641726417364174641756417664177641786417964180641816418264183641846418564186641876418864189641906419164192641936419464195641966419764198641996420064201642026420364204642056420664207642086420964210642116421264213642146421564216642176421864219642206422164222642236422464225642266422764228642296423064231642326423364234642356423664237642386423964240642416424264243642446424564246642476424864249642506425164252642536425464255642566425764258642596426064261642626426364264642656426664267642686426964270642716427264273642746427564276642776427864279642806428164282642836428464285642866428764288642896429064291642926429364294642956429664297642986429964300643016430264303643046430564306643076430864309643106431164312643136431464315643166431764318643196432064321643226432364324643256432664327643286432964330643316433264333643346433564336643376433864339643406434164342643436434464345643466434764348643496435064351643526435364354643556435664357643586435964360643616436264363643646436564366643676436864369643706437164372643736437464375643766437764378643796438064381643826438364384643856438664387643886438964390643916439264393643946439564396643976439864399644006440164402644036440464405644066440764408644096441064411644126441364414644156441664417644186441964420644216442264423644246442564426644276442864429644306443164432644336443464435644366443764438644396444064441644426444364444644456444664447644486444964450644516445264453644546445564456644576445864459644606446164462644636446464465644666446764468644696447064471644726447364474644756447664477644786447964480644816448264483644846448564486644876448864489644906449164492644936449464495644966449764498644996450064501645026450364504645056450664507645086450964510645116451264513645146451564516645176451864519645206452164522645236452464525645266452764528645296453064531645326453364534645356453664537645386453964540645416454264543645446454564546645476454864549645506455164552645536455464555645566455764558645596456064561645626456364564645656456664567645686456964570645716457264573645746457564576645776457864579645806458164582645836458464585645866458764588645896459064591645926459364594645956459664597645986459964600646016460264603646046460564606646076460864609646106461164612646136461464615646166461764618646196462064621646226462364624646256462664627646286462964630646316463264633646346463564636646376463864639646406464164642646436464464645646466464764648646496465064651646526465364654646556465664657646586465964660646616466264663646646466564666646676466864669646706467164672646736467464675646766467764678646796468064681646826468364684646856468664687646886468964690646916469264693646946469564696646976469864699647006470164702647036470464705647066470764708647096471064711647126471364714647156471664717647186471964720647216472264723647246472564726647276472864729647306473164732647336473464735647366473764738647396474064741647426474364744647456474664747647486474964750647516475264753647546475564756647576475864759647606476164762647636476464765647666476764768647696477064771647726477364774647756477664777647786477964780647816478264783647846478564786647876478864789647906479164792647936479464795647966479764798647996480064801648026480364804648056480664807648086480964810648116481264813648146481564816648176481864819648206482164822648236482464825648266482764828648296483064831648326483364834648356483664837648386483964840648416484264843648446484564846648476484864849648506485164852648536485464855648566485764858648596486064861648626486364864648656486664867648686486964870648716487264873648746487564876648776487864879648806488164882648836488464885648866488764888648896489064891648926489364894648956489664897648986489964900649016490264903649046490564906649076490864909649106491164912649136491464915649166491764918649196492064921649226492364924649256492664927649286492964930649316493264933649346493564936649376493864939649406494164942649436494464945649466494764948649496495064951649526495364954649556495664957649586495964960649616496264963649646496564966649676496864969649706497164972649736497464975649766497764978649796498064981649826498364984649856498664987649886498964990649916499264993649946499564996649976499864999650006500165002650036500465005650066500765008650096501065011650126501365014650156501665017650186501965020650216502265023650246502565026650276502865029650306503165032650336503465035650366503765038650396504065041650426504365044650456504665047650486504965050650516505265053650546505565056650576505865059650606506165062650636506465065650666506765068650696507065071650726507365074650756507665077650786507965080650816508265083650846508565086650876508865089650906509165092650936509465095650966509765098650996510065101651026510365104651056510665107651086510965110651116511265113651146511565116651176511865119651206512165122651236512465125651266512765128651296513065131651326513365134651356513665137651386513965140651416514265143651446514565146651476514865149651506515165152651536515465155651566515765158651596516065161651626516365164651656516665167651686516965170651716517265173651746517565176651776517865179651806518165182651836518465185651866518765188651896519065191651926519365194651956519665197651986519965200652016520265203652046520565206652076520865209652106521165212652136521465215652166521765218652196522065221652226522365224652256522665227652286522965230652316523265233652346523565236652376523865239652406524165242652436524465245652466524765248652496525065251652526525365254652556525665257652586525965260652616526265263652646526565266652676526865269652706527165272652736527465275652766527765278652796528065281652826528365284652856528665287652886528965290652916529265293652946529565296652976529865299653006530165302653036530465305653066530765308653096531065311653126531365314653156531665317653186531965320653216532265323653246532565326653276532865329653306533165332653336533465335653366533765338653396534065341653426534365344653456534665347653486534965350653516535265353653546535565356653576535865359653606536165362653636536465365653666536765368653696537065371653726537365374653756537665377653786537965380653816538265383653846538565386653876538865389653906539165392653936539465395653966539765398653996540065401654026540365404654056540665407654086540965410654116541265413654146541565416654176541865419654206542165422654236542465425654266542765428654296543065431654326543365434654356543665437654386543965440654416544265443654446544565446654476544865449654506545165452654536545465455654566545765458654596546065461654626546365464654656546665467654686546965470654716547265473654746547565476654776547865479654806548165482654836548465485654866548765488654896549065491654926549365494654956549665497654986549965500655016550265503655046550565506655076550865509655106551165512655136551465515655166551765518655196552065521655226552365524655256552665527655286552965530655316553265533655346553565536655376553865539655406554165542655436554465545655466554765548655496555065551655526555365554655556555665557655586555965560655616556265563655646556565566655676556865569655706557165572655736557465575655766557765578655796558065581655826558365584655856558665587655886558965590655916559265593655946559565596655976559865599656006560165602656036560465605656066560765608656096561065611656126561365614656156561665617656186561965620656216562265623656246562565626656276562865629656306563165632656336563465635656366563765638656396564065641656426564365644656456564665647656486564965650656516565265653656546565565656656576565865659656606566165662656636566465665656666566765668656696567065671656726567365674656756567665677656786567965680656816568265683656846568565686656876568865689656906569165692656936569465695656966569765698656996570065701657026570365704657056570665707657086570965710657116571265713657146571565716657176571865719657206572165722657236572465725657266572765728657296573065731657326573365734657356573665737657386573965740657416574265743657446574565746657476574865749657506575165752657536575465755657566575765758657596576065761657626576365764657656576665767657686576965770657716577265773657746577565776657776577865779657806578165782657836578465785657866578765788657896579065791657926579365794657956579665797657986579965800658016580265803658046580565806658076580865809658106581165812658136581465815658166581765818658196582065821658226582365824658256582665827658286582965830658316583265833658346583565836658376583865839658406584165842658436584465845658466584765848658496585065851658526585365854658556585665857658586585965860658616586265863658646586565866658676586865869658706587165872658736587465875658766587765878658796588065881658826588365884658856588665887658886588965890658916589265893658946589565896658976589865899659006590165902659036590465905659066590765908659096591065911659126591365914659156591665917659186591965920659216592265923659246592565926659276592865929659306593165932659336593465935659366593765938659396594065941659426594365944659456594665947659486594965950659516595265953659546595565956659576595865959659606596165962659636596465965659666596765968659696597065971659726597365974659756597665977659786597965980659816598265983659846598565986659876598865989659906599165992659936599465995659966599765998659996600066001660026600366004660056600666007660086600966010660116601266013660146601566016660176601866019660206602166022660236602466025660266602766028660296603066031660326603366034660356603666037660386603966040660416604266043660446604566046660476604866049660506605166052660536605466055660566605766058660596606066061660626606366064660656606666067660686606966070660716607266073660746607566076660776607866079660806608166082660836608466085660866608766088660896609066091660926609366094660956609666097660986609966100661016610266103661046610566106661076610866109661106611166112661136611466115661166611766118661196612066121661226612366124661256612666127661286612966130661316613266133661346613566136661376613866139661406614166142661436614466145661466614766148661496615066151661526615366154661556615666157661586615966160661616616266163661646616566166661676616866169661706617166172661736617466175661766617766178661796618066181661826618366184661856618666187661886618966190661916619266193661946619566196661976619866199662006620166202662036620466205662066620766208662096621066211662126621366214662156621666217662186621966220662216622266223662246622566226662276622866229662306623166232662336623466235662366623766238662396624066241662426624366244662456624666247662486624966250662516625266253662546625566256662576625866259662606626166262662636626466265662666626766268662696627066271662726627366274662756627666277662786627966280662816628266283662846628566286662876628866289662906629166292662936629466295662966629766298662996630066301663026630366304663056630666307663086630966310663116631266313663146631566316663176631866319663206632166322663236632466325663266632766328663296633066331663326633366334663356633666337663386633966340663416634266343663446634566346663476634866349663506635166352663536635466355
  1. // #include "config/config.h"
  2. #ifndef ENTT_CONFIG_CONFIG_H
  3. #define ENTT_CONFIG_CONFIG_H
  4. // #include "version.h"
  5. #ifndef ENTT_CONFIG_VERSION_H
  6. #define ENTT_CONFIG_VERSION_H
  7. // #include "macro.h"
  8. #ifndef ENTT_CONFIG_MACRO_H
  9. #define ENTT_CONFIG_MACRO_H
  10. #define ENTT_STR(arg) #arg
  11. #define ENTT_XSTR(arg) ENTT_STR(arg)
  12. #endif
  13. #define ENTT_VERSION_MAJOR 3
  14. #define ENTT_VERSION_MINOR 10
  15. #define ENTT_VERSION_PATCH 3
  16. #define ENTT_VERSION \
  17. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  18. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  19. #endif
  20. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  21. # define ENTT_THROW throw
  22. # define ENTT_TRY try
  23. # define ENTT_CATCH catch(...)
  24. #else
  25. # define ENTT_THROW
  26. # define ENTT_TRY if(true)
  27. # define ENTT_CATCH if(false)
  28. #endif
  29. #ifndef ENTT_NOEXCEPT
  30. # define ENTT_NOEXCEPT noexcept
  31. # define ENTT_NOEXCEPT_IF(expr) noexcept(expr)
  32. # else
  33. # define ENTT_NOEXCEPT_IF(...)
  34. #endif
  35. #ifdef ENTT_USE_ATOMIC
  36. # include <atomic>
  37. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  38. #else
  39. # define ENTT_MAYBE_ATOMIC(Type) Type
  40. #endif
  41. #ifndef ENTT_ID_TYPE
  42. # include <cstdint>
  43. # define ENTT_ID_TYPE std::uint32_t
  44. #endif
  45. #ifndef ENTT_SPARSE_PAGE
  46. # define ENTT_SPARSE_PAGE 4096
  47. #endif
  48. #ifndef ENTT_PACKED_PAGE
  49. # define ENTT_PACKED_PAGE 1024
  50. #endif
  51. #ifdef ENTT_DISABLE_ASSERT
  52. # undef ENTT_ASSERT
  53. # define ENTT_ASSERT(...) (void(0))
  54. #elif !defined ENTT_ASSERT
  55. # include <cassert>
  56. # define ENTT_ASSERT(condition, ...) assert(condition)
  57. #endif
  58. #ifdef ENTT_NO_ETO
  59. # define ENTT_IGNORE_IF_EMPTY false
  60. #else
  61. # define ENTT_IGNORE_IF_EMPTY true
  62. #endif
  63. #ifdef ENTT_STANDARD_CPP
  64. # define ENTT_NONSTD false
  65. #else
  66. # define ENTT_NONSTD true
  67. # if defined __clang__ || defined __GNUC__
  68. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  69. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  70. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  71. # elif defined _MSC_VER
  72. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  73. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  74. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  75. # endif
  76. #endif
  77. #if defined _MSC_VER
  78. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  79. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  80. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  81. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  82. #endif
  83. #endif
  84. // #include "config/macro.h"
  85. #ifndef ENTT_CONFIG_MACRO_H
  86. #define ENTT_CONFIG_MACRO_H
  87. #define ENTT_STR(arg) #arg
  88. #define ENTT_XSTR(arg) ENTT_STR(arg)
  89. #endif
  90. // #include "config/version.h"
  91. #ifndef ENTT_CONFIG_VERSION_H
  92. #define ENTT_CONFIG_VERSION_H
  93. // #include "macro.h"
  94. #define ENTT_VERSION_MAJOR 3
  95. #define ENTT_VERSION_MINOR 10
  96. #define ENTT_VERSION_PATCH 3
  97. #define ENTT_VERSION \
  98. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  99. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  100. #endif
  101. // #include "container/dense_map.hpp"
  102. #ifndef ENTT_CONTAINER_DENSE_MAP_HPP
  103. #define ENTT_CONTAINER_DENSE_MAP_HPP
  104. #include <algorithm>
  105. #include <cmath>
  106. #include <cstddef>
  107. #include <functional>
  108. #include <iterator>
  109. #include <limits>
  110. #include <memory>
  111. #include <tuple>
  112. #include <type_traits>
  113. #include <utility>
  114. #include <vector>
  115. // #include "../config/config.h"
  116. #ifndef ENTT_CONFIG_CONFIG_H
  117. #define ENTT_CONFIG_CONFIG_H
  118. // #include "version.h"
  119. #ifndef ENTT_CONFIG_VERSION_H
  120. #define ENTT_CONFIG_VERSION_H
  121. // #include "macro.h"
  122. #ifndef ENTT_CONFIG_MACRO_H
  123. #define ENTT_CONFIG_MACRO_H
  124. #define ENTT_STR(arg) #arg
  125. #define ENTT_XSTR(arg) ENTT_STR(arg)
  126. #endif
  127. #define ENTT_VERSION_MAJOR 3
  128. #define ENTT_VERSION_MINOR 10
  129. #define ENTT_VERSION_PATCH 3
  130. #define ENTT_VERSION \
  131. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  132. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  133. #endif
  134. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  135. # define ENTT_THROW throw
  136. # define ENTT_TRY try
  137. # define ENTT_CATCH catch(...)
  138. #else
  139. # define ENTT_THROW
  140. # define ENTT_TRY if(true)
  141. # define ENTT_CATCH if(false)
  142. #endif
  143. #ifndef ENTT_NOEXCEPT
  144. # define ENTT_NOEXCEPT noexcept
  145. # define ENTT_NOEXCEPT_IF(expr) noexcept(expr)
  146. # else
  147. # define ENTT_NOEXCEPT_IF(...)
  148. #endif
  149. #ifdef ENTT_USE_ATOMIC
  150. # include <atomic>
  151. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  152. #else
  153. # define ENTT_MAYBE_ATOMIC(Type) Type
  154. #endif
  155. #ifndef ENTT_ID_TYPE
  156. # include <cstdint>
  157. # define ENTT_ID_TYPE std::uint32_t
  158. #endif
  159. #ifndef ENTT_SPARSE_PAGE
  160. # define ENTT_SPARSE_PAGE 4096
  161. #endif
  162. #ifndef ENTT_PACKED_PAGE
  163. # define ENTT_PACKED_PAGE 1024
  164. #endif
  165. #ifdef ENTT_DISABLE_ASSERT
  166. # undef ENTT_ASSERT
  167. # define ENTT_ASSERT(...) (void(0))
  168. #elif !defined ENTT_ASSERT
  169. # include <cassert>
  170. # define ENTT_ASSERT(condition, ...) assert(condition)
  171. #endif
  172. #ifdef ENTT_NO_ETO
  173. # define ENTT_IGNORE_IF_EMPTY false
  174. #else
  175. # define ENTT_IGNORE_IF_EMPTY true
  176. #endif
  177. #ifdef ENTT_STANDARD_CPP
  178. # define ENTT_NONSTD false
  179. #else
  180. # define ENTT_NONSTD true
  181. # if defined __clang__ || defined __GNUC__
  182. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  183. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  184. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  185. # elif defined _MSC_VER
  186. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  187. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  188. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  189. # endif
  190. #endif
  191. #if defined _MSC_VER
  192. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  193. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  194. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  195. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  196. #endif
  197. #endif
  198. // #include "../core/compressed_pair.hpp"
  199. #ifndef ENTT_CORE_COMPRESSED_PAIR_HPP
  200. #define ENTT_CORE_COMPRESSED_PAIR_HPP
  201. #include <cstddef>
  202. #include <tuple>
  203. #include <type_traits>
  204. #include <utility>
  205. // #include "../config/config.h"
  206. #ifndef ENTT_CONFIG_CONFIG_H
  207. #define ENTT_CONFIG_CONFIG_H
  208. // #include "version.h"
  209. #ifndef ENTT_CONFIG_VERSION_H
  210. #define ENTT_CONFIG_VERSION_H
  211. // #include "macro.h"
  212. #ifndef ENTT_CONFIG_MACRO_H
  213. #define ENTT_CONFIG_MACRO_H
  214. #define ENTT_STR(arg) #arg
  215. #define ENTT_XSTR(arg) ENTT_STR(arg)
  216. #endif
  217. #define ENTT_VERSION_MAJOR 3
  218. #define ENTT_VERSION_MINOR 10
  219. #define ENTT_VERSION_PATCH 3
  220. #define ENTT_VERSION \
  221. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  222. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  223. #endif
  224. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  225. # define ENTT_THROW throw
  226. # define ENTT_TRY try
  227. # define ENTT_CATCH catch(...)
  228. #else
  229. # define ENTT_THROW
  230. # define ENTT_TRY if(true)
  231. # define ENTT_CATCH if(false)
  232. #endif
  233. #ifndef ENTT_NOEXCEPT
  234. # define ENTT_NOEXCEPT noexcept
  235. # define ENTT_NOEXCEPT_IF(expr) noexcept(expr)
  236. # else
  237. # define ENTT_NOEXCEPT_IF(...)
  238. #endif
  239. #ifdef ENTT_USE_ATOMIC
  240. # include <atomic>
  241. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  242. #else
  243. # define ENTT_MAYBE_ATOMIC(Type) Type
  244. #endif
  245. #ifndef ENTT_ID_TYPE
  246. # include <cstdint>
  247. # define ENTT_ID_TYPE std::uint32_t
  248. #endif
  249. #ifndef ENTT_SPARSE_PAGE
  250. # define ENTT_SPARSE_PAGE 4096
  251. #endif
  252. #ifndef ENTT_PACKED_PAGE
  253. # define ENTT_PACKED_PAGE 1024
  254. #endif
  255. #ifdef ENTT_DISABLE_ASSERT
  256. # undef ENTT_ASSERT
  257. # define ENTT_ASSERT(...) (void(0))
  258. #elif !defined ENTT_ASSERT
  259. # include <cassert>
  260. # define ENTT_ASSERT(condition, ...) assert(condition)
  261. #endif
  262. #ifdef ENTT_NO_ETO
  263. # define ENTT_IGNORE_IF_EMPTY false
  264. #else
  265. # define ENTT_IGNORE_IF_EMPTY true
  266. #endif
  267. #ifdef ENTT_STANDARD_CPP
  268. # define ENTT_NONSTD false
  269. #else
  270. # define ENTT_NONSTD true
  271. # if defined __clang__ || defined __GNUC__
  272. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  273. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  274. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  275. # elif defined _MSC_VER
  276. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  277. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  278. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  279. # endif
  280. #endif
  281. #if defined _MSC_VER
  282. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  283. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  284. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  285. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  286. #endif
  287. #endif
  288. // #include "type_traits.hpp"
  289. #ifndef ENTT_CORE_TYPE_TRAITS_HPP
  290. #define ENTT_CORE_TYPE_TRAITS_HPP
  291. #include <cstddef>
  292. #include <iterator>
  293. #include <type_traits>
  294. #include <utility>
  295. // #include "../config/config.h"
  296. // #include "fwd.hpp"
  297. #ifndef ENTT_CORE_FWD_HPP
  298. #define ENTT_CORE_FWD_HPP
  299. #include <cstdint>
  300. #include <type_traits>
  301. // #include "../config/config.h"
  302. namespace entt {
  303. template<std::size_t Len = sizeof(double[2]), std::size_t = alignof(typename std::aligned_storage_t<Len + !Len>)>
  304. class basic_any;
  305. /*! @brief Alias declaration for type identifiers. */
  306. using id_type = ENTT_ID_TYPE;
  307. /*! @brief Alias declaration for the most common use case. */
  308. using any = basic_any<>;
  309. } // namespace entt
  310. #endif
  311. namespace entt {
  312. /**
  313. * @brief Utility class to disambiguate overloaded functions.
  314. * @tparam N Number of choices available.
  315. */
  316. template<std::size_t N>
  317. struct choice_t
  318. // Unfortunately, doxygen cannot parse such a construct.
  319. : /*! @cond TURN_OFF_DOXYGEN */ choice_t<N - 1> /*! @endcond */
  320. {};
  321. /*! @copybrief choice_t */
  322. template<>
  323. struct choice_t<0> {};
  324. /**
  325. * @brief Variable template for the choice trick.
  326. * @tparam N Number of choices available.
  327. */
  328. template<std::size_t N>
  329. inline constexpr choice_t<N> choice{};
  330. /**
  331. * @brief Identity type trait.
  332. *
  333. * Useful to establish non-deduced contexts in template argument deduction
  334. * (waiting for C++20) or to provide types through function arguments.
  335. *
  336. * @tparam Type A type.
  337. */
  338. template<typename Type>
  339. struct type_identity {
  340. /*! @brief Identity type. */
  341. using type = Type;
  342. };
  343. /**
  344. * @brief Helper type.
  345. * @tparam Type A type.
  346. */
  347. template<typename Type>
  348. using type_identity_t = typename type_identity<Type>::type;
  349. /**
  350. * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains.
  351. * @tparam Type The type of which to return the size.
  352. * @tparam The size of the type if `sizeof` accepts it, 0 otherwise.
  353. */
  354. template<typename Type, typename = void>
  355. struct size_of: std::integral_constant<std::size_t, 0u> {};
  356. /*! @copydoc size_of */
  357. template<typename Type>
  358. struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
  359. : std::integral_constant<std::size_t, sizeof(Type)> {};
  360. /**
  361. * @brief Helper variable template.
  362. * @tparam Type The type of which to return the size.
  363. */
  364. template<typename Type>
  365. inline constexpr std::size_t size_of_v = size_of<Type>::value;
  366. /**
  367. * @brief Using declaration to be used to _repeat_ the same type a number of
  368. * times equal to the size of a given parameter pack.
  369. * @tparam Type A type to repeat.
  370. */
  371. template<typename Type, typename>
  372. using unpack_as_type = Type;
  373. /**
  374. * @brief Helper variable template to be used to _repeat_ the same value a
  375. * number of times equal to the size of a given parameter pack.
  376. * @tparam Value A value to repeat.
  377. */
  378. template<auto Value, typename>
  379. inline constexpr auto unpack_as_value = Value;
  380. /**
  381. * @brief Wraps a static constant.
  382. * @tparam Value A static constant.
  383. */
  384. template<auto Value>
  385. using integral_constant = std::integral_constant<decltype(Value), Value>;
  386. /**
  387. * @brief Alias template to facilitate the creation of named values.
  388. * @tparam Value A constant value at least convertible to `id_type`.
  389. */
  390. template<id_type Value>
  391. using tag = integral_constant<Value>;
  392. /**
  393. * @brief A class to use to push around lists of types, nothing more.
  394. * @tparam Type Types provided by the type list.
  395. */
  396. template<typename... Type>
  397. struct type_list {
  398. /*! @brief Type list type. */
  399. using type = type_list;
  400. /*! @brief Compile-time number of elements in the type list. */
  401. static constexpr auto size = sizeof...(Type);
  402. };
  403. /*! @brief Primary template isn't defined on purpose. */
  404. template<std::size_t, typename>
  405. struct type_list_element;
  406. /**
  407. * @brief Provides compile-time indexed access to the types of a type list.
  408. * @tparam Index Index of the type to return.
  409. * @tparam Type First type provided by the type list.
  410. * @tparam Other Other types provided by the type list.
  411. */
  412. template<std::size_t Index, typename Type, typename... Other>
  413. struct type_list_element<Index, type_list<Type, Other...>>
  414. : type_list_element<Index - 1u, type_list<Other...>> {};
  415. /**
  416. * @brief Provides compile-time indexed access to the types of a type list.
  417. * @tparam Type First type provided by the type list.
  418. * @tparam Other Other types provided by the type list.
  419. */
  420. template<typename Type, typename... Other>
  421. struct type_list_element<0u, type_list<Type, Other...>> {
  422. /*! @brief Searched type. */
  423. using type = Type;
  424. };
  425. /**
  426. * @brief Helper type.
  427. * @tparam Index Index of the type to return.
  428. * @tparam List Type list to search into.
  429. */
  430. template<std::size_t Index, typename List>
  431. using type_list_element_t = typename type_list_element<Index, List>::type;
  432. /**
  433. * @brief Concatenates multiple type lists.
  434. * @tparam Type Types provided by the first type list.
  435. * @tparam Other Types provided by the second type list.
  436. * @return A type list composed by the types of both the type lists.
  437. */
  438. template<typename... Type, typename... Other>
  439. constexpr type_list<Type..., Other...> operator+(type_list<Type...>, type_list<Other...>) {
  440. return {};
  441. }
  442. /*! @brief Primary template isn't defined on purpose. */
  443. template<typename...>
  444. struct type_list_cat;
  445. /*! @brief Concatenates multiple type lists. */
  446. template<>
  447. struct type_list_cat<> {
  448. /*! @brief A type list composed by the types of all the type lists. */
  449. using type = type_list<>;
  450. };
  451. /**
  452. * @brief Concatenates multiple type lists.
  453. * @tparam Type Types provided by the first type list.
  454. * @tparam Other Types provided by the second type list.
  455. * @tparam List Other type lists, if any.
  456. */
  457. template<typename... Type, typename... Other, typename... List>
  458. struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
  459. /*! @brief A type list composed by the types of all the type lists. */
  460. using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
  461. };
  462. /**
  463. * @brief Concatenates multiple type lists.
  464. * @tparam Type Types provided by the type list.
  465. */
  466. template<typename... Type>
  467. struct type_list_cat<type_list<Type...>> {
  468. /*! @brief A type list composed by the types of all the type lists. */
  469. using type = type_list<Type...>;
  470. };
  471. /**
  472. * @brief Helper type.
  473. * @tparam List Type lists to concatenate.
  474. */
  475. template<typename... List>
  476. using type_list_cat_t = typename type_list_cat<List...>::type;
  477. /*! @brief Primary template isn't defined on purpose. */
  478. template<typename>
  479. struct type_list_unique;
  480. /**
  481. * @brief Removes duplicates types from a type list.
  482. * @tparam Type One of the types provided by the given type list.
  483. * @tparam Other The other types provided by the given type list.
  484. */
  485. template<typename Type, typename... Other>
  486. struct type_list_unique<type_list<Type, Other...>> {
  487. /*! @brief A type list without duplicate types. */
  488. using type = std::conditional_t<
  489. (std::is_same_v<Type, Other> || ...),
  490. typename type_list_unique<type_list<Other...>>::type,
  491. type_list_cat_t<type_list<Type>, typename type_list_unique<type_list<Other...>>::type>>;
  492. };
  493. /*! @brief Removes duplicates types from a type list. */
  494. template<>
  495. struct type_list_unique<type_list<>> {
  496. /*! @brief A type list without duplicate types. */
  497. using type = type_list<>;
  498. };
  499. /**
  500. * @brief Helper type.
  501. * @tparam Type A type list.
  502. */
  503. template<typename Type>
  504. using type_list_unique_t = typename type_list_unique<Type>::type;
  505. /**
  506. * @brief Provides the member constant `value` to true if a type list contains a
  507. * given type, false otherwise.
  508. * @tparam List Type list.
  509. * @tparam Type Type to look for.
  510. */
  511. template<typename List, typename Type>
  512. struct type_list_contains;
  513. /**
  514. * @copybrief type_list_contains
  515. * @tparam Type Types provided by the type list.
  516. * @tparam Other Type to look for.
  517. */
  518. template<typename... Type, typename Other>
  519. struct type_list_contains<type_list<Type...>, Other>: std::disjunction<std::is_same<Type, Other>...> {};
  520. /**
  521. * @brief Helper variable template.
  522. * @tparam List Type list.
  523. * @tparam Type Type to look for.
  524. */
  525. template<typename List, typename Type>
  526. inline constexpr bool type_list_contains_v = type_list_contains<List, Type>::value;
  527. /*! @brief Primary template isn't defined on purpose. */
  528. template<typename...>
  529. struct type_list_diff;
  530. /**
  531. * @brief Computes the difference between two type lists.
  532. * @tparam Type Types provided by the first type list.
  533. * @tparam Other Types provided by the second type list.
  534. */
  535. template<typename... Type, typename... Other>
  536. struct type_list_diff<type_list<Type...>, type_list<Other...>> {
  537. /*! @brief A type list that is the difference between the two type lists. */
  538. using type = type_list_cat_t<std::conditional_t<type_list_contains_v<type_list<Other...>, Type>, type_list<>, type_list<Type>>...>;
  539. };
  540. /**
  541. * @brief Helper type.
  542. * @tparam List Type lists between which to compute the difference.
  543. */
  544. template<typename... List>
  545. using type_list_diff_t = typename type_list_diff<List...>::type;
  546. /**
  547. * @brief A class to use to push around lists of constant values, nothing more.
  548. * @tparam Value Values provided by the value list.
  549. */
  550. template<auto... Value>
  551. struct value_list {
  552. /*! @brief Value list type. */
  553. using type = value_list;
  554. /*! @brief Compile-time number of elements in the value list. */
  555. static constexpr auto size = sizeof...(Value);
  556. };
  557. /*! @brief Primary template isn't defined on purpose. */
  558. template<std::size_t, typename>
  559. struct value_list_element;
  560. /**
  561. * @brief Provides compile-time indexed access to the values of a value list.
  562. * @tparam Index Index of the value to return.
  563. * @tparam Value First value provided by the value list.
  564. * @tparam Other Other values provided by the value list.
  565. */
  566. template<std::size_t Index, auto Value, auto... Other>
  567. struct value_list_element<Index, value_list<Value, Other...>>
  568. : value_list_element<Index - 1u, value_list<Other...>> {};
  569. /**
  570. * @brief Provides compile-time indexed access to the types of a type list.
  571. * @tparam Value First value provided by the value list.
  572. * @tparam Other Other values provided by the value list.
  573. */
  574. template<auto Value, auto... Other>
  575. struct value_list_element<0u, value_list<Value, Other...>> {
  576. /*! @brief Searched value. */
  577. static constexpr auto value = Value;
  578. };
  579. /**
  580. * @brief Helper type.
  581. * @tparam Index Index of the value to return.
  582. * @tparam List Value list to search into.
  583. */
  584. template<std::size_t Index, typename List>
  585. inline constexpr auto value_list_element_v = value_list_element<Index, List>::value;
  586. /**
  587. * @brief Concatenates multiple value lists.
  588. * @tparam Value Values provided by the first value list.
  589. * @tparam Other Values provided by the second value list.
  590. * @return A value list composed by the values of both the value lists.
  591. */
  592. template<auto... Value, auto... Other>
  593. constexpr value_list<Value..., Other...> operator+(value_list<Value...>, value_list<Other...>) {
  594. return {};
  595. }
  596. /*! @brief Primary template isn't defined on purpose. */
  597. template<typename...>
  598. struct value_list_cat;
  599. /*! @brief Concatenates multiple value lists. */
  600. template<>
  601. struct value_list_cat<> {
  602. /*! @brief A value list composed by the values of all the value lists. */
  603. using type = value_list<>;
  604. };
  605. /**
  606. * @brief Concatenates multiple value lists.
  607. * @tparam Value Values provided by the first value list.
  608. * @tparam Other Values provided by the second value list.
  609. * @tparam List Other value lists, if any.
  610. */
  611. template<auto... Value, auto... Other, typename... List>
  612. struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
  613. /*! @brief A value list composed by the values of all the value lists. */
  614. using type = typename value_list_cat<value_list<Value..., Other...>, List...>::type;
  615. };
  616. /**
  617. * @brief Concatenates multiple value lists.
  618. * @tparam Value Values provided by the value list.
  619. */
  620. template<auto... Value>
  621. struct value_list_cat<value_list<Value...>> {
  622. /*! @brief A value list composed by the values of all the value lists. */
  623. using type = value_list<Value...>;
  624. };
  625. /**
  626. * @brief Helper type.
  627. * @tparam List Value lists to concatenate.
  628. */
  629. template<typename... List>
  630. using value_list_cat_t = typename value_list_cat<List...>::type;
  631. /*! @brief Same as std::is_invocable, but with tuples. */
  632. template<typename, typename>
  633. struct is_applicable: std::false_type {};
  634. /**
  635. * @copybrief is_applicable
  636. * @tparam Func A valid function type.
  637. * @tparam Tuple Tuple-like type.
  638. * @tparam Args The list of arguments to use to probe the function type.
  639. */
  640. template<typename Func, template<typename...> class Tuple, typename... Args>
  641. struct is_applicable<Func, Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  642. /**
  643. * @copybrief is_applicable
  644. * @tparam Func A valid function type.
  645. * @tparam Tuple Tuple-like type.
  646. * @tparam Args The list of arguments to use to probe the function type.
  647. */
  648. template<typename Func, template<typename...> class Tuple, typename... Args>
  649. struct is_applicable<Func, const Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  650. /**
  651. * @brief Helper variable template.
  652. * @tparam Func A valid function type.
  653. * @tparam Args The list of arguments to use to probe the function type.
  654. */
  655. template<typename Func, typename Args>
  656. inline constexpr bool is_applicable_v = is_applicable<Func, Args>::value;
  657. /*! @brief Same as std::is_invocable_r, but with tuples for arguments. */
  658. template<typename, typename, typename>
  659. struct is_applicable_r: std::false_type {};
  660. /**
  661. * @copybrief is_applicable_r
  662. * @tparam Ret The type to which the return type of the function should be
  663. * convertible.
  664. * @tparam Func A valid function type.
  665. * @tparam Args The list of arguments to use to probe the function type.
  666. */
  667. template<typename Ret, typename Func, typename... Args>
  668. struct is_applicable_r<Ret, Func, std::tuple<Args...>>: std::is_invocable_r<Ret, Func, Args...> {};
  669. /**
  670. * @brief Helper variable template.
  671. * @tparam Ret The type to which the return type of the function should be
  672. * convertible.
  673. * @tparam Func A valid function type.
  674. * @tparam Args The list of arguments to use to probe the function type.
  675. */
  676. template<typename Ret, typename Func, typename Args>
  677. inline constexpr bool is_applicable_r_v = is_applicable_r<Ret, Func, Args>::value;
  678. /**
  679. * @brief Provides the member constant `value` to true if a given type is
  680. * complete, false otherwise.
  681. * @tparam Type The type to test.
  682. */
  683. template<typename Type, typename = void>
  684. struct is_complete: std::false_type {};
  685. /*! @copydoc is_complete */
  686. template<typename Type>
  687. struct is_complete<Type, std::void_t<decltype(sizeof(Type))>>: std::true_type {};
  688. /**
  689. * @brief Helper variable template.
  690. * @tparam Type The type to test.
  691. */
  692. template<typename Type>
  693. inline constexpr bool is_complete_v = is_complete<Type>::value;
  694. /**
  695. * @brief Provides the member constant `value` to true if a given type is an
  696. * iterator, false otherwise.
  697. * @tparam Type The type to test.
  698. */
  699. template<typename Type, typename = void>
  700. struct is_iterator: std::false_type {};
  701. /**
  702. * @cond TURN_OFF_DOXYGEN
  703. * Internal details not to be documented.
  704. */
  705. namespace internal {
  706. template<typename, typename = void>
  707. struct has_iterator_category: std::false_type {};
  708. template<typename Type>
  709. struct has_iterator_category<Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>: std::true_type {};
  710. } // namespace internal
  711. /**
  712. * Internal details not to be documented.
  713. * @endcond
  714. */
  715. /*! @copydoc is_iterator */
  716. template<typename Type>
  717. struct is_iterator<Type, std::enable_if_t<!std::is_same_v<std::remove_const_t<std::remove_pointer_t<Type>>, void>>>
  718. : internal::has_iterator_category<Type> {};
  719. /**
  720. * @brief Helper variable template.
  721. * @tparam Type The type to test.
  722. */
  723. template<typename Type>
  724. inline constexpr bool is_iterator_v = is_iterator<Type>::value;
  725. /**
  726. * @brief Provides the member constant `value` to true if a given type is both
  727. * an empty and non-final class, false otherwise.
  728. * @tparam Type The type to test
  729. */
  730. template<typename Type>
  731. struct is_ebco_eligible
  732. : std::conjunction<std::is_empty<Type>, std::negation<std::is_final<Type>>> {};
  733. /**
  734. * @brief Helper variable template.
  735. * @tparam Type The type to test.
  736. */
  737. template<typename Type>
  738. inline constexpr bool is_ebco_eligible_v = is_ebco_eligible<Type>::value;
  739. /**
  740. * @brief Provides the member constant `value` to true if `Type::is_transparent`
  741. * is valid and denotes a type, false otherwise.
  742. * @tparam Type The type to test.
  743. */
  744. template<typename Type, typename = void>
  745. struct is_transparent: std::false_type {};
  746. /*! @copydoc is_transparent */
  747. template<typename Type>
  748. struct is_transparent<Type, std::void_t<typename Type::is_transparent>>: std::true_type {};
  749. /**
  750. * @brief Helper variable template.
  751. * @tparam Type The type to test.
  752. */
  753. template<typename Type>
  754. inline constexpr bool is_transparent_v = is_transparent<Type>::value;
  755. /**
  756. * @brief Provides the member constant `value` to true if a given type is
  757. * equality comparable, false otherwise.
  758. * @tparam Type The type to test.
  759. */
  760. template<typename Type, typename = void>
  761. struct is_equality_comparable: std::false_type {};
  762. /**
  763. * @cond TURN_OFF_DOXYGEN
  764. * Internal details not to be documented.
  765. */
  766. namespace internal {
  767. template<typename, typename = void>
  768. struct has_tuple_size_value: std::false_type {};
  769. template<typename Type>
  770. struct has_tuple_size_value<Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>: std::true_type {};
  771. template<typename Type, std::size_t... Index>
  772. [[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
  773. return (is_equality_comparable<std::tuple_element_t<Index, Type>>::value && ...);
  774. }
  775. template<typename>
  776. [[nodiscard]] constexpr bool maybe_equality_comparable(choice_t<0>) {
  777. return true;
  778. }
  779. template<typename Type>
  780. [[nodiscard]] constexpr auto maybe_equality_comparable(choice_t<1>) -> decltype(std::declval<typename Type::value_type>(), bool{}) {
  781. if constexpr(is_iterator_v<Type>) {
  782. return true;
  783. } else if constexpr(std::is_same_v<typename Type::value_type, Type>) {
  784. return maybe_equality_comparable<Type>(choice<0>);
  785. } else {
  786. return is_equality_comparable<typename Type::value_type>::value;
  787. }
  788. }
  789. template<typename Type>
  790. [[nodiscard]] constexpr std::enable_if_t<is_complete_v<std::tuple_size<std::remove_const_t<Type>>>, bool> maybe_equality_comparable(choice_t<2>) {
  791. if constexpr(has_tuple_size_value<Type>::value) {
  792. return unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
  793. } else {
  794. return maybe_equality_comparable<Type>(choice<1>);
  795. }
  796. }
  797. } // namespace internal
  798. /**
  799. * Internal details not to be documented.
  800. * @endcond
  801. */
  802. /*! @copydoc is_equality_comparable */
  803. template<typename Type>
  804. struct is_equality_comparable<Type, std::void_t<decltype(std::declval<Type>() == std::declval<Type>())>>
  805. : std::bool_constant<internal::maybe_equality_comparable<Type>(choice<2>)> {};
  806. /**
  807. * @brief Helper variable template.
  808. * @tparam Type The type to test.
  809. */
  810. template<typename Type>
  811. inline constexpr bool is_equality_comparable_v = is_equality_comparable<Type>::value;
  812. /**
  813. * @brief Transcribes the constness of a type to another type.
  814. * @tparam To The type to which to transcribe the constness.
  815. * @tparam From The type from which to transcribe the constness.
  816. */
  817. template<typename To, typename From>
  818. struct constness_as {
  819. /*! @brief The type resulting from the transcription of the constness. */
  820. using type = std::remove_const_t<To>;
  821. };
  822. /*! @copydoc constness_as */
  823. template<typename To, typename From>
  824. struct constness_as<To, const From> {
  825. /*! @brief The type resulting from the transcription of the constness. */
  826. using type = std::add_const_t<To>;
  827. };
  828. /**
  829. * @brief Alias template to facilitate the transcription of the constness.
  830. * @tparam To The type to which to transcribe the constness.
  831. * @tparam From The type from which to transcribe the constness.
  832. */
  833. template<typename To, typename From>
  834. using constness_as_t = typename constness_as<To, From>::type;
  835. /**
  836. * @brief Extracts the class of a non-static member object or function.
  837. * @tparam Member A pointer to a non-static member object or function.
  838. */
  839. template<typename Member>
  840. class member_class {
  841. static_assert(std::is_member_pointer_v<Member>, "Invalid pointer type to non-static member object or function");
  842. template<typename Class, typename Ret, typename... Args>
  843. static Class *clazz(Ret (Class::*)(Args...));
  844. template<typename Class, typename Ret, typename... Args>
  845. static Class *clazz(Ret (Class::*)(Args...) const);
  846. template<typename Class, typename Type>
  847. static Class *clazz(Type Class::*);
  848. public:
  849. /*! @brief The class of the given non-static member object or function. */
  850. using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
  851. };
  852. /**
  853. * @brief Helper type.
  854. * @tparam Member A pointer to a non-static member object or function.
  855. */
  856. template<typename Member>
  857. using member_class_t = typename member_class<Member>::type;
  858. } // namespace entt
  859. #endif
  860. namespace entt {
  861. /**
  862. * @cond TURN_OFF_DOXYGEN
  863. * Internal details not to be documented.
  864. */
  865. namespace internal {
  866. template<typename Type, std::size_t, typename = void>
  867. struct compressed_pair_element {
  868. using reference = Type &;
  869. using const_reference = const Type &;
  870. template<bool Dummy = true, typename = std::enable_if_t<Dummy && std::is_default_constructible_v<Type>>>
  871. compressed_pair_element()
  872. : value{} {}
  873. template<typename Args, typename = std::enable_if_t<!std::is_same_v<std::remove_cv_t<std::remove_reference_t<Args>>, compressed_pair_element>>>
  874. compressed_pair_element(Args &&args)
  875. : value{std::forward<Args>(args)} {}
  876. template<typename... Args, std::size_t... Index>
  877. compressed_pair_element(std::tuple<Args...> args, std::index_sequence<Index...>)
  878. : value{std::forward<Args>(std::get<Index>(args))...} {}
  879. [[nodiscard]] reference get() ENTT_NOEXCEPT {
  880. return value;
  881. }
  882. [[nodiscard]] const_reference get() const ENTT_NOEXCEPT {
  883. return value;
  884. }
  885. private:
  886. Type value;
  887. };
  888. template<typename Type, std::size_t Tag>
  889. struct compressed_pair_element<Type, Tag, std::enable_if_t<is_ebco_eligible_v<Type>>>: Type {
  890. using reference = Type &;
  891. using const_reference = const Type &;
  892. using base_type = Type;
  893. template<bool Dummy = true, typename = std::enable_if_t<Dummy && std::is_default_constructible_v<base_type>>>
  894. compressed_pair_element()
  895. : base_type{} {}
  896. template<typename Args, typename = std::enable_if_t<!std::is_same_v<std::remove_cv_t<std::remove_reference_t<Args>>, compressed_pair_element>>>
  897. compressed_pair_element(Args &&args)
  898. : base_type{std::forward<Args>(args)} {}
  899. template<typename... Args, std::size_t... Index>
  900. compressed_pair_element(std::tuple<Args...> args, std::index_sequence<Index...>)
  901. : base_type{std::forward<Args>(std::get<Index>(args))...} {}
  902. [[nodiscard]] reference get() ENTT_NOEXCEPT {
  903. return *this;
  904. }
  905. [[nodiscard]] const_reference get() const ENTT_NOEXCEPT {
  906. return *this;
  907. }
  908. };
  909. } // namespace internal
  910. /**
  911. * Internal details not to be documented.
  912. * @endcond
  913. */
  914. /**
  915. * @brief A compressed pair.
  916. *
  917. * A pair that exploits the _Empty Base Class Optimization_ (or _EBCO_) to
  918. * reduce its final size to a minimum.
  919. *
  920. * @tparam First The type of the first element that the pair stores.
  921. * @tparam Second The type of the second element that the pair stores.
  922. */
  923. template<typename First, typename Second>
  924. class compressed_pair final
  925. : internal::compressed_pair_element<First, 0u>,
  926. internal::compressed_pair_element<Second, 1u> {
  927. using first_base = internal::compressed_pair_element<First, 0u>;
  928. using second_base = internal::compressed_pair_element<Second, 1u>;
  929. public:
  930. /*! @brief The type of the first element that the pair stores. */
  931. using first_type = First;
  932. /*! @brief The type of the second element that the pair stores. */
  933. using second_type = Second;
  934. /**
  935. * @brief Default constructor, conditionally enabled.
  936. *
  937. * This constructor is only available when the types that the pair stores
  938. * are both at least default constructible.
  939. *
  940. * @tparam Dummy Dummy template parameter used for internal purposes.
  941. */
  942. template<bool Dummy = true, typename = std::enable_if_t<Dummy && std::is_default_constructible_v<first_type> && std::is_default_constructible_v<second_type>>>
  943. constexpr compressed_pair()
  944. : first_base{},
  945. second_base{} {}
  946. /**
  947. * @brief Copy constructor.
  948. * @param other The instance to copy from.
  949. */
  950. constexpr compressed_pair(const compressed_pair &other) = default;
  951. /**
  952. * @brief Move constructor.
  953. * @param other The instance to move from.
  954. */
  955. constexpr compressed_pair(compressed_pair &&other) = default;
  956. /**
  957. * @brief Constructs a pair from its values.
  958. * @tparam Arg Type of value to use to initialize the first element.
  959. * @tparam Other Type of value to use to initialize the second element.
  960. * @param arg Value to use to initialize the first element.
  961. * @param other Value to use to initialize the second element.
  962. */
  963. template<typename Arg, typename Other>
  964. constexpr compressed_pair(Arg &&arg, Other &&other)
  965. : first_base{std::forward<Arg>(arg)},
  966. second_base{std::forward<Other>(other)} {}
  967. /**
  968. * @brief Constructs a pair by forwarding the arguments to its parts.
  969. * @tparam Args Types of arguments to use to initialize the first element.
  970. * @tparam Other Types of arguments to use to initialize the second element.
  971. * @param args Arguments to use to initialize the first element.
  972. * @param other Arguments to use to initialize the second element.
  973. */
  974. template<typename... Args, typename... Other>
  975. constexpr compressed_pair(std::piecewise_construct_t, std::tuple<Args...> args, std::tuple<Other...> other)
  976. : first_base{std::move(args), std::index_sequence_for<Args...>{}},
  977. second_base{std::move(other), std::index_sequence_for<Other...>{}} {}
  978. /**
  979. * @brief Copy assignment operator.
  980. * @param other The instance to copy from.
  981. * @return This compressed pair object.
  982. */
  983. constexpr compressed_pair &operator=(const compressed_pair &other) = default;
  984. /**
  985. * @brief Move assignment operator.
  986. * @param other The instance to move from.
  987. * @return This compressed pair object.
  988. */
  989. constexpr compressed_pair &operator=(compressed_pair &&other) = default;
  990. /**
  991. * @brief Returns the first element that a pair stores.
  992. * @return The first element that a pair stores.
  993. */
  994. [[nodiscard]] first_type &first() ENTT_NOEXCEPT {
  995. return static_cast<first_base &>(*this).get();
  996. }
  997. /*! @copydoc first */
  998. [[nodiscard]] const first_type &first() const ENTT_NOEXCEPT {
  999. return static_cast<const first_base &>(*this).get();
  1000. }
  1001. /**
  1002. * @brief Returns the second element that a pair stores.
  1003. * @return The second element that a pair stores.
  1004. */
  1005. [[nodiscard]] second_type &second() ENTT_NOEXCEPT {
  1006. return static_cast<second_base &>(*this).get();
  1007. }
  1008. /*! @copydoc second */
  1009. [[nodiscard]] const second_type &second() const ENTT_NOEXCEPT {
  1010. return static_cast<const second_base &>(*this).get();
  1011. }
  1012. /**
  1013. * @brief Swaps two compressed pair objects.
  1014. * @param other The compressed pair to swap with.
  1015. */
  1016. void swap(compressed_pair &other) {
  1017. using std::swap;
  1018. swap(first(), other.first());
  1019. swap(second(), other.second());
  1020. }
  1021. /**
  1022. * @brief Extracts an element from the compressed pair.
  1023. * @tparam Index An integer value that is either 0 or 1.
  1024. * @return Returns a reference to the first element if `Index` is 0 and a
  1025. * reference to the second element if `Index` is 1.
  1026. */
  1027. template<std::size_t Index>
  1028. decltype(auto) get() ENTT_NOEXCEPT {
  1029. if constexpr(Index == 0u) {
  1030. return first();
  1031. } else {
  1032. static_assert(Index == 1u, "Index out of bounds");
  1033. return second();
  1034. }
  1035. }
  1036. /*! @copydoc get */
  1037. template<std::size_t Index>
  1038. decltype(auto) get() const ENTT_NOEXCEPT {
  1039. if constexpr(Index == 0u) {
  1040. return first();
  1041. } else {
  1042. static_assert(Index == 1u, "Index out of bounds");
  1043. return second();
  1044. }
  1045. }
  1046. };
  1047. /**
  1048. * @brief Deduction guide.
  1049. * @tparam Type Type of value to use to initialize the first element.
  1050. * @tparam Other Type of value to use to initialize the second element.
  1051. */
  1052. template<typename Type, typename Other>
  1053. compressed_pair(Type &&, Other &&) -> compressed_pair<std::decay_t<Type>, std::decay_t<Other>>;
  1054. /**
  1055. * @brief Swaps two compressed pair objects.
  1056. * @tparam First The type of the first element that the pairs store.
  1057. * @tparam Second The type of the second element that the pairs store.
  1058. * @param lhs A valid compressed pair object.
  1059. * @param rhs A valid compressed pair object.
  1060. */
  1061. template<typename First, typename Second>
  1062. inline void swap(compressed_pair<First, Second> &lhs, compressed_pair<First, Second> &rhs) {
  1063. lhs.swap(rhs);
  1064. }
  1065. } // namespace entt
  1066. // disable structured binding support for clang 6, it messes when specializing tuple_size
  1067. #if !defined __clang_major__ || __clang_major__ > 6
  1068. namespace std {
  1069. /**
  1070. * @brief `std::tuple_size` specialization for `compressed_pair`s.
  1071. * @tparam First The type of the first element that the pair stores.
  1072. * @tparam Second The type of the second element that the pair stores.
  1073. */
  1074. template<typename First, typename Second>
  1075. struct tuple_size<entt::compressed_pair<First, Second>>: integral_constant<size_t, 2u> {};
  1076. /**
  1077. * @brief `std::tuple_element` specialization for `compressed_pair`s.
  1078. * @tparam Index The index of the type to return.
  1079. * @tparam First The type of the first element that the pair stores.
  1080. * @tparam Second The type of the second element that the pair stores.
  1081. */
  1082. template<size_t Index, typename First, typename Second>
  1083. struct tuple_element<Index, entt::compressed_pair<First, Second>>: conditional<Index == 0u, First, Second> {
  1084. static_assert(Index < 2u, "Index out of bounds");
  1085. };
  1086. } // namespace std
  1087. #endif
  1088. #endif
  1089. // #include "../core/iterator.hpp"
  1090. #ifndef ENTT_CORE_ITERATOR_HPP
  1091. #define ENTT_CORE_ITERATOR_HPP
  1092. #include <iterator>
  1093. #include <memory>
  1094. #include <utility>
  1095. // #include "../config/config.h"
  1096. namespace entt {
  1097. /**
  1098. * @brief Helper type to use as pointer with input iterators.
  1099. * @tparam Type of wrapped value.
  1100. */
  1101. template<typename Type>
  1102. struct input_iterator_pointer final {
  1103. /*! @brief Pointer type. */
  1104. using pointer = Type *;
  1105. /*! @brief Default copy constructor, deleted on purpose. */
  1106. input_iterator_pointer(const input_iterator_pointer &) = delete;
  1107. /*! @brief Default move constructor. */
  1108. input_iterator_pointer(input_iterator_pointer &&) = default;
  1109. /**
  1110. * @brief Constructs a proxy object by move.
  1111. * @param val Value to use to initialize the proxy object.
  1112. */
  1113. input_iterator_pointer(Type &&val)
  1114. : value{std::move(val)} {}
  1115. /**
  1116. * @brief Default copy assignment operator, deleted on purpose.
  1117. * @return This proxy object.
  1118. */
  1119. input_iterator_pointer &operator=(const input_iterator_pointer &) = delete;
  1120. /**
  1121. * @brief Default move assignment operator.
  1122. * @return This proxy object.
  1123. */
  1124. input_iterator_pointer &operator=(input_iterator_pointer &&) = default;
  1125. /**
  1126. * @brief Access operator for accessing wrapped values.
  1127. * @return A pointer to the wrapped value.
  1128. */
  1129. [[nodiscard]] pointer operator->() ENTT_NOEXCEPT {
  1130. return std::addressof(value);
  1131. }
  1132. private:
  1133. Type value;
  1134. };
  1135. /**
  1136. * @brief Utility class to create an iterable object from a pair of iterators.
  1137. * @tparam It Type of iterator.
  1138. * @tparam Sentinel Type of sentinel.
  1139. */
  1140. template<typename It, typename Sentinel = It>
  1141. struct iterable_adaptor final {
  1142. /*! @brief Value type. */
  1143. using value_type = typename std::iterator_traits<It>::value_type;
  1144. /*! @brief Iterator type. */
  1145. using iterator = It;
  1146. /*! @brief Sentinel type. */
  1147. using sentinel = Sentinel;
  1148. /*! @brief Default constructor. */
  1149. iterable_adaptor() = default;
  1150. /**
  1151. * @brief Creates an iterable object from a pair of iterators.
  1152. * @param from Begin iterator.
  1153. * @param to End iterator.
  1154. */
  1155. iterable_adaptor(iterator from, sentinel to)
  1156. : first{from},
  1157. last{to} {}
  1158. /**
  1159. * @brief Returns an iterator to the beginning.
  1160. * @return An iterator to the first element of the range.
  1161. */
  1162. [[nodiscard]] iterator begin() const ENTT_NOEXCEPT {
  1163. return first;
  1164. }
  1165. /**
  1166. * @brief Returns an iterator to the end.
  1167. * @return An iterator to the element following the last element of the
  1168. * range.
  1169. */
  1170. [[nodiscard]] sentinel end() const ENTT_NOEXCEPT {
  1171. return last;
  1172. }
  1173. /*! @copydoc begin */
  1174. [[nodiscard]] iterator cbegin() const ENTT_NOEXCEPT {
  1175. return begin();
  1176. }
  1177. /*! @copydoc end */
  1178. [[nodiscard]] sentinel cend() const ENTT_NOEXCEPT {
  1179. return end();
  1180. }
  1181. private:
  1182. It first;
  1183. Sentinel last;
  1184. };
  1185. } // namespace entt
  1186. #endif
  1187. // #include "../core/memory.hpp"
  1188. #ifndef ENTT_CORE_MEMORY_HPP
  1189. #define ENTT_CORE_MEMORY_HPP
  1190. #include <cstddef>
  1191. #include <limits>
  1192. #include <memory>
  1193. #include <tuple>
  1194. #include <type_traits>
  1195. #include <utility>
  1196. // #include "../config/config.h"
  1197. namespace entt {
  1198. /**
  1199. * @brief Unwraps fancy pointers, does nothing otherwise (waiting for C++20).
  1200. * @tparam Type Pointer type.
  1201. * @param ptr Fancy or raw pointer.
  1202. * @return A raw pointer that represents the address of the original pointer.
  1203. */
  1204. template<typename Type>
  1205. [[nodiscard]] constexpr auto to_address(Type &&ptr) ENTT_NOEXCEPT {
  1206. if constexpr(std::is_pointer_v<std::remove_cv_t<std::remove_reference_t<Type>>>) {
  1207. return ptr;
  1208. } else {
  1209. return to_address(std::forward<Type>(ptr).operator->());
  1210. }
  1211. }
  1212. /**
  1213. * @brief Utility function to design allocation-aware containers.
  1214. * @tparam Allocator Type of allocator.
  1215. * @param lhs A valid allocator.
  1216. * @param rhs Another valid allocator.
  1217. */
  1218. template<typename Allocator>
  1219. constexpr void propagate_on_container_copy_assignment([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) ENTT_NOEXCEPT {
  1220. if constexpr(std::allocator_traits<Allocator>::propagate_on_container_copy_assignment::value) {
  1221. lhs = rhs;
  1222. }
  1223. }
  1224. /**
  1225. * @brief Utility function to design allocation-aware containers.
  1226. * @tparam Allocator Type of allocator.
  1227. * @param lhs A valid allocator.
  1228. * @param rhs Another valid allocator.
  1229. */
  1230. template<typename Allocator>
  1231. constexpr void propagate_on_container_move_assignment([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) ENTT_NOEXCEPT {
  1232. if constexpr(std::allocator_traits<Allocator>::propagate_on_container_move_assignment::value) {
  1233. lhs = std::move(rhs);
  1234. }
  1235. }
  1236. /**
  1237. * @brief Utility function to design allocation-aware containers.
  1238. * @tparam Allocator Type of allocator.
  1239. * @param lhs A valid allocator.
  1240. * @param rhs Another valid allocator.
  1241. */
  1242. template<typename Allocator>
  1243. constexpr void propagate_on_container_swap([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) ENTT_NOEXCEPT {
  1244. ENTT_ASSERT(std::allocator_traits<Allocator>::propagate_on_container_swap::value || lhs == rhs, "Cannot swap the containers");
  1245. if constexpr(std::allocator_traits<Allocator>::propagate_on_container_swap::value) {
  1246. using std::swap;
  1247. swap(lhs, rhs);
  1248. }
  1249. }
  1250. /**
  1251. * @brief Checks whether a value is a power of two or not.
  1252. * @param value A value that may or may not be a power of two.
  1253. * @return True if the value is a power of two, false otherwise.
  1254. */
  1255. [[nodiscard]] inline constexpr bool is_power_of_two(const std::size_t value) ENTT_NOEXCEPT {
  1256. return value && ((value & (value - 1)) == 0);
  1257. }
  1258. /**
  1259. * @brief Computes the smallest power of two greater than or equal to a value.
  1260. * @param value The value to use.
  1261. * @return The smallest power of two greater than or equal to the given value.
  1262. */
  1263. [[nodiscard]] inline constexpr std::size_t next_power_of_two(const std::size_t value) ENTT_NOEXCEPT {
  1264. ENTT_ASSERT(value < (std::size_t{1u} << (std::numeric_limits<std::size_t>::digits - 1)), "Numeric limits exceeded");
  1265. std::size_t curr = value - (value != 0u);
  1266. for(int next = 1; next < std::numeric_limits<std::size_t>::digits; next = next * 2) {
  1267. curr |= curr >> next;
  1268. }
  1269. return ++curr;
  1270. }
  1271. /**
  1272. * @brief Fast module utility function (powers of two only).
  1273. * @param value A value for which to calculate the modulus.
  1274. * @param mod _Modulus_, it must be a power of two.
  1275. * @return The common remainder.
  1276. */
  1277. [[nodiscard]] inline constexpr std::size_t fast_mod(const std::size_t value, const std::size_t mod) ENTT_NOEXCEPT {
  1278. ENTT_ASSERT(is_power_of_two(mod), "Value must be a power of two");
  1279. return value & (mod - 1u);
  1280. }
  1281. /**
  1282. * @brief Deleter for allocator-aware unique pointers (waiting for C++20).
  1283. * @tparam Args Types of arguments to use to construct the object.
  1284. */
  1285. template<typename Allocator>
  1286. struct allocation_deleter: private Allocator {
  1287. /*! @brief Allocator type. */
  1288. using allocator_type = Allocator;
  1289. /*! @brief Pointer type. */
  1290. using pointer = typename std::allocator_traits<Allocator>::pointer;
  1291. /**
  1292. * @brief Inherited constructors.
  1293. * @param alloc The allocator to use.
  1294. */
  1295. allocation_deleter(const allocator_type &alloc)
  1296. : Allocator{alloc} {}
  1297. /**
  1298. * @brief Destroys the pointed object and deallocates its memory.
  1299. * @param ptr A valid pointer to an object of the given type.
  1300. */
  1301. void operator()(pointer ptr) {
  1302. using alloc_traits = typename std::allocator_traits<Allocator>;
  1303. alloc_traits::destroy(*this, to_address(ptr));
  1304. alloc_traits::deallocate(*this, ptr, 1u);
  1305. }
  1306. };
  1307. /**
  1308. * @brief Allows `std::unique_ptr` to use allocators (waiting for C++20).
  1309. * @tparam Type Type of object to allocate for and to construct.
  1310. * @tparam Allocator Type of allocator used to manage memory and elements.
  1311. * @tparam Args Types of arguments to use to construct the object.
  1312. * @param allocator The allocator to use.
  1313. * @param args Parameters to use to construct the object.
  1314. * @return A properly initialized unique pointer with a custom deleter.
  1315. */
  1316. template<typename Type, typename Allocator, typename... Args>
  1317. auto allocate_unique(Allocator &allocator, Args &&...args) {
  1318. static_assert(!std::is_array_v<Type>, "Array types are not supported");
  1319. using alloc_traits = typename std::allocator_traits<Allocator>::template rebind_traits<Type>;
  1320. using allocator_type = typename alloc_traits::allocator_type;
  1321. allocator_type alloc{allocator};
  1322. auto ptr = alloc_traits::allocate(alloc, 1u);
  1323. ENTT_TRY {
  1324. alloc_traits::construct(alloc, to_address(ptr), std::forward<Args>(args)...);
  1325. }
  1326. ENTT_CATCH {
  1327. alloc_traits::deallocate(alloc, ptr, 1u);
  1328. ENTT_THROW;
  1329. }
  1330. return std::unique_ptr<Type, allocation_deleter<allocator_type>>{ptr, alloc};
  1331. }
  1332. /**
  1333. * @cond TURN_OFF_DOXYGEN
  1334. * Internal details not to be documented.
  1335. */
  1336. namespace internal {
  1337. template<typename Type>
  1338. struct uses_allocator_construction {
  1339. template<typename Allocator, typename... Params>
  1340. static constexpr auto args([[maybe_unused]] const Allocator &allocator, Params &&...params) ENTT_NOEXCEPT {
  1341. if constexpr(!std::uses_allocator_v<Type, Allocator> && std::is_constructible_v<Type, Params...>) {
  1342. return std::forward_as_tuple(std::forward<Params>(params)...);
  1343. } else {
  1344. static_assert(std::uses_allocator_v<Type, Allocator>, "Ill-formed request");
  1345. if constexpr(std::is_constructible_v<Type, std::allocator_arg_t, const Allocator &, Params...>) {
  1346. return std::tuple<std::allocator_arg_t, const Allocator &, Params &&...>(std::allocator_arg, allocator, std::forward<Params>(params)...);
  1347. } else {
  1348. static_assert(std::is_constructible_v<Type, Params..., const Allocator &>, "Ill-formed request");
  1349. return std::forward_as_tuple(std::forward<Params>(params)..., allocator);
  1350. }
  1351. }
  1352. }
  1353. };
  1354. template<typename Type, typename Other>
  1355. struct uses_allocator_construction<std::pair<Type, Other>> {
  1356. using type = std::pair<Type, Other>;
  1357. template<typename Allocator, typename First, typename Second>
  1358. static constexpr auto args(const Allocator &allocator, std::piecewise_construct_t, First &&first, Second &&second) ENTT_NOEXCEPT {
  1359. return std::make_tuple(
  1360. std::piecewise_construct,
  1361. std::apply([&allocator](auto &&...curr) { return uses_allocator_construction<Type>::args(allocator, std::forward<decltype(curr)>(curr)...); }, std::forward<First>(first)),
  1362. std::apply([&allocator](auto &&...curr) { return uses_allocator_construction<Other>::args(allocator, std::forward<decltype(curr)>(curr)...); }, std::forward<Second>(second)));
  1363. }
  1364. template<typename Allocator>
  1365. static constexpr auto args(const Allocator &allocator) ENTT_NOEXCEPT {
  1366. return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::tuple<>{}, std::tuple<>{});
  1367. }
  1368. template<typename Allocator, typename First, typename Second>
  1369. static constexpr auto args(const Allocator &allocator, First &&first, Second &&second) ENTT_NOEXCEPT {
  1370. 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)));
  1371. }
  1372. template<typename Allocator, typename First, typename Second>
  1373. static constexpr auto args(const Allocator &allocator, const std::pair<First, Second> &value) ENTT_NOEXCEPT {
  1374. return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::forward_as_tuple(value.first), std::forward_as_tuple(value.second));
  1375. }
  1376. template<typename Allocator, typename First, typename Second>
  1377. static constexpr auto args(const Allocator &allocator, std::pair<First, Second> &&value) ENTT_NOEXCEPT {
  1378. 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)));
  1379. }
  1380. };
  1381. } // namespace internal
  1382. /**
  1383. * Internal details not to be documented.
  1384. * @endcond
  1385. */
  1386. /**
  1387. * @brief Uses-allocator construction utility (waiting for C++20).
  1388. *
  1389. * Primarily intended for internal use. Prepares the argument list needed to
  1390. * create an object of a given type by means of uses-allocator construction.
  1391. *
  1392. * @tparam Type Type to return arguments for.
  1393. * @tparam Allocator Type of allocator used to manage memory and elements.
  1394. * @tparam Args Types of arguments to use to construct the object.
  1395. * @param allocator The allocator to use.
  1396. * @param args Parameters to use to construct the object.
  1397. * @return The arguments needed to create an object of the given type.
  1398. */
  1399. template<typename Type, typename Allocator, typename... Args>
  1400. constexpr auto uses_allocator_construction_args(const Allocator &allocator, Args &&...args) ENTT_NOEXCEPT {
  1401. return internal::uses_allocator_construction<Type>::args(allocator, std::forward<Args>(args)...);
  1402. }
  1403. /**
  1404. * @brief Uses-allocator construction utility (waiting for C++20).
  1405. *
  1406. * Primarily intended for internal use. Creates an object of a given type by
  1407. * means of uses-allocator construction.
  1408. *
  1409. * @tparam Type Type of object to create.
  1410. * @tparam Allocator Type of allocator used to manage memory and elements.
  1411. * @tparam Args Types of arguments to use to construct the object.
  1412. * @param allocator The allocator to use.
  1413. * @param args Parameters to use to construct the object.
  1414. * @return A newly created object of the given type.
  1415. */
  1416. template<typename Type, typename Allocator, typename... Args>
  1417. constexpr Type make_obj_using_allocator(const Allocator &allocator, Args &&...args) {
  1418. return std::make_from_tuple<Type>(internal::uses_allocator_construction<Type>::args(allocator, std::forward<Args>(args)...));
  1419. }
  1420. /**
  1421. * @brief Uses-allocator construction utility (waiting for C++20).
  1422. *
  1423. * Primarily intended for internal use. Creates an object of a given type by
  1424. * means of uses-allocator construction at an uninitialized memory location.
  1425. *
  1426. * @tparam Type Type of object to create.
  1427. * @tparam Allocator Type of allocator used to manage memory and elements.
  1428. * @tparam Args Types of arguments to use to construct the object.
  1429. * @param value Memory location in which to place the object.
  1430. * @param allocator The allocator to use.
  1431. * @param args Parameters to use to construct the object.
  1432. * @return A pointer to the newly created object of the given type.
  1433. */
  1434. template<typename Type, typename Allocator, typename... Args>
  1435. constexpr Type *uninitialized_construct_using_allocator(Type *value, const Allocator &allocator, Args &&...args) {
  1436. return std::apply([&](auto &&...curr) { return new(value) Type(std::forward<decltype(curr)>(curr)...); }, internal::uses_allocator_construction<Type>::args(allocator, std::forward<Args>(args)...));
  1437. }
  1438. } // namespace entt
  1439. #endif
  1440. // #include "../core/type_traits.hpp"
  1441. #ifndef ENTT_CORE_TYPE_TRAITS_HPP
  1442. #define ENTT_CORE_TYPE_TRAITS_HPP
  1443. #include <cstddef>
  1444. #include <iterator>
  1445. #include <type_traits>
  1446. #include <utility>
  1447. // #include "../config/config.h"
  1448. // #include "fwd.hpp"
  1449. namespace entt {
  1450. /**
  1451. * @brief Utility class to disambiguate overloaded functions.
  1452. * @tparam N Number of choices available.
  1453. */
  1454. template<std::size_t N>
  1455. struct choice_t
  1456. // Unfortunately, doxygen cannot parse such a construct.
  1457. : /*! @cond TURN_OFF_DOXYGEN */ choice_t<N - 1> /*! @endcond */
  1458. {};
  1459. /*! @copybrief choice_t */
  1460. template<>
  1461. struct choice_t<0> {};
  1462. /**
  1463. * @brief Variable template for the choice trick.
  1464. * @tparam N Number of choices available.
  1465. */
  1466. template<std::size_t N>
  1467. inline constexpr choice_t<N> choice{};
  1468. /**
  1469. * @brief Identity type trait.
  1470. *
  1471. * Useful to establish non-deduced contexts in template argument deduction
  1472. * (waiting for C++20) or to provide types through function arguments.
  1473. *
  1474. * @tparam Type A type.
  1475. */
  1476. template<typename Type>
  1477. struct type_identity {
  1478. /*! @brief Identity type. */
  1479. using type = Type;
  1480. };
  1481. /**
  1482. * @brief Helper type.
  1483. * @tparam Type A type.
  1484. */
  1485. template<typename Type>
  1486. using type_identity_t = typename type_identity<Type>::type;
  1487. /**
  1488. * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains.
  1489. * @tparam Type The type of which to return the size.
  1490. * @tparam The size of the type if `sizeof` accepts it, 0 otherwise.
  1491. */
  1492. template<typename Type, typename = void>
  1493. struct size_of: std::integral_constant<std::size_t, 0u> {};
  1494. /*! @copydoc size_of */
  1495. template<typename Type>
  1496. struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
  1497. : std::integral_constant<std::size_t, sizeof(Type)> {};
  1498. /**
  1499. * @brief Helper variable template.
  1500. * @tparam Type The type of which to return the size.
  1501. */
  1502. template<typename Type>
  1503. inline constexpr std::size_t size_of_v = size_of<Type>::value;
  1504. /**
  1505. * @brief Using declaration to be used to _repeat_ the same type a number of
  1506. * times equal to the size of a given parameter pack.
  1507. * @tparam Type A type to repeat.
  1508. */
  1509. template<typename Type, typename>
  1510. using unpack_as_type = Type;
  1511. /**
  1512. * @brief Helper variable template to be used to _repeat_ the same value a
  1513. * number of times equal to the size of a given parameter pack.
  1514. * @tparam Value A value to repeat.
  1515. */
  1516. template<auto Value, typename>
  1517. inline constexpr auto unpack_as_value = Value;
  1518. /**
  1519. * @brief Wraps a static constant.
  1520. * @tparam Value A static constant.
  1521. */
  1522. template<auto Value>
  1523. using integral_constant = std::integral_constant<decltype(Value), Value>;
  1524. /**
  1525. * @brief Alias template to facilitate the creation of named values.
  1526. * @tparam Value A constant value at least convertible to `id_type`.
  1527. */
  1528. template<id_type Value>
  1529. using tag = integral_constant<Value>;
  1530. /**
  1531. * @brief A class to use to push around lists of types, nothing more.
  1532. * @tparam Type Types provided by the type list.
  1533. */
  1534. template<typename... Type>
  1535. struct type_list {
  1536. /*! @brief Type list type. */
  1537. using type = type_list;
  1538. /*! @brief Compile-time number of elements in the type list. */
  1539. static constexpr auto size = sizeof...(Type);
  1540. };
  1541. /*! @brief Primary template isn't defined on purpose. */
  1542. template<std::size_t, typename>
  1543. struct type_list_element;
  1544. /**
  1545. * @brief Provides compile-time indexed access to the types of a type list.
  1546. * @tparam Index Index of the type to return.
  1547. * @tparam Type First type provided by the type list.
  1548. * @tparam Other Other types provided by the type list.
  1549. */
  1550. template<std::size_t Index, typename Type, typename... Other>
  1551. struct type_list_element<Index, type_list<Type, Other...>>
  1552. : type_list_element<Index - 1u, type_list<Other...>> {};
  1553. /**
  1554. * @brief Provides compile-time indexed access to the types of a type list.
  1555. * @tparam Type First type provided by the type list.
  1556. * @tparam Other Other types provided by the type list.
  1557. */
  1558. template<typename Type, typename... Other>
  1559. struct type_list_element<0u, type_list<Type, Other...>> {
  1560. /*! @brief Searched type. */
  1561. using type = Type;
  1562. };
  1563. /**
  1564. * @brief Helper type.
  1565. * @tparam Index Index of the type to return.
  1566. * @tparam List Type list to search into.
  1567. */
  1568. template<std::size_t Index, typename List>
  1569. using type_list_element_t = typename type_list_element<Index, List>::type;
  1570. /**
  1571. * @brief Concatenates multiple type lists.
  1572. * @tparam Type Types provided by the first type list.
  1573. * @tparam Other Types provided by the second type list.
  1574. * @return A type list composed by the types of both the type lists.
  1575. */
  1576. template<typename... Type, typename... Other>
  1577. constexpr type_list<Type..., Other...> operator+(type_list<Type...>, type_list<Other...>) {
  1578. return {};
  1579. }
  1580. /*! @brief Primary template isn't defined on purpose. */
  1581. template<typename...>
  1582. struct type_list_cat;
  1583. /*! @brief Concatenates multiple type lists. */
  1584. template<>
  1585. struct type_list_cat<> {
  1586. /*! @brief A type list composed by the types of all the type lists. */
  1587. using type = type_list<>;
  1588. };
  1589. /**
  1590. * @brief Concatenates multiple type lists.
  1591. * @tparam Type Types provided by the first type list.
  1592. * @tparam Other Types provided by the second type list.
  1593. * @tparam List Other type lists, if any.
  1594. */
  1595. template<typename... Type, typename... Other, typename... List>
  1596. struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
  1597. /*! @brief A type list composed by the types of all the type lists. */
  1598. using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
  1599. };
  1600. /**
  1601. * @brief Concatenates multiple type lists.
  1602. * @tparam Type Types provided by the type list.
  1603. */
  1604. template<typename... Type>
  1605. struct type_list_cat<type_list<Type...>> {
  1606. /*! @brief A type list composed by the types of all the type lists. */
  1607. using type = type_list<Type...>;
  1608. };
  1609. /**
  1610. * @brief Helper type.
  1611. * @tparam List Type lists to concatenate.
  1612. */
  1613. template<typename... List>
  1614. using type_list_cat_t = typename type_list_cat<List...>::type;
  1615. /*! @brief Primary template isn't defined on purpose. */
  1616. template<typename>
  1617. struct type_list_unique;
  1618. /**
  1619. * @brief Removes duplicates types from a type list.
  1620. * @tparam Type One of the types provided by the given type list.
  1621. * @tparam Other The other types provided by the given type list.
  1622. */
  1623. template<typename Type, typename... Other>
  1624. struct type_list_unique<type_list<Type, Other...>> {
  1625. /*! @brief A type list without duplicate types. */
  1626. using type = std::conditional_t<
  1627. (std::is_same_v<Type, Other> || ...),
  1628. typename type_list_unique<type_list<Other...>>::type,
  1629. type_list_cat_t<type_list<Type>, typename type_list_unique<type_list<Other...>>::type>>;
  1630. };
  1631. /*! @brief Removes duplicates types from a type list. */
  1632. template<>
  1633. struct type_list_unique<type_list<>> {
  1634. /*! @brief A type list without duplicate types. */
  1635. using type = type_list<>;
  1636. };
  1637. /**
  1638. * @brief Helper type.
  1639. * @tparam Type A type list.
  1640. */
  1641. template<typename Type>
  1642. using type_list_unique_t = typename type_list_unique<Type>::type;
  1643. /**
  1644. * @brief Provides the member constant `value` to true if a type list contains a
  1645. * given type, false otherwise.
  1646. * @tparam List Type list.
  1647. * @tparam Type Type to look for.
  1648. */
  1649. template<typename List, typename Type>
  1650. struct type_list_contains;
  1651. /**
  1652. * @copybrief type_list_contains
  1653. * @tparam Type Types provided by the type list.
  1654. * @tparam Other Type to look for.
  1655. */
  1656. template<typename... Type, typename Other>
  1657. struct type_list_contains<type_list<Type...>, Other>: std::disjunction<std::is_same<Type, Other>...> {};
  1658. /**
  1659. * @brief Helper variable template.
  1660. * @tparam List Type list.
  1661. * @tparam Type Type to look for.
  1662. */
  1663. template<typename List, typename Type>
  1664. inline constexpr bool type_list_contains_v = type_list_contains<List, Type>::value;
  1665. /*! @brief Primary template isn't defined on purpose. */
  1666. template<typename...>
  1667. struct type_list_diff;
  1668. /**
  1669. * @brief Computes the difference between two type lists.
  1670. * @tparam Type Types provided by the first type list.
  1671. * @tparam Other Types provided by the second type list.
  1672. */
  1673. template<typename... Type, typename... Other>
  1674. struct type_list_diff<type_list<Type...>, type_list<Other...>> {
  1675. /*! @brief A type list that is the difference between the two type lists. */
  1676. using type = type_list_cat_t<std::conditional_t<type_list_contains_v<type_list<Other...>, Type>, type_list<>, type_list<Type>>...>;
  1677. };
  1678. /**
  1679. * @brief Helper type.
  1680. * @tparam List Type lists between which to compute the difference.
  1681. */
  1682. template<typename... List>
  1683. using type_list_diff_t = typename type_list_diff<List...>::type;
  1684. /**
  1685. * @brief A class to use to push around lists of constant values, nothing more.
  1686. * @tparam Value Values provided by the value list.
  1687. */
  1688. template<auto... Value>
  1689. struct value_list {
  1690. /*! @brief Value list type. */
  1691. using type = value_list;
  1692. /*! @brief Compile-time number of elements in the value list. */
  1693. static constexpr auto size = sizeof...(Value);
  1694. };
  1695. /*! @brief Primary template isn't defined on purpose. */
  1696. template<std::size_t, typename>
  1697. struct value_list_element;
  1698. /**
  1699. * @brief Provides compile-time indexed access to the values of a value list.
  1700. * @tparam Index Index of the value to return.
  1701. * @tparam Value First value provided by the value list.
  1702. * @tparam Other Other values provided by the value list.
  1703. */
  1704. template<std::size_t Index, auto Value, auto... Other>
  1705. struct value_list_element<Index, value_list<Value, Other...>>
  1706. : value_list_element<Index - 1u, value_list<Other...>> {};
  1707. /**
  1708. * @brief Provides compile-time indexed access to the types of a type list.
  1709. * @tparam Value First value provided by the value list.
  1710. * @tparam Other Other values provided by the value list.
  1711. */
  1712. template<auto Value, auto... Other>
  1713. struct value_list_element<0u, value_list<Value, Other...>> {
  1714. /*! @brief Searched value. */
  1715. static constexpr auto value = Value;
  1716. };
  1717. /**
  1718. * @brief Helper type.
  1719. * @tparam Index Index of the value to return.
  1720. * @tparam List Value list to search into.
  1721. */
  1722. template<std::size_t Index, typename List>
  1723. inline constexpr auto value_list_element_v = value_list_element<Index, List>::value;
  1724. /**
  1725. * @brief Concatenates multiple value lists.
  1726. * @tparam Value Values provided by the first value list.
  1727. * @tparam Other Values provided by the second value list.
  1728. * @return A value list composed by the values of both the value lists.
  1729. */
  1730. template<auto... Value, auto... Other>
  1731. constexpr value_list<Value..., Other...> operator+(value_list<Value...>, value_list<Other...>) {
  1732. return {};
  1733. }
  1734. /*! @brief Primary template isn't defined on purpose. */
  1735. template<typename...>
  1736. struct value_list_cat;
  1737. /*! @brief Concatenates multiple value lists. */
  1738. template<>
  1739. struct value_list_cat<> {
  1740. /*! @brief A value list composed by the values of all the value lists. */
  1741. using type = value_list<>;
  1742. };
  1743. /**
  1744. * @brief Concatenates multiple value lists.
  1745. * @tparam Value Values provided by the first value list.
  1746. * @tparam Other Values provided by the second value list.
  1747. * @tparam List Other value lists, if any.
  1748. */
  1749. template<auto... Value, auto... Other, typename... List>
  1750. struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
  1751. /*! @brief A value list composed by the values of all the value lists. */
  1752. using type = typename value_list_cat<value_list<Value..., Other...>, List...>::type;
  1753. };
  1754. /**
  1755. * @brief Concatenates multiple value lists.
  1756. * @tparam Value Values provided by the value list.
  1757. */
  1758. template<auto... Value>
  1759. struct value_list_cat<value_list<Value...>> {
  1760. /*! @brief A value list composed by the values of all the value lists. */
  1761. using type = value_list<Value...>;
  1762. };
  1763. /**
  1764. * @brief Helper type.
  1765. * @tparam List Value lists to concatenate.
  1766. */
  1767. template<typename... List>
  1768. using value_list_cat_t = typename value_list_cat<List...>::type;
  1769. /*! @brief Same as std::is_invocable, but with tuples. */
  1770. template<typename, typename>
  1771. struct is_applicable: std::false_type {};
  1772. /**
  1773. * @copybrief is_applicable
  1774. * @tparam Func A valid function type.
  1775. * @tparam Tuple Tuple-like type.
  1776. * @tparam Args The list of arguments to use to probe the function type.
  1777. */
  1778. template<typename Func, template<typename...> class Tuple, typename... Args>
  1779. struct is_applicable<Func, Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  1780. /**
  1781. * @copybrief is_applicable
  1782. * @tparam Func A valid function type.
  1783. * @tparam Tuple Tuple-like type.
  1784. * @tparam Args The list of arguments to use to probe the function type.
  1785. */
  1786. template<typename Func, template<typename...> class Tuple, typename... Args>
  1787. struct is_applicable<Func, const Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  1788. /**
  1789. * @brief Helper variable template.
  1790. * @tparam Func A valid function type.
  1791. * @tparam Args The list of arguments to use to probe the function type.
  1792. */
  1793. template<typename Func, typename Args>
  1794. inline constexpr bool is_applicable_v = is_applicable<Func, Args>::value;
  1795. /*! @brief Same as std::is_invocable_r, but with tuples for arguments. */
  1796. template<typename, typename, typename>
  1797. struct is_applicable_r: std::false_type {};
  1798. /**
  1799. * @copybrief is_applicable_r
  1800. * @tparam Ret The type to which the return type of the function should be
  1801. * convertible.
  1802. * @tparam Func A valid function type.
  1803. * @tparam Args The list of arguments to use to probe the function type.
  1804. */
  1805. template<typename Ret, typename Func, typename... Args>
  1806. struct is_applicable_r<Ret, Func, std::tuple<Args...>>: std::is_invocable_r<Ret, Func, Args...> {};
  1807. /**
  1808. * @brief Helper variable template.
  1809. * @tparam Ret The type to which the return type of the function should be
  1810. * convertible.
  1811. * @tparam Func A valid function type.
  1812. * @tparam Args The list of arguments to use to probe the function type.
  1813. */
  1814. template<typename Ret, typename Func, typename Args>
  1815. inline constexpr bool is_applicable_r_v = is_applicable_r<Ret, Func, Args>::value;
  1816. /**
  1817. * @brief Provides the member constant `value` to true if a given type is
  1818. * complete, false otherwise.
  1819. * @tparam Type The type to test.
  1820. */
  1821. template<typename Type, typename = void>
  1822. struct is_complete: std::false_type {};
  1823. /*! @copydoc is_complete */
  1824. template<typename Type>
  1825. struct is_complete<Type, std::void_t<decltype(sizeof(Type))>>: std::true_type {};
  1826. /**
  1827. * @brief Helper variable template.
  1828. * @tparam Type The type to test.
  1829. */
  1830. template<typename Type>
  1831. inline constexpr bool is_complete_v = is_complete<Type>::value;
  1832. /**
  1833. * @brief Provides the member constant `value` to true if a given type is an
  1834. * iterator, false otherwise.
  1835. * @tparam Type The type to test.
  1836. */
  1837. template<typename Type, typename = void>
  1838. struct is_iterator: std::false_type {};
  1839. /**
  1840. * @cond TURN_OFF_DOXYGEN
  1841. * Internal details not to be documented.
  1842. */
  1843. namespace internal {
  1844. template<typename, typename = void>
  1845. struct has_iterator_category: std::false_type {};
  1846. template<typename Type>
  1847. struct has_iterator_category<Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>: std::true_type {};
  1848. } // namespace internal
  1849. /**
  1850. * Internal details not to be documented.
  1851. * @endcond
  1852. */
  1853. /*! @copydoc is_iterator */
  1854. template<typename Type>
  1855. struct is_iterator<Type, std::enable_if_t<!std::is_same_v<std::remove_const_t<std::remove_pointer_t<Type>>, void>>>
  1856. : internal::has_iterator_category<Type> {};
  1857. /**
  1858. * @brief Helper variable template.
  1859. * @tparam Type The type to test.
  1860. */
  1861. template<typename Type>
  1862. inline constexpr bool is_iterator_v = is_iterator<Type>::value;
  1863. /**
  1864. * @brief Provides the member constant `value` to true if a given type is both
  1865. * an empty and non-final class, false otherwise.
  1866. * @tparam Type The type to test
  1867. */
  1868. template<typename Type>
  1869. struct is_ebco_eligible
  1870. : std::conjunction<std::is_empty<Type>, std::negation<std::is_final<Type>>> {};
  1871. /**
  1872. * @brief Helper variable template.
  1873. * @tparam Type The type to test.
  1874. */
  1875. template<typename Type>
  1876. inline constexpr bool is_ebco_eligible_v = is_ebco_eligible<Type>::value;
  1877. /**
  1878. * @brief Provides the member constant `value` to true if `Type::is_transparent`
  1879. * is valid and denotes a type, false otherwise.
  1880. * @tparam Type The type to test.
  1881. */
  1882. template<typename Type, typename = void>
  1883. struct is_transparent: std::false_type {};
  1884. /*! @copydoc is_transparent */
  1885. template<typename Type>
  1886. struct is_transparent<Type, std::void_t<typename Type::is_transparent>>: std::true_type {};
  1887. /**
  1888. * @brief Helper variable template.
  1889. * @tparam Type The type to test.
  1890. */
  1891. template<typename Type>
  1892. inline constexpr bool is_transparent_v = is_transparent<Type>::value;
  1893. /**
  1894. * @brief Provides the member constant `value` to true if a given type is
  1895. * equality comparable, false otherwise.
  1896. * @tparam Type The type to test.
  1897. */
  1898. template<typename Type, typename = void>
  1899. struct is_equality_comparable: std::false_type {};
  1900. /**
  1901. * @cond TURN_OFF_DOXYGEN
  1902. * Internal details not to be documented.
  1903. */
  1904. namespace internal {
  1905. template<typename, typename = void>
  1906. struct has_tuple_size_value: std::false_type {};
  1907. template<typename Type>
  1908. struct has_tuple_size_value<Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>: std::true_type {};
  1909. template<typename Type, std::size_t... Index>
  1910. [[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
  1911. return (is_equality_comparable<std::tuple_element_t<Index, Type>>::value && ...);
  1912. }
  1913. template<typename>
  1914. [[nodiscard]] constexpr bool maybe_equality_comparable(choice_t<0>) {
  1915. return true;
  1916. }
  1917. template<typename Type>
  1918. [[nodiscard]] constexpr auto maybe_equality_comparable(choice_t<1>) -> decltype(std::declval<typename Type::value_type>(), bool{}) {
  1919. if constexpr(is_iterator_v<Type>) {
  1920. return true;
  1921. } else if constexpr(std::is_same_v<typename Type::value_type, Type>) {
  1922. return maybe_equality_comparable<Type>(choice<0>);
  1923. } else {
  1924. return is_equality_comparable<typename Type::value_type>::value;
  1925. }
  1926. }
  1927. template<typename Type>
  1928. [[nodiscard]] constexpr std::enable_if_t<is_complete_v<std::tuple_size<std::remove_const_t<Type>>>, bool> maybe_equality_comparable(choice_t<2>) {
  1929. if constexpr(has_tuple_size_value<Type>::value) {
  1930. return unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
  1931. } else {
  1932. return maybe_equality_comparable<Type>(choice<1>);
  1933. }
  1934. }
  1935. } // namespace internal
  1936. /**
  1937. * Internal details not to be documented.
  1938. * @endcond
  1939. */
  1940. /*! @copydoc is_equality_comparable */
  1941. template<typename Type>
  1942. struct is_equality_comparable<Type, std::void_t<decltype(std::declval<Type>() == std::declval<Type>())>>
  1943. : std::bool_constant<internal::maybe_equality_comparable<Type>(choice<2>)> {};
  1944. /**
  1945. * @brief Helper variable template.
  1946. * @tparam Type The type to test.
  1947. */
  1948. template<typename Type>
  1949. inline constexpr bool is_equality_comparable_v = is_equality_comparable<Type>::value;
  1950. /**
  1951. * @brief Transcribes the constness of a type to another type.
  1952. * @tparam To The type to which to transcribe the constness.
  1953. * @tparam From The type from which to transcribe the constness.
  1954. */
  1955. template<typename To, typename From>
  1956. struct constness_as {
  1957. /*! @brief The type resulting from the transcription of the constness. */
  1958. using type = std::remove_const_t<To>;
  1959. };
  1960. /*! @copydoc constness_as */
  1961. template<typename To, typename From>
  1962. struct constness_as<To, const From> {
  1963. /*! @brief The type resulting from the transcription of the constness. */
  1964. using type = std::add_const_t<To>;
  1965. };
  1966. /**
  1967. * @brief Alias template to facilitate the transcription of the constness.
  1968. * @tparam To The type to which to transcribe the constness.
  1969. * @tparam From The type from which to transcribe the constness.
  1970. */
  1971. template<typename To, typename From>
  1972. using constness_as_t = typename constness_as<To, From>::type;
  1973. /**
  1974. * @brief Extracts the class of a non-static member object or function.
  1975. * @tparam Member A pointer to a non-static member object or function.
  1976. */
  1977. template<typename Member>
  1978. class member_class {
  1979. static_assert(std::is_member_pointer_v<Member>, "Invalid pointer type to non-static member object or function");
  1980. template<typename Class, typename Ret, typename... Args>
  1981. static Class *clazz(Ret (Class::*)(Args...));
  1982. template<typename Class, typename Ret, typename... Args>
  1983. static Class *clazz(Ret (Class::*)(Args...) const);
  1984. template<typename Class, typename Type>
  1985. static Class *clazz(Type Class::*);
  1986. public:
  1987. /*! @brief The class of the given non-static member object or function. */
  1988. using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
  1989. };
  1990. /**
  1991. * @brief Helper type.
  1992. * @tparam Member A pointer to a non-static member object or function.
  1993. */
  1994. template<typename Member>
  1995. using member_class_t = typename member_class<Member>::type;
  1996. } // namespace entt
  1997. #endif
  1998. // #include "fwd.hpp"
  1999. #ifndef ENTT_CONTAINER_FWD_HPP
  2000. #define ENTT_CONTAINER_FWD_HPP
  2001. #include <functional>
  2002. #include <memory>
  2003. namespace entt {
  2004. template<
  2005. typename Key,
  2006. typename Type,
  2007. typename = std::hash<Key>,
  2008. typename = std::equal_to<Key>,
  2009. typename = std::allocator<std::pair<const Key, Type>>>
  2010. class dense_map;
  2011. template<
  2012. typename Type,
  2013. typename = std::hash<Type>,
  2014. typename = std::equal_to<Type>,
  2015. typename = std::allocator<Type>>
  2016. class dense_set;
  2017. } // namespace entt
  2018. #endif
  2019. namespace entt {
  2020. /**
  2021. * @cond TURN_OFF_DOXYGEN
  2022. * Internal details not to be documented.
  2023. */
  2024. namespace internal {
  2025. template<typename Key, typename Type>
  2026. struct dense_map_node final {
  2027. using value_type = std::pair<Key, Type>;
  2028. template<typename... Args>
  2029. dense_map_node(const std::size_t pos, Args &&...args)
  2030. : next{pos},
  2031. element{std::forward<Args>(args)...} {}
  2032. template<typename Allocator, typename... Args>
  2033. dense_map_node(std::allocator_arg_t, const Allocator &allocator, const std::size_t pos, Args &&...args)
  2034. : next{pos},
  2035. element{entt::make_obj_using_allocator<value_type>(allocator, std::forward<Args>(args)...)} {}
  2036. template<typename Allocator>
  2037. dense_map_node(std::allocator_arg_t, const Allocator &allocator, const dense_map_node &other)
  2038. : next{other.next},
  2039. element{entt::make_obj_using_allocator<value_type>(allocator, other.element)} {}
  2040. template<typename Allocator>
  2041. dense_map_node(std::allocator_arg_t, const Allocator &allocator, dense_map_node &&other)
  2042. : next{other.next},
  2043. element{entt::make_obj_using_allocator<value_type>(allocator, std::move(other.element))} {}
  2044. std::size_t next;
  2045. value_type element;
  2046. };
  2047. template<typename It>
  2048. class dense_map_iterator final {
  2049. template<typename>
  2050. friend class dense_map_iterator;
  2051. using first_type = decltype(std::as_const(std::declval<It>()->element.first));
  2052. using second_type = decltype((std::declval<It>()->element.second));
  2053. public:
  2054. using value_type = std::pair<first_type, second_type>;
  2055. using pointer = input_iterator_pointer<value_type>;
  2056. using reference = value_type;
  2057. using difference_type = std::ptrdiff_t;
  2058. using iterator_category = std::input_iterator_tag;
  2059. dense_map_iterator() ENTT_NOEXCEPT
  2060. : it{} {}
  2061. dense_map_iterator(const It iter) ENTT_NOEXCEPT
  2062. : it{iter} {}
  2063. template<typename Other, typename = std::enable_if_t<!std::is_same_v<It, Other> && std::is_constructible_v<It, Other>>>
  2064. dense_map_iterator(const dense_map_iterator<Other> &other) ENTT_NOEXCEPT
  2065. : it{other.it} {}
  2066. dense_map_iterator &operator++() ENTT_NOEXCEPT {
  2067. return ++it, *this;
  2068. }
  2069. dense_map_iterator operator++(int) ENTT_NOEXCEPT {
  2070. dense_map_iterator orig = *this;
  2071. return ++(*this), orig;
  2072. }
  2073. dense_map_iterator &operator--() ENTT_NOEXCEPT {
  2074. return --it, *this;
  2075. }
  2076. dense_map_iterator operator--(int) ENTT_NOEXCEPT {
  2077. dense_map_iterator orig = *this;
  2078. return operator--(), orig;
  2079. }
  2080. dense_map_iterator &operator+=(const difference_type value) ENTT_NOEXCEPT {
  2081. it += value;
  2082. return *this;
  2083. }
  2084. dense_map_iterator operator+(const difference_type value) const ENTT_NOEXCEPT {
  2085. dense_map_iterator copy = *this;
  2086. return (copy += value);
  2087. }
  2088. dense_map_iterator &operator-=(const difference_type value) ENTT_NOEXCEPT {
  2089. return (*this += -value);
  2090. }
  2091. dense_map_iterator operator-(const difference_type value) const ENTT_NOEXCEPT {
  2092. return (*this + -value);
  2093. }
  2094. [[nodiscard]] reference operator[](const difference_type value) const ENTT_NOEXCEPT {
  2095. return {it[value].element.first, it[value].element.second};
  2096. }
  2097. [[nodiscard]] pointer operator->() const ENTT_NOEXCEPT {
  2098. return operator*();
  2099. }
  2100. [[nodiscard]] reference operator*() const ENTT_NOEXCEPT {
  2101. return {it->element.first, it->element.second};
  2102. }
  2103. template<typename ILhs, typename IRhs>
  2104. friend std::ptrdiff_t operator-(const dense_map_iterator<ILhs> &, const dense_map_iterator<IRhs> &) ENTT_NOEXCEPT;
  2105. template<typename ILhs, typename IRhs>
  2106. friend bool operator==(const dense_map_iterator<ILhs> &, const dense_map_iterator<IRhs> &) ENTT_NOEXCEPT;
  2107. template<typename ILhs, typename IRhs>
  2108. friend bool operator<(const dense_map_iterator<ILhs> &, const dense_map_iterator<IRhs> &) ENTT_NOEXCEPT;
  2109. private:
  2110. It it;
  2111. };
  2112. template<typename ILhs, typename IRhs>
  2113. [[nodiscard]] std::ptrdiff_t operator-(const dense_map_iterator<ILhs> &lhs, const dense_map_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  2114. return lhs.it - rhs.it;
  2115. }
  2116. template<typename ILhs, typename IRhs>
  2117. [[nodiscard]] bool operator==(const dense_map_iterator<ILhs> &lhs, const dense_map_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  2118. return lhs.it == rhs.it;
  2119. }
  2120. template<typename ILhs, typename IRhs>
  2121. [[nodiscard]] bool operator!=(const dense_map_iterator<ILhs> &lhs, const dense_map_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  2122. return !(lhs == rhs);
  2123. }
  2124. template<typename ILhs, typename IRhs>
  2125. [[nodiscard]] bool operator<(const dense_map_iterator<ILhs> &lhs, const dense_map_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  2126. return lhs.it < rhs.it;
  2127. }
  2128. template<typename ILhs, typename IRhs>
  2129. [[nodiscard]] bool operator>(const dense_map_iterator<ILhs> &lhs, const dense_map_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  2130. return rhs < lhs;
  2131. }
  2132. template<typename ILhs, typename IRhs>
  2133. [[nodiscard]] bool operator<=(const dense_map_iterator<ILhs> &lhs, const dense_map_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  2134. return !(lhs > rhs);
  2135. }
  2136. template<typename ILhs, typename IRhs>
  2137. [[nodiscard]] bool operator>=(const dense_map_iterator<ILhs> &lhs, const dense_map_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  2138. return !(lhs < rhs);
  2139. }
  2140. template<typename It>
  2141. class dense_map_local_iterator final {
  2142. template<typename>
  2143. friend class dense_map_local_iterator;
  2144. using first_type = decltype(std::as_const(std::declval<It>()->element.first));
  2145. using second_type = decltype((std::declval<It>()->element.second));
  2146. public:
  2147. using value_type = std::pair<first_type, second_type>;
  2148. using pointer = input_iterator_pointer<value_type>;
  2149. using reference = value_type;
  2150. using difference_type = std::ptrdiff_t;
  2151. using iterator_category = std::input_iterator_tag;
  2152. dense_map_local_iterator() ENTT_NOEXCEPT
  2153. : it{},
  2154. offset{} {}
  2155. dense_map_local_iterator(It iter, const std::size_t pos) ENTT_NOEXCEPT
  2156. : it{iter},
  2157. offset{pos} {}
  2158. template<typename Other, typename = std::enable_if_t<!std::is_same_v<It, Other> && std::is_constructible_v<It, Other>>>
  2159. dense_map_local_iterator(const dense_map_local_iterator<Other> &other) ENTT_NOEXCEPT
  2160. : it{other.it},
  2161. offset{other.offset} {}
  2162. dense_map_local_iterator &operator++() ENTT_NOEXCEPT {
  2163. return offset = it[offset].next, *this;
  2164. }
  2165. dense_map_local_iterator operator++(int) ENTT_NOEXCEPT {
  2166. dense_map_local_iterator orig = *this;
  2167. return ++(*this), orig;
  2168. }
  2169. [[nodiscard]] pointer operator->() const ENTT_NOEXCEPT {
  2170. return operator*();
  2171. }
  2172. [[nodiscard]] reference operator*() const ENTT_NOEXCEPT {
  2173. return {it[offset].element.first, it[offset].element.second};
  2174. }
  2175. [[nodiscard]] std::size_t index() const ENTT_NOEXCEPT {
  2176. return offset;
  2177. }
  2178. private:
  2179. It it;
  2180. std::size_t offset;
  2181. };
  2182. template<typename ILhs, typename IRhs>
  2183. [[nodiscard]] bool operator==(const dense_map_local_iterator<ILhs> &lhs, const dense_map_local_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  2184. return lhs.index() == rhs.index();
  2185. }
  2186. template<typename ILhs, typename IRhs>
  2187. [[nodiscard]] bool operator!=(const dense_map_local_iterator<ILhs> &lhs, const dense_map_local_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  2188. return !(lhs == rhs);
  2189. }
  2190. } // namespace internal
  2191. /**
  2192. * Internal details not to be documented.
  2193. * @endcond
  2194. */
  2195. /**
  2196. * @brief Associative container for key-value pairs with unique keys.
  2197. *
  2198. * Internally, elements are organized into buckets. Which bucket an element is
  2199. * placed into depends entirely on the hash of its key. Keys with the same hash
  2200. * code appear in the same bucket.
  2201. *
  2202. * @tparam Key Key type of the associative container.
  2203. * @tparam Type Mapped type of the associative container.
  2204. * @tparam Hash Type of function to use to hash the keys.
  2205. * @tparam KeyEqual Type of function to use to compare the keys for equality.
  2206. * @tparam Allocator Type of allocator used to manage memory and elements.
  2207. */
  2208. template<typename Key, typename Type, typename Hash, typename KeyEqual, typename Allocator>
  2209. class dense_map {
  2210. static constexpr float default_threshold = 0.875f;
  2211. static constexpr std::size_t minimum_capacity = 8u;
  2212. using node_type = internal::dense_map_node<Key, Type>;
  2213. using alloc_traits = typename std::allocator_traits<Allocator>;
  2214. static_assert(std::is_same_v<typename alloc_traits::value_type, std::pair<const Key, Type>>, "Invalid value type");
  2215. using sparse_container_type = std::vector<std::size_t, typename alloc_traits::template rebind_alloc<std::size_t>>;
  2216. using packed_container_type = std::vector<node_type, typename alloc_traits::template rebind_alloc<node_type>>;
  2217. template<typename Other>
  2218. [[nodiscard]] std::size_t key_to_bucket(const Other &key) const ENTT_NOEXCEPT {
  2219. return fast_mod(sparse.second()(key), bucket_count());
  2220. }
  2221. template<typename Other>
  2222. [[nodiscard]] auto constrained_find(const Other &key, std::size_t bucket) {
  2223. for(auto it = begin(bucket), last = end(bucket); it != last; ++it) {
  2224. if(packed.second()(it->first, key)) {
  2225. return begin() + static_cast<typename iterator::difference_type>(it.index());
  2226. }
  2227. }
  2228. return end();
  2229. }
  2230. template<typename Other>
  2231. [[nodiscard]] auto constrained_find(const Other &key, std::size_t bucket) const {
  2232. for(auto it = cbegin(bucket), last = cend(bucket); it != last; ++it) {
  2233. if(packed.second()(it->first, key)) {
  2234. return cbegin() + static_cast<typename iterator::difference_type>(it.index());
  2235. }
  2236. }
  2237. return cend();
  2238. }
  2239. template<typename Other, typename... Args>
  2240. [[nodiscard]] auto insert_or_do_nothing(Other &&key, Args &&...args) {
  2241. const auto index = key_to_bucket(key);
  2242. if(auto it = constrained_find(key, index); it != end()) {
  2243. return std::make_pair(it, false);
  2244. }
  2245. 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)...));
  2246. sparse.first()[index] = packed.first().size() - 1u;
  2247. rehash_if_required();
  2248. return std::make_pair(--end(), true);
  2249. }
  2250. template<typename Other, typename Arg>
  2251. [[nodiscard]] auto insert_or_overwrite(Other &&key, Arg &&value) {
  2252. const auto index = key_to_bucket(key);
  2253. if(auto it = constrained_find(key, index); it != end()) {
  2254. it->second = std::forward<Arg>(value);
  2255. return std::make_pair(it, false);
  2256. }
  2257. packed.first().emplace_back(sparse.first()[index], std::forward<Other>(key), std::forward<Arg>(value));
  2258. sparse.first()[index] = packed.first().size() - 1u;
  2259. rehash_if_required();
  2260. return std::make_pair(--end(), true);
  2261. }
  2262. void move_and_pop(const std::size_t pos) {
  2263. if(const auto last = size() - 1u; pos != last) {
  2264. packed.first()[pos] = std::move(packed.first().back());
  2265. size_type *curr = sparse.first().data() + key_to_bucket(packed.first().back().element.first);
  2266. for(; *curr != last; curr = &packed.first()[*curr].next) {}
  2267. *curr = pos;
  2268. }
  2269. packed.first().pop_back();
  2270. }
  2271. void rehash_if_required() {
  2272. if(size() > (bucket_count() * max_load_factor())) {
  2273. rehash(bucket_count() * 2u);
  2274. }
  2275. }
  2276. public:
  2277. /*! @brief Key type of the container. */
  2278. using key_type = Key;
  2279. /*! @brief Mapped type of the container. */
  2280. using mapped_type = Type;
  2281. /*! @brief Key-value type of the container. */
  2282. using value_type = std::pair<const Key, Type>;
  2283. /*! @brief Unsigned integer type. */
  2284. using size_type = std::size_t;
  2285. /*! @brief Type of function to use to hash the keys. */
  2286. using hasher = Hash;
  2287. /*! @brief Type of function to use to compare the keys for equality. */
  2288. using key_equal = KeyEqual;
  2289. /*! @brief Allocator type. */
  2290. using allocator_type = Allocator;
  2291. /*! @brief Input iterator type. */
  2292. using iterator = internal::dense_map_iterator<typename packed_container_type::iterator>;
  2293. /*! @brief Constant input iterator type. */
  2294. using const_iterator = internal::dense_map_iterator<typename packed_container_type::const_iterator>;
  2295. /*! @brief Input iterator type. */
  2296. using local_iterator = internal::dense_map_local_iterator<typename packed_container_type::iterator>;
  2297. /*! @brief Constant input iterator type. */
  2298. using const_local_iterator = internal::dense_map_local_iterator<typename packed_container_type::const_iterator>;
  2299. /*! @brief Default constructor. */
  2300. dense_map()
  2301. : dense_map(minimum_capacity) {}
  2302. /**
  2303. * @brief Constructs an empty container with a given allocator.
  2304. * @param allocator The allocator to use.
  2305. */
  2306. explicit dense_map(const allocator_type &allocator)
  2307. : dense_map{minimum_capacity, hasher{}, key_equal{}, allocator} {}
  2308. /**
  2309. * @brief Constructs an empty container with a given allocator and user
  2310. * supplied minimal number of buckets.
  2311. * @param bucket_count Minimal number of buckets.
  2312. * @param allocator The allocator to use.
  2313. */
  2314. dense_map(const size_type bucket_count, const allocator_type &allocator)
  2315. : dense_map{bucket_count, hasher{}, key_equal{}, allocator} {}
  2316. /**
  2317. * @brief Constructs an empty container with a given allocator, hash
  2318. * function and user supplied minimal number of buckets.
  2319. * @param bucket_count Minimal number of buckets.
  2320. * @param hash Hash function to use.
  2321. * @param allocator The allocator to use.
  2322. */
  2323. dense_map(const size_type bucket_count, const hasher &hash, const allocator_type &allocator)
  2324. : dense_map{bucket_count, hash, key_equal{}, allocator} {}
  2325. /**
  2326. * @brief Constructs an empty container with a given allocator, hash
  2327. * function, compare function and user supplied minimal number of buckets.
  2328. * @param bucket_count Minimal number of buckets.
  2329. * @param hash Hash function to use.
  2330. * @param equal Compare function to use.
  2331. * @param allocator The allocator to use.
  2332. */
  2333. explicit dense_map(const size_type bucket_count, const hasher &hash = hasher{}, const key_equal &equal = key_equal{}, const allocator_type &allocator = allocator_type{})
  2334. : sparse{allocator, hash},
  2335. packed{allocator, equal},
  2336. threshold{default_threshold} {
  2337. rehash(bucket_count);
  2338. }
  2339. /*! @brief Default copy constructor. */
  2340. dense_map(const dense_map &) = default;
  2341. /**
  2342. * @brief Allocator-extended copy constructor.
  2343. * @param other The instance to copy from.
  2344. * @param allocator The allocator to use.
  2345. */
  2346. dense_map(const dense_map &other, const allocator_type &allocator)
  2347. : sparse{std::piecewise_construct, std::forward_as_tuple(other.sparse.first(), allocator), std::forward_as_tuple(other.sparse.second())},
  2348. packed{std::piecewise_construct, std::forward_as_tuple(other.packed.first(), allocator), std::forward_as_tuple(other.packed.second())},
  2349. threshold{other.threshold} {}
  2350. /*! @brief Default move constructor. */
  2351. dense_map(dense_map &&) = default;
  2352. /**
  2353. * @brief Allocator-extended move constructor.
  2354. * @param other The instance to move from.
  2355. * @param allocator The allocator to use.
  2356. */
  2357. dense_map(dense_map &&other, const allocator_type &allocator)
  2358. : sparse{std::piecewise_construct, std::forward_as_tuple(std::move(other.sparse.first()), allocator), std::forward_as_tuple(std::move(other.sparse.second()))},
  2359. packed{std::piecewise_construct, std::forward_as_tuple(std::move(other.packed.first()), allocator), std::forward_as_tuple(std::move(other.packed.second()))},
  2360. threshold{other.threshold} {}
  2361. /**
  2362. * @brief Default copy assignment operator.
  2363. * @return This container.
  2364. */
  2365. dense_map &operator=(const dense_map &) = default;
  2366. /**
  2367. * @brief Default move assignment operator.
  2368. * @return This container.
  2369. */
  2370. dense_map &operator=(dense_map &&) = default;
  2371. /**
  2372. * @brief Returns the associated allocator.
  2373. * @return The associated allocator.
  2374. */
  2375. [[nodiscard]] constexpr allocator_type get_allocator() const ENTT_NOEXCEPT {
  2376. return sparse.first().get_allocator();
  2377. }
  2378. /**
  2379. * @brief Returns an iterator to the beginning.
  2380. *
  2381. * The returned iterator points to the first instance of the internal array.
  2382. * If the array is empty, the returned iterator will be equal to `end()`.
  2383. *
  2384. * @return An iterator to the first instance of the internal array.
  2385. */
  2386. [[nodiscard]] const_iterator cbegin() const ENTT_NOEXCEPT {
  2387. return packed.first().begin();
  2388. }
  2389. /*! @copydoc cbegin */
  2390. [[nodiscard]] const_iterator begin() const ENTT_NOEXCEPT {
  2391. return cbegin();
  2392. }
  2393. /*! @copydoc begin */
  2394. [[nodiscard]] iterator begin() ENTT_NOEXCEPT {
  2395. return packed.first().begin();
  2396. }
  2397. /**
  2398. * @brief Returns an iterator to the end.
  2399. *
  2400. * The returned iterator points to the element following the last instance
  2401. * of the internal array. Attempting to dereference the returned iterator
  2402. * results in undefined behavior.
  2403. *
  2404. * @return An iterator to the element following the last instance of the
  2405. * internal array.
  2406. */
  2407. [[nodiscard]] const_iterator cend() const ENTT_NOEXCEPT {
  2408. return packed.first().end();
  2409. }
  2410. /*! @copydoc cend */
  2411. [[nodiscard]] const_iterator end() const ENTT_NOEXCEPT {
  2412. return cend();
  2413. }
  2414. /*! @copydoc end */
  2415. [[nodiscard]] iterator end() ENTT_NOEXCEPT {
  2416. return packed.first().end();
  2417. }
  2418. /**
  2419. * @brief Checks whether a container is empty.
  2420. * @return True if the container is empty, false otherwise.
  2421. */
  2422. [[nodiscard]] bool empty() const ENTT_NOEXCEPT {
  2423. return packed.first().empty();
  2424. }
  2425. /**
  2426. * @brief Returns the number of elements in a container.
  2427. * @return Number of elements in a container.
  2428. */
  2429. [[nodiscard]] size_type size() const ENTT_NOEXCEPT {
  2430. return packed.first().size();
  2431. }
  2432. /*! @brief Clears the container. */
  2433. void clear() ENTT_NOEXCEPT {
  2434. sparse.first().clear();
  2435. packed.first().clear();
  2436. rehash(0u);
  2437. }
  2438. /**
  2439. * @brief Inserts an element into the container, if the key does not exist.
  2440. * @param value A key-value pair eventually convertible to the value type.
  2441. * @return A pair consisting of an iterator to the inserted element (or to
  2442. * the element that prevented the insertion) and a bool denoting whether the
  2443. * insertion took place.
  2444. */
  2445. std::pair<iterator, bool> insert(const value_type &value) {
  2446. return insert_or_do_nothing(value.first, value.second);
  2447. }
  2448. /*! @copydoc insert */
  2449. std::pair<iterator, bool> insert(value_type &&value) {
  2450. return insert_or_do_nothing(std::move(value.first), std::move(value.second));
  2451. }
  2452. /**
  2453. * @copydoc insert
  2454. * @tparam Arg Type of the key-value pair to insert into the container.
  2455. */
  2456. template<typename Arg>
  2457. std::enable_if_t<std::is_constructible_v<value_type, Arg &&>, std::pair<iterator, bool>>
  2458. insert(Arg &&value) {
  2459. return insert_or_do_nothing(std::forward<Arg>(value).first, std::forward<Arg>(value).second);
  2460. }
  2461. /**
  2462. * @brief Inserts elements into the container, if their keys do not exist.
  2463. * @tparam It Type of input iterator.
  2464. * @param first An iterator to the first element of the range of elements.
  2465. * @param last An iterator past the last element of the range of elements.
  2466. */
  2467. template<typename It>
  2468. void insert(It first, It last) {
  2469. for(; first != last; ++first) {
  2470. insert(*first);
  2471. }
  2472. }
  2473. /**
  2474. * @brief Inserts an element into the container or assigns to the current
  2475. * element if the key already exists.
  2476. * @tparam Arg Type of the value to insert or assign.
  2477. * @param key A key used both to look up and to insert if not found.
  2478. * @param value A value to insert or assign.
  2479. * @return A pair consisting of an iterator to the element and a bool
  2480. * denoting whether the insertion took place.
  2481. */
  2482. template<typename Arg>
  2483. std::pair<iterator, bool> insert_or_assign(const key_type &key, Arg &&value) {
  2484. return insert_or_overwrite(key, std::forward<Arg>(value));
  2485. }
  2486. /*! @copydoc insert_or_assign */
  2487. template<typename Arg>
  2488. std::pair<iterator, bool> insert_or_assign(key_type &&key, Arg &&value) {
  2489. return insert_or_overwrite(std::move(key), std::forward<Arg>(value));
  2490. }
  2491. /**
  2492. * @brief Constructs an element in-place, if the key does not exist.
  2493. *
  2494. * The element is also constructed when the container already has the key,
  2495. * in which case the newly constructed object is destroyed immediately.
  2496. *
  2497. * @tparam Args Types of arguments to forward to the constructor of the
  2498. * element.
  2499. * @param args Arguments to forward to the constructor of the element.
  2500. * @return A pair consisting of an iterator to the inserted element (or to
  2501. * the element that prevented the insertion) and a bool denoting whether the
  2502. * insertion took place.
  2503. */
  2504. template<typename... Args>
  2505. std::pair<iterator, bool> emplace([[maybe_unused]] Args &&...args) {
  2506. if constexpr(sizeof...(Args) == 0u) {
  2507. return insert_or_do_nothing(key_type{});
  2508. } else if constexpr(sizeof...(Args) == 1u) {
  2509. return insert_or_do_nothing(std::forward<Args>(args).first..., std::forward<Args>(args).second...);
  2510. } else if constexpr(sizeof...(Args) == 2u) {
  2511. return insert_or_do_nothing(std::forward<Args>(args)...);
  2512. } else {
  2513. auto &node = packed.first().emplace_back(packed.first().size(), std::forward<Args>(args)...);
  2514. const auto index = key_to_bucket(node.element.first);
  2515. if(auto it = constrained_find(node.element.first, index); it != end()) {
  2516. packed.first().pop_back();
  2517. return std::make_pair(it, false);
  2518. }
  2519. std::swap(node.next, sparse.first()[index]);
  2520. rehash_if_required();
  2521. return std::make_pair(--end(), true);
  2522. }
  2523. }
  2524. /**
  2525. * @brief Inserts in-place if the key does not exist, does nothing if the
  2526. * key exists.
  2527. * @tparam Args Types of arguments to forward to the constructor of the
  2528. * element.
  2529. * @param key A key used both to look up and to insert if not found.
  2530. * @param args Arguments to forward to the constructor of the element.
  2531. * @return A pair consisting of an iterator to the inserted element (or to
  2532. * the element that prevented the insertion) and a bool denoting whether the
  2533. * insertion took place.
  2534. */
  2535. template<typename... Args>
  2536. std::pair<iterator, bool> try_emplace(const key_type &key, Args &&...args) {
  2537. return insert_or_do_nothing(key, std::forward<Args>(args)...);
  2538. }
  2539. /*! @copydoc try_emplace */
  2540. template<typename... Args>
  2541. std::pair<iterator, bool> try_emplace(key_type &&key, Args &&...args) {
  2542. return insert_or_do_nothing(std::move(key), std::forward<Args>(args)...);
  2543. }
  2544. /**
  2545. * @brief Removes an element from a given position.
  2546. * @param pos An iterator to the element to remove.
  2547. * @return An iterator following the removed element.
  2548. */
  2549. iterator erase(const_iterator pos) {
  2550. const auto diff = pos - cbegin();
  2551. erase(pos->first);
  2552. return begin() + diff;
  2553. }
  2554. /**
  2555. * @brief Removes the given elements from a container.
  2556. * @param first An iterator to the first element of the range of elements.
  2557. * @param last An iterator past the last element of the range of elements.
  2558. * @return An iterator following the last removed element.
  2559. */
  2560. iterator erase(const_iterator first, const_iterator last) {
  2561. const auto dist = first - cbegin();
  2562. for(auto from = last - cbegin(); from != dist; --from) {
  2563. erase(packed.first()[from - 1u].element.first);
  2564. }
  2565. return (begin() + dist);
  2566. }
  2567. /**
  2568. * @brief Removes the element associated with a given key.
  2569. * @param key A key value of an element to remove.
  2570. * @return Number of elements removed (either 0 or 1).
  2571. */
  2572. size_type erase(const key_type &key) {
  2573. for(size_type *curr = sparse.first().data() + key_to_bucket(key); *curr != (std::numeric_limits<size_type>::max)(); curr = &packed.first()[*curr].next) {
  2574. if(packed.second()(packed.first()[*curr].element.first, key)) {
  2575. const auto index = *curr;
  2576. *curr = packed.first()[*curr].next;
  2577. move_and_pop(index);
  2578. return 1u;
  2579. }
  2580. }
  2581. return 0u;
  2582. }
  2583. /**
  2584. * @brief Exchanges the contents with those of a given container.
  2585. * @param other Container to exchange the content with.
  2586. */
  2587. void swap(dense_map &other) {
  2588. using std::swap;
  2589. swap(sparse, other.sparse);
  2590. swap(packed, other.packed);
  2591. swap(threshold, other.threshold);
  2592. }
  2593. /**
  2594. * @brief Accesses a given element with bounds checking.
  2595. * @param key A key of an element to find.
  2596. * @return A reference to the mapped value of the requested element.
  2597. */
  2598. [[nodiscard]] mapped_type &at(const key_type &key) {
  2599. auto it = find(key);
  2600. ENTT_ASSERT(it != end(), "Invalid key");
  2601. return it->second;
  2602. }
  2603. /*! @copydoc at */
  2604. [[nodiscard]] const mapped_type &at(const key_type &key) const {
  2605. auto it = find(key);
  2606. ENTT_ASSERT(it != cend(), "Invalid key");
  2607. return it->second;
  2608. }
  2609. /**
  2610. * @brief Accesses or inserts a given element.
  2611. * @param key A key of an element to find or insert.
  2612. * @return A reference to the mapped value of the requested element.
  2613. */
  2614. [[nodiscard]] mapped_type &operator[](const key_type &key) {
  2615. return insert_or_do_nothing(key).first->second;
  2616. }
  2617. /**
  2618. * @brief Accesses or inserts a given element.
  2619. * @param key A key of an element to find or insert.
  2620. * @return A reference to the mapped value of the requested element.
  2621. */
  2622. [[nodiscard]] mapped_type &operator[](key_type &&key) {
  2623. return insert_or_do_nothing(std::move(key)).first->second;
  2624. }
  2625. /**
  2626. * @brief Finds an element with a given key.
  2627. * @param key Key value of an element to search for.
  2628. * @return An iterator to an element with the given key. If no such element
  2629. * is found, a past-the-end iterator is returned.
  2630. */
  2631. [[nodiscard]] iterator find(const key_type &key) {
  2632. return constrained_find(key, key_to_bucket(key));
  2633. }
  2634. /*! @copydoc find */
  2635. [[nodiscard]] const_iterator find(const key_type &key) const {
  2636. return constrained_find(key, key_to_bucket(key));
  2637. }
  2638. /**
  2639. * @brief Finds an element with a key that compares _equivalent_ to a given
  2640. * value.
  2641. * @tparam Other Type of the key value of an element to search for.
  2642. * @param key Key value of an element to search for.
  2643. * @return An iterator to an element with the given key. If no such element
  2644. * is found, a past-the-end iterator is returned.
  2645. */
  2646. template<typename Other>
  2647. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, iterator>>
  2648. find(const Other &key) {
  2649. return constrained_find(key, key_to_bucket(key));
  2650. }
  2651. /*! @copydoc find */
  2652. template<typename Other>
  2653. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, const_iterator>>
  2654. find(const Other &key) const {
  2655. return constrained_find(key, key_to_bucket(key));
  2656. }
  2657. /**
  2658. * @brief Checks if the container contains an element with a given key.
  2659. * @param key Key value of an element to search for.
  2660. * @return True if there is such an element, false otherwise.
  2661. */
  2662. [[nodiscard]] bool contains(const key_type &key) const {
  2663. return (find(key) != cend());
  2664. }
  2665. /**
  2666. * @brief Checks if the container contains an element with a key that
  2667. * compares _equivalent_ to a given value.
  2668. * @tparam Other Type of the key value of an element to search for.
  2669. * @param key Key value of an element to search for.
  2670. * @return True if there is such an element, false otherwise.
  2671. */
  2672. template<typename Other>
  2673. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, bool>>
  2674. contains(const Other &key) const {
  2675. return (find(key) != cend());
  2676. }
  2677. /**
  2678. * @brief Returns an iterator to the beginning of a given bucket.
  2679. * @param index An index of a bucket to access.
  2680. * @return An iterator to the beginning of the given bucket.
  2681. */
  2682. [[nodiscard]] const_local_iterator cbegin(const size_type index) const {
  2683. return {packed.first().begin(), sparse.first()[index]};
  2684. }
  2685. /**
  2686. * @brief Returns an iterator to the beginning of a given bucket.
  2687. * @param index An index of a bucket to access.
  2688. * @return An iterator to the beginning of the given bucket.
  2689. */
  2690. [[nodiscard]] const_local_iterator begin(const size_type index) const {
  2691. return cbegin(index);
  2692. }
  2693. /**
  2694. * @brief Returns an iterator to the beginning of a given bucket.
  2695. * @param index An index of a bucket to access.
  2696. * @return An iterator to the beginning of the given bucket.
  2697. */
  2698. [[nodiscard]] local_iterator begin(const size_type index) {
  2699. return {packed.first().begin(), sparse.first()[index]};
  2700. }
  2701. /**
  2702. * @brief Returns an iterator to the end of a given bucket.
  2703. * @param index An index of a bucket to access.
  2704. * @return An iterator to the end of the given bucket.
  2705. */
  2706. [[nodiscard]] const_local_iterator cend([[maybe_unused]] const size_type index) const {
  2707. return {packed.first().begin(), (std::numeric_limits<size_type>::max)()};
  2708. }
  2709. /**
  2710. * @brief Returns an iterator to the end of a given bucket.
  2711. * @param index An index of a bucket to access.
  2712. * @return An iterator to the end of the given bucket.
  2713. */
  2714. [[nodiscard]] const_local_iterator end([[maybe_unused]] const size_type index) const {
  2715. return cend(index);
  2716. }
  2717. /**
  2718. * @brief Returns an iterator to the end of a given bucket.
  2719. * @param index An index of a bucket to access.
  2720. * @return An iterator to the end of the given bucket.
  2721. */
  2722. [[nodiscard]] local_iterator end([[maybe_unused]] const size_type index) {
  2723. return {packed.first().begin(), (std::numeric_limits<size_type>::max)()};
  2724. }
  2725. /**
  2726. * @brief Returns the number of buckets.
  2727. * @return The number of buckets.
  2728. */
  2729. [[nodiscard]] size_type bucket_count() const {
  2730. return sparse.first().size();
  2731. }
  2732. /**
  2733. * @brief Returns the maximum number of buckets.
  2734. * @return The maximum number of buckets.
  2735. */
  2736. [[nodiscard]] size_type max_bucket_count() const {
  2737. return sparse.first().max_size();
  2738. }
  2739. /**
  2740. * @brief Returns the number of elements in a given bucket.
  2741. * @param index The index of the bucket to examine.
  2742. * @return The number of elements in the given bucket.
  2743. */
  2744. [[nodiscard]] size_type bucket_size(const size_type index) const {
  2745. return static_cast<size_type>(std::distance(begin(index), end(index)));
  2746. }
  2747. /**
  2748. * @brief Returns the bucket for a given key.
  2749. * @param key The value of the key to examine.
  2750. * @return The bucket for the given key.
  2751. */
  2752. [[nodiscard]] size_type bucket(const key_type &key) const {
  2753. return key_to_bucket(key);
  2754. }
  2755. /**
  2756. * @brief Returns the average number of elements per bucket.
  2757. * @return The average number of elements per bucket.
  2758. */
  2759. [[nodiscard]] float load_factor() const {
  2760. return size() / static_cast<float>(bucket_count());
  2761. }
  2762. /**
  2763. * @brief Returns the maximum average number of elements per bucket.
  2764. * @return The maximum average number of elements per bucket.
  2765. */
  2766. [[nodiscard]] float max_load_factor() const {
  2767. return threshold;
  2768. }
  2769. /**
  2770. * @brief Sets the desired maximum average number of elements per bucket.
  2771. * @param value A desired maximum average number of elements per bucket.
  2772. */
  2773. void max_load_factor(const float value) {
  2774. ENTT_ASSERT(value > 0.f, "Invalid load factor");
  2775. threshold = value;
  2776. rehash(0u);
  2777. }
  2778. /**
  2779. * @brief Reserves at least the specified number of buckets and regenerates
  2780. * the hash table.
  2781. * @param count New number of buckets.
  2782. */
  2783. void rehash(const size_type count) {
  2784. auto value = (std::max)(count, minimum_capacity);
  2785. value = (std::max)(value, static_cast<size_type>(size() / max_load_factor()));
  2786. if(const auto sz = next_power_of_two(value); sz != bucket_count()) {
  2787. sparse.first().resize(sz);
  2788. std::fill(sparse.first().begin(), sparse.first().end(), (std::numeric_limits<size_type>::max)());
  2789. for(size_type pos{}, last = size(); pos < last; ++pos) {
  2790. const auto index = key_to_bucket(packed.first()[pos].element.first);
  2791. packed.first()[pos].next = std::exchange(sparse.first()[index], pos);
  2792. }
  2793. }
  2794. }
  2795. /**
  2796. * @brief Reserves space for at least the specified number of elements and
  2797. * regenerates the hash table.
  2798. * @param count New number of elements.
  2799. */
  2800. void reserve(const size_type count) {
  2801. packed.first().reserve(count);
  2802. rehash(static_cast<size_type>(std::ceil(count / max_load_factor())));
  2803. }
  2804. /**
  2805. * @brief Returns the function used to hash the keys.
  2806. * @return The function used to hash the keys.
  2807. */
  2808. [[nodiscard]] hasher hash_function() const {
  2809. return sparse.second();
  2810. }
  2811. /**
  2812. * @brief Returns the function used to compare keys for equality.
  2813. * @return The function used to compare keys for equality.
  2814. */
  2815. [[nodiscard]] key_equal key_eq() const {
  2816. return packed.second();
  2817. }
  2818. private:
  2819. compressed_pair<sparse_container_type, hasher> sparse;
  2820. compressed_pair<packed_container_type, key_equal> packed;
  2821. float threshold;
  2822. };
  2823. } // namespace entt
  2824. /**
  2825. * @cond TURN_OFF_DOXYGEN
  2826. * Internal details not to be documented.
  2827. */
  2828. namespace std {
  2829. template<typename Key, typename Value, typename Allocator>
  2830. struct uses_allocator<entt::internal::dense_map_node<Key, Value>, Allocator>
  2831. : std::true_type {};
  2832. } // namespace std
  2833. /**
  2834. * Internal details not to be documented.
  2835. * @endcond
  2836. */
  2837. #endif
  2838. // #include "container/dense_set.hpp"
  2839. #ifndef ENTT_CONTAINER_DENSE_SET_HPP
  2840. #define ENTT_CONTAINER_DENSE_SET_HPP
  2841. #include <algorithm>
  2842. #include <cmath>
  2843. #include <cstddef>
  2844. #include <functional>
  2845. #include <iterator>
  2846. #include <limits>
  2847. #include <memory>
  2848. #include <tuple>
  2849. #include <type_traits>
  2850. #include <utility>
  2851. #include <vector>
  2852. // #include "../config/config.h"
  2853. // #include "../core/compressed_pair.hpp"
  2854. // #include "../core/memory.hpp"
  2855. // #include "../core/type_traits.hpp"
  2856. // #include "fwd.hpp"
  2857. namespace entt {
  2858. /**
  2859. * @cond TURN_OFF_DOXYGEN
  2860. * Internal details not to be documented.
  2861. */
  2862. namespace internal {
  2863. template<typename It>
  2864. class dense_set_iterator final {
  2865. template<typename>
  2866. friend class dense_set_iterator;
  2867. public:
  2868. using value_type = typename It::value_type::second_type;
  2869. using pointer = const value_type *;
  2870. using reference = const value_type &;
  2871. using difference_type = std::ptrdiff_t;
  2872. using iterator_category = std::random_access_iterator_tag;
  2873. dense_set_iterator() ENTT_NOEXCEPT
  2874. : it{} {}
  2875. dense_set_iterator(const It iter) ENTT_NOEXCEPT
  2876. : it{iter} {}
  2877. template<typename Other, typename = std::enable_if_t<!std::is_same_v<It, Other> && std::is_constructible_v<It, Other>>>
  2878. dense_set_iterator(const dense_set_iterator<Other> &other) ENTT_NOEXCEPT
  2879. : it{other.it} {}
  2880. dense_set_iterator &operator++() ENTT_NOEXCEPT {
  2881. return ++it, *this;
  2882. }
  2883. dense_set_iterator operator++(int) ENTT_NOEXCEPT {
  2884. dense_set_iterator orig = *this;
  2885. return ++(*this), orig;
  2886. }
  2887. dense_set_iterator &operator--() ENTT_NOEXCEPT {
  2888. return --it, *this;
  2889. }
  2890. dense_set_iterator operator--(int) ENTT_NOEXCEPT {
  2891. dense_set_iterator orig = *this;
  2892. return operator--(), orig;
  2893. }
  2894. dense_set_iterator &operator+=(const difference_type value) ENTT_NOEXCEPT {
  2895. it += value;
  2896. return *this;
  2897. }
  2898. dense_set_iterator operator+(const difference_type value) const ENTT_NOEXCEPT {
  2899. dense_set_iterator copy = *this;
  2900. return (copy += value);
  2901. }
  2902. dense_set_iterator &operator-=(const difference_type value) ENTT_NOEXCEPT {
  2903. return (*this += -value);
  2904. }
  2905. dense_set_iterator operator-(const difference_type value) const ENTT_NOEXCEPT {
  2906. return (*this + -value);
  2907. }
  2908. [[nodiscard]] reference operator[](const difference_type value) const ENTT_NOEXCEPT {
  2909. return it[value].second;
  2910. }
  2911. [[nodiscard]] pointer operator->() const ENTT_NOEXCEPT {
  2912. return std::addressof(it->second);
  2913. }
  2914. [[nodiscard]] reference operator*() const ENTT_NOEXCEPT {
  2915. return *operator->();
  2916. }
  2917. template<typename ILhs, typename IRhs>
  2918. friend std::ptrdiff_t operator-(const dense_set_iterator<ILhs> &, const dense_set_iterator<IRhs> &) ENTT_NOEXCEPT;
  2919. template<typename ILhs, typename IRhs>
  2920. friend bool operator==(const dense_set_iterator<ILhs> &, const dense_set_iterator<IRhs> &) ENTT_NOEXCEPT;
  2921. template<typename ILhs, typename IRhs>
  2922. friend bool operator<(const dense_set_iterator<ILhs> &, const dense_set_iterator<IRhs> &) ENTT_NOEXCEPT;
  2923. private:
  2924. It it;
  2925. };
  2926. template<typename ILhs, typename IRhs>
  2927. [[nodiscard]] std::ptrdiff_t operator-(const dense_set_iterator<ILhs> &lhs, const dense_set_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  2928. return lhs.it - rhs.it;
  2929. }
  2930. template<typename ILhs, typename IRhs>
  2931. [[nodiscard]] bool operator==(const dense_set_iterator<ILhs> &lhs, const dense_set_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  2932. return lhs.it == rhs.it;
  2933. }
  2934. template<typename ILhs, typename IRhs>
  2935. [[nodiscard]] bool operator!=(const dense_set_iterator<ILhs> &lhs, const dense_set_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  2936. return !(lhs == rhs);
  2937. }
  2938. template<typename ILhs, typename IRhs>
  2939. [[nodiscard]] bool operator<(const dense_set_iterator<ILhs> &lhs, const dense_set_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  2940. return lhs.it < rhs.it;
  2941. }
  2942. template<typename ILhs, typename IRhs>
  2943. [[nodiscard]] bool operator>(const dense_set_iterator<ILhs> &lhs, const dense_set_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  2944. return rhs < lhs;
  2945. }
  2946. template<typename ILhs, typename IRhs>
  2947. [[nodiscard]] bool operator<=(const dense_set_iterator<ILhs> &lhs, const dense_set_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  2948. return !(lhs > rhs);
  2949. }
  2950. template<typename ILhs, typename IRhs>
  2951. [[nodiscard]] bool operator>=(const dense_set_iterator<ILhs> &lhs, const dense_set_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  2952. return !(lhs < rhs);
  2953. }
  2954. template<typename It>
  2955. class dense_set_local_iterator final {
  2956. template<typename>
  2957. friend class dense_set_local_iterator;
  2958. public:
  2959. using value_type = typename It::value_type::second_type;
  2960. using pointer = const value_type *;
  2961. using reference = const value_type &;
  2962. using difference_type = std::ptrdiff_t;
  2963. using iterator_category = std::forward_iterator_tag;
  2964. dense_set_local_iterator() ENTT_NOEXCEPT
  2965. : it{},
  2966. offset{} {}
  2967. dense_set_local_iterator(It iter, const std::size_t pos) ENTT_NOEXCEPT
  2968. : it{iter},
  2969. offset{pos} {}
  2970. template<typename Other, typename = std::enable_if_t<!std::is_same_v<It, Other> && std::is_constructible_v<It, Other>>>
  2971. dense_set_local_iterator(const dense_set_local_iterator<Other> &other) ENTT_NOEXCEPT
  2972. : it{other.it},
  2973. offset{other.offset} {}
  2974. dense_set_local_iterator &operator++() ENTT_NOEXCEPT {
  2975. return offset = it[offset].first, *this;
  2976. }
  2977. dense_set_local_iterator operator++(int) ENTT_NOEXCEPT {
  2978. dense_set_local_iterator orig = *this;
  2979. return ++(*this), orig;
  2980. }
  2981. [[nodiscard]] pointer operator->() const ENTT_NOEXCEPT {
  2982. return std::addressof(it[offset].second);
  2983. }
  2984. [[nodiscard]] reference operator*() const ENTT_NOEXCEPT {
  2985. return *operator->();
  2986. }
  2987. [[nodiscard]] std::size_t index() const ENTT_NOEXCEPT {
  2988. return offset;
  2989. }
  2990. private:
  2991. It it;
  2992. std::size_t offset;
  2993. };
  2994. template<typename ILhs, typename IRhs>
  2995. [[nodiscard]] bool operator==(const dense_set_local_iterator<ILhs> &lhs, const dense_set_local_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  2996. return lhs.index() == rhs.index();
  2997. }
  2998. template<typename ILhs, typename IRhs>
  2999. [[nodiscard]] bool operator!=(const dense_set_local_iterator<ILhs> &lhs, const dense_set_local_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  3000. return !(lhs == rhs);
  3001. }
  3002. } // namespace internal
  3003. /**
  3004. * Internal details not to be documented.
  3005. * @endcond
  3006. */
  3007. /**
  3008. * @brief Associative container for unique objects of a given type.
  3009. *
  3010. * Internally, elements are organized into buckets. Which bucket an element is
  3011. * placed into depends entirely on its hash. Elements with the same hash code
  3012. * appear in the same bucket.
  3013. *
  3014. * @tparam Type Value type of the associative container.
  3015. * @tparam Hash Type of function to use to hash the values.
  3016. * @tparam KeyEqual Type of function to use to compare the values for equality.
  3017. * @tparam Allocator Type of allocator used to manage memory and elements.
  3018. */
  3019. template<typename Type, typename Hash, typename KeyEqual, typename Allocator>
  3020. class dense_set {
  3021. static constexpr float default_threshold = 0.875f;
  3022. static constexpr std::size_t minimum_capacity = 8u;
  3023. using node_type = std::pair<std::size_t, Type>;
  3024. using alloc_traits = std::allocator_traits<Allocator>;
  3025. static_assert(std::is_same_v<typename alloc_traits::value_type, Type>, "Invalid value type");
  3026. using sparse_container_type = std::vector<std::size_t, typename alloc_traits::template rebind_alloc<std::size_t>>;
  3027. using packed_container_type = std::vector<node_type, typename alloc_traits::template rebind_alloc<node_type>>;
  3028. template<typename Other>
  3029. [[nodiscard]] std::size_t value_to_bucket(const Other &value) const ENTT_NOEXCEPT {
  3030. return fast_mod(sparse.second()(value), bucket_count());
  3031. }
  3032. template<typename Other>
  3033. [[nodiscard]] auto constrained_find(const Other &value, std::size_t bucket) {
  3034. for(auto it = begin(bucket), last = end(bucket); it != last; ++it) {
  3035. if(packed.second()(*it, value)) {
  3036. return begin() + static_cast<typename iterator::difference_type>(it.index());
  3037. }
  3038. }
  3039. return end();
  3040. }
  3041. template<typename Other>
  3042. [[nodiscard]] auto constrained_find(const Other &value, std::size_t bucket) const {
  3043. for(auto it = cbegin(bucket), last = cend(bucket); it != last; ++it) {
  3044. if(packed.second()(*it, value)) {
  3045. return cbegin() + static_cast<typename iterator::difference_type>(it.index());
  3046. }
  3047. }
  3048. return cend();
  3049. }
  3050. template<typename Other>
  3051. [[nodiscard]] auto insert_or_do_nothing(Other &&value) {
  3052. const auto index = value_to_bucket(value);
  3053. if(auto it = constrained_find(value, index); it != end()) {
  3054. return std::make_pair(it, false);
  3055. }
  3056. packed.first().emplace_back(sparse.first()[index], std::forward<Other>(value));
  3057. sparse.first()[index] = packed.first().size() - 1u;
  3058. rehash_if_required();
  3059. return std::make_pair(--end(), true);
  3060. }
  3061. void move_and_pop(const std::size_t pos) {
  3062. if(const auto last = size() - 1u; pos != last) {
  3063. packed.first()[pos] = std::move(packed.first().back());
  3064. size_type *curr = sparse.first().data() + value_to_bucket(packed.first().back().second);
  3065. for(; *curr != last; curr = &packed.first()[*curr].first) {}
  3066. *curr = pos;
  3067. }
  3068. packed.first().pop_back();
  3069. }
  3070. void rehash_if_required() {
  3071. if(size() > (bucket_count() * max_load_factor())) {
  3072. rehash(bucket_count() * 2u);
  3073. }
  3074. }
  3075. public:
  3076. /*! @brief Key type of the container. */
  3077. using key_type = Type;
  3078. /*! @brief Value type of the container. */
  3079. using value_type = Type;
  3080. /*! @brief Unsigned integer type. */
  3081. using size_type = std::size_t;
  3082. /*! @brief Type of function to use to hash the elements. */
  3083. using hasher = Hash;
  3084. /*! @brief Type of function to use to compare the elements for equality. */
  3085. using key_equal = KeyEqual;
  3086. /*! @brief Allocator type. */
  3087. using allocator_type = Allocator;
  3088. /*! @brief Random access iterator type. */
  3089. using iterator = internal::dense_set_iterator<typename packed_container_type::iterator>;
  3090. /*! @brief Constant random access iterator type. */
  3091. using const_iterator = internal::dense_set_iterator<typename packed_container_type::const_iterator>;
  3092. /*! @brief Forward iterator type. */
  3093. using local_iterator = internal::dense_set_local_iterator<typename packed_container_type::iterator>;
  3094. /*! @brief Constant forward iterator type. */
  3095. using const_local_iterator = internal::dense_set_local_iterator<typename packed_container_type::const_iterator>;
  3096. /*! @brief Default constructor. */
  3097. dense_set()
  3098. : dense_set(minimum_capacity) {}
  3099. /**
  3100. * @brief Constructs an empty container with a given allocator.
  3101. * @param allocator The allocator to use.
  3102. */
  3103. explicit dense_set(const allocator_type &allocator)
  3104. : dense_set{minimum_capacity, hasher{}, key_equal{}, allocator} {}
  3105. /**
  3106. * @brief Constructs an empty container with a given allocator and user
  3107. * supplied minimal number of buckets.
  3108. * @param bucket_count Minimal number of buckets.
  3109. * @param allocator The allocator to use.
  3110. */
  3111. dense_set(const size_type bucket_count, const allocator_type &allocator)
  3112. : dense_set{bucket_count, hasher{}, key_equal{}, allocator} {}
  3113. /**
  3114. * @brief Constructs an empty container with a given allocator, hash
  3115. * function and user supplied minimal number of buckets.
  3116. * @param bucket_count Minimal number of buckets.
  3117. * @param hash Hash function to use.
  3118. * @param allocator The allocator to use.
  3119. */
  3120. dense_set(const size_type bucket_count, const hasher &hash, const allocator_type &allocator)
  3121. : dense_set{bucket_count, hash, key_equal{}, allocator} {}
  3122. /**
  3123. * @brief Constructs an empty container with a given allocator, hash
  3124. * function, compare function and user supplied minimal number of buckets.
  3125. * @param bucket_count Minimal number of buckets.
  3126. * @param hash Hash function to use.
  3127. * @param equal Compare function to use.
  3128. * @param allocator The allocator to use.
  3129. */
  3130. explicit dense_set(const size_type bucket_count, const hasher &hash = hasher{}, const key_equal &equal = key_equal{}, const allocator_type &allocator = allocator_type{})
  3131. : sparse{allocator, hash},
  3132. packed{allocator, equal},
  3133. threshold{default_threshold} {
  3134. rehash(bucket_count);
  3135. }
  3136. /*! @brief Default copy constructor. */
  3137. dense_set(const dense_set &) = default;
  3138. /**
  3139. * @brief Allocator-extended copy constructor.
  3140. * @param other The instance to copy from.
  3141. * @param allocator The allocator to use.
  3142. */
  3143. dense_set(const dense_set &other, const allocator_type &allocator)
  3144. : sparse{std::piecewise_construct, std::forward_as_tuple(other.sparse.first(), allocator), std::forward_as_tuple(other.sparse.second())},
  3145. packed{std::piecewise_construct, std::forward_as_tuple(other.packed.first(), allocator), std::forward_as_tuple(other.packed.second())},
  3146. threshold{other.threshold} {}
  3147. /*! @brief Default move constructor. */
  3148. dense_set(dense_set &&) = default;
  3149. /**
  3150. * @brief Allocator-extended move constructor.
  3151. * @param other The instance to move from.
  3152. * @param allocator The allocator to use.
  3153. */
  3154. dense_set(dense_set &&other, const allocator_type &allocator)
  3155. : sparse{std::piecewise_construct, std::forward_as_tuple(std::move(other.sparse.first()), allocator), std::forward_as_tuple(std::move(other.sparse.second()))},
  3156. packed{std::piecewise_construct, std::forward_as_tuple(std::move(other.packed.first()), allocator), std::forward_as_tuple(std::move(other.packed.second()))},
  3157. threshold{other.threshold} {}
  3158. /**
  3159. * @brief Default copy assignment operator.
  3160. * @return This container.
  3161. */
  3162. dense_set &operator=(const dense_set &) = default;
  3163. /**
  3164. * @brief Default move assignment operator.
  3165. * @return This container.
  3166. */
  3167. dense_set &operator=(dense_set &&) = default;
  3168. /**
  3169. * @brief Returns the associated allocator.
  3170. * @return The associated allocator.
  3171. */
  3172. [[nodiscard]] constexpr allocator_type get_allocator() const ENTT_NOEXCEPT {
  3173. return sparse.first().get_allocator();
  3174. }
  3175. /**
  3176. * @brief Returns an iterator to the beginning.
  3177. *
  3178. * The returned iterator points to the first instance of the internal array.
  3179. * If the array is empty, the returned iterator will be equal to `end()`.
  3180. *
  3181. * @return An iterator to the first instance of the internal array.
  3182. */
  3183. [[nodiscard]] const_iterator cbegin() const ENTT_NOEXCEPT {
  3184. return packed.first().begin();
  3185. }
  3186. /*! @copydoc cbegin */
  3187. [[nodiscard]] const_iterator begin() const ENTT_NOEXCEPT {
  3188. return cbegin();
  3189. }
  3190. /*! @copydoc begin */
  3191. [[nodiscard]] iterator begin() ENTT_NOEXCEPT {
  3192. return packed.first().begin();
  3193. }
  3194. /**
  3195. * @brief Returns an iterator to the end.
  3196. *
  3197. * The returned iterator points to the element following the last instance
  3198. * of the internal array. Attempting to dereference the returned iterator
  3199. * results in undefined behavior.
  3200. *
  3201. * @return An iterator to the element following the last instance of the
  3202. * internal array.
  3203. */
  3204. [[nodiscard]] const_iterator cend() const ENTT_NOEXCEPT {
  3205. return packed.first().end();
  3206. }
  3207. /*! @copydoc cend */
  3208. [[nodiscard]] const_iterator end() const ENTT_NOEXCEPT {
  3209. return cend();
  3210. }
  3211. /*! @copydoc end */
  3212. [[nodiscard]] iterator end() ENTT_NOEXCEPT {
  3213. return packed.first().end();
  3214. }
  3215. /**
  3216. * @brief Checks whether a container is empty.
  3217. * @return True if the container is empty, false otherwise.
  3218. */
  3219. [[nodiscard]] bool empty() const ENTT_NOEXCEPT {
  3220. return packed.first().empty();
  3221. }
  3222. /**
  3223. * @brief Returns the number of elements in a container.
  3224. * @return Number of elements in a container.
  3225. */
  3226. [[nodiscard]] size_type size() const ENTT_NOEXCEPT {
  3227. return packed.first().size();
  3228. }
  3229. /*! @brief Clears the container. */
  3230. void clear() ENTT_NOEXCEPT {
  3231. sparse.first().clear();
  3232. packed.first().clear();
  3233. rehash(0u);
  3234. }
  3235. /**
  3236. * @brief Inserts an element into the container, if it does not exist.
  3237. * @param value An element to insert into the container.
  3238. * @return A pair consisting of an iterator to the inserted element (or to
  3239. * the element that prevented the insertion) and a bool denoting whether the
  3240. * insertion took place.
  3241. */
  3242. std::pair<iterator, bool> insert(const value_type &value) {
  3243. return insert_or_do_nothing(value);
  3244. }
  3245. /*! @copydoc insert */
  3246. std::pair<iterator, bool> insert(value_type &&value) {
  3247. return insert_or_do_nothing(std::move(value));
  3248. }
  3249. /**
  3250. * @brief Inserts elements into the container, if they do not exist.
  3251. * @tparam It Type of input iterator.
  3252. * @param first An iterator to the first element of the range of elements.
  3253. * @param last An iterator past the last element of the range of elements.
  3254. */
  3255. template<typename It>
  3256. void insert(It first, It last) {
  3257. for(; first != last; ++first) {
  3258. insert(*first);
  3259. }
  3260. }
  3261. /**
  3262. * @brief Constructs an element in-place, if it does not exist.
  3263. *
  3264. * The element is also constructed when the container already has the key,
  3265. * in which case the newly constructed object is destroyed immediately.
  3266. *
  3267. * @tparam Args Types of arguments to forward to the constructor of the
  3268. * element.
  3269. * @param args Arguments to forward to the constructor of the element.
  3270. * @return A pair consisting of an iterator to the inserted element (or to
  3271. * the element that prevented the insertion) and a bool denoting whether the
  3272. * insertion took place.
  3273. */
  3274. template<typename... Args>
  3275. std::pair<iterator, bool> emplace(Args &&...args) {
  3276. if constexpr(((sizeof...(Args) == 1u) && ... && std::is_same_v<std::remove_cv_t<std::remove_reference_t<Args>>, value_type>)) {
  3277. return insert_or_do_nothing(std::forward<Args>(args)...);
  3278. } else {
  3279. auto &node = packed.first().emplace_back(std::piecewise_construct, std::make_tuple(packed.first().size()), std::forward_as_tuple(std::forward<Args>(args)...));
  3280. const auto index = value_to_bucket(node.second);
  3281. if(auto it = constrained_find(node.second, index); it != end()) {
  3282. packed.first().pop_back();
  3283. return std::make_pair(it, false);
  3284. }
  3285. std::swap(node.first, sparse.first()[index]);
  3286. rehash_if_required();
  3287. return std::make_pair(--end(), true);
  3288. }
  3289. }
  3290. /**
  3291. * @brief Removes an element from a given position.
  3292. * @param pos An iterator to the element to remove.
  3293. * @return An iterator following the removed element.
  3294. */
  3295. iterator erase(const_iterator pos) {
  3296. const auto diff = pos - cbegin();
  3297. erase(*pos);
  3298. return begin() + diff;
  3299. }
  3300. /**
  3301. * @brief Removes the given elements from a container.
  3302. * @param first An iterator to the first element of the range of elements.
  3303. * @param last An iterator past the last element of the range of elements.
  3304. * @return An iterator following the last removed element.
  3305. */
  3306. iterator erase(const_iterator first, const_iterator last) {
  3307. const auto dist = first - cbegin();
  3308. for(auto from = last - cbegin(); from != dist; --from) {
  3309. erase(packed.first()[from - 1u].second);
  3310. }
  3311. return (begin() + dist);
  3312. }
  3313. /**
  3314. * @brief Removes the element associated with a given value.
  3315. * @param value Value of an element to remove.
  3316. * @return Number of elements removed (either 0 or 1).
  3317. */
  3318. size_type erase(const value_type &value) {
  3319. for(size_type *curr = sparse.first().data() + value_to_bucket(value); *curr != (std::numeric_limits<size_type>::max)(); curr = &packed.first()[*curr].first) {
  3320. if(packed.second()(packed.first()[*curr].second, value)) {
  3321. const auto index = *curr;
  3322. *curr = packed.first()[*curr].first;
  3323. move_and_pop(index);
  3324. return 1u;
  3325. }
  3326. }
  3327. return 0u;
  3328. }
  3329. /**
  3330. * @brief Exchanges the contents with those of a given container.
  3331. * @param other Container to exchange the content with.
  3332. */
  3333. void swap(dense_set &other) {
  3334. using std::swap;
  3335. swap(sparse, other.sparse);
  3336. swap(packed, other.packed);
  3337. swap(threshold, other.threshold);
  3338. }
  3339. /**
  3340. * @brief Finds an element with a given value.
  3341. * @param value Value of an element to search for.
  3342. * @return An iterator to an element with the given value. If no such
  3343. * element is found, a past-the-end iterator is returned.
  3344. */
  3345. [[nodiscard]] iterator find(const value_type &value) {
  3346. return constrained_find(value, value_to_bucket(value));
  3347. }
  3348. /*! @copydoc find */
  3349. [[nodiscard]] const_iterator find(const value_type &value) const {
  3350. return constrained_find(value, value_to_bucket(value));
  3351. }
  3352. /**
  3353. * @brief Finds an element that compares _equivalent_ to a given value.
  3354. * @tparam Other Type of an element to search for.
  3355. * @param value Value of an element to search for.
  3356. * @return An iterator to an element with the given value. If no such
  3357. * element is found, a past-the-end iterator is returned.
  3358. */
  3359. template<typename Other>
  3360. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, iterator>>
  3361. find(const Other &value) {
  3362. return constrained_find(value, value_to_bucket(value));
  3363. }
  3364. /*! @copydoc find */
  3365. template<typename Other>
  3366. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, const_iterator>>
  3367. find(const Other &value) const {
  3368. return constrained_find(value, value_to_bucket(value));
  3369. }
  3370. /**
  3371. * @brief Checks if the container contains an element with a given value.
  3372. * @param value Value of an element to search for.
  3373. * @return True if there is such an element, false otherwise.
  3374. */
  3375. [[nodiscard]] bool contains(const value_type &value) const {
  3376. return (find(value) != cend());
  3377. }
  3378. /**
  3379. * @brief Checks if the container contains an element that compares
  3380. * _equivalent_ to a given value.
  3381. * @tparam Other Type of an element to search for.
  3382. * @param value Value of an element to search for.
  3383. * @return True if there is such an element, false otherwise.
  3384. */
  3385. template<typename Other>
  3386. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, bool>>
  3387. contains(const Other &value) const {
  3388. return (find(value) != cend());
  3389. }
  3390. /**
  3391. * @brief Returns an iterator to the beginning of a given bucket.
  3392. * @param index An index of a bucket to access.
  3393. * @return An iterator to the beginning of the given bucket.
  3394. */
  3395. [[nodiscard]] const_local_iterator cbegin(const size_type index) const {
  3396. return {packed.first().begin(), sparse.first()[index]};
  3397. }
  3398. /**
  3399. * @brief Returns an iterator to the beginning of a given bucket.
  3400. * @param index An index of a bucket to access.
  3401. * @return An iterator to the beginning of the given bucket.
  3402. */
  3403. [[nodiscard]] const_local_iterator begin(const size_type index) const {
  3404. return cbegin(index);
  3405. }
  3406. /**
  3407. * @brief Returns an iterator to the beginning of a given bucket.
  3408. * @param index An index of a bucket to access.
  3409. * @return An iterator to the beginning of the given bucket.
  3410. */
  3411. [[nodiscard]] local_iterator begin(const size_type index) {
  3412. return {packed.first().begin(), sparse.first()[index]};
  3413. }
  3414. /**
  3415. * @brief Returns an iterator to the end of a given bucket.
  3416. * @param index An index of a bucket to access.
  3417. * @return An iterator to the end of the given bucket.
  3418. */
  3419. [[nodiscard]] const_local_iterator cend([[maybe_unused]] const size_type index) const {
  3420. return {packed.first().begin(), (std::numeric_limits<size_type>::max)()};
  3421. }
  3422. /**
  3423. * @brief Returns an iterator to the end of a given bucket.
  3424. * @param index An index of a bucket to access.
  3425. * @return An iterator to the end of the given bucket.
  3426. */
  3427. [[nodiscard]] const_local_iterator end([[maybe_unused]] const size_type index) const {
  3428. return cend(index);
  3429. }
  3430. /**
  3431. * @brief Returns an iterator to the end of a given bucket.
  3432. * @param index An index of a bucket to access.
  3433. * @return An iterator to the end of the given bucket.
  3434. */
  3435. [[nodiscard]] local_iterator end([[maybe_unused]] const size_type index) {
  3436. return {packed.first().begin(), (std::numeric_limits<size_type>::max)()};
  3437. }
  3438. /**
  3439. * @brief Returns the number of buckets.
  3440. * @return The number of buckets.
  3441. */
  3442. [[nodiscard]] size_type bucket_count() const {
  3443. return sparse.first().size();
  3444. }
  3445. /**
  3446. * @brief Returns the maximum number of buckets.
  3447. * @return The maximum number of buckets.
  3448. */
  3449. [[nodiscard]] size_type max_bucket_count() const {
  3450. return sparse.first().max_size();
  3451. }
  3452. /**
  3453. * @brief Returns the number of elements in a given bucket.
  3454. * @param index The index of the bucket to examine.
  3455. * @return The number of elements in the given bucket.
  3456. */
  3457. [[nodiscard]] size_type bucket_size(const size_type index) const {
  3458. return static_cast<size_type>(std::distance(begin(index), end(index)));
  3459. }
  3460. /**
  3461. * @brief Returns the bucket for a given element.
  3462. * @param value The value of the element to examine.
  3463. * @return The bucket for the given element.
  3464. */
  3465. [[nodiscard]] size_type bucket(const value_type &value) const {
  3466. return value_to_bucket(value);
  3467. }
  3468. /**
  3469. * @brief Returns the average number of elements per bucket.
  3470. * @return The average number of elements per bucket.
  3471. */
  3472. [[nodiscard]] float load_factor() const {
  3473. return size() / static_cast<float>(bucket_count());
  3474. }
  3475. /**
  3476. * @brief Returns the maximum average number of elements per bucket.
  3477. * @return The maximum average number of elements per bucket.
  3478. */
  3479. [[nodiscard]] float max_load_factor() const {
  3480. return threshold;
  3481. }
  3482. /**
  3483. * @brief Sets the desired maximum average number of elements per bucket.
  3484. * @param value A desired maximum average number of elements per bucket.
  3485. */
  3486. void max_load_factor(const float value) {
  3487. ENTT_ASSERT(value > 0.f, "Invalid load factor");
  3488. threshold = value;
  3489. rehash(0u);
  3490. }
  3491. /**
  3492. * @brief Reserves at least the specified number of buckets and regenerates
  3493. * the hash table.
  3494. * @param count New number of buckets.
  3495. */
  3496. void rehash(const size_type count) {
  3497. auto value = (std::max)(count, minimum_capacity);
  3498. value = (std::max)(value, static_cast<size_type>(size() / max_load_factor()));
  3499. if(const auto sz = next_power_of_two(value); sz != bucket_count()) {
  3500. sparse.first().resize(sz);
  3501. std::fill(sparse.first().begin(), sparse.first().end(), (std::numeric_limits<size_type>::max)());
  3502. for(size_type pos{}, last = size(); pos < last; ++pos) {
  3503. const auto index = value_to_bucket(packed.first()[pos].second);
  3504. packed.first()[pos].first = std::exchange(sparse.first()[index], pos);
  3505. }
  3506. }
  3507. }
  3508. /**
  3509. * @brief Reserves space for at least the specified number of elements and
  3510. * regenerates the hash table.
  3511. * @param count New number of elements.
  3512. */
  3513. void reserve(const size_type count) {
  3514. packed.first().reserve(count);
  3515. rehash(static_cast<size_type>(std::ceil(count / max_load_factor())));
  3516. }
  3517. /**
  3518. * @brief Returns the function used to hash the elements.
  3519. * @return The function used to hash the elements.
  3520. */
  3521. [[nodiscard]] hasher hash_function() const {
  3522. return sparse.second();
  3523. }
  3524. /**
  3525. * @brief Returns the function used to compare elements for equality.
  3526. * @return The function used to compare elements for equality.
  3527. */
  3528. [[nodiscard]] key_equal key_eq() const {
  3529. return packed.second();
  3530. }
  3531. private:
  3532. compressed_pair<sparse_container_type, hasher> sparse;
  3533. compressed_pair<packed_container_type, key_equal> packed;
  3534. float threshold;
  3535. };
  3536. } // namespace entt
  3537. #endif
  3538. // #include "core/algorithm.hpp"
  3539. #ifndef ENTT_CORE_ALGORITHM_HPP
  3540. #define ENTT_CORE_ALGORITHM_HPP
  3541. #include <algorithm>
  3542. #include <functional>
  3543. #include <iterator>
  3544. #include <utility>
  3545. #include <vector>
  3546. // #include "utility.hpp"
  3547. #ifndef ENTT_CORE_UTILITY_HPP
  3548. #define ENTT_CORE_UTILITY_HPP
  3549. #include <utility>
  3550. // #include "../config/config.h"
  3551. #ifndef ENTT_CONFIG_CONFIG_H
  3552. #define ENTT_CONFIG_CONFIG_H
  3553. // #include "version.h"
  3554. #ifndef ENTT_CONFIG_VERSION_H
  3555. #define ENTT_CONFIG_VERSION_H
  3556. // #include "macro.h"
  3557. #ifndef ENTT_CONFIG_MACRO_H
  3558. #define ENTT_CONFIG_MACRO_H
  3559. #define ENTT_STR(arg) #arg
  3560. #define ENTT_XSTR(arg) ENTT_STR(arg)
  3561. #endif
  3562. #define ENTT_VERSION_MAJOR 3
  3563. #define ENTT_VERSION_MINOR 10
  3564. #define ENTT_VERSION_PATCH 3
  3565. #define ENTT_VERSION \
  3566. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  3567. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  3568. #endif
  3569. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  3570. # define ENTT_THROW throw
  3571. # define ENTT_TRY try
  3572. # define ENTT_CATCH catch(...)
  3573. #else
  3574. # define ENTT_THROW
  3575. # define ENTT_TRY if(true)
  3576. # define ENTT_CATCH if(false)
  3577. #endif
  3578. #ifndef ENTT_NOEXCEPT
  3579. # define ENTT_NOEXCEPT noexcept
  3580. # define ENTT_NOEXCEPT_IF(expr) noexcept(expr)
  3581. # else
  3582. # define ENTT_NOEXCEPT_IF(...)
  3583. #endif
  3584. #ifdef ENTT_USE_ATOMIC
  3585. # include <atomic>
  3586. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  3587. #else
  3588. # define ENTT_MAYBE_ATOMIC(Type) Type
  3589. #endif
  3590. #ifndef ENTT_ID_TYPE
  3591. # include <cstdint>
  3592. # define ENTT_ID_TYPE std::uint32_t
  3593. #endif
  3594. #ifndef ENTT_SPARSE_PAGE
  3595. # define ENTT_SPARSE_PAGE 4096
  3596. #endif
  3597. #ifndef ENTT_PACKED_PAGE
  3598. # define ENTT_PACKED_PAGE 1024
  3599. #endif
  3600. #ifdef ENTT_DISABLE_ASSERT
  3601. # undef ENTT_ASSERT
  3602. # define ENTT_ASSERT(...) (void(0))
  3603. #elif !defined ENTT_ASSERT
  3604. # include <cassert>
  3605. # define ENTT_ASSERT(condition, ...) assert(condition)
  3606. #endif
  3607. #ifdef ENTT_NO_ETO
  3608. # define ENTT_IGNORE_IF_EMPTY false
  3609. #else
  3610. # define ENTT_IGNORE_IF_EMPTY true
  3611. #endif
  3612. #ifdef ENTT_STANDARD_CPP
  3613. # define ENTT_NONSTD false
  3614. #else
  3615. # define ENTT_NONSTD true
  3616. # if defined __clang__ || defined __GNUC__
  3617. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  3618. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  3619. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  3620. # elif defined _MSC_VER
  3621. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  3622. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  3623. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  3624. # endif
  3625. #endif
  3626. #if defined _MSC_VER
  3627. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  3628. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  3629. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  3630. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  3631. #endif
  3632. #endif
  3633. namespace entt {
  3634. /*! @brief Identity function object (waiting for C++20). */
  3635. struct identity {
  3636. /*! @brief Indicates that this is a transparent function object. */
  3637. using is_transparent = void;
  3638. /**
  3639. * @brief Returns its argument unchanged.
  3640. * @tparam Type Type of the argument.
  3641. * @param value The actual argument.
  3642. * @return The submitted value as-is.
  3643. */
  3644. template<class Type>
  3645. [[nodiscard]] constexpr Type &&operator()(Type &&value) const ENTT_NOEXCEPT {
  3646. return std::forward<Type>(value);
  3647. }
  3648. };
  3649. /**
  3650. * @brief Constant utility to disambiguate overloaded members of a class.
  3651. * @tparam Type Type of the desired overload.
  3652. * @tparam Class Type of class to which the member belongs.
  3653. * @param member A valid pointer to a member.
  3654. * @return Pointer to the member.
  3655. */
  3656. template<typename Type, typename Class>
  3657. [[nodiscard]] constexpr auto overload(Type Class::*member) ENTT_NOEXCEPT {
  3658. return member;
  3659. }
  3660. /**
  3661. * @brief Constant utility to disambiguate overloaded functions.
  3662. * @tparam Func Function type of the desired overload.
  3663. * @param func A valid pointer to a function.
  3664. * @return Pointer to the function.
  3665. */
  3666. template<typename Func>
  3667. [[nodiscard]] constexpr auto overload(Func *func) ENTT_NOEXCEPT {
  3668. return func;
  3669. }
  3670. /**
  3671. * @brief Helper type for visitors.
  3672. * @tparam Func Types of function objects.
  3673. */
  3674. template<class... Func>
  3675. struct overloaded: Func... {
  3676. using Func::operator()...;
  3677. };
  3678. /**
  3679. * @brief Deduction guide.
  3680. * @tparam Func Types of function objects.
  3681. */
  3682. template<class... Func>
  3683. overloaded(Func...) -> overloaded<Func...>;
  3684. /**
  3685. * @brief Basic implementation of a y-combinator.
  3686. * @tparam Func Type of a potentially recursive function.
  3687. */
  3688. template<class Func>
  3689. struct y_combinator {
  3690. /**
  3691. * @brief Constructs a y-combinator from a given function.
  3692. * @param recursive A potentially recursive function.
  3693. */
  3694. y_combinator(Func recursive)
  3695. : func{std::move(recursive)} {}
  3696. /**
  3697. * @brief Invokes a y-combinator and therefore its underlying function.
  3698. * @tparam Args Types of arguments to use to invoke the underlying function.
  3699. * @param args Parameters to use to invoke the underlying function.
  3700. * @return Return value of the underlying function, if any.
  3701. */
  3702. template<class... Args>
  3703. decltype(auto) operator()(Args &&...args) const {
  3704. return func(*this, std::forward<Args>(args)...);
  3705. }
  3706. /*! @copydoc operator()() */
  3707. template<class... Args>
  3708. decltype(auto) operator()(Args &&...args) {
  3709. return func(*this, std::forward<Args>(args)...);
  3710. }
  3711. private:
  3712. Func func;
  3713. };
  3714. } // namespace entt
  3715. #endif
  3716. namespace entt {
  3717. /**
  3718. * @brief Function object to wrap `std::sort` in a class type.
  3719. *
  3720. * Unfortunately, `std::sort` cannot be passed as template argument to a class
  3721. * template or a function template.<br/>
  3722. * This class fills the gap by wrapping some flavors of `std::sort` in a
  3723. * function object.
  3724. */
  3725. struct std_sort {
  3726. /**
  3727. * @brief Sorts the elements in a range.
  3728. *
  3729. * Sorts the elements in a range using the given binary comparison function.
  3730. *
  3731. * @tparam It Type of random access iterator.
  3732. * @tparam Compare Type of comparison function object.
  3733. * @tparam Args Types of arguments to forward to the sort function.
  3734. * @param first An iterator to the first element of the range to sort.
  3735. * @param last An iterator past the last element of the range to sort.
  3736. * @param compare A valid comparison function object.
  3737. * @param args Arguments to forward to the sort function, if any.
  3738. */
  3739. template<typename It, typename Compare = std::less<>, typename... Args>
  3740. void operator()(It first, It last, Compare compare = Compare{}, Args &&...args) const {
  3741. std::sort(std::forward<Args>(args)..., std::move(first), std::move(last), std::move(compare));
  3742. }
  3743. };
  3744. /*! @brief Function object for performing insertion sort. */
  3745. struct insertion_sort {
  3746. /**
  3747. * @brief Sorts the elements in a range.
  3748. *
  3749. * Sorts the elements in a range using the given binary comparison function.
  3750. *
  3751. * @tparam It Type of random access iterator.
  3752. * @tparam Compare Type of comparison function object.
  3753. * @param first An iterator to the first element of the range to sort.
  3754. * @param last An iterator past the last element of the range to sort.
  3755. * @param compare A valid comparison function object.
  3756. */
  3757. template<typename It, typename Compare = std::less<>>
  3758. void operator()(It first, It last, Compare compare = Compare{}) const {
  3759. if(first < last) {
  3760. for(auto it = first + 1; it < last; ++it) {
  3761. auto value = std::move(*it);
  3762. auto pre = it;
  3763. for(; pre > first && compare(value, *(pre - 1)); --pre) {
  3764. *pre = std::move(*(pre - 1));
  3765. }
  3766. *pre = std::move(value);
  3767. }
  3768. }
  3769. }
  3770. };
  3771. /**
  3772. * @brief Function object for performing LSD radix sort.
  3773. * @tparam Bit Number of bits processed per pass.
  3774. * @tparam N Maximum number of bits to sort.
  3775. */
  3776. template<std::size_t Bit, std::size_t N>
  3777. struct radix_sort {
  3778. static_assert((N % Bit) == 0, "The maximum number of bits to sort must be a multiple of the number of bits processed per pass");
  3779. /**
  3780. * @brief Sorts the elements in a range.
  3781. *
  3782. * Sorts the elements in a range using the given _getter_ to access the
  3783. * actual data to be sorted.
  3784. *
  3785. * This implementation is inspired by the online book
  3786. * [Physically Based Rendering](http://www.pbr-book.org/3ed-2018/Primitives_and_Intersection_Acceleration/Bounding_Volume_Hierarchies.html#RadixSort).
  3787. *
  3788. * @tparam It Type of random access iterator.
  3789. * @tparam Getter Type of _getter_ function object.
  3790. * @param first An iterator to the first element of the range to sort.
  3791. * @param last An iterator past the last element of the range to sort.
  3792. * @param getter A valid _getter_ function object.
  3793. */
  3794. template<typename It, typename Getter = identity>
  3795. void operator()(It first, It last, Getter getter = Getter{}) const {
  3796. if(first < last) {
  3797. static constexpr auto mask = (1 << Bit) - 1;
  3798. static constexpr auto buckets = 1 << Bit;
  3799. static constexpr auto passes = N / Bit;
  3800. using value_type = typename std::iterator_traits<It>::value_type;
  3801. std::vector<value_type> aux(std::distance(first, last));
  3802. auto part = [getter = std::move(getter)](auto from, auto to, auto out, auto start) {
  3803. std::size_t index[buckets]{};
  3804. std::size_t count[buckets]{};
  3805. for(auto it = from; it != to; ++it) {
  3806. ++count[(getter(*it) >> start) & mask];
  3807. }
  3808. for(std::size_t pos{}, end = buckets - 1u; pos < end; ++pos) {
  3809. index[pos + 1u] = index[pos] + count[pos];
  3810. }
  3811. for(auto it = from; it != to; ++it) {
  3812. out[index[(getter(*it) >> start) & mask]++] = std::move(*it);
  3813. }
  3814. };
  3815. for(std::size_t pass = 0; pass < (passes & ~1); pass += 2) {
  3816. part(first, last, aux.begin(), pass * Bit);
  3817. part(aux.begin(), aux.end(), first, (pass + 1) * Bit);
  3818. }
  3819. if constexpr(passes & 1) {
  3820. part(first, last, aux.begin(), (passes - 1) * Bit);
  3821. std::move(aux.begin(), aux.end(), first);
  3822. }
  3823. }
  3824. }
  3825. };
  3826. } // namespace entt
  3827. #endif
  3828. // #include "core/any.hpp"
  3829. #ifndef ENTT_CORE_ANY_HPP
  3830. #define ENTT_CORE_ANY_HPP
  3831. #include <cstddef>
  3832. #include <memory>
  3833. #include <type_traits>
  3834. #include <utility>
  3835. // #include "../config/config.h"
  3836. // #include "../core/utility.hpp"
  3837. #ifndef ENTT_CORE_UTILITY_HPP
  3838. #define ENTT_CORE_UTILITY_HPP
  3839. #include <utility>
  3840. // #include "../config/config.h"
  3841. #ifndef ENTT_CONFIG_CONFIG_H
  3842. #define ENTT_CONFIG_CONFIG_H
  3843. // #include "version.h"
  3844. #ifndef ENTT_CONFIG_VERSION_H
  3845. #define ENTT_CONFIG_VERSION_H
  3846. // #include "macro.h"
  3847. #ifndef ENTT_CONFIG_MACRO_H
  3848. #define ENTT_CONFIG_MACRO_H
  3849. #define ENTT_STR(arg) #arg
  3850. #define ENTT_XSTR(arg) ENTT_STR(arg)
  3851. #endif
  3852. #define ENTT_VERSION_MAJOR 3
  3853. #define ENTT_VERSION_MINOR 10
  3854. #define ENTT_VERSION_PATCH 3
  3855. #define ENTT_VERSION \
  3856. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  3857. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  3858. #endif
  3859. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  3860. # define ENTT_THROW throw
  3861. # define ENTT_TRY try
  3862. # define ENTT_CATCH catch(...)
  3863. #else
  3864. # define ENTT_THROW
  3865. # define ENTT_TRY if(true)
  3866. # define ENTT_CATCH if(false)
  3867. #endif
  3868. #ifndef ENTT_NOEXCEPT
  3869. # define ENTT_NOEXCEPT noexcept
  3870. # define ENTT_NOEXCEPT_IF(expr) noexcept(expr)
  3871. # else
  3872. # define ENTT_NOEXCEPT_IF(...)
  3873. #endif
  3874. #ifdef ENTT_USE_ATOMIC
  3875. # include <atomic>
  3876. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  3877. #else
  3878. # define ENTT_MAYBE_ATOMIC(Type) Type
  3879. #endif
  3880. #ifndef ENTT_ID_TYPE
  3881. # include <cstdint>
  3882. # define ENTT_ID_TYPE std::uint32_t
  3883. #endif
  3884. #ifndef ENTT_SPARSE_PAGE
  3885. # define ENTT_SPARSE_PAGE 4096
  3886. #endif
  3887. #ifndef ENTT_PACKED_PAGE
  3888. # define ENTT_PACKED_PAGE 1024
  3889. #endif
  3890. #ifdef ENTT_DISABLE_ASSERT
  3891. # undef ENTT_ASSERT
  3892. # define ENTT_ASSERT(...) (void(0))
  3893. #elif !defined ENTT_ASSERT
  3894. # include <cassert>
  3895. # define ENTT_ASSERT(condition, ...) assert(condition)
  3896. #endif
  3897. #ifdef ENTT_NO_ETO
  3898. # define ENTT_IGNORE_IF_EMPTY false
  3899. #else
  3900. # define ENTT_IGNORE_IF_EMPTY true
  3901. #endif
  3902. #ifdef ENTT_STANDARD_CPP
  3903. # define ENTT_NONSTD false
  3904. #else
  3905. # define ENTT_NONSTD true
  3906. # if defined __clang__ || defined __GNUC__
  3907. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  3908. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  3909. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  3910. # elif defined _MSC_VER
  3911. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  3912. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  3913. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  3914. # endif
  3915. #endif
  3916. #if defined _MSC_VER
  3917. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  3918. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  3919. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  3920. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  3921. #endif
  3922. #endif
  3923. namespace entt {
  3924. /*! @brief Identity function object (waiting for C++20). */
  3925. struct identity {
  3926. /*! @brief Indicates that this is a transparent function object. */
  3927. using is_transparent = void;
  3928. /**
  3929. * @brief Returns its argument unchanged.
  3930. * @tparam Type Type of the argument.
  3931. * @param value The actual argument.
  3932. * @return The submitted value as-is.
  3933. */
  3934. template<class Type>
  3935. [[nodiscard]] constexpr Type &&operator()(Type &&value) const ENTT_NOEXCEPT {
  3936. return std::forward<Type>(value);
  3937. }
  3938. };
  3939. /**
  3940. * @brief Constant utility to disambiguate overloaded members of a class.
  3941. * @tparam Type Type of the desired overload.
  3942. * @tparam Class Type of class to which the member belongs.
  3943. * @param member A valid pointer to a member.
  3944. * @return Pointer to the member.
  3945. */
  3946. template<typename Type, typename Class>
  3947. [[nodiscard]] constexpr auto overload(Type Class::*member) ENTT_NOEXCEPT {
  3948. return member;
  3949. }
  3950. /**
  3951. * @brief Constant utility to disambiguate overloaded functions.
  3952. * @tparam Func Function type of the desired overload.
  3953. * @param func A valid pointer to a function.
  3954. * @return Pointer to the function.
  3955. */
  3956. template<typename Func>
  3957. [[nodiscard]] constexpr auto overload(Func *func) ENTT_NOEXCEPT {
  3958. return func;
  3959. }
  3960. /**
  3961. * @brief Helper type for visitors.
  3962. * @tparam Func Types of function objects.
  3963. */
  3964. template<class... Func>
  3965. struct overloaded: Func... {
  3966. using Func::operator()...;
  3967. };
  3968. /**
  3969. * @brief Deduction guide.
  3970. * @tparam Func Types of function objects.
  3971. */
  3972. template<class... Func>
  3973. overloaded(Func...) -> overloaded<Func...>;
  3974. /**
  3975. * @brief Basic implementation of a y-combinator.
  3976. * @tparam Func Type of a potentially recursive function.
  3977. */
  3978. template<class Func>
  3979. struct y_combinator {
  3980. /**
  3981. * @brief Constructs a y-combinator from a given function.
  3982. * @param recursive A potentially recursive function.
  3983. */
  3984. y_combinator(Func recursive)
  3985. : func{std::move(recursive)} {}
  3986. /**
  3987. * @brief Invokes a y-combinator and therefore its underlying function.
  3988. * @tparam Args Types of arguments to use to invoke the underlying function.
  3989. * @param args Parameters to use to invoke the underlying function.
  3990. * @return Return value of the underlying function, if any.
  3991. */
  3992. template<class... Args>
  3993. decltype(auto) operator()(Args &&...args) const {
  3994. return func(*this, std::forward<Args>(args)...);
  3995. }
  3996. /*! @copydoc operator()() */
  3997. template<class... Args>
  3998. decltype(auto) operator()(Args &&...args) {
  3999. return func(*this, std::forward<Args>(args)...);
  4000. }
  4001. private:
  4002. Func func;
  4003. };
  4004. } // namespace entt
  4005. #endif
  4006. // #include "fwd.hpp"
  4007. #ifndef ENTT_CORE_FWD_HPP
  4008. #define ENTT_CORE_FWD_HPP
  4009. #include <cstdint>
  4010. #include <type_traits>
  4011. // #include "../config/config.h"
  4012. namespace entt {
  4013. template<std::size_t Len = sizeof(double[2]), std::size_t = alignof(typename std::aligned_storage_t<Len + !Len>)>
  4014. class basic_any;
  4015. /*! @brief Alias declaration for type identifiers. */
  4016. using id_type = ENTT_ID_TYPE;
  4017. /*! @brief Alias declaration for the most common use case. */
  4018. using any = basic_any<>;
  4019. } // namespace entt
  4020. #endif
  4021. // #include "type_info.hpp"
  4022. #ifndef ENTT_CORE_TYPE_INFO_HPP
  4023. #define ENTT_CORE_TYPE_INFO_HPP
  4024. #include <string_view>
  4025. #include <type_traits>
  4026. #include <utility>
  4027. // #include "../config/config.h"
  4028. // #include "../core/attribute.h"
  4029. #ifndef ENTT_CORE_ATTRIBUTE_H
  4030. #define ENTT_CORE_ATTRIBUTE_H
  4031. #ifndef ENTT_EXPORT
  4032. # if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER
  4033. # define ENTT_EXPORT __declspec(dllexport)
  4034. # define ENTT_IMPORT __declspec(dllimport)
  4035. # define ENTT_HIDDEN
  4036. # elif defined __GNUC__ && __GNUC__ >= 4
  4037. # define ENTT_EXPORT __attribute__((visibility("default")))
  4038. # define ENTT_IMPORT __attribute__((visibility("default")))
  4039. # define ENTT_HIDDEN __attribute__((visibility("hidden")))
  4040. # else /* Unsupported compiler */
  4041. # define ENTT_EXPORT
  4042. # define ENTT_IMPORT
  4043. # define ENTT_HIDDEN
  4044. # endif
  4045. #endif
  4046. #ifndef ENTT_API
  4047. # if defined ENTT_API_EXPORT
  4048. # define ENTT_API ENTT_EXPORT
  4049. # elif defined ENTT_API_IMPORT
  4050. # define ENTT_API ENTT_IMPORT
  4051. # else /* No API */
  4052. # define ENTT_API
  4053. # endif
  4054. #endif
  4055. #endif
  4056. // #include "fwd.hpp"
  4057. // #include "hashed_string.hpp"
  4058. #ifndef ENTT_CORE_HASHED_STRING_HPP
  4059. #define ENTT_CORE_HASHED_STRING_HPP
  4060. #include <cstddef>
  4061. #include <cstdint>
  4062. // #include "../config/config.h"
  4063. // #include "fwd.hpp"
  4064. namespace entt {
  4065. /**
  4066. * @cond TURN_OFF_DOXYGEN
  4067. * Internal details not to be documented.
  4068. */
  4069. namespace internal {
  4070. template<typename>
  4071. struct fnv1a_traits;
  4072. template<>
  4073. struct fnv1a_traits<std::uint32_t> {
  4074. using type = std::uint32_t;
  4075. static constexpr std::uint32_t offset = 2166136261;
  4076. static constexpr std::uint32_t prime = 16777619;
  4077. };
  4078. template<>
  4079. struct fnv1a_traits<std::uint64_t> {
  4080. using type = std::uint64_t;
  4081. static constexpr std::uint64_t offset = 14695981039346656037ull;
  4082. static constexpr std::uint64_t prime = 1099511628211ull;
  4083. };
  4084. template<typename Char>
  4085. struct basic_hashed_string {
  4086. using value_type = Char;
  4087. using size_type = std::size_t;
  4088. using hash_type = id_type;
  4089. const value_type *repr;
  4090. size_type length;
  4091. hash_type hash;
  4092. };
  4093. } // namespace internal
  4094. /**
  4095. * Internal details not to be documented.
  4096. * @endcond
  4097. */
  4098. /**
  4099. * @brief Zero overhead unique identifier.
  4100. *
  4101. * A hashed string is a compile-time tool that allows users to use
  4102. * human-readable identifiers in the codebase while using their numeric
  4103. * counterparts at runtime.<br/>
  4104. * Because of that, a hashed string can also be used in constant expressions if
  4105. * required.
  4106. *
  4107. * @warning
  4108. * This class doesn't take ownership of user-supplied strings nor does it make a
  4109. * copy of them.
  4110. *
  4111. * @tparam Char Character type.
  4112. */
  4113. template<typename Char>
  4114. class basic_hashed_string: internal::basic_hashed_string<Char> {
  4115. using base_type = internal::basic_hashed_string<Char>;
  4116. using hs_traits = internal::fnv1a_traits<id_type>;
  4117. struct const_wrapper {
  4118. // non-explicit constructor on purpose
  4119. constexpr const_wrapper(const Char *str) ENTT_NOEXCEPT: repr{str} {}
  4120. const Char *repr;
  4121. };
  4122. // Fowler–Noll–Vo hash function v. 1a - the good
  4123. [[nodiscard]] static constexpr auto helper(const Char *str) ENTT_NOEXCEPT {
  4124. base_type base{str, 0u, hs_traits::offset};
  4125. for(; str[base.length]; ++base.length) {
  4126. base.hash = (base.hash ^ static_cast<hs_traits::type>(str[base.length])) * hs_traits::prime;
  4127. }
  4128. return base;
  4129. }
  4130. // Fowler–Noll–Vo hash function v. 1a - the good
  4131. [[nodiscard]] static constexpr auto helper(const Char *str, const std::size_t len) ENTT_NOEXCEPT {
  4132. base_type base{str, len, hs_traits::offset};
  4133. for(size_type pos{}; pos < len; ++pos) {
  4134. base.hash = (base.hash ^ static_cast<hs_traits::type>(str[pos])) * hs_traits::prime;
  4135. }
  4136. return base;
  4137. }
  4138. public:
  4139. /*! @brief Character type. */
  4140. using value_type = typename base_type::value_type;
  4141. /*! @brief Unsigned integer type. */
  4142. using size_type = typename base_type::size_type;
  4143. /*! @brief Unsigned integer type. */
  4144. using hash_type = typename base_type::hash_type;
  4145. /**
  4146. * @brief Returns directly the numeric representation of a string view.
  4147. * @param str Human-readable identifier.
  4148. * @param len Length of the string to hash.
  4149. * @return The numeric representation of the string.
  4150. */
  4151. [[nodiscard]] static constexpr hash_type value(const value_type *str, const size_type len) ENTT_NOEXCEPT {
  4152. return basic_hashed_string{str, len};
  4153. }
  4154. /**
  4155. * @brief Returns directly the numeric representation of a string.
  4156. * @tparam N Number of characters of the identifier.
  4157. * @param str Human-readable identifier.
  4158. * @return The numeric representation of the string.
  4159. */
  4160. template<std::size_t N>
  4161. [[nodiscard]] static constexpr hash_type value(const value_type (&str)[N]) ENTT_NOEXCEPT {
  4162. return basic_hashed_string{str};
  4163. }
  4164. /**
  4165. * @brief Returns directly the numeric representation of a string.
  4166. * @param wrapper Helps achieving the purpose by relying on overloading.
  4167. * @return The numeric representation of the string.
  4168. */
  4169. [[nodiscard]] static constexpr hash_type value(const_wrapper wrapper) ENTT_NOEXCEPT {
  4170. return basic_hashed_string{wrapper};
  4171. }
  4172. /*! @brief Constructs an empty hashed string. */
  4173. constexpr basic_hashed_string() ENTT_NOEXCEPT
  4174. : base_type{} {}
  4175. /**
  4176. * @brief Constructs a hashed string from a string view.
  4177. * @param str Human-readable identifier.
  4178. * @param len Length of the string to hash.
  4179. */
  4180. constexpr basic_hashed_string(const value_type *str, const size_type len) ENTT_NOEXCEPT
  4181. : base_type{helper(str, len)} {}
  4182. /**
  4183. * @brief Constructs a hashed string from an array of const characters.
  4184. * @tparam N Number of characters of the identifier.
  4185. * @param str Human-readable identifier.
  4186. */
  4187. template<std::size_t N>
  4188. constexpr basic_hashed_string(const value_type (&str)[N]) ENTT_NOEXCEPT
  4189. : base_type{helper(str)} {}
  4190. /**
  4191. * @brief Explicit constructor on purpose to avoid constructing a hashed
  4192. * string directly from a `const value_type *`.
  4193. *
  4194. * @warning
  4195. * The lifetime of the string is not extended nor is it copied.
  4196. *
  4197. * @param wrapper Helps achieving the purpose by relying on overloading.
  4198. */
  4199. explicit constexpr basic_hashed_string(const_wrapper wrapper) ENTT_NOEXCEPT
  4200. : base_type{helper(wrapper.repr)} {}
  4201. /**
  4202. * @brief Returns the size a hashed string.
  4203. * @return The size of the hashed string.
  4204. */
  4205. [[nodiscard]] constexpr size_type size() const ENTT_NOEXCEPT {
  4206. return base_type::length;
  4207. }
  4208. /**
  4209. * @brief Returns the human-readable representation of a hashed string.
  4210. * @return The string used to initialize the hashed string.
  4211. */
  4212. [[nodiscard]] constexpr const value_type *data() const ENTT_NOEXCEPT {
  4213. return base_type::repr;
  4214. }
  4215. /**
  4216. * @brief Returns the numeric representation of a hashed string.
  4217. * @return The numeric representation of the hashed string.
  4218. */
  4219. [[nodiscard]] constexpr hash_type value() const ENTT_NOEXCEPT {
  4220. return base_type::hash;
  4221. }
  4222. /*! @copydoc data */
  4223. [[nodiscard]] constexpr operator const value_type *() const ENTT_NOEXCEPT {
  4224. return data();
  4225. }
  4226. /**
  4227. * @brief Returns the numeric representation of a hashed string.
  4228. * @return The numeric representation of the hashed string.
  4229. */
  4230. [[nodiscard]] constexpr operator hash_type() const ENTT_NOEXCEPT {
  4231. return value();
  4232. }
  4233. };
  4234. /**
  4235. * @brief Deduction guide.
  4236. * @tparam Char Character type.
  4237. * @param str Human-readable identifier.
  4238. * @param len Length of the string to hash.
  4239. */
  4240. template<typename Char>
  4241. basic_hashed_string(const Char *str, const std::size_t len) -> basic_hashed_string<Char>;
  4242. /**
  4243. * @brief Deduction guide.
  4244. * @tparam Char Character type.
  4245. * @tparam N Number of characters of the identifier.
  4246. * @param str Human-readable identifier.
  4247. */
  4248. template<typename Char, std::size_t N>
  4249. basic_hashed_string(const Char (&str)[N]) -> basic_hashed_string<Char>;
  4250. /**
  4251. * @brief Compares two hashed strings.
  4252. * @tparam Char Character type.
  4253. * @param lhs A valid hashed string.
  4254. * @param rhs A valid hashed string.
  4255. * @return True if the two hashed strings are identical, false otherwise.
  4256. */
  4257. template<typename Char>
  4258. [[nodiscard]] constexpr bool operator==(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) ENTT_NOEXCEPT {
  4259. return lhs.value() == rhs.value();
  4260. }
  4261. /**
  4262. * @brief Compares two hashed strings.
  4263. * @tparam Char Character type.
  4264. * @param lhs A valid hashed string.
  4265. * @param rhs A valid hashed string.
  4266. * @return True if the two hashed strings differ, false otherwise.
  4267. */
  4268. template<typename Char>
  4269. [[nodiscard]] constexpr bool operator!=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) ENTT_NOEXCEPT {
  4270. return !(lhs == rhs);
  4271. }
  4272. /**
  4273. * @brief Compares two hashed strings.
  4274. * @tparam Char Character type.
  4275. * @param lhs A valid hashed string.
  4276. * @param rhs A valid hashed string.
  4277. * @return True if the first element is less than the second, false otherwise.
  4278. */
  4279. template<typename Char>
  4280. [[nodiscard]] constexpr bool operator<(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) ENTT_NOEXCEPT {
  4281. return lhs.value() < rhs.value();
  4282. }
  4283. /**
  4284. * @brief Compares two hashed strings.
  4285. * @tparam Char Character type.
  4286. * @param lhs A valid hashed string.
  4287. * @param rhs A valid hashed string.
  4288. * @return True if the first element is less than or equal to the second, false
  4289. * otherwise.
  4290. */
  4291. template<typename Char>
  4292. [[nodiscard]] constexpr bool operator<=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) ENTT_NOEXCEPT {
  4293. return !(rhs < lhs);
  4294. }
  4295. /**
  4296. * @brief Compares two hashed strings.
  4297. * @tparam Char Character type.
  4298. * @param lhs A valid hashed string.
  4299. * @param rhs A valid hashed string.
  4300. * @return True if the first element is greater than the second, false
  4301. * otherwise.
  4302. */
  4303. template<typename Char>
  4304. [[nodiscard]] constexpr bool operator>(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) ENTT_NOEXCEPT {
  4305. return rhs < lhs;
  4306. }
  4307. /**
  4308. * @brief Compares two hashed strings.
  4309. * @tparam Char Character type.
  4310. * @param lhs A valid hashed string.
  4311. * @param rhs A valid hashed string.
  4312. * @return True if the first element is greater than or equal to the second,
  4313. * false otherwise.
  4314. */
  4315. template<typename Char>
  4316. [[nodiscard]] constexpr bool operator>=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) ENTT_NOEXCEPT {
  4317. return !(lhs < rhs);
  4318. }
  4319. /*! @brief Aliases for common character types. */
  4320. using hashed_string = basic_hashed_string<char>;
  4321. /*! @brief Aliases for common character types. */
  4322. using hashed_wstring = basic_hashed_string<wchar_t>;
  4323. inline namespace literals {
  4324. /**
  4325. * @brief User defined literal for hashed strings.
  4326. * @param str The literal without its suffix.
  4327. * @return A properly initialized hashed string.
  4328. */
  4329. [[nodiscard]] constexpr hashed_string operator"" _hs(const char *str, std::size_t) ENTT_NOEXCEPT {
  4330. return hashed_string{str};
  4331. }
  4332. /**
  4333. * @brief User defined literal for hashed wstrings.
  4334. * @param str The literal without its suffix.
  4335. * @return A properly initialized hashed wstring.
  4336. */
  4337. [[nodiscard]] constexpr hashed_wstring operator"" _hws(const wchar_t *str, std::size_t) ENTT_NOEXCEPT {
  4338. return hashed_wstring{str};
  4339. }
  4340. } // namespace literals
  4341. } // namespace entt
  4342. #endif
  4343. namespace entt {
  4344. /**
  4345. * @cond TURN_OFF_DOXYGEN
  4346. * Internal details not to be documented.
  4347. */
  4348. namespace internal {
  4349. struct ENTT_API type_index final {
  4350. [[nodiscard]] static id_type next() ENTT_NOEXCEPT {
  4351. static ENTT_MAYBE_ATOMIC(id_type) value{};
  4352. return value++;
  4353. }
  4354. };
  4355. template<typename Type>
  4356. [[nodiscard]] constexpr auto stripped_type_name() ENTT_NOEXCEPT {
  4357. #if defined ENTT_PRETTY_FUNCTION
  4358. std::string_view pretty_function{ENTT_PRETTY_FUNCTION};
  4359. auto first = pretty_function.find_first_not_of(' ', pretty_function.find_first_of(ENTT_PRETTY_FUNCTION_PREFIX) + 1);
  4360. auto value = pretty_function.substr(first, pretty_function.find_last_of(ENTT_PRETTY_FUNCTION_SUFFIX) - first);
  4361. return value;
  4362. #else
  4363. return std::string_view{""};
  4364. #endif
  4365. }
  4366. template<typename Type, auto = stripped_type_name<Type>().find_first_of('.')>
  4367. [[nodiscard]] static constexpr std::string_view type_name(int) ENTT_NOEXCEPT {
  4368. constexpr auto value = stripped_type_name<Type>();
  4369. return value;
  4370. }
  4371. template<typename Type>
  4372. [[nodiscard]] static std::string_view type_name(char) ENTT_NOEXCEPT {
  4373. static const auto value = stripped_type_name<Type>();
  4374. return value;
  4375. }
  4376. template<typename Type, auto = stripped_type_name<Type>().find_first_of('.')>
  4377. [[nodiscard]] static constexpr id_type type_hash(int) ENTT_NOEXCEPT {
  4378. constexpr auto stripped = stripped_type_name<Type>();
  4379. constexpr auto value = hashed_string::value(stripped.data(), stripped.size());
  4380. return value;
  4381. }
  4382. template<typename Type>
  4383. [[nodiscard]] static id_type type_hash(char) ENTT_NOEXCEPT {
  4384. static const auto value = [](const auto stripped) {
  4385. return hashed_string::value(stripped.data(), stripped.size());
  4386. }(stripped_type_name<Type>());
  4387. return value;
  4388. }
  4389. } // namespace internal
  4390. /**
  4391. * Internal details not to be documented.
  4392. * @endcond
  4393. */
  4394. /**
  4395. * @brief Type sequential identifier.
  4396. * @tparam Type Type for which to generate a sequential identifier.
  4397. */
  4398. template<typename Type, typename = void>
  4399. struct ENTT_API type_index final {
  4400. /**
  4401. * @brief Returns the sequential identifier of a given type.
  4402. * @return The sequential identifier of a given type.
  4403. */
  4404. [[nodiscard]] static id_type value() ENTT_NOEXCEPT {
  4405. static const id_type value = internal::type_index::next();
  4406. return value;
  4407. }
  4408. /*! @copydoc value */
  4409. [[nodiscard]] constexpr operator id_type() const ENTT_NOEXCEPT {
  4410. return value();
  4411. }
  4412. };
  4413. /**
  4414. * @brief Type hash.
  4415. * @tparam Type Type for which to generate a hash value.
  4416. */
  4417. template<typename Type, typename = void>
  4418. struct type_hash final {
  4419. /**
  4420. * @brief Returns the numeric representation of a given type.
  4421. * @return The numeric representation of the given type.
  4422. */
  4423. #if defined ENTT_PRETTY_FUNCTION
  4424. [[nodiscard]] static constexpr id_type value() ENTT_NOEXCEPT {
  4425. return internal::type_hash<Type>(0);
  4426. #else
  4427. [[nodiscard]] static constexpr id_type value() ENTT_NOEXCEPT {
  4428. return type_index<Type>::value();
  4429. #endif
  4430. }
  4431. /*! @copydoc value */
  4432. [[nodiscard]] constexpr operator id_type() const ENTT_NOEXCEPT {
  4433. return value();
  4434. }
  4435. };
  4436. /**
  4437. * @brief Type name.
  4438. * @tparam Type Type for which to generate a name.
  4439. */
  4440. template<typename Type, typename = void>
  4441. struct type_name final {
  4442. /**
  4443. * @brief Returns the name of a given type.
  4444. * @return The name of the given type.
  4445. */
  4446. [[nodiscard]] static constexpr std::string_view value() ENTT_NOEXCEPT {
  4447. return internal::type_name<Type>(0);
  4448. }
  4449. /*! @copydoc value */
  4450. [[nodiscard]] constexpr operator std::string_view() const ENTT_NOEXCEPT {
  4451. return value();
  4452. }
  4453. };
  4454. /*! @brief Implementation specific information about a type. */
  4455. struct type_info final {
  4456. /**
  4457. * @brief Constructs a type info object for a given type.
  4458. * @tparam Type Type for which to construct a type info object.
  4459. */
  4460. template<typename Type>
  4461. constexpr type_info(std::in_place_type_t<Type>) ENTT_NOEXCEPT
  4462. : seq{type_index<std::remove_cv_t<std::remove_reference_t<Type>>>::value()},
  4463. identifier{type_hash<std::remove_cv_t<std::remove_reference_t<Type>>>::value()},
  4464. alias{type_name<std::remove_cv_t<std::remove_reference_t<Type>>>::value()} {}
  4465. /**
  4466. * @brief Type index.
  4467. * @return Type index.
  4468. */
  4469. [[nodiscard]] constexpr id_type index() const ENTT_NOEXCEPT {
  4470. return seq;
  4471. }
  4472. /**
  4473. * @brief Type hash.
  4474. * @return Type hash.
  4475. */
  4476. [[nodiscard]] constexpr id_type hash() const ENTT_NOEXCEPT {
  4477. return identifier;
  4478. }
  4479. /**
  4480. * @brief Type name.
  4481. * @return Type name.
  4482. */
  4483. [[nodiscard]] constexpr std::string_view name() const ENTT_NOEXCEPT {
  4484. return alias;
  4485. }
  4486. private:
  4487. id_type seq;
  4488. id_type identifier;
  4489. std::string_view alias;
  4490. };
  4491. /**
  4492. * @brief Compares the contents of two type info objects.
  4493. * @param lhs A type info object.
  4494. * @param rhs A type info object.
  4495. * @return True if the two type info objects are identical, false otherwise.
  4496. */
  4497. [[nodiscard]] inline constexpr bool operator==(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT {
  4498. return lhs.hash() == rhs.hash();
  4499. }
  4500. /**
  4501. * @brief Compares the contents of two type info objects.
  4502. * @param lhs A type info object.
  4503. * @param rhs A type info object.
  4504. * @return True if the two type info objects differ, false otherwise.
  4505. */
  4506. [[nodiscard]] inline constexpr bool operator!=(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT {
  4507. return !(lhs == rhs);
  4508. }
  4509. /**
  4510. * @brief Compares two type info objects.
  4511. * @param lhs A valid type info object.
  4512. * @param rhs A valid type info object.
  4513. * @return True if the first element is less than the second, false otherwise.
  4514. */
  4515. [[nodiscard]] constexpr bool operator<(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT {
  4516. return lhs.index() < rhs.index();
  4517. }
  4518. /**
  4519. * @brief Compares two type info objects.
  4520. * @param lhs A valid type info object.
  4521. * @param rhs A valid type info object.
  4522. * @return True if the first element is less than or equal to the second, false
  4523. * otherwise.
  4524. */
  4525. [[nodiscard]] constexpr bool operator<=(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT {
  4526. return !(rhs < lhs);
  4527. }
  4528. /**
  4529. * @brief Compares two type info objects.
  4530. * @param lhs A valid type info object.
  4531. * @param rhs A valid type info object.
  4532. * @return True if the first element is greater than the second, false
  4533. * otherwise.
  4534. */
  4535. [[nodiscard]] constexpr bool operator>(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT {
  4536. return rhs < lhs;
  4537. }
  4538. /**
  4539. * @brief Compares two type info objects.
  4540. * @param lhs A valid type info object.
  4541. * @param rhs A valid type info object.
  4542. * @return True if the first element is greater than or equal to the second,
  4543. * false otherwise.
  4544. */
  4545. [[nodiscard]] constexpr bool operator>=(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT {
  4546. return !(lhs < rhs);
  4547. }
  4548. /**
  4549. * @brief Returns the type info object associated to a given type.
  4550. *
  4551. * The returned element refers to an object with static storage duration.<br/>
  4552. * The type doesn't need to be a complete type. If the type is a reference, the
  4553. * result refers to the referenced type. In all cases, top-level cv-qualifiers
  4554. * are ignored.
  4555. *
  4556. * @tparam Type Type for which to generate a type info object.
  4557. * @return A reference to a properly initialized type info object.
  4558. */
  4559. template<typename Type>
  4560. [[nodiscard]] const type_info &type_id() ENTT_NOEXCEPT {
  4561. if constexpr(std::is_same_v<Type, std::remove_cv_t<std::remove_reference_t<Type>>>) {
  4562. static type_info instance{std::in_place_type<Type>};
  4563. return instance;
  4564. } else {
  4565. return type_id<std::remove_cv_t<std::remove_reference_t<Type>>>();
  4566. }
  4567. }
  4568. /*! @copydoc type_id */
  4569. template<typename Type>
  4570. [[nodiscard]] const type_info &type_id(Type &&) ENTT_NOEXCEPT {
  4571. return type_id<std::remove_cv_t<std::remove_reference_t<Type>>>();
  4572. }
  4573. } // namespace entt
  4574. #endif
  4575. // #include "type_traits.hpp"
  4576. #ifndef ENTT_CORE_TYPE_TRAITS_HPP
  4577. #define ENTT_CORE_TYPE_TRAITS_HPP
  4578. #include <cstddef>
  4579. #include <iterator>
  4580. #include <type_traits>
  4581. #include <utility>
  4582. // #include "../config/config.h"
  4583. // #include "fwd.hpp"
  4584. namespace entt {
  4585. /**
  4586. * @brief Utility class to disambiguate overloaded functions.
  4587. * @tparam N Number of choices available.
  4588. */
  4589. template<std::size_t N>
  4590. struct choice_t
  4591. // Unfortunately, doxygen cannot parse such a construct.
  4592. : /*! @cond TURN_OFF_DOXYGEN */ choice_t<N - 1> /*! @endcond */
  4593. {};
  4594. /*! @copybrief choice_t */
  4595. template<>
  4596. struct choice_t<0> {};
  4597. /**
  4598. * @brief Variable template for the choice trick.
  4599. * @tparam N Number of choices available.
  4600. */
  4601. template<std::size_t N>
  4602. inline constexpr choice_t<N> choice{};
  4603. /**
  4604. * @brief Identity type trait.
  4605. *
  4606. * Useful to establish non-deduced contexts in template argument deduction
  4607. * (waiting for C++20) or to provide types through function arguments.
  4608. *
  4609. * @tparam Type A type.
  4610. */
  4611. template<typename Type>
  4612. struct type_identity {
  4613. /*! @brief Identity type. */
  4614. using type = Type;
  4615. };
  4616. /**
  4617. * @brief Helper type.
  4618. * @tparam Type A type.
  4619. */
  4620. template<typename Type>
  4621. using type_identity_t = typename type_identity<Type>::type;
  4622. /**
  4623. * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains.
  4624. * @tparam Type The type of which to return the size.
  4625. * @tparam The size of the type if `sizeof` accepts it, 0 otherwise.
  4626. */
  4627. template<typename Type, typename = void>
  4628. struct size_of: std::integral_constant<std::size_t, 0u> {};
  4629. /*! @copydoc size_of */
  4630. template<typename Type>
  4631. struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
  4632. : std::integral_constant<std::size_t, sizeof(Type)> {};
  4633. /**
  4634. * @brief Helper variable template.
  4635. * @tparam Type The type of which to return the size.
  4636. */
  4637. template<typename Type>
  4638. inline constexpr std::size_t size_of_v = size_of<Type>::value;
  4639. /**
  4640. * @brief Using declaration to be used to _repeat_ the same type a number of
  4641. * times equal to the size of a given parameter pack.
  4642. * @tparam Type A type to repeat.
  4643. */
  4644. template<typename Type, typename>
  4645. using unpack_as_type = Type;
  4646. /**
  4647. * @brief Helper variable template to be used to _repeat_ the same value a
  4648. * number of times equal to the size of a given parameter pack.
  4649. * @tparam Value A value to repeat.
  4650. */
  4651. template<auto Value, typename>
  4652. inline constexpr auto unpack_as_value = Value;
  4653. /**
  4654. * @brief Wraps a static constant.
  4655. * @tparam Value A static constant.
  4656. */
  4657. template<auto Value>
  4658. using integral_constant = std::integral_constant<decltype(Value), Value>;
  4659. /**
  4660. * @brief Alias template to facilitate the creation of named values.
  4661. * @tparam Value A constant value at least convertible to `id_type`.
  4662. */
  4663. template<id_type Value>
  4664. using tag = integral_constant<Value>;
  4665. /**
  4666. * @brief A class to use to push around lists of types, nothing more.
  4667. * @tparam Type Types provided by the type list.
  4668. */
  4669. template<typename... Type>
  4670. struct type_list {
  4671. /*! @brief Type list type. */
  4672. using type = type_list;
  4673. /*! @brief Compile-time number of elements in the type list. */
  4674. static constexpr auto size = sizeof...(Type);
  4675. };
  4676. /*! @brief Primary template isn't defined on purpose. */
  4677. template<std::size_t, typename>
  4678. struct type_list_element;
  4679. /**
  4680. * @brief Provides compile-time indexed access to the types of a type list.
  4681. * @tparam Index Index of the type to return.
  4682. * @tparam Type First type provided by the type list.
  4683. * @tparam Other Other types provided by the type list.
  4684. */
  4685. template<std::size_t Index, typename Type, typename... Other>
  4686. struct type_list_element<Index, type_list<Type, Other...>>
  4687. : type_list_element<Index - 1u, type_list<Other...>> {};
  4688. /**
  4689. * @brief Provides compile-time indexed access to the types of a type list.
  4690. * @tparam Type First type provided by the type list.
  4691. * @tparam Other Other types provided by the type list.
  4692. */
  4693. template<typename Type, typename... Other>
  4694. struct type_list_element<0u, type_list<Type, Other...>> {
  4695. /*! @brief Searched type. */
  4696. using type = Type;
  4697. };
  4698. /**
  4699. * @brief Helper type.
  4700. * @tparam Index Index of the type to return.
  4701. * @tparam List Type list to search into.
  4702. */
  4703. template<std::size_t Index, typename List>
  4704. using type_list_element_t = typename type_list_element<Index, List>::type;
  4705. /**
  4706. * @brief Concatenates multiple type lists.
  4707. * @tparam Type Types provided by the first type list.
  4708. * @tparam Other Types provided by the second type list.
  4709. * @return A type list composed by the types of both the type lists.
  4710. */
  4711. template<typename... Type, typename... Other>
  4712. constexpr type_list<Type..., Other...> operator+(type_list<Type...>, type_list<Other...>) {
  4713. return {};
  4714. }
  4715. /*! @brief Primary template isn't defined on purpose. */
  4716. template<typename...>
  4717. struct type_list_cat;
  4718. /*! @brief Concatenates multiple type lists. */
  4719. template<>
  4720. struct type_list_cat<> {
  4721. /*! @brief A type list composed by the types of all the type lists. */
  4722. using type = type_list<>;
  4723. };
  4724. /**
  4725. * @brief Concatenates multiple type lists.
  4726. * @tparam Type Types provided by the first type list.
  4727. * @tparam Other Types provided by the second type list.
  4728. * @tparam List Other type lists, if any.
  4729. */
  4730. template<typename... Type, typename... Other, typename... List>
  4731. struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
  4732. /*! @brief A type list composed by the types of all the type lists. */
  4733. using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
  4734. };
  4735. /**
  4736. * @brief Concatenates multiple type lists.
  4737. * @tparam Type Types provided by the type list.
  4738. */
  4739. template<typename... Type>
  4740. struct type_list_cat<type_list<Type...>> {
  4741. /*! @brief A type list composed by the types of all the type lists. */
  4742. using type = type_list<Type...>;
  4743. };
  4744. /**
  4745. * @brief Helper type.
  4746. * @tparam List Type lists to concatenate.
  4747. */
  4748. template<typename... List>
  4749. using type_list_cat_t = typename type_list_cat<List...>::type;
  4750. /*! @brief Primary template isn't defined on purpose. */
  4751. template<typename>
  4752. struct type_list_unique;
  4753. /**
  4754. * @brief Removes duplicates types from a type list.
  4755. * @tparam Type One of the types provided by the given type list.
  4756. * @tparam Other The other types provided by the given type list.
  4757. */
  4758. template<typename Type, typename... Other>
  4759. struct type_list_unique<type_list<Type, Other...>> {
  4760. /*! @brief A type list without duplicate types. */
  4761. using type = std::conditional_t<
  4762. (std::is_same_v<Type, Other> || ...),
  4763. typename type_list_unique<type_list<Other...>>::type,
  4764. type_list_cat_t<type_list<Type>, typename type_list_unique<type_list<Other...>>::type>>;
  4765. };
  4766. /*! @brief Removes duplicates types from a type list. */
  4767. template<>
  4768. struct type_list_unique<type_list<>> {
  4769. /*! @brief A type list without duplicate types. */
  4770. using type = type_list<>;
  4771. };
  4772. /**
  4773. * @brief Helper type.
  4774. * @tparam Type A type list.
  4775. */
  4776. template<typename Type>
  4777. using type_list_unique_t = typename type_list_unique<Type>::type;
  4778. /**
  4779. * @brief Provides the member constant `value` to true if a type list contains a
  4780. * given type, false otherwise.
  4781. * @tparam List Type list.
  4782. * @tparam Type Type to look for.
  4783. */
  4784. template<typename List, typename Type>
  4785. struct type_list_contains;
  4786. /**
  4787. * @copybrief type_list_contains
  4788. * @tparam Type Types provided by the type list.
  4789. * @tparam Other Type to look for.
  4790. */
  4791. template<typename... Type, typename Other>
  4792. struct type_list_contains<type_list<Type...>, Other>: std::disjunction<std::is_same<Type, Other>...> {};
  4793. /**
  4794. * @brief Helper variable template.
  4795. * @tparam List Type list.
  4796. * @tparam Type Type to look for.
  4797. */
  4798. template<typename List, typename Type>
  4799. inline constexpr bool type_list_contains_v = type_list_contains<List, Type>::value;
  4800. /*! @brief Primary template isn't defined on purpose. */
  4801. template<typename...>
  4802. struct type_list_diff;
  4803. /**
  4804. * @brief Computes the difference between two type lists.
  4805. * @tparam Type Types provided by the first type list.
  4806. * @tparam Other Types provided by the second type list.
  4807. */
  4808. template<typename... Type, typename... Other>
  4809. struct type_list_diff<type_list<Type...>, type_list<Other...>> {
  4810. /*! @brief A type list that is the difference between the two type lists. */
  4811. using type = type_list_cat_t<std::conditional_t<type_list_contains_v<type_list<Other...>, Type>, type_list<>, type_list<Type>>...>;
  4812. };
  4813. /**
  4814. * @brief Helper type.
  4815. * @tparam List Type lists between which to compute the difference.
  4816. */
  4817. template<typename... List>
  4818. using type_list_diff_t = typename type_list_diff<List...>::type;
  4819. /**
  4820. * @brief A class to use to push around lists of constant values, nothing more.
  4821. * @tparam Value Values provided by the value list.
  4822. */
  4823. template<auto... Value>
  4824. struct value_list {
  4825. /*! @brief Value list type. */
  4826. using type = value_list;
  4827. /*! @brief Compile-time number of elements in the value list. */
  4828. static constexpr auto size = sizeof...(Value);
  4829. };
  4830. /*! @brief Primary template isn't defined on purpose. */
  4831. template<std::size_t, typename>
  4832. struct value_list_element;
  4833. /**
  4834. * @brief Provides compile-time indexed access to the values of a value list.
  4835. * @tparam Index Index of the value to return.
  4836. * @tparam Value First value provided by the value list.
  4837. * @tparam Other Other values provided by the value list.
  4838. */
  4839. template<std::size_t Index, auto Value, auto... Other>
  4840. struct value_list_element<Index, value_list<Value, Other...>>
  4841. : value_list_element<Index - 1u, value_list<Other...>> {};
  4842. /**
  4843. * @brief Provides compile-time indexed access to the types of a type list.
  4844. * @tparam Value First value provided by the value list.
  4845. * @tparam Other Other values provided by the value list.
  4846. */
  4847. template<auto Value, auto... Other>
  4848. struct value_list_element<0u, value_list<Value, Other...>> {
  4849. /*! @brief Searched value. */
  4850. static constexpr auto value = Value;
  4851. };
  4852. /**
  4853. * @brief Helper type.
  4854. * @tparam Index Index of the value to return.
  4855. * @tparam List Value list to search into.
  4856. */
  4857. template<std::size_t Index, typename List>
  4858. inline constexpr auto value_list_element_v = value_list_element<Index, List>::value;
  4859. /**
  4860. * @brief Concatenates multiple value lists.
  4861. * @tparam Value Values provided by the first value list.
  4862. * @tparam Other Values provided by the second value list.
  4863. * @return A value list composed by the values of both the value lists.
  4864. */
  4865. template<auto... Value, auto... Other>
  4866. constexpr value_list<Value..., Other...> operator+(value_list<Value...>, value_list<Other...>) {
  4867. return {};
  4868. }
  4869. /*! @brief Primary template isn't defined on purpose. */
  4870. template<typename...>
  4871. struct value_list_cat;
  4872. /*! @brief Concatenates multiple value lists. */
  4873. template<>
  4874. struct value_list_cat<> {
  4875. /*! @brief A value list composed by the values of all the value lists. */
  4876. using type = value_list<>;
  4877. };
  4878. /**
  4879. * @brief Concatenates multiple value lists.
  4880. * @tparam Value Values provided by the first value list.
  4881. * @tparam Other Values provided by the second value list.
  4882. * @tparam List Other value lists, if any.
  4883. */
  4884. template<auto... Value, auto... Other, typename... List>
  4885. struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
  4886. /*! @brief A value list composed by the values of all the value lists. */
  4887. using type = typename value_list_cat<value_list<Value..., Other...>, List...>::type;
  4888. };
  4889. /**
  4890. * @brief Concatenates multiple value lists.
  4891. * @tparam Value Values provided by the value list.
  4892. */
  4893. template<auto... Value>
  4894. struct value_list_cat<value_list<Value...>> {
  4895. /*! @brief A value list composed by the values of all the value lists. */
  4896. using type = value_list<Value...>;
  4897. };
  4898. /**
  4899. * @brief Helper type.
  4900. * @tparam List Value lists to concatenate.
  4901. */
  4902. template<typename... List>
  4903. using value_list_cat_t = typename value_list_cat<List...>::type;
  4904. /*! @brief Same as std::is_invocable, but with tuples. */
  4905. template<typename, typename>
  4906. struct is_applicable: std::false_type {};
  4907. /**
  4908. * @copybrief is_applicable
  4909. * @tparam Func A valid function type.
  4910. * @tparam Tuple Tuple-like type.
  4911. * @tparam Args The list of arguments to use to probe the function type.
  4912. */
  4913. template<typename Func, template<typename...> class Tuple, typename... Args>
  4914. struct is_applicable<Func, Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  4915. /**
  4916. * @copybrief is_applicable
  4917. * @tparam Func A valid function type.
  4918. * @tparam Tuple Tuple-like type.
  4919. * @tparam Args The list of arguments to use to probe the function type.
  4920. */
  4921. template<typename Func, template<typename...> class Tuple, typename... Args>
  4922. struct is_applicable<Func, const Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  4923. /**
  4924. * @brief Helper variable template.
  4925. * @tparam Func A valid function type.
  4926. * @tparam Args The list of arguments to use to probe the function type.
  4927. */
  4928. template<typename Func, typename Args>
  4929. inline constexpr bool is_applicable_v = is_applicable<Func, Args>::value;
  4930. /*! @brief Same as std::is_invocable_r, but with tuples for arguments. */
  4931. template<typename, typename, typename>
  4932. struct is_applicable_r: std::false_type {};
  4933. /**
  4934. * @copybrief is_applicable_r
  4935. * @tparam Ret The type to which the return type of the function should be
  4936. * convertible.
  4937. * @tparam Func A valid function type.
  4938. * @tparam Args The list of arguments to use to probe the function type.
  4939. */
  4940. template<typename Ret, typename Func, typename... Args>
  4941. struct is_applicable_r<Ret, Func, std::tuple<Args...>>: std::is_invocable_r<Ret, Func, Args...> {};
  4942. /**
  4943. * @brief Helper variable template.
  4944. * @tparam Ret The type to which the return type of the function should be
  4945. * convertible.
  4946. * @tparam Func A valid function type.
  4947. * @tparam Args The list of arguments to use to probe the function type.
  4948. */
  4949. template<typename Ret, typename Func, typename Args>
  4950. inline constexpr bool is_applicable_r_v = is_applicable_r<Ret, Func, Args>::value;
  4951. /**
  4952. * @brief Provides the member constant `value` to true if a given type is
  4953. * complete, false otherwise.
  4954. * @tparam Type The type to test.
  4955. */
  4956. template<typename Type, typename = void>
  4957. struct is_complete: std::false_type {};
  4958. /*! @copydoc is_complete */
  4959. template<typename Type>
  4960. struct is_complete<Type, std::void_t<decltype(sizeof(Type))>>: std::true_type {};
  4961. /**
  4962. * @brief Helper variable template.
  4963. * @tparam Type The type to test.
  4964. */
  4965. template<typename Type>
  4966. inline constexpr bool is_complete_v = is_complete<Type>::value;
  4967. /**
  4968. * @brief Provides the member constant `value` to true if a given type is an
  4969. * iterator, false otherwise.
  4970. * @tparam Type The type to test.
  4971. */
  4972. template<typename Type, typename = void>
  4973. struct is_iterator: std::false_type {};
  4974. /**
  4975. * @cond TURN_OFF_DOXYGEN
  4976. * Internal details not to be documented.
  4977. */
  4978. namespace internal {
  4979. template<typename, typename = void>
  4980. struct has_iterator_category: std::false_type {};
  4981. template<typename Type>
  4982. struct has_iterator_category<Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>: std::true_type {};
  4983. } // namespace internal
  4984. /**
  4985. * Internal details not to be documented.
  4986. * @endcond
  4987. */
  4988. /*! @copydoc is_iterator */
  4989. template<typename Type>
  4990. struct is_iterator<Type, std::enable_if_t<!std::is_same_v<std::remove_const_t<std::remove_pointer_t<Type>>, void>>>
  4991. : internal::has_iterator_category<Type> {};
  4992. /**
  4993. * @brief Helper variable template.
  4994. * @tparam Type The type to test.
  4995. */
  4996. template<typename Type>
  4997. inline constexpr bool is_iterator_v = is_iterator<Type>::value;
  4998. /**
  4999. * @brief Provides the member constant `value` to true if a given type is both
  5000. * an empty and non-final class, false otherwise.
  5001. * @tparam Type The type to test
  5002. */
  5003. template<typename Type>
  5004. struct is_ebco_eligible
  5005. : std::conjunction<std::is_empty<Type>, std::negation<std::is_final<Type>>> {};
  5006. /**
  5007. * @brief Helper variable template.
  5008. * @tparam Type The type to test.
  5009. */
  5010. template<typename Type>
  5011. inline constexpr bool is_ebco_eligible_v = is_ebco_eligible<Type>::value;
  5012. /**
  5013. * @brief Provides the member constant `value` to true if `Type::is_transparent`
  5014. * is valid and denotes a type, false otherwise.
  5015. * @tparam Type The type to test.
  5016. */
  5017. template<typename Type, typename = void>
  5018. struct is_transparent: std::false_type {};
  5019. /*! @copydoc is_transparent */
  5020. template<typename Type>
  5021. struct is_transparent<Type, std::void_t<typename Type::is_transparent>>: std::true_type {};
  5022. /**
  5023. * @brief Helper variable template.
  5024. * @tparam Type The type to test.
  5025. */
  5026. template<typename Type>
  5027. inline constexpr bool is_transparent_v = is_transparent<Type>::value;
  5028. /**
  5029. * @brief Provides the member constant `value` to true if a given type is
  5030. * equality comparable, false otherwise.
  5031. * @tparam Type The type to test.
  5032. */
  5033. template<typename Type, typename = void>
  5034. struct is_equality_comparable: std::false_type {};
  5035. /**
  5036. * @cond TURN_OFF_DOXYGEN
  5037. * Internal details not to be documented.
  5038. */
  5039. namespace internal {
  5040. template<typename, typename = void>
  5041. struct has_tuple_size_value: std::false_type {};
  5042. template<typename Type>
  5043. struct has_tuple_size_value<Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>: std::true_type {};
  5044. template<typename Type, std::size_t... Index>
  5045. [[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
  5046. return (is_equality_comparable<std::tuple_element_t<Index, Type>>::value && ...);
  5047. }
  5048. template<typename>
  5049. [[nodiscard]] constexpr bool maybe_equality_comparable(choice_t<0>) {
  5050. return true;
  5051. }
  5052. template<typename Type>
  5053. [[nodiscard]] constexpr auto maybe_equality_comparable(choice_t<1>) -> decltype(std::declval<typename Type::value_type>(), bool{}) {
  5054. if constexpr(is_iterator_v<Type>) {
  5055. return true;
  5056. } else if constexpr(std::is_same_v<typename Type::value_type, Type>) {
  5057. return maybe_equality_comparable<Type>(choice<0>);
  5058. } else {
  5059. return is_equality_comparable<typename Type::value_type>::value;
  5060. }
  5061. }
  5062. template<typename Type>
  5063. [[nodiscard]] constexpr std::enable_if_t<is_complete_v<std::tuple_size<std::remove_const_t<Type>>>, bool> maybe_equality_comparable(choice_t<2>) {
  5064. if constexpr(has_tuple_size_value<Type>::value) {
  5065. return unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
  5066. } else {
  5067. return maybe_equality_comparable<Type>(choice<1>);
  5068. }
  5069. }
  5070. } // namespace internal
  5071. /**
  5072. * Internal details not to be documented.
  5073. * @endcond
  5074. */
  5075. /*! @copydoc is_equality_comparable */
  5076. template<typename Type>
  5077. struct is_equality_comparable<Type, std::void_t<decltype(std::declval<Type>() == std::declval<Type>())>>
  5078. : std::bool_constant<internal::maybe_equality_comparable<Type>(choice<2>)> {};
  5079. /**
  5080. * @brief Helper variable template.
  5081. * @tparam Type The type to test.
  5082. */
  5083. template<typename Type>
  5084. inline constexpr bool is_equality_comparable_v = is_equality_comparable<Type>::value;
  5085. /**
  5086. * @brief Transcribes the constness of a type to another type.
  5087. * @tparam To The type to which to transcribe the constness.
  5088. * @tparam From The type from which to transcribe the constness.
  5089. */
  5090. template<typename To, typename From>
  5091. struct constness_as {
  5092. /*! @brief The type resulting from the transcription of the constness. */
  5093. using type = std::remove_const_t<To>;
  5094. };
  5095. /*! @copydoc constness_as */
  5096. template<typename To, typename From>
  5097. struct constness_as<To, const From> {
  5098. /*! @brief The type resulting from the transcription of the constness. */
  5099. using type = std::add_const_t<To>;
  5100. };
  5101. /**
  5102. * @brief Alias template to facilitate the transcription of the constness.
  5103. * @tparam To The type to which to transcribe the constness.
  5104. * @tparam From The type from which to transcribe the constness.
  5105. */
  5106. template<typename To, typename From>
  5107. using constness_as_t = typename constness_as<To, From>::type;
  5108. /**
  5109. * @brief Extracts the class of a non-static member object or function.
  5110. * @tparam Member A pointer to a non-static member object or function.
  5111. */
  5112. template<typename Member>
  5113. class member_class {
  5114. static_assert(std::is_member_pointer_v<Member>, "Invalid pointer type to non-static member object or function");
  5115. template<typename Class, typename Ret, typename... Args>
  5116. static Class *clazz(Ret (Class::*)(Args...));
  5117. template<typename Class, typename Ret, typename... Args>
  5118. static Class *clazz(Ret (Class::*)(Args...) const);
  5119. template<typename Class, typename Type>
  5120. static Class *clazz(Type Class::*);
  5121. public:
  5122. /*! @brief The class of the given non-static member object or function. */
  5123. using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
  5124. };
  5125. /**
  5126. * @brief Helper type.
  5127. * @tparam Member A pointer to a non-static member object or function.
  5128. */
  5129. template<typename Member>
  5130. using member_class_t = typename member_class<Member>::type;
  5131. } // namespace entt
  5132. #endif
  5133. namespace entt {
  5134. /**
  5135. * @brief A SBO friendly, type-safe container for single values of any type.
  5136. * @tparam Len Size of the storage reserved for the small buffer optimization.
  5137. * @tparam Align Optional alignment requirement.
  5138. */
  5139. template<std::size_t Len, std::size_t Align>
  5140. class basic_any {
  5141. enum class operation : std::uint8_t {
  5142. copy,
  5143. move,
  5144. transfer,
  5145. assign,
  5146. destroy,
  5147. compare,
  5148. get
  5149. };
  5150. enum class policy : std::uint8_t {
  5151. owner,
  5152. ref,
  5153. cref
  5154. };
  5155. using storage_type = std::aligned_storage_t<Len + !Len, Align>;
  5156. using vtable_type = const void *(const operation, const basic_any &, const void *);
  5157. template<typename Type>
  5158. static constexpr bool in_situ = Len && alignof(Type) <= alignof(storage_type) && sizeof(Type) <= sizeof(storage_type) && std::is_nothrow_move_constructible_v<Type>;
  5159. template<typename Type>
  5160. static const void *basic_vtable([[maybe_unused]] const operation op, [[maybe_unused]] const basic_any &value, [[maybe_unused]] const void *other) {
  5161. static_assert(!std::is_same_v<Type, void> && std::is_same_v<std::remove_cv_t<std::remove_reference_t<Type>>, Type>, "Invalid type");
  5162. const Type *element = nullptr;
  5163. if constexpr(in_situ<Type>) {
  5164. element = value.owner() ? reinterpret_cast<const Type *>(&value.storage) : static_cast<const Type *>(value.instance);
  5165. } else {
  5166. element = static_cast<const Type *>(value.instance);
  5167. }
  5168. switch(op) {
  5169. case operation::copy:
  5170. if constexpr(std::is_copy_constructible_v<Type>) {
  5171. static_cast<basic_any *>(const_cast<void *>(other))->initialize<Type>(*element);
  5172. }
  5173. break;
  5174. case operation::move:
  5175. if constexpr(in_situ<Type>) {
  5176. if(value.owner()) {
  5177. return new(&static_cast<basic_any *>(const_cast<void *>(other))->storage) Type{std::move(*const_cast<Type *>(element))};
  5178. }
  5179. }
  5180. return (static_cast<basic_any *>(const_cast<void *>(other))->instance = std::exchange(const_cast<basic_any &>(value).instance, nullptr));
  5181. case operation::transfer:
  5182. if constexpr(std::is_move_assignable_v<Type>) {
  5183. *const_cast<Type *>(element) = std::move(*static_cast<Type *>(const_cast<void *>(other)));
  5184. return other;
  5185. }
  5186. [[fallthrough]];
  5187. case operation::assign:
  5188. if constexpr(std::is_copy_assignable_v<Type>) {
  5189. *const_cast<Type *>(element) = *static_cast<const Type *>(other);
  5190. return other;
  5191. }
  5192. break;
  5193. case operation::destroy:
  5194. if constexpr(in_situ<Type>) {
  5195. element->~Type();
  5196. } else if constexpr(std::is_array_v<Type>) {
  5197. delete[] element;
  5198. } else {
  5199. delete element;
  5200. }
  5201. break;
  5202. case operation::compare:
  5203. if constexpr(!std::is_function_v<Type> && !std::is_array_v<Type> && is_equality_comparable_v<Type>) {
  5204. return *static_cast<const Type *>(element) == *static_cast<const Type *>(other) ? other : nullptr;
  5205. } else {
  5206. return (element == other) ? other : nullptr;
  5207. }
  5208. case operation::get:
  5209. return element;
  5210. }
  5211. return nullptr;
  5212. }
  5213. template<typename Type, typename... Args>
  5214. void initialize([[maybe_unused]] Args &&...args) {
  5215. if constexpr(!std::is_void_v<Type>) {
  5216. info = &type_id<std::remove_cv_t<std::remove_reference_t<Type>>>();
  5217. vtable = basic_vtable<std::remove_cv_t<std::remove_reference_t<Type>>>;
  5218. if constexpr(std::is_lvalue_reference_v<Type>) {
  5219. static_assert(sizeof...(Args) == 1u && (std::is_lvalue_reference_v<Args> && ...), "Invalid arguments");
  5220. mode = std::is_const_v<std::remove_reference_t<Type>> ? policy::cref : policy::ref;
  5221. instance = (std::addressof(args), ...);
  5222. } else if constexpr(in_situ<Type>) {
  5223. if constexpr(sizeof...(Args) != 0u && std::is_aggregate_v<Type>) {
  5224. new(&storage) Type{std::forward<Args>(args)...};
  5225. } else {
  5226. new(&storage) Type(std::forward<Args>(args)...);
  5227. }
  5228. } else {
  5229. if constexpr(sizeof...(Args) != 0u && std::is_aggregate_v<Type>) {
  5230. instance = new Type{std::forward<Args>(args)...};
  5231. } else {
  5232. instance = new Type(std::forward<Args>(args)...);
  5233. }
  5234. }
  5235. }
  5236. }
  5237. basic_any(const basic_any &other, const policy pol) ENTT_NOEXCEPT
  5238. : instance{other.data()},
  5239. info{other.info},
  5240. vtable{other.vtable},
  5241. mode{pol} {}
  5242. public:
  5243. /*! @brief Size of the internal storage. */
  5244. static constexpr auto length = Len;
  5245. /*! @brief Alignment requirement. */
  5246. static constexpr auto alignment = Align;
  5247. /*! @brief Default constructor. */
  5248. constexpr basic_any() ENTT_NOEXCEPT
  5249. : instance{},
  5250. info{&type_id<void>()},
  5251. vtable{},
  5252. mode{policy::owner} {}
  5253. /**
  5254. * @brief Constructs a wrapper by directly initializing the new object.
  5255. * @tparam Type Type of object to use to initialize the wrapper.
  5256. * @tparam Args Types of arguments to use to construct the new instance.
  5257. * @param args Parameters to use to construct the instance.
  5258. */
  5259. template<typename Type, typename... Args>
  5260. explicit basic_any(std::in_place_type_t<Type>, Args &&...args)
  5261. : basic_any{} {
  5262. initialize<Type>(std::forward<Args>(args)...);
  5263. }
  5264. /**
  5265. * @brief Constructs a wrapper from a given value.
  5266. * @tparam Type Type of object to use to initialize the wrapper.
  5267. * @param value An instance of an object to use to initialize the wrapper.
  5268. */
  5269. template<typename Type, typename = std::enable_if_t<!std::is_same_v<std::decay_t<Type>, basic_any>>>
  5270. basic_any(Type &&value)
  5271. : basic_any{} {
  5272. initialize<std::decay_t<Type>>(std::forward<Type>(value));
  5273. }
  5274. /**
  5275. * @brief Copy constructor.
  5276. * @param other The instance to copy from.
  5277. */
  5278. basic_any(const basic_any &other)
  5279. : basic_any{} {
  5280. if(other.vtable) {
  5281. other.vtable(operation::copy, other, this);
  5282. }
  5283. }
  5284. /**
  5285. * @brief Move constructor.
  5286. * @param other The instance to move from.
  5287. */
  5288. basic_any(basic_any &&other) ENTT_NOEXCEPT
  5289. : instance{},
  5290. info{other.info},
  5291. vtable{other.vtable},
  5292. mode{other.mode} {
  5293. if(other.vtable) {
  5294. other.vtable(operation::move, other, this);
  5295. }
  5296. }
  5297. /*! @brief Frees the internal storage, whatever it means. */
  5298. ~basic_any() {
  5299. if(vtable && owner()) {
  5300. vtable(operation::destroy, *this, nullptr);
  5301. }
  5302. }
  5303. /**
  5304. * @brief Copy assignment operator.
  5305. * @param other The instance to copy from.
  5306. * @return This any object.
  5307. */
  5308. basic_any &operator=(const basic_any &other) {
  5309. reset();
  5310. if(other.vtable) {
  5311. other.vtable(operation::copy, other, this);
  5312. }
  5313. return *this;
  5314. }
  5315. /**
  5316. * @brief Move assignment operator.
  5317. * @param other The instance to move from.
  5318. * @return This any object.
  5319. */
  5320. basic_any &operator=(basic_any &&other) ENTT_NOEXCEPT {
  5321. reset();
  5322. if(other.vtable) {
  5323. other.vtable(operation::move, other, this);
  5324. info = other.info;
  5325. vtable = other.vtable;
  5326. mode = other.mode;
  5327. }
  5328. return *this;
  5329. }
  5330. /**
  5331. * @brief Value assignment operator.
  5332. * @tparam Type Type of object to use to initialize the wrapper.
  5333. * @param value An instance of an object to use to initialize the wrapper.
  5334. * @return This any object.
  5335. */
  5336. template<typename Type>
  5337. std::enable_if_t<!std::is_same_v<std::decay_t<Type>, basic_any>, basic_any &>
  5338. operator=(Type &&value) {
  5339. emplace<std::decay_t<Type>>(std::forward<Type>(value));
  5340. return *this;
  5341. }
  5342. /**
  5343. * @brief Returns the object type if any, `type_id<void>()` otherwise.
  5344. * @return The object type if any, `type_id<void>()` otherwise.
  5345. */
  5346. [[nodiscard]] const type_info &type() const ENTT_NOEXCEPT {
  5347. return *info;
  5348. }
  5349. /**
  5350. * @brief Returns an opaque pointer to the contained instance.
  5351. * @return An opaque pointer the contained instance, if any.
  5352. */
  5353. [[nodiscard]] const void *data() const ENTT_NOEXCEPT {
  5354. return vtable ? vtable(operation::get, *this, nullptr) : nullptr;
  5355. }
  5356. /**
  5357. * @brief Returns an opaque pointer to the contained instance.
  5358. * @param req Expected type.
  5359. * @return An opaque pointer the contained instance, if any.
  5360. */
  5361. [[nodiscard]] const void *data(const type_info &req) const ENTT_NOEXCEPT {
  5362. return *info == req ? data() : nullptr;
  5363. }
  5364. /**
  5365. * @brief Returns an opaque pointer to the contained instance.
  5366. * @return An opaque pointer the contained instance, if any.
  5367. */
  5368. [[nodiscard]] void *data() ENTT_NOEXCEPT {
  5369. return (!vtable || mode == policy::cref) ? nullptr : const_cast<void *>(vtable(operation::get, *this, nullptr));
  5370. }
  5371. /**
  5372. * @brief Returns an opaque pointer to the contained instance.
  5373. * @param req Expected type.
  5374. * @return An opaque pointer the contained instance, if any.
  5375. */
  5376. [[nodiscard]] void *data(const type_info &req) ENTT_NOEXCEPT {
  5377. return *info == req ? data() : nullptr;
  5378. }
  5379. /**
  5380. * @brief Replaces the contained object by creating a new instance directly.
  5381. * @tparam Type Type of object to use to initialize the wrapper.
  5382. * @tparam Args Types of arguments to use to construct the new instance.
  5383. * @param args Parameters to use to construct the instance.
  5384. */
  5385. template<typename Type, typename... Args>
  5386. void emplace(Args &&...args) {
  5387. reset();
  5388. initialize<Type>(std::forward<Args>(args)...);
  5389. }
  5390. /**
  5391. * @brief Assigns a value to the contained object without replacing it.
  5392. * @param other The value to assign to the contained object.
  5393. * @return True in case of success, false otherwise.
  5394. */
  5395. bool assign(const any &other) {
  5396. if(vtable && mode != policy::cref && *info == *other.info) {
  5397. return (vtable(operation::assign, *this, other.data()) != nullptr);
  5398. }
  5399. return false;
  5400. }
  5401. /*! @copydoc assign */
  5402. bool assign(any &&other) {
  5403. if(vtable && mode != policy::cref && *info == *other.info) {
  5404. if(auto *val = other.data(); val) {
  5405. return (vtable(operation::transfer, *this, val) != nullptr);
  5406. } else {
  5407. return (vtable(operation::assign, *this, std::as_const(other).data()) != nullptr);
  5408. }
  5409. }
  5410. return false;
  5411. }
  5412. /*! @brief Destroys contained object */
  5413. void reset() {
  5414. if(vtable && owner()) {
  5415. vtable(operation::destroy, *this, nullptr);
  5416. }
  5417. info = &type_id<void>();
  5418. vtable = nullptr;
  5419. mode = policy::owner;
  5420. }
  5421. /**
  5422. * @brief Returns false if a wrapper is empty, true otherwise.
  5423. * @return False if the wrapper is empty, true otherwise.
  5424. */
  5425. [[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
  5426. return vtable != nullptr;
  5427. }
  5428. /**
  5429. * @brief Checks if two wrappers differ in their content.
  5430. * @param other Wrapper with which to compare.
  5431. * @return False if the two objects differ in their content, true otherwise.
  5432. */
  5433. bool operator==(const basic_any &other) const ENTT_NOEXCEPT {
  5434. if(vtable && *info == *other.info) {
  5435. return (vtable(operation::compare, *this, other.data()) != nullptr);
  5436. }
  5437. return (!vtable && !other.vtable);
  5438. }
  5439. /**
  5440. * @brief Aliasing constructor.
  5441. * @return A wrapper that shares a reference to an unmanaged object.
  5442. */
  5443. [[nodiscard]] basic_any as_ref() ENTT_NOEXCEPT {
  5444. return basic_any{*this, (mode == policy::cref ? policy::cref : policy::ref)};
  5445. }
  5446. /*! @copydoc as_ref */
  5447. [[nodiscard]] basic_any as_ref() const ENTT_NOEXCEPT {
  5448. return basic_any{*this, policy::cref};
  5449. }
  5450. /**
  5451. * @brief Returns true if a wrapper owns its object, false otherwise.
  5452. * @return True if the wrapper owns its object, false otherwise.
  5453. */
  5454. [[nodiscard]] bool owner() const ENTT_NOEXCEPT {
  5455. return (mode == policy::owner);
  5456. }
  5457. private:
  5458. union {
  5459. const void *instance;
  5460. storage_type storage;
  5461. };
  5462. const type_info *info;
  5463. vtable_type *vtable;
  5464. policy mode;
  5465. };
  5466. /**
  5467. * @brief Checks if two wrappers differ in their content.
  5468. * @tparam Len Size of the storage reserved for the small buffer optimization.
  5469. * @tparam Align Alignment requirement.
  5470. * @param lhs A wrapper, either empty or not.
  5471. * @param rhs A wrapper, either empty or not.
  5472. * @return True if the two wrappers differ in their content, false otherwise.
  5473. */
  5474. template<std::size_t Len, std::size_t Align>
  5475. [[nodiscard]] inline bool operator!=(const basic_any<Len, Align> &lhs, const basic_any<Len, Align> &rhs) ENTT_NOEXCEPT {
  5476. return !(lhs == rhs);
  5477. }
  5478. /**
  5479. * @brief Performs type-safe access to the contained object.
  5480. * @tparam Type Type to which conversion is required.
  5481. * @tparam Len Size of the storage reserved for the small buffer optimization.
  5482. * @tparam Align Alignment requirement.
  5483. * @param data Target any object.
  5484. * @return The element converted to the requested type.
  5485. */
  5486. template<typename Type, std::size_t Len, std::size_t Align>
  5487. Type any_cast(const basic_any<Len, Align> &data) ENTT_NOEXCEPT {
  5488. const auto *const instance = any_cast<std::remove_reference_t<Type>>(&data);
  5489. ENTT_ASSERT(instance, "Invalid instance");
  5490. return static_cast<Type>(*instance);
  5491. }
  5492. /*! @copydoc any_cast */
  5493. template<typename Type, std::size_t Len, std::size_t Align>
  5494. Type any_cast(basic_any<Len, Align> &data) ENTT_NOEXCEPT {
  5495. // forces const on non-reference types to make them work also with wrappers for const references
  5496. auto *const instance = any_cast<std::remove_reference_t<const Type>>(&data);
  5497. ENTT_ASSERT(instance, "Invalid instance");
  5498. return static_cast<Type>(*instance);
  5499. }
  5500. /*! @copydoc any_cast */
  5501. template<typename Type, std::size_t Len, std::size_t Align>
  5502. Type any_cast(basic_any<Len, Align> &&data) ENTT_NOEXCEPT {
  5503. if constexpr(std::is_copy_constructible_v<std::remove_cv_t<std::remove_reference_t<Type>>>) {
  5504. if(auto *const instance = any_cast<std::remove_reference_t<Type>>(&data); instance) {
  5505. return static_cast<Type>(std::move(*instance));
  5506. } else {
  5507. return any_cast<Type>(data);
  5508. }
  5509. } else {
  5510. auto *const instance = any_cast<std::remove_reference_t<Type>>(&data);
  5511. ENTT_ASSERT(instance, "Invalid instance");
  5512. return static_cast<Type>(std::move(*instance));
  5513. }
  5514. }
  5515. /*! @copydoc any_cast */
  5516. template<typename Type, std::size_t Len, std::size_t Align>
  5517. const Type *any_cast(const basic_any<Len, Align> *data) ENTT_NOEXCEPT {
  5518. const auto &info = type_id<std::remove_cv_t<std::remove_reference_t<Type>>>();
  5519. return static_cast<const Type *>(data->data(info));
  5520. }
  5521. /*! @copydoc any_cast */
  5522. template<typename Type, std::size_t Len, std::size_t Align>
  5523. Type *any_cast(basic_any<Len, Align> *data) ENTT_NOEXCEPT {
  5524. const auto &info = type_id<std::remove_cv_t<std::remove_reference_t<Type>>>();
  5525. // last attempt to make wrappers for const references return their values
  5526. return static_cast<Type *>(static_cast<constness_as_t<basic_any<Len, Align>, Type> *>(data)->data(info));
  5527. }
  5528. /**
  5529. * @brief Constructs a wrapper from a given type, passing it all arguments.
  5530. * @tparam Type Type of object to use to initialize the wrapper.
  5531. * @tparam Len Size of the storage reserved for the small buffer optimization.
  5532. * @tparam Align Optional alignment requirement.
  5533. * @tparam Args Types of arguments to use to construct the new instance.
  5534. * @param args Parameters to use to construct the instance.
  5535. * @return A properly initialized wrapper for an object of the given type.
  5536. */
  5537. template<typename Type, std::size_t Len = basic_any<>::length, std::size_t Align = basic_any<Len>::alignment, typename... Args>
  5538. basic_any<Len, Align> make_any(Args &&...args) {
  5539. return basic_any<Len, Align>{std::in_place_type<Type>, std::forward<Args>(args)...};
  5540. }
  5541. /**
  5542. * @brief Forwards its argument and avoids copies for lvalue references.
  5543. * @tparam Len Size of the storage reserved for the small buffer optimization.
  5544. * @tparam Align Optional alignment requirement.
  5545. * @tparam Type Type of argument to use to construct the new instance.
  5546. * @param value Parameter to use to construct the instance.
  5547. * @return A properly initialized and not necessarily owning wrapper.
  5548. */
  5549. template<std::size_t Len = basic_any<>::length, std::size_t Align = basic_any<Len>::alignment, typename Type>
  5550. basic_any<Len, Align> forward_as_any(Type &&value) {
  5551. return basic_any<Len, Align>{std::in_place_type<std::conditional_t<std::is_rvalue_reference_v<Type>, std::decay_t<Type>, Type>>, std::forward<Type>(value)};
  5552. }
  5553. } // namespace entt
  5554. #endif
  5555. // #include "core/attribute.h"
  5556. #ifndef ENTT_CORE_ATTRIBUTE_H
  5557. #define ENTT_CORE_ATTRIBUTE_H
  5558. #ifndef ENTT_EXPORT
  5559. # if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER
  5560. # define ENTT_EXPORT __declspec(dllexport)
  5561. # define ENTT_IMPORT __declspec(dllimport)
  5562. # define ENTT_HIDDEN
  5563. # elif defined __GNUC__ && __GNUC__ >= 4
  5564. # define ENTT_EXPORT __attribute__((visibility("default")))
  5565. # define ENTT_IMPORT __attribute__((visibility("default")))
  5566. # define ENTT_HIDDEN __attribute__((visibility("hidden")))
  5567. # else /* Unsupported compiler */
  5568. # define ENTT_EXPORT
  5569. # define ENTT_IMPORT
  5570. # define ENTT_HIDDEN
  5571. # endif
  5572. #endif
  5573. #ifndef ENTT_API
  5574. # if defined ENTT_API_EXPORT
  5575. # define ENTT_API ENTT_EXPORT
  5576. # elif defined ENTT_API_IMPORT
  5577. # define ENTT_API ENTT_IMPORT
  5578. # else /* No API */
  5579. # define ENTT_API
  5580. # endif
  5581. #endif
  5582. #endif
  5583. // #include "core/compressed_pair.hpp"
  5584. #ifndef ENTT_CORE_COMPRESSED_PAIR_HPP
  5585. #define ENTT_CORE_COMPRESSED_PAIR_HPP
  5586. #include <cstddef>
  5587. #include <tuple>
  5588. #include <type_traits>
  5589. #include <utility>
  5590. // #include "../config/config.h"
  5591. // #include "type_traits.hpp"
  5592. namespace entt {
  5593. /**
  5594. * @cond TURN_OFF_DOXYGEN
  5595. * Internal details not to be documented.
  5596. */
  5597. namespace internal {
  5598. template<typename Type, std::size_t, typename = void>
  5599. struct compressed_pair_element {
  5600. using reference = Type &;
  5601. using const_reference = const Type &;
  5602. template<bool Dummy = true, typename = std::enable_if_t<Dummy && std::is_default_constructible_v<Type>>>
  5603. compressed_pair_element()
  5604. : value{} {}
  5605. template<typename Args, typename = std::enable_if_t<!std::is_same_v<std::remove_cv_t<std::remove_reference_t<Args>>, compressed_pair_element>>>
  5606. compressed_pair_element(Args &&args)
  5607. : value{std::forward<Args>(args)} {}
  5608. template<typename... Args, std::size_t... Index>
  5609. compressed_pair_element(std::tuple<Args...> args, std::index_sequence<Index...>)
  5610. : value{std::forward<Args>(std::get<Index>(args))...} {}
  5611. [[nodiscard]] reference get() ENTT_NOEXCEPT {
  5612. return value;
  5613. }
  5614. [[nodiscard]] const_reference get() const ENTT_NOEXCEPT {
  5615. return value;
  5616. }
  5617. private:
  5618. Type value;
  5619. };
  5620. template<typename Type, std::size_t Tag>
  5621. struct compressed_pair_element<Type, Tag, std::enable_if_t<is_ebco_eligible_v<Type>>>: Type {
  5622. using reference = Type &;
  5623. using const_reference = const Type &;
  5624. using base_type = Type;
  5625. template<bool Dummy = true, typename = std::enable_if_t<Dummy && std::is_default_constructible_v<base_type>>>
  5626. compressed_pair_element()
  5627. : base_type{} {}
  5628. template<typename Args, typename = std::enable_if_t<!std::is_same_v<std::remove_cv_t<std::remove_reference_t<Args>>, compressed_pair_element>>>
  5629. compressed_pair_element(Args &&args)
  5630. : base_type{std::forward<Args>(args)} {}
  5631. template<typename... Args, std::size_t... Index>
  5632. compressed_pair_element(std::tuple<Args...> args, std::index_sequence<Index...>)
  5633. : base_type{std::forward<Args>(std::get<Index>(args))...} {}
  5634. [[nodiscard]] reference get() ENTT_NOEXCEPT {
  5635. return *this;
  5636. }
  5637. [[nodiscard]] const_reference get() const ENTT_NOEXCEPT {
  5638. return *this;
  5639. }
  5640. };
  5641. } // namespace internal
  5642. /**
  5643. * Internal details not to be documented.
  5644. * @endcond
  5645. */
  5646. /**
  5647. * @brief A compressed pair.
  5648. *
  5649. * A pair that exploits the _Empty Base Class Optimization_ (or _EBCO_) to
  5650. * reduce its final size to a minimum.
  5651. *
  5652. * @tparam First The type of the first element that the pair stores.
  5653. * @tparam Second The type of the second element that the pair stores.
  5654. */
  5655. template<typename First, typename Second>
  5656. class compressed_pair final
  5657. : internal::compressed_pair_element<First, 0u>,
  5658. internal::compressed_pair_element<Second, 1u> {
  5659. using first_base = internal::compressed_pair_element<First, 0u>;
  5660. using second_base = internal::compressed_pair_element<Second, 1u>;
  5661. public:
  5662. /*! @brief The type of the first element that the pair stores. */
  5663. using first_type = First;
  5664. /*! @brief The type of the second element that the pair stores. */
  5665. using second_type = Second;
  5666. /**
  5667. * @brief Default constructor, conditionally enabled.
  5668. *
  5669. * This constructor is only available when the types that the pair stores
  5670. * are both at least default constructible.
  5671. *
  5672. * @tparam Dummy Dummy template parameter used for internal purposes.
  5673. */
  5674. template<bool Dummy = true, typename = std::enable_if_t<Dummy && std::is_default_constructible_v<first_type> && std::is_default_constructible_v<second_type>>>
  5675. constexpr compressed_pair()
  5676. : first_base{},
  5677. second_base{} {}
  5678. /**
  5679. * @brief Copy constructor.
  5680. * @param other The instance to copy from.
  5681. */
  5682. constexpr compressed_pair(const compressed_pair &other) = default;
  5683. /**
  5684. * @brief Move constructor.
  5685. * @param other The instance to move from.
  5686. */
  5687. constexpr compressed_pair(compressed_pair &&other) = default;
  5688. /**
  5689. * @brief Constructs a pair from its values.
  5690. * @tparam Arg Type of value to use to initialize the first element.
  5691. * @tparam Other Type of value to use to initialize the second element.
  5692. * @param arg Value to use to initialize the first element.
  5693. * @param other Value to use to initialize the second element.
  5694. */
  5695. template<typename Arg, typename Other>
  5696. constexpr compressed_pair(Arg &&arg, Other &&other)
  5697. : first_base{std::forward<Arg>(arg)},
  5698. second_base{std::forward<Other>(other)} {}
  5699. /**
  5700. * @brief Constructs a pair by forwarding the arguments to its parts.
  5701. * @tparam Args Types of arguments to use to initialize the first element.
  5702. * @tparam Other Types of arguments to use to initialize the second element.
  5703. * @param args Arguments to use to initialize the first element.
  5704. * @param other Arguments to use to initialize the second element.
  5705. */
  5706. template<typename... Args, typename... Other>
  5707. constexpr compressed_pair(std::piecewise_construct_t, std::tuple<Args...> args, std::tuple<Other...> other)
  5708. : first_base{std::move(args), std::index_sequence_for<Args...>{}},
  5709. second_base{std::move(other), std::index_sequence_for<Other...>{}} {}
  5710. /**
  5711. * @brief Copy assignment operator.
  5712. * @param other The instance to copy from.
  5713. * @return This compressed pair object.
  5714. */
  5715. constexpr compressed_pair &operator=(const compressed_pair &other) = default;
  5716. /**
  5717. * @brief Move assignment operator.
  5718. * @param other The instance to move from.
  5719. * @return This compressed pair object.
  5720. */
  5721. constexpr compressed_pair &operator=(compressed_pair &&other) = default;
  5722. /**
  5723. * @brief Returns the first element that a pair stores.
  5724. * @return The first element that a pair stores.
  5725. */
  5726. [[nodiscard]] first_type &first() ENTT_NOEXCEPT {
  5727. return static_cast<first_base &>(*this).get();
  5728. }
  5729. /*! @copydoc first */
  5730. [[nodiscard]] const first_type &first() const ENTT_NOEXCEPT {
  5731. return static_cast<const first_base &>(*this).get();
  5732. }
  5733. /**
  5734. * @brief Returns the second element that a pair stores.
  5735. * @return The second element that a pair stores.
  5736. */
  5737. [[nodiscard]] second_type &second() ENTT_NOEXCEPT {
  5738. return static_cast<second_base &>(*this).get();
  5739. }
  5740. /*! @copydoc second */
  5741. [[nodiscard]] const second_type &second() const ENTT_NOEXCEPT {
  5742. return static_cast<const second_base &>(*this).get();
  5743. }
  5744. /**
  5745. * @brief Swaps two compressed pair objects.
  5746. * @param other The compressed pair to swap with.
  5747. */
  5748. void swap(compressed_pair &other) {
  5749. using std::swap;
  5750. swap(first(), other.first());
  5751. swap(second(), other.second());
  5752. }
  5753. /**
  5754. * @brief Extracts an element from the compressed pair.
  5755. * @tparam Index An integer value that is either 0 or 1.
  5756. * @return Returns a reference to the first element if `Index` is 0 and a
  5757. * reference to the second element if `Index` is 1.
  5758. */
  5759. template<std::size_t Index>
  5760. decltype(auto) get() ENTT_NOEXCEPT {
  5761. if constexpr(Index == 0u) {
  5762. return first();
  5763. } else {
  5764. static_assert(Index == 1u, "Index out of bounds");
  5765. return second();
  5766. }
  5767. }
  5768. /*! @copydoc get */
  5769. template<std::size_t Index>
  5770. decltype(auto) get() const ENTT_NOEXCEPT {
  5771. if constexpr(Index == 0u) {
  5772. return first();
  5773. } else {
  5774. static_assert(Index == 1u, "Index out of bounds");
  5775. return second();
  5776. }
  5777. }
  5778. };
  5779. /**
  5780. * @brief Deduction guide.
  5781. * @tparam Type Type of value to use to initialize the first element.
  5782. * @tparam Other Type of value to use to initialize the second element.
  5783. */
  5784. template<typename Type, typename Other>
  5785. compressed_pair(Type &&, Other &&) -> compressed_pair<std::decay_t<Type>, std::decay_t<Other>>;
  5786. /**
  5787. * @brief Swaps two compressed pair objects.
  5788. * @tparam First The type of the first element that the pairs store.
  5789. * @tparam Second The type of the second element that the pairs store.
  5790. * @param lhs A valid compressed pair object.
  5791. * @param rhs A valid compressed pair object.
  5792. */
  5793. template<typename First, typename Second>
  5794. inline void swap(compressed_pair<First, Second> &lhs, compressed_pair<First, Second> &rhs) {
  5795. lhs.swap(rhs);
  5796. }
  5797. } // namespace entt
  5798. // disable structured binding support for clang 6, it messes when specializing tuple_size
  5799. #if !defined __clang_major__ || __clang_major__ > 6
  5800. namespace std {
  5801. /**
  5802. * @brief `std::tuple_size` specialization for `compressed_pair`s.
  5803. * @tparam First The type of the first element that the pair stores.
  5804. * @tparam Second The type of the second element that the pair stores.
  5805. */
  5806. template<typename First, typename Second>
  5807. struct tuple_size<entt::compressed_pair<First, Second>>: integral_constant<size_t, 2u> {};
  5808. /**
  5809. * @brief `std::tuple_element` specialization for `compressed_pair`s.
  5810. * @tparam Index The index of the type to return.
  5811. * @tparam First The type of the first element that the pair stores.
  5812. * @tparam Second The type of the second element that the pair stores.
  5813. */
  5814. template<size_t Index, typename First, typename Second>
  5815. struct tuple_element<Index, entt::compressed_pair<First, Second>>: conditional<Index == 0u, First, Second> {
  5816. static_assert(Index < 2u, "Index out of bounds");
  5817. };
  5818. } // namespace std
  5819. #endif
  5820. #endif
  5821. // #include "core/enum.hpp"
  5822. #ifndef ENTT_CORE_ENUM_HPP
  5823. #define ENTT_CORE_ENUM_HPP
  5824. #include <type_traits>
  5825. // #include "../config/config.h"
  5826. namespace entt {
  5827. /**
  5828. * @brief Enable bitmask support for enum classes.
  5829. * @tparam Type The enum type for which to enable bitmask support.
  5830. */
  5831. template<typename Type, typename = void>
  5832. struct enum_as_bitmask: std::false_type {};
  5833. /*! @copydoc enum_as_bitmask */
  5834. template<typename Type>
  5835. struct enum_as_bitmask<Type, std::void_t<decltype(Type::_entt_enum_as_bitmask)>>: std::is_enum<Type> {};
  5836. /**
  5837. * @brief Helper variable template.
  5838. * @tparam Type The enum class type for which to enable bitmask support.
  5839. */
  5840. template<typename Type>
  5841. inline constexpr bool enum_as_bitmask_v = enum_as_bitmask<Type>::value;
  5842. } // namespace entt
  5843. /**
  5844. * @brief Operator available for enums for which bitmask support is enabled.
  5845. * @tparam Type Enum class type.
  5846. * @param lhs The first value to use.
  5847. * @param rhs The second value to use.
  5848. * @return The result of invoking the operator on the underlying types of the
  5849. * two values provided.
  5850. */
  5851. template<typename Type>
  5852. [[nodiscard]] constexpr std::enable_if_t<entt::enum_as_bitmask_v<Type>, Type>
  5853. operator|(const Type lhs, const Type rhs) ENTT_NOEXCEPT {
  5854. return static_cast<Type>(static_cast<std::underlying_type_t<Type>>(lhs) | static_cast<std::underlying_type_t<Type>>(rhs));
  5855. }
  5856. /*! @copydoc operator| */
  5857. template<typename Type>
  5858. [[nodiscard]] constexpr std::enable_if_t<entt::enum_as_bitmask_v<Type>, Type>
  5859. operator&(const Type lhs, const Type rhs) ENTT_NOEXCEPT {
  5860. return static_cast<Type>(static_cast<std::underlying_type_t<Type>>(lhs) & static_cast<std::underlying_type_t<Type>>(rhs));
  5861. }
  5862. /*! @copydoc operator| */
  5863. template<typename Type>
  5864. [[nodiscard]] constexpr std::enable_if_t<entt::enum_as_bitmask_v<Type>, Type>
  5865. operator^(const Type lhs, const Type rhs) ENTT_NOEXCEPT {
  5866. return static_cast<Type>(static_cast<std::underlying_type_t<Type>>(lhs) ^ static_cast<std::underlying_type_t<Type>>(rhs));
  5867. }
  5868. /**
  5869. * @brief Operator available for enums for which bitmask support is enabled.
  5870. * @tparam Type Enum class type.
  5871. * @param value The value to use.
  5872. * @return The result of invoking the operator on the underlying types of the
  5873. * value provided.
  5874. */
  5875. template<typename Type>
  5876. [[nodiscard]] constexpr std::enable_if_t<entt::enum_as_bitmask_v<Type>, Type>
  5877. operator~(const Type value) ENTT_NOEXCEPT {
  5878. return static_cast<Type>(~static_cast<std::underlying_type_t<Type>>(value));
  5879. }
  5880. /*! @copydoc operator~ */
  5881. template<typename Type>
  5882. [[nodiscard]] constexpr std::enable_if_t<entt::enum_as_bitmask_v<Type>, bool>
  5883. operator!(const Type value) ENTT_NOEXCEPT {
  5884. return !static_cast<std::underlying_type_t<Type>>(value);
  5885. }
  5886. /*! @copydoc operator| */
  5887. template<typename Type>
  5888. constexpr std::enable_if_t<entt::enum_as_bitmask_v<Type>, Type &>
  5889. operator|=(Type &lhs, const Type rhs) ENTT_NOEXCEPT {
  5890. return (lhs = (lhs | rhs));
  5891. }
  5892. /*! @copydoc operator| */
  5893. template<typename Type>
  5894. constexpr std::enable_if_t<entt::enum_as_bitmask_v<Type>, Type &>
  5895. operator&=(Type &lhs, const Type rhs) ENTT_NOEXCEPT {
  5896. return (lhs = (lhs & rhs));
  5897. }
  5898. /*! @copydoc operator| */
  5899. template<typename Type>
  5900. constexpr std::enable_if_t<entt::enum_as_bitmask_v<Type>, Type &>
  5901. operator^=(Type &lhs, const Type rhs) ENTT_NOEXCEPT {
  5902. return (lhs = (lhs ^ rhs));
  5903. }
  5904. #endif
  5905. // #include "core/family.hpp"
  5906. #ifndef ENTT_CORE_FAMILY_HPP
  5907. #define ENTT_CORE_FAMILY_HPP
  5908. // #include "../config/config.h"
  5909. // #include "fwd.hpp"
  5910. namespace entt {
  5911. /**
  5912. * @brief Dynamic identifier generator.
  5913. *
  5914. * Utility class template that can be used to assign unique identifiers to types
  5915. * at runtime. Use different specializations to create separate sets of
  5916. * identifiers.
  5917. */
  5918. template<typename...>
  5919. class family {
  5920. inline static ENTT_MAYBE_ATOMIC(id_type) identifier{};
  5921. public:
  5922. /*! @brief Unsigned integer type. */
  5923. using family_type = id_type;
  5924. /*! @brief Statically generated unique identifier for the given type. */
  5925. template<typename... Type>
  5926. // at the time I'm writing, clang crashes during compilation if auto is used instead of family_type
  5927. inline static const family_type type = identifier++;
  5928. };
  5929. } // namespace entt
  5930. #endif
  5931. // #include "core/hashed_string.hpp"
  5932. #ifndef ENTT_CORE_HASHED_STRING_HPP
  5933. #define ENTT_CORE_HASHED_STRING_HPP
  5934. #include <cstddef>
  5935. #include <cstdint>
  5936. // #include "../config/config.h"
  5937. // #include "fwd.hpp"
  5938. namespace entt {
  5939. /**
  5940. * @cond TURN_OFF_DOXYGEN
  5941. * Internal details not to be documented.
  5942. */
  5943. namespace internal {
  5944. template<typename>
  5945. struct fnv1a_traits;
  5946. template<>
  5947. struct fnv1a_traits<std::uint32_t> {
  5948. using type = std::uint32_t;
  5949. static constexpr std::uint32_t offset = 2166136261;
  5950. static constexpr std::uint32_t prime = 16777619;
  5951. };
  5952. template<>
  5953. struct fnv1a_traits<std::uint64_t> {
  5954. using type = std::uint64_t;
  5955. static constexpr std::uint64_t offset = 14695981039346656037ull;
  5956. static constexpr std::uint64_t prime = 1099511628211ull;
  5957. };
  5958. template<typename Char>
  5959. struct basic_hashed_string {
  5960. using value_type = Char;
  5961. using size_type = std::size_t;
  5962. using hash_type = id_type;
  5963. const value_type *repr;
  5964. size_type length;
  5965. hash_type hash;
  5966. };
  5967. } // namespace internal
  5968. /**
  5969. * Internal details not to be documented.
  5970. * @endcond
  5971. */
  5972. /**
  5973. * @brief Zero overhead unique identifier.
  5974. *
  5975. * A hashed string is a compile-time tool that allows users to use
  5976. * human-readable identifiers in the codebase while using their numeric
  5977. * counterparts at runtime.<br/>
  5978. * Because of that, a hashed string can also be used in constant expressions if
  5979. * required.
  5980. *
  5981. * @warning
  5982. * This class doesn't take ownership of user-supplied strings nor does it make a
  5983. * copy of them.
  5984. *
  5985. * @tparam Char Character type.
  5986. */
  5987. template<typename Char>
  5988. class basic_hashed_string: internal::basic_hashed_string<Char> {
  5989. using base_type = internal::basic_hashed_string<Char>;
  5990. using hs_traits = internal::fnv1a_traits<id_type>;
  5991. struct const_wrapper {
  5992. // non-explicit constructor on purpose
  5993. constexpr const_wrapper(const Char *str) ENTT_NOEXCEPT: repr{str} {}
  5994. const Char *repr;
  5995. };
  5996. // Fowler–Noll–Vo hash function v. 1a - the good
  5997. [[nodiscard]] static constexpr auto helper(const Char *str) ENTT_NOEXCEPT {
  5998. base_type base{str, 0u, hs_traits::offset};
  5999. for(; str[base.length]; ++base.length) {
  6000. base.hash = (base.hash ^ static_cast<hs_traits::type>(str[base.length])) * hs_traits::prime;
  6001. }
  6002. return base;
  6003. }
  6004. // Fowler–Noll–Vo hash function v. 1a - the good
  6005. [[nodiscard]] static constexpr auto helper(const Char *str, const std::size_t len) ENTT_NOEXCEPT {
  6006. base_type base{str, len, hs_traits::offset};
  6007. for(size_type pos{}; pos < len; ++pos) {
  6008. base.hash = (base.hash ^ static_cast<hs_traits::type>(str[pos])) * hs_traits::prime;
  6009. }
  6010. return base;
  6011. }
  6012. public:
  6013. /*! @brief Character type. */
  6014. using value_type = typename base_type::value_type;
  6015. /*! @brief Unsigned integer type. */
  6016. using size_type = typename base_type::size_type;
  6017. /*! @brief Unsigned integer type. */
  6018. using hash_type = typename base_type::hash_type;
  6019. /**
  6020. * @brief Returns directly the numeric representation of a string view.
  6021. * @param str Human-readable identifier.
  6022. * @param len Length of the string to hash.
  6023. * @return The numeric representation of the string.
  6024. */
  6025. [[nodiscard]] static constexpr hash_type value(const value_type *str, const size_type len) ENTT_NOEXCEPT {
  6026. return basic_hashed_string{str, len};
  6027. }
  6028. /**
  6029. * @brief Returns directly the numeric representation of a string.
  6030. * @tparam N Number of characters of the identifier.
  6031. * @param str Human-readable identifier.
  6032. * @return The numeric representation of the string.
  6033. */
  6034. template<std::size_t N>
  6035. [[nodiscard]] static constexpr hash_type value(const value_type (&str)[N]) ENTT_NOEXCEPT {
  6036. return basic_hashed_string{str};
  6037. }
  6038. /**
  6039. * @brief Returns directly the numeric representation of a string.
  6040. * @param wrapper Helps achieving the purpose by relying on overloading.
  6041. * @return The numeric representation of the string.
  6042. */
  6043. [[nodiscard]] static constexpr hash_type value(const_wrapper wrapper) ENTT_NOEXCEPT {
  6044. return basic_hashed_string{wrapper};
  6045. }
  6046. /*! @brief Constructs an empty hashed string. */
  6047. constexpr basic_hashed_string() ENTT_NOEXCEPT
  6048. : base_type{} {}
  6049. /**
  6050. * @brief Constructs a hashed string from a string view.
  6051. * @param str Human-readable identifier.
  6052. * @param len Length of the string to hash.
  6053. */
  6054. constexpr basic_hashed_string(const value_type *str, const size_type len) ENTT_NOEXCEPT
  6055. : base_type{helper(str, len)} {}
  6056. /**
  6057. * @brief Constructs a hashed string from an array of const characters.
  6058. * @tparam N Number of characters of the identifier.
  6059. * @param str Human-readable identifier.
  6060. */
  6061. template<std::size_t N>
  6062. constexpr basic_hashed_string(const value_type (&str)[N]) ENTT_NOEXCEPT
  6063. : base_type{helper(str)} {}
  6064. /**
  6065. * @brief Explicit constructor on purpose to avoid constructing a hashed
  6066. * string directly from a `const value_type *`.
  6067. *
  6068. * @warning
  6069. * The lifetime of the string is not extended nor is it copied.
  6070. *
  6071. * @param wrapper Helps achieving the purpose by relying on overloading.
  6072. */
  6073. explicit constexpr basic_hashed_string(const_wrapper wrapper) ENTT_NOEXCEPT
  6074. : base_type{helper(wrapper.repr)} {}
  6075. /**
  6076. * @brief Returns the size a hashed string.
  6077. * @return The size of the hashed string.
  6078. */
  6079. [[nodiscard]] constexpr size_type size() const ENTT_NOEXCEPT {
  6080. return base_type::length;
  6081. }
  6082. /**
  6083. * @brief Returns the human-readable representation of a hashed string.
  6084. * @return The string used to initialize the hashed string.
  6085. */
  6086. [[nodiscard]] constexpr const value_type *data() const ENTT_NOEXCEPT {
  6087. return base_type::repr;
  6088. }
  6089. /**
  6090. * @brief Returns the numeric representation of a hashed string.
  6091. * @return The numeric representation of the hashed string.
  6092. */
  6093. [[nodiscard]] constexpr hash_type value() const ENTT_NOEXCEPT {
  6094. return base_type::hash;
  6095. }
  6096. /*! @copydoc data */
  6097. [[nodiscard]] constexpr operator const value_type *() const ENTT_NOEXCEPT {
  6098. return data();
  6099. }
  6100. /**
  6101. * @brief Returns the numeric representation of a hashed string.
  6102. * @return The numeric representation of the hashed string.
  6103. */
  6104. [[nodiscard]] constexpr operator hash_type() const ENTT_NOEXCEPT {
  6105. return value();
  6106. }
  6107. };
  6108. /**
  6109. * @brief Deduction guide.
  6110. * @tparam Char Character type.
  6111. * @param str Human-readable identifier.
  6112. * @param len Length of the string to hash.
  6113. */
  6114. template<typename Char>
  6115. basic_hashed_string(const Char *str, const std::size_t len) -> basic_hashed_string<Char>;
  6116. /**
  6117. * @brief Deduction guide.
  6118. * @tparam Char Character type.
  6119. * @tparam N Number of characters of the identifier.
  6120. * @param str Human-readable identifier.
  6121. */
  6122. template<typename Char, std::size_t N>
  6123. basic_hashed_string(const Char (&str)[N]) -> basic_hashed_string<Char>;
  6124. /**
  6125. * @brief Compares two hashed strings.
  6126. * @tparam Char Character type.
  6127. * @param lhs A valid hashed string.
  6128. * @param rhs A valid hashed string.
  6129. * @return True if the two hashed strings are identical, false otherwise.
  6130. */
  6131. template<typename Char>
  6132. [[nodiscard]] constexpr bool operator==(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) ENTT_NOEXCEPT {
  6133. return lhs.value() == rhs.value();
  6134. }
  6135. /**
  6136. * @brief Compares two hashed strings.
  6137. * @tparam Char Character type.
  6138. * @param lhs A valid hashed string.
  6139. * @param rhs A valid hashed string.
  6140. * @return True if the two hashed strings differ, false otherwise.
  6141. */
  6142. template<typename Char>
  6143. [[nodiscard]] constexpr bool operator!=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) ENTT_NOEXCEPT {
  6144. return !(lhs == rhs);
  6145. }
  6146. /**
  6147. * @brief Compares two hashed strings.
  6148. * @tparam Char Character type.
  6149. * @param lhs A valid hashed string.
  6150. * @param rhs A valid hashed string.
  6151. * @return True if the first element is less than the second, false otherwise.
  6152. */
  6153. template<typename Char>
  6154. [[nodiscard]] constexpr bool operator<(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) ENTT_NOEXCEPT {
  6155. return lhs.value() < rhs.value();
  6156. }
  6157. /**
  6158. * @brief Compares two hashed strings.
  6159. * @tparam Char Character type.
  6160. * @param lhs A valid hashed string.
  6161. * @param rhs A valid hashed string.
  6162. * @return True if the first element is less than or equal to the second, false
  6163. * otherwise.
  6164. */
  6165. template<typename Char>
  6166. [[nodiscard]] constexpr bool operator<=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) ENTT_NOEXCEPT {
  6167. return !(rhs < lhs);
  6168. }
  6169. /**
  6170. * @brief Compares two hashed strings.
  6171. * @tparam Char Character type.
  6172. * @param lhs A valid hashed string.
  6173. * @param rhs A valid hashed string.
  6174. * @return True if the first element is greater than the second, false
  6175. * otherwise.
  6176. */
  6177. template<typename Char>
  6178. [[nodiscard]] constexpr bool operator>(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) ENTT_NOEXCEPT {
  6179. return rhs < lhs;
  6180. }
  6181. /**
  6182. * @brief Compares two hashed strings.
  6183. * @tparam Char Character type.
  6184. * @param lhs A valid hashed string.
  6185. * @param rhs A valid hashed string.
  6186. * @return True if the first element is greater than or equal to the second,
  6187. * false otherwise.
  6188. */
  6189. template<typename Char>
  6190. [[nodiscard]] constexpr bool operator>=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) ENTT_NOEXCEPT {
  6191. return !(lhs < rhs);
  6192. }
  6193. /*! @brief Aliases for common character types. */
  6194. using hashed_string = basic_hashed_string<char>;
  6195. /*! @brief Aliases for common character types. */
  6196. using hashed_wstring = basic_hashed_string<wchar_t>;
  6197. inline namespace literals {
  6198. /**
  6199. * @brief User defined literal for hashed strings.
  6200. * @param str The literal without its suffix.
  6201. * @return A properly initialized hashed string.
  6202. */
  6203. [[nodiscard]] constexpr hashed_string operator"" _hs(const char *str, std::size_t) ENTT_NOEXCEPT {
  6204. return hashed_string{str};
  6205. }
  6206. /**
  6207. * @brief User defined literal for hashed wstrings.
  6208. * @param str The literal without its suffix.
  6209. * @return A properly initialized hashed wstring.
  6210. */
  6211. [[nodiscard]] constexpr hashed_wstring operator"" _hws(const wchar_t *str, std::size_t) ENTT_NOEXCEPT {
  6212. return hashed_wstring{str};
  6213. }
  6214. } // namespace literals
  6215. } // namespace entt
  6216. #endif
  6217. // #include "core/ident.hpp"
  6218. #ifndef ENTT_CORE_IDENT_HPP
  6219. #define ENTT_CORE_IDENT_HPP
  6220. #include <cstddef>
  6221. #include <type_traits>
  6222. #include <utility>
  6223. // #include "../config/config.h"
  6224. // #include "fwd.hpp"
  6225. // #include "type_traits.hpp"
  6226. namespace entt {
  6227. /**
  6228. * @brief Types identifiers.
  6229. *
  6230. * Variable template used to generate identifiers at compile-time for the given
  6231. * types. Use the `get` member function to know what's the identifier associated
  6232. * to the specific type.
  6233. *
  6234. * @note
  6235. * Identifiers are constant expression and can be used in any context where such
  6236. * an expression is required. As an example:
  6237. * @code{.cpp}
  6238. * using id = entt::identifier<a_type, another_type>;
  6239. *
  6240. * switch(a_type_identifier) {
  6241. * case id::type<a_type>:
  6242. * // ...
  6243. * break;
  6244. * case id::type<another_type>:
  6245. * // ...
  6246. * break;
  6247. * default:
  6248. * // ...
  6249. * }
  6250. * @endcode
  6251. *
  6252. * @tparam Types List of types for which to generate identifiers.
  6253. */
  6254. template<typename... Types>
  6255. class identifier {
  6256. template<typename Type, std::size_t... Index>
  6257. [[nodiscard]] static constexpr id_type get(std::index_sequence<Index...>) ENTT_NOEXCEPT {
  6258. static_assert((std::is_same_v<Type, Types> || ...), "Invalid type");
  6259. return (0 + ... + (std::is_same_v<Type, type_list_element_t<Index, type_list<std::decay_t<Types>...>>> ? id_type{Index} : id_type{}));
  6260. }
  6261. public:
  6262. /*! @brief Unsigned integer type. */
  6263. using identifier_type = id_type;
  6264. /*! @brief Statically generated unique identifier for the given type. */
  6265. template<typename Type>
  6266. static constexpr identifier_type type = get<std::decay_t<Type>>(std::index_sequence_for<Types...>{});
  6267. };
  6268. } // namespace entt
  6269. #endif
  6270. // #include "core/iterator.hpp"
  6271. #ifndef ENTT_CORE_ITERATOR_HPP
  6272. #define ENTT_CORE_ITERATOR_HPP
  6273. #include <iterator>
  6274. #include <memory>
  6275. #include <utility>
  6276. // #include "../config/config.h"
  6277. namespace entt {
  6278. /**
  6279. * @brief Helper type to use as pointer with input iterators.
  6280. * @tparam Type of wrapped value.
  6281. */
  6282. template<typename Type>
  6283. struct input_iterator_pointer final {
  6284. /*! @brief Pointer type. */
  6285. using pointer = Type *;
  6286. /*! @brief Default copy constructor, deleted on purpose. */
  6287. input_iterator_pointer(const input_iterator_pointer &) = delete;
  6288. /*! @brief Default move constructor. */
  6289. input_iterator_pointer(input_iterator_pointer &&) = default;
  6290. /**
  6291. * @brief Constructs a proxy object by move.
  6292. * @param val Value to use to initialize the proxy object.
  6293. */
  6294. input_iterator_pointer(Type &&val)
  6295. : value{std::move(val)} {}
  6296. /**
  6297. * @brief Default copy assignment operator, deleted on purpose.
  6298. * @return This proxy object.
  6299. */
  6300. input_iterator_pointer &operator=(const input_iterator_pointer &) = delete;
  6301. /**
  6302. * @brief Default move assignment operator.
  6303. * @return This proxy object.
  6304. */
  6305. input_iterator_pointer &operator=(input_iterator_pointer &&) = default;
  6306. /**
  6307. * @brief Access operator for accessing wrapped values.
  6308. * @return A pointer to the wrapped value.
  6309. */
  6310. [[nodiscard]] pointer operator->() ENTT_NOEXCEPT {
  6311. return std::addressof(value);
  6312. }
  6313. private:
  6314. Type value;
  6315. };
  6316. /**
  6317. * @brief Utility class to create an iterable object from a pair of iterators.
  6318. * @tparam It Type of iterator.
  6319. * @tparam Sentinel Type of sentinel.
  6320. */
  6321. template<typename It, typename Sentinel = It>
  6322. struct iterable_adaptor final {
  6323. /*! @brief Value type. */
  6324. using value_type = typename std::iterator_traits<It>::value_type;
  6325. /*! @brief Iterator type. */
  6326. using iterator = It;
  6327. /*! @brief Sentinel type. */
  6328. using sentinel = Sentinel;
  6329. /*! @brief Default constructor. */
  6330. iterable_adaptor() = default;
  6331. /**
  6332. * @brief Creates an iterable object from a pair of iterators.
  6333. * @param from Begin iterator.
  6334. * @param to End iterator.
  6335. */
  6336. iterable_adaptor(iterator from, sentinel to)
  6337. : first{from},
  6338. last{to} {}
  6339. /**
  6340. * @brief Returns an iterator to the beginning.
  6341. * @return An iterator to the first element of the range.
  6342. */
  6343. [[nodiscard]] iterator begin() const ENTT_NOEXCEPT {
  6344. return first;
  6345. }
  6346. /**
  6347. * @brief Returns an iterator to the end.
  6348. * @return An iterator to the element following the last element of the
  6349. * range.
  6350. */
  6351. [[nodiscard]] sentinel end() const ENTT_NOEXCEPT {
  6352. return last;
  6353. }
  6354. /*! @copydoc begin */
  6355. [[nodiscard]] iterator cbegin() const ENTT_NOEXCEPT {
  6356. return begin();
  6357. }
  6358. /*! @copydoc end */
  6359. [[nodiscard]] sentinel cend() const ENTT_NOEXCEPT {
  6360. return end();
  6361. }
  6362. private:
  6363. It first;
  6364. Sentinel last;
  6365. };
  6366. } // namespace entt
  6367. #endif
  6368. // #include "core/memory.hpp"
  6369. #ifndef ENTT_CORE_MEMORY_HPP
  6370. #define ENTT_CORE_MEMORY_HPP
  6371. #include <cstddef>
  6372. #include <limits>
  6373. #include <memory>
  6374. #include <tuple>
  6375. #include <type_traits>
  6376. #include <utility>
  6377. // #include "../config/config.h"
  6378. namespace entt {
  6379. /**
  6380. * @brief Unwraps fancy pointers, does nothing otherwise (waiting for C++20).
  6381. * @tparam Type Pointer type.
  6382. * @param ptr Fancy or raw pointer.
  6383. * @return A raw pointer that represents the address of the original pointer.
  6384. */
  6385. template<typename Type>
  6386. [[nodiscard]] constexpr auto to_address(Type &&ptr) ENTT_NOEXCEPT {
  6387. if constexpr(std::is_pointer_v<std::remove_cv_t<std::remove_reference_t<Type>>>) {
  6388. return ptr;
  6389. } else {
  6390. return to_address(std::forward<Type>(ptr).operator->());
  6391. }
  6392. }
  6393. /**
  6394. * @brief Utility function to design allocation-aware containers.
  6395. * @tparam Allocator Type of allocator.
  6396. * @param lhs A valid allocator.
  6397. * @param rhs Another valid allocator.
  6398. */
  6399. template<typename Allocator>
  6400. constexpr void propagate_on_container_copy_assignment([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) ENTT_NOEXCEPT {
  6401. if constexpr(std::allocator_traits<Allocator>::propagate_on_container_copy_assignment::value) {
  6402. lhs = rhs;
  6403. }
  6404. }
  6405. /**
  6406. * @brief Utility function to design allocation-aware containers.
  6407. * @tparam Allocator Type of allocator.
  6408. * @param lhs A valid allocator.
  6409. * @param rhs Another valid allocator.
  6410. */
  6411. template<typename Allocator>
  6412. constexpr void propagate_on_container_move_assignment([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) ENTT_NOEXCEPT {
  6413. if constexpr(std::allocator_traits<Allocator>::propagate_on_container_move_assignment::value) {
  6414. lhs = std::move(rhs);
  6415. }
  6416. }
  6417. /**
  6418. * @brief Utility function to design allocation-aware containers.
  6419. * @tparam Allocator Type of allocator.
  6420. * @param lhs A valid allocator.
  6421. * @param rhs Another valid allocator.
  6422. */
  6423. template<typename Allocator>
  6424. constexpr void propagate_on_container_swap([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) ENTT_NOEXCEPT {
  6425. ENTT_ASSERT(std::allocator_traits<Allocator>::propagate_on_container_swap::value || lhs == rhs, "Cannot swap the containers");
  6426. if constexpr(std::allocator_traits<Allocator>::propagate_on_container_swap::value) {
  6427. using std::swap;
  6428. swap(lhs, rhs);
  6429. }
  6430. }
  6431. /**
  6432. * @brief Checks whether a value is a power of two or not.
  6433. * @param value A value that may or may not be a power of two.
  6434. * @return True if the value is a power of two, false otherwise.
  6435. */
  6436. [[nodiscard]] inline constexpr bool is_power_of_two(const std::size_t value) ENTT_NOEXCEPT {
  6437. return value && ((value & (value - 1)) == 0);
  6438. }
  6439. /**
  6440. * @brief Computes the smallest power of two greater than or equal to a value.
  6441. * @param value The value to use.
  6442. * @return The smallest power of two greater than or equal to the given value.
  6443. */
  6444. [[nodiscard]] inline constexpr std::size_t next_power_of_two(const std::size_t value) ENTT_NOEXCEPT {
  6445. ENTT_ASSERT(value < (std::size_t{1u} << (std::numeric_limits<std::size_t>::digits - 1)), "Numeric limits exceeded");
  6446. std::size_t curr = value - (value != 0u);
  6447. for(int next = 1; next < std::numeric_limits<std::size_t>::digits; next = next * 2) {
  6448. curr |= curr >> next;
  6449. }
  6450. return ++curr;
  6451. }
  6452. /**
  6453. * @brief Fast module utility function (powers of two only).
  6454. * @param value A value for which to calculate the modulus.
  6455. * @param mod _Modulus_, it must be a power of two.
  6456. * @return The common remainder.
  6457. */
  6458. [[nodiscard]] inline constexpr std::size_t fast_mod(const std::size_t value, const std::size_t mod) ENTT_NOEXCEPT {
  6459. ENTT_ASSERT(is_power_of_two(mod), "Value must be a power of two");
  6460. return value & (mod - 1u);
  6461. }
  6462. /**
  6463. * @brief Deleter for allocator-aware unique pointers (waiting for C++20).
  6464. * @tparam Args Types of arguments to use to construct the object.
  6465. */
  6466. template<typename Allocator>
  6467. struct allocation_deleter: private Allocator {
  6468. /*! @brief Allocator type. */
  6469. using allocator_type = Allocator;
  6470. /*! @brief Pointer type. */
  6471. using pointer = typename std::allocator_traits<Allocator>::pointer;
  6472. /**
  6473. * @brief Inherited constructors.
  6474. * @param alloc The allocator to use.
  6475. */
  6476. allocation_deleter(const allocator_type &alloc)
  6477. : Allocator{alloc} {}
  6478. /**
  6479. * @brief Destroys the pointed object and deallocates its memory.
  6480. * @param ptr A valid pointer to an object of the given type.
  6481. */
  6482. void operator()(pointer ptr) {
  6483. using alloc_traits = typename std::allocator_traits<Allocator>;
  6484. alloc_traits::destroy(*this, to_address(ptr));
  6485. alloc_traits::deallocate(*this, ptr, 1u);
  6486. }
  6487. };
  6488. /**
  6489. * @brief Allows `std::unique_ptr` to use allocators (waiting for C++20).
  6490. * @tparam Type Type of object to allocate for and to construct.
  6491. * @tparam Allocator Type of allocator used to manage memory and elements.
  6492. * @tparam Args Types of arguments to use to construct the object.
  6493. * @param allocator The allocator to use.
  6494. * @param args Parameters to use to construct the object.
  6495. * @return A properly initialized unique pointer with a custom deleter.
  6496. */
  6497. template<typename Type, typename Allocator, typename... Args>
  6498. auto allocate_unique(Allocator &allocator, Args &&...args) {
  6499. static_assert(!std::is_array_v<Type>, "Array types are not supported");
  6500. using alloc_traits = typename std::allocator_traits<Allocator>::template rebind_traits<Type>;
  6501. using allocator_type = typename alloc_traits::allocator_type;
  6502. allocator_type alloc{allocator};
  6503. auto ptr = alloc_traits::allocate(alloc, 1u);
  6504. ENTT_TRY {
  6505. alloc_traits::construct(alloc, to_address(ptr), std::forward<Args>(args)...);
  6506. }
  6507. ENTT_CATCH {
  6508. alloc_traits::deallocate(alloc, ptr, 1u);
  6509. ENTT_THROW;
  6510. }
  6511. return std::unique_ptr<Type, allocation_deleter<allocator_type>>{ptr, alloc};
  6512. }
  6513. /**
  6514. * @cond TURN_OFF_DOXYGEN
  6515. * Internal details not to be documented.
  6516. */
  6517. namespace internal {
  6518. template<typename Type>
  6519. struct uses_allocator_construction {
  6520. template<typename Allocator, typename... Params>
  6521. static constexpr auto args([[maybe_unused]] const Allocator &allocator, Params &&...params) ENTT_NOEXCEPT {
  6522. if constexpr(!std::uses_allocator_v<Type, Allocator> && std::is_constructible_v<Type, Params...>) {
  6523. return std::forward_as_tuple(std::forward<Params>(params)...);
  6524. } else {
  6525. static_assert(std::uses_allocator_v<Type, Allocator>, "Ill-formed request");
  6526. if constexpr(std::is_constructible_v<Type, std::allocator_arg_t, const Allocator &, Params...>) {
  6527. return std::tuple<std::allocator_arg_t, const Allocator &, Params &&...>(std::allocator_arg, allocator, std::forward<Params>(params)...);
  6528. } else {
  6529. static_assert(std::is_constructible_v<Type, Params..., const Allocator &>, "Ill-formed request");
  6530. return std::forward_as_tuple(std::forward<Params>(params)..., allocator);
  6531. }
  6532. }
  6533. }
  6534. };
  6535. template<typename Type, typename Other>
  6536. struct uses_allocator_construction<std::pair<Type, Other>> {
  6537. using type = std::pair<Type, Other>;
  6538. template<typename Allocator, typename First, typename Second>
  6539. static constexpr auto args(const Allocator &allocator, std::piecewise_construct_t, First &&first, Second &&second) ENTT_NOEXCEPT {
  6540. return std::make_tuple(
  6541. std::piecewise_construct,
  6542. std::apply([&allocator](auto &&...curr) { return uses_allocator_construction<Type>::args(allocator, std::forward<decltype(curr)>(curr)...); }, std::forward<First>(first)),
  6543. std::apply([&allocator](auto &&...curr) { return uses_allocator_construction<Other>::args(allocator, std::forward<decltype(curr)>(curr)...); }, std::forward<Second>(second)));
  6544. }
  6545. template<typename Allocator>
  6546. static constexpr auto args(const Allocator &allocator) ENTT_NOEXCEPT {
  6547. return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::tuple<>{}, std::tuple<>{});
  6548. }
  6549. template<typename Allocator, typename First, typename Second>
  6550. static constexpr auto args(const Allocator &allocator, First &&first, Second &&second) ENTT_NOEXCEPT {
  6551. 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)));
  6552. }
  6553. template<typename Allocator, typename First, typename Second>
  6554. static constexpr auto args(const Allocator &allocator, const std::pair<First, Second> &value) ENTT_NOEXCEPT {
  6555. return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::forward_as_tuple(value.first), std::forward_as_tuple(value.second));
  6556. }
  6557. template<typename Allocator, typename First, typename Second>
  6558. static constexpr auto args(const Allocator &allocator, std::pair<First, Second> &&value) ENTT_NOEXCEPT {
  6559. 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)));
  6560. }
  6561. };
  6562. } // namespace internal
  6563. /**
  6564. * Internal details not to be documented.
  6565. * @endcond
  6566. */
  6567. /**
  6568. * @brief Uses-allocator construction utility (waiting for C++20).
  6569. *
  6570. * Primarily intended for internal use. Prepares the argument list needed to
  6571. * create an object of a given type by means of uses-allocator construction.
  6572. *
  6573. * @tparam Type Type to return arguments for.
  6574. * @tparam Allocator Type of allocator used to manage memory and elements.
  6575. * @tparam Args Types of arguments to use to construct the object.
  6576. * @param allocator The allocator to use.
  6577. * @param args Parameters to use to construct the object.
  6578. * @return The arguments needed to create an object of the given type.
  6579. */
  6580. template<typename Type, typename Allocator, typename... Args>
  6581. constexpr auto uses_allocator_construction_args(const Allocator &allocator, Args &&...args) ENTT_NOEXCEPT {
  6582. return internal::uses_allocator_construction<Type>::args(allocator, std::forward<Args>(args)...);
  6583. }
  6584. /**
  6585. * @brief Uses-allocator construction utility (waiting for C++20).
  6586. *
  6587. * Primarily intended for internal use. Creates an object of a given type by
  6588. * means of uses-allocator construction.
  6589. *
  6590. * @tparam Type Type of object to create.
  6591. * @tparam Allocator Type of allocator used to manage memory and elements.
  6592. * @tparam Args Types of arguments to use to construct the object.
  6593. * @param allocator The allocator to use.
  6594. * @param args Parameters to use to construct the object.
  6595. * @return A newly created object of the given type.
  6596. */
  6597. template<typename Type, typename Allocator, typename... Args>
  6598. constexpr Type make_obj_using_allocator(const Allocator &allocator, Args &&...args) {
  6599. return std::make_from_tuple<Type>(internal::uses_allocator_construction<Type>::args(allocator, std::forward<Args>(args)...));
  6600. }
  6601. /**
  6602. * @brief Uses-allocator construction utility (waiting for C++20).
  6603. *
  6604. * Primarily intended for internal use. Creates an object of a given type by
  6605. * means of uses-allocator construction at an uninitialized memory location.
  6606. *
  6607. * @tparam Type Type of object to create.
  6608. * @tparam Allocator Type of allocator used to manage memory and elements.
  6609. * @tparam Args Types of arguments to use to construct the object.
  6610. * @param value Memory location in which to place the object.
  6611. * @param allocator The allocator to use.
  6612. * @param args Parameters to use to construct the object.
  6613. * @return A pointer to the newly created object of the given type.
  6614. */
  6615. template<typename Type, typename Allocator, typename... Args>
  6616. constexpr Type *uninitialized_construct_using_allocator(Type *value, const Allocator &allocator, Args &&...args) {
  6617. return std::apply([&](auto &&...curr) { return new(value) Type(std::forward<decltype(curr)>(curr)...); }, internal::uses_allocator_construction<Type>::args(allocator, std::forward<Args>(args)...));
  6618. }
  6619. } // namespace entt
  6620. #endif
  6621. // #include "core/monostate.hpp"
  6622. #ifndef ENTT_CORE_MONOSTATE_HPP
  6623. #define ENTT_CORE_MONOSTATE_HPP
  6624. // #include "../config/config.h"
  6625. // #include "fwd.hpp"
  6626. namespace entt {
  6627. /**
  6628. * @brief Minimal implementation of the monostate pattern.
  6629. *
  6630. * A minimal, yet complete configuration system built on top of the monostate
  6631. * pattern. Thread safe by design, it works only with basic types like `int`s or
  6632. * `bool`s.<br/>
  6633. * Multiple types and therefore more than one value can be associated with a
  6634. * single key. Because of this, users must pay attention to use the same type
  6635. * both during an assignment and when they try to read back their data.
  6636. * Otherwise, they can incur in unexpected results.
  6637. */
  6638. template<id_type>
  6639. struct monostate {
  6640. /**
  6641. * @brief Assigns a value of a specific type to a given key.
  6642. * @tparam Type Type of the value to assign.
  6643. * @param val User data to assign to the given key.
  6644. */
  6645. template<typename Type>
  6646. void operator=(Type val) const ENTT_NOEXCEPT {
  6647. value<Type> = val;
  6648. }
  6649. /**
  6650. * @brief Gets a value of a specific type for a given key.
  6651. * @tparam Type Type of the value to get.
  6652. * @return Stored value, if any.
  6653. */
  6654. template<typename Type>
  6655. operator Type() const ENTT_NOEXCEPT {
  6656. return value<Type>;
  6657. }
  6658. private:
  6659. template<typename Type>
  6660. inline static ENTT_MAYBE_ATOMIC(Type) value{};
  6661. };
  6662. /**
  6663. * @brief Helper variable template.
  6664. * @tparam Value Value used to differentiate between different variables.
  6665. */
  6666. template<id_type Value>
  6667. inline monostate<Value> monostate_v = {};
  6668. } // namespace entt
  6669. #endif
  6670. // #include "core/tuple.hpp"
  6671. #ifndef ENTT_CORE_TUPLE_HPP
  6672. #define ENTT_CORE_TUPLE_HPP
  6673. #include <tuple>
  6674. #include <type_traits>
  6675. #include <utility>
  6676. // #include "../config/config.h"
  6677. namespace entt {
  6678. /**
  6679. * @brief Utility function to unwrap tuples of a single element.
  6680. * @tparam Type Tuple type of any sizes.
  6681. * @param value A tuple object of the given type.
  6682. * @return The tuple itself if it contains more than one element, the first
  6683. * element otherwise.
  6684. */
  6685. template<typename Type>
  6686. constexpr decltype(auto) unwrap_tuple(Type &&value) ENTT_NOEXCEPT {
  6687. if constexpr(std::tuple_size_v<std::remove_reference_t<Type>> == 1u) {
  6688. return std::get<0>(std::forward<Type>(value));
  6689. } else {
  6690. return std::forward<Type>(value);
  6691. }
  6692. }
  6693. } // namespace entt
  6694. #endif
  6695. // #include "core/type_info.hpp"
  6696. #ifndef ENTT_CORE_TYPE_INFO_HPP
  6697. #define ENTT_CORE_TYPE_INFO_HPP
  6698. #include <string_view>
  6699. #include <type_traits>
  6700. #include <utility>
  6701. // #include "../config/config.h"
  6702. // #include "../core/attribute.h"
  6703. // #include "fwd.hpp"
  6704. // #include "hashed_string.hpp"
  6705. namespace entt {
  6706. /**
  6707. * @cond TURN_OFF_DOXYGEN
  6708. * Internal details not to be documented.
  6709. */
  6710. namespace internal {
  6711. struct ENTT_API type_index final {
  6712. [[nodiscard]] static id_type next() ENTT_NOEXCEPT {
  6713. static ENTT_MAYBE_ATOMIC(id_type) value{};
  6714. return value++;
  6715. }
  6716. };
  6717. template<typename Type>
  6718. [[nodiscard]] constexpr auto stripped_type_name() ENTT_NOEXCEPT {
  6719. #if defined ENTT_PRETTY_FUNCTION
  6720. std::string_view pretty_function{ENTT_PRETTY_FUNCTION};
  6721. auto first = pretty_function.find_first_not_of(' ', pretty_function.find_first_of(ENTT_PRETTY_FUNCTION_PREFIX) + 1);
  6722. auto value = pretty_function.substr(first, pretty_function.find_last_of(ENTT_PRETTY_FUNCTION_SUFFIX) - first);
  6723. return value;
  6724. #else
  6725. return std::string_view{""};
  6726. #endif
  6727. }
  6728. template<typename Type, auto = stripped_type_name<Type>().find_first_of('.')>
  6729. [[nodiscard]] static constexpr std::string_view type_name(int) ENTT_NOEXCEPT {
  6730. constexpr auto value = stripped_type_name<Type>();
  6731. return value;
  6732. }
  6733. template<typename Type>
  6734. [[nodiscard]] static std::string_view type_name(char) ENTT_NOEXCEPT {
  6735. static const auto value = stripped_type_name<Type>();
  6736. return value;
  6737. }
  6738. template<typename Type, auto = stripped_type_name<Type>().find_first_of('.')>
  6739. [[nodiscard]] static constexpr id_type type_hash(int) ENTT_NOEXCEPT {
  6740. constexpr auto stripped = stripped_type_name<Type>();
  6741. constexpr auto value = hashed_string::value(stripped.data(), stripped.size());
  6742. return value;
  6743. }
  6744. template<typename Type>
  6745. [[nodiscard]] static id_type type_hash(char) ENTT_NOEXCEPT {
  6746. static const auto value = [](const auto stripped) {
  6747. return hashed_string::value(stripped.data(), stripped.size());
  6748. }(stripped_type_name<Type>());
  6749. return value;
  6750. }
  6751. } // namespace internal
  6752. /**
  6753. * Internal details not to be documented.
  6754. * @endcond
  6755. */
  6756. /**
  6757. * @brief Type sequential identifier.
  6758. * @tparam Type Type for which to generate a sequential identifier.
  6759. */
  6760. template<typename Type, typename = void>
  6761. struct ENTT_API type_index final {
  6762. /**
  6763. * @brief Returns the sequential identifier of a given type.
  6764. * @return The sequential identifier of a given type.
  6765. */
  6766. [[nodiscard]] static id_type value() ENTT_NOEXCEPT {
  6767. static const id_type value = internal::type_index::next();
  6768. return value;
  6769. }
  6770. /*! @copydoc value */
  6771. [[nodiscard]] constexpr operator id_type() const ENTT_NOEXCEPT {
  6772. return value();
  6773. }
  6774. };
  6775. /**
  6776. * @brief Type hash.
  6777. * @tparam Type Type for which to generate a hash value.
  6778. */
  6779. template<typename Type, typename = void>
  6780. struct type_hash final {
  6781. /**
  6782. * @brief Returns the numeric representation of a given type.
  6783. * @return The numeric representation of the given type.
  6784. */
  6785. #if defined ENTT_PRETTY_FUNCTION
  6786. [[nodiscard]] static constexpr id_type value() ENTT_NOEXCEPT {
  6787. return internal::type_hash<Type>(0);
  6788. #else
  6789. [[nodiscard]] static constexpr id_type value() ENTT_NOEXCEPT {
  6790. return type_index<Type>::value();
  6791. #endif
  6792. }
  6793. /*! @copydoc value */
  6794. [[nodiscard]] constexpr operator id_type() const ENTT_NOEXCEPT {
  6795. return value();
  6796. }
  6797. };
  6798. /**
  6799. * @brief Type name.
  6800. * @tparam Type Type for which to generate a name.
  6801. */
  6802. template<typename Type, typename = void>
  6803. struct type_name final {
  6804. /**
  6805. * @brief Returns the name of a given type.
  6806. * @return The name of the given type.
  6807. */
  6808. [[nodiscard]] static constexpr std::string_view value() ENTT_NOEXCEPT {
  6809. return internal::type_name<Type>(0);
  6810. }
  6811. /*! @copydoc value */
  6812. [[nodiscard]] constexpr operator std::string_view() const ENTT_NOEXCEPT {
  6813. return value();
  6814. }
  6815. };
  6816. /*! @brief Implementation specific information about a type. */
  6817. struct type_info final {
  6818. /**
  6819. * @brief Constructs a type info object for a given type.
  6820. * @tparam Type Type for which to construct a type info object.
  6821. */
  6822. template<typename Type>
  6823. constexpr type_info(std::in_place_type_t<Type>) ENTT_NOEXCEPT
  6824. : seq{type_index<std::remove_cv_t<std::remove_reference_t<Type>>>::value()},
  6825. identifier{type_hash<std::remove_cv_t<std::remove_reference_t<Type>>>::value()},
  6826. alias{type_name<std::remove_cv_t<std::remove_reference_t<Type>>>::value()} {}
  6827. /**
  6828. * @brief Type index.
  6829. * @return Type index.
  6830. */
  6831. [[nodiscard]] constexpr id_type index() const ENTT_NOEXCEPT {
  6832. return seq;
  6833. }
  6834. /**
  6835. * @brief Type hash.
  6836. * @return Type hash.
  6837. */
  6838. [[nodiscard]] constexpr id_type hash() const ENTT_NOEXCEPT {
  6839. return identifier;
  6840. }
  6841. /**
  6842. * @brief Type name.
  6843. * @return Type name.
  6844. */
  6845. [[nodiscard]] constexpr std::string_view name() const ENTT_NOEXCEPT {
  6846. return alias;
  6847. }
  6848. private:
  6849. id_type seq;
  6850. id_type identifier;
  6851. std::string_view alias;
  6852. };
  6853. /**
  6854. * @brief Compares the contents of two type info objects.
  6855. * @param lhs A type info object.
  6856. * @param rhs A type info object.
  6857. * @return True if the two type info objects are identical, false otherwise.
  6858. */
  6859. [[nodiscard]] inline constexpr bool operator==(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT {
  6860. return lhs.hash() == rhs.hash();
  6861. }
  6862. /**
  6863. * @brief Compares the contents of two type info objects.
  6864. * @param lhs A type info object.
  6865. * @param rhs A type info object.
  6866. * @return True if the two type info objects differ, false otherwise.
  6867. */
  6868. [[nodiscard]] inline constexpr bool operator!=(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT {
  6869. return !(lhs == rhs);
  6870. }
  6871. /**
  6872. * @brief Compares two type info objects.
  6873. * @param lhs A valid type info object.
  6874. * @param rhs A valid type info object.
  6875. * @return True if the first element is less than the second, false otherwise.
  6876. */
  6877. [[nodiscard]] constexpr bool operator<(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT {
  6878. return lhs.index() < rhs.index();
  6879. }
  6880. /**
  6881. * @brief Compares two type info objects.
  6882. * @param lhs A valid type info object.
  6883. * @param rhs A valid type info object.
  6884. * @return True if the first element is less than or equal to the second, false
  6885. * otherwise.
  6886. */
  6887. [[nodiscard]] constexpr bool operator<=(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT {
  6888. return !(rhs < lhs);
  6889. }
  6890. /**
  6891. * @brief Compares two type info objects.
  6892. * @param lhs A valid type info object.
  6893. * @param rhs A valid type info object.
  6894. * @return True if the first element is greater than the second, false
  6895. * otherwise.
  6896. */
  6897. [[nodiscard]] constexpr bool operator>(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT {
  6898. return rhs < lhs;
  6899. }
  6900. /**
  6901. * @brief Compares two type info objects.
  6902. * @param lhs A valid type info object.
  6903. * @param rhs A valid type info object.
  6904. * @return True if the first element is greater than or equal to the second,
  6905. * false otherwise.
  6906. */
  6907. [[nodiscard]] constexpr bool operator>=(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT {
  6908. return !(lhs < rhs);
  6909. }
  6910. /**
  6911. * @brief Returns the type info object associated to a given type.
  6912. *
  6913. * The returned element refers to an object with static storage duration.<br/>
  6914. * The type doesn't need to be a complete type. If the type is a reference, the
  6915. * result refers to the referenced type. In all cases, top-level cv-qualifiers
  6916. * are ignored.
  6917. *
  6918. * @tparam Type Type for which to generate a type info object.
  6919. * @return A reference to a properly initialized type info object.
  6920. */
  6921. template<typename Type>
  6922. [[nodiscard]] const type_info &type_id() ENTT_NOEXCEPT {
  6923. if constexpr(std::is_same_v<Type, std::remove_cv_t<std::remove_reference_t<Type>>>) {
  6924. static type_info instance{std::in_place_type<Type>};
  6925. return instance;
  6926. } else {
  6927. return type_id<std::remove_cv_t<std::remove_reference_t<Type>>>();
  6928. }
  6929. }
  6930. /*! @copydoc type_id */
  6931. template<typename Type>
  6932. [[nodiscard]] const type_info &type_id(Type &&) ENTT_NOEXCEPT {
  6933. return type_id<std::remove_cv_t<std::remove_reference_t<Type>>>();
  6934. }
  6935. } // namespace entt
  6936. #endif
  6937. // #include "core/type_traits.hpp"
  6938. #ifndef ENTT_CORE_TYPE_TRAITS_HPP
  6939. #define ENTT_CORE_TYPE_TRAITS_HPP
  6940. #include <cstddef>
  6941. #include <iterator>
  6942. #include <type_traits>
  6943. #include <utility>
  6944. // #include "../config/config.h"
  6945. // #include "fwd.hpp"
  6946. namespace entt {
  6947. /**
  6948. * @brief Utility class to disambiguate overloaded functions.
  6949. * @tparam N Number of choices available.
  6950. */
  6951. template<std::size_t N>
  6952. struct choice_t
  6953. // Unfortunately, doxygen cannot parse such a construct.
  6954. : /*! @cond TURN_OFF_DOXYGEN */ choice_t<N - 1> /*! @endcond */
  6955. {};
  6956. /*! @copybrief choice_t */
  6957. template<>
  6958. struct choice_t<0> {};
  6959. /**
  6960. * @brief Variable template for the choice trick.
  6961. * @tparam N Number of choices available.
  6962. */
  6963. template<std::size_t N>
  6964. inline constexpr choice_t<N> choice{};
  6965. /**
  6966. * @brief Identity type trait.
  6967. *
  6968. * Useful to establish non-deduced contexts in template argument deduction
  6969. * (waiting for C++20) or to provide types through function arguments.
  6970. *
  6971. * @tparam Type A type.
  6972. */
  6973. template<typename Type>
  6974. struct type_identity {
  6975. /*! @brief Identity type. */
  6976. using type = Type;
  6977. };
  6978. /**
  6979. * @brief Helper type.
  6980. * @tparam Type A type.
  6981. */
  6982. template<typename Type>
  6983. using type_identity_t = typename type_identity<Type>::type;
  6984. /**
  6985. * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains.
  6986. * @tparam Type The type of which to return the size.
  6987. * @tparam The size of the type if `sizeof` accepts it, 0 otherwise.
  6988. */
  6989. template<typename Type, typename = void>
  6990. struct size_of: std::integral_constant<std::size_t, 0u> {};
  6991. /*! @copydoc size_of */
  6992. template<typename Type>
  6993. struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
  6994. : std::integral_constant<std::size_t, sizeof(Type)> {};
  6995. /**
  6996. * @brief Helper variable template.
  6997. * @tparam Type The type of which to return the size.
  6998. */
  6999. template<typename Type>
  7000. inline constexpr std::size_t size_of_v = size_of<Type>::value;
  7001. /**
  7002. * @brief Using declaration to be used to _repeat_ the same type a number of
  7003. * times equal to the size of a given parameter pack.
  7004. * @tparam Type A type to repeat.
  7005. */
  7006. template<typename Type, typename>
  7007. using unpack_as_type = Type;
  7008. /**
  7009. * @brief Helper variable template to be used to _repeat_ the same value a
  7010. * number of times equal to the size of a given parameter pack.
  7011. * @tparam Value A value to repeat.
  7012. */
  7013. template<auto Value, typename>
  7014. inline constexpr auto unpack_as_value = Value;
  7015. /**
  7016. * @brief Wraps a static constant.
  7017. * @tparam Value A static constant.
  7018. */
  7019. template<auto Value>
  7020. using integral_constant = std::integral_constant<decltype(Value), Value>;
  7021. /**
  7022. * @brief Alias template to facilitate the creation of named values.
  7023. * @tparam Value A constant value at least convertible to `id_type`.
  7024. */
  7025. template<id_type Value>
  7026. using tag = integral_constant<Value>;
  7027. /**
  7028. * @brief A class to use to push around lists of types, nothing more.
  7029. * @tparam Type Types provided by the type list.
  7030. */
  7031. template<typename... Type>
  7032. struct type_list {
  7033. /*! @brief Type list type. */
  7034. using type = type_list;
  7035. /*! @brief Compile-time number of elements in the type list. */
  7036. static constexpr auto size = sizeof...(Type);
  7037. };
  7038. /*! @brief Primary template isn't defined on purpose. */
  7039. template<std::size_t, typename>
  7040. struct type_list_element;
  7041. /**
  7042. * @brief Provides compile-time indexed access to the types of a type list.
  7043. * @tparam Index Index of the type to return.
  7044. * @tparam Type First type provided by the type list.
  7045. * @tparam Other Other types provided by the type list.
  7046. */
  7047. template<std::size_t Index, typename Type, typename... Other>
  7048. struct type_list_element<Index, type_list<Type, Other...>>
  7049. : type_list_element<Index - 1u, type_list<Other...>> {};
  7050. /**
  7051. * @brief Provides compile-time indexed access to the types of a type list.
  7052. * @tparam Type First type provided by the type list.
  7053. * @tparam Other Other types provided by the type list.
  7054. */
  7055. template<typename Type, typename... Other>
  7056. struct type_list_element<0u, type_list<Type, Other...>> {
  7057. /*! @brief Searched type. */
  7058. using type = Type;
  7059. };
  7060. /**
  7061. * @brief Helper type.
  7062. * @tparam Index Index of the type to return.
  7063. * @tparam List Type list to search into.
  7064. */
  7065. template<std::size_t Index, typename List>
  7066. using type_list_element_t = typename type_list_element<Index, List>::type;
  7067. /**
  7068. * @brief Concatenates multiple type lists.
  7069. * @tparam Type Types provided by the first type list.
  7070. * @tparam Other Types provided by the second type list.
  7071. * @return A type list composed by the types of both the type lists.
  7072. */
  7073. template<typename... Type, typename... Other>
  7074. constexpr type_list<Type..., Other...> operator+(type_list<Type...>, type_list<Other...>) {
  7075. return {};
  7076. }
  7077. /*! @brief Primary template isn't defined on purpose. */
  7078. template<typename...>
  7079. struct type_list_cat;
  7080. /*! @brief Concatenates multiple type lists. */
  7081. template<>
  7082. struct type_list_cat<> {
  7083. /*! @brief A type list composed by the types of all the type lists. */
  7084. using type = type_list<>;
  7085. };
  7086. /**
  7087. * @brief Concatenates multiple type lists.
  7088. * @tparam Type Types provided by the first type list.
  7089. * @tparam Other Types provided by the second type list.
  7090. * @tparam List Other type lists, if any.
  7091. */
  7092. template<typename... Type, typename... Other, typename... List>
  7093. struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
  7094. /*! @brief A type list composed by the types of all the type lists. */
  7095. using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
  7096. };
  7097. /**
  7098. * @brief Concatenates multiple type lists.
  7099. * @tparam Type Types provided by the type list.
  7100. */
  7101. template<typename... Type>
  7102. struct type_list_cat<type_list<Type...>> {
  7103. /*! @brief A type list composed by the types of all the type lists. */
  7104. using type = type_list<Type...>;
  7105. };
  7106. /**
  7107. * @brief Helper type.
  7108. * @tparam List Type lists to concatenate.
  7109. */
  7110. template<typename... List>
  7111. using type_list_cat_t = typename type_list_cat<List...>::type;
  7112. /*! @brief Primary template isn't defined on purpose. */
  7113. template<typename>
  7114. struct type_list_unique;
  7115. /**
  7116. * @brief Removes duplicates types from a type list.
  7117. * @tparam Type One of the types provided by the given type list.
  7118. * @tparam Other The other types provided by the given type list.
  7119. */
  7120. template<typename Type, typename... Other>
  7121. struct type_list_unique<type_list<Type, Other...>> {
  7122. /*! @brief A type list without duplicate types. */
  7123. using type = std::conditional_t<
  7124. (std::is_same_v<Type, Other> || ...),
  7125. typename type_list_unique<type_list<Other...>>::type,
  7126. type_list_cat_t<type_list<Type>, typename type_list_unique<type_list<Other...>>::type>>;
  7127. };
  7128. /*! @brief Removes duplicates types from a type list. */
  7129. template<>
  7130. struct type_list_unique<type_list<>> {
  7131. /*! @brief A type list without duplicate types. */
  7132. using type = type_list<>;
  7133. };
  7134. /**
  7135. * @brief Helper type.
  7136. * @tparam Type A type list.
  7137. */
  7138. template<typename Type>
  7139. using type_list_unique_t = typename type_list_unique<Type>::type;
  7140. /**
  7141. * @brief Provides the member constant `value` to true if a type list contains a
  7142. * given type, false otherwise.
  7143. * @tparam List Type list.
  7144. * @tparam Type Type to look for.
  7145. */
  7146. template<typename List, typename Type>
  7147. struct type_list_contains;
  7148. /**
  7149. * @copybrief type_list_contains
  7150. * @tparam Type Types provided by the type list.
  7151. * @tparam Other Type to look for.
  7152. */
  7153. template<typename... Type, typename Other>
  7154. struct type_list_contains<type_list<Type...>, Other>: std::disjunction<std::is_same<Type, Other>...> {};
  7155. /**
  7156. * @brief Helper variable template.
  7157. * @tparam List Type list.
  7158. * @tparam Type Type to look for.
  7159. */
  7160. template<typename List, typename Type>
  7161. inline constexpr bool type_list_contains_v = type_list_contains<List, Type>::value;
  7162. /*! @brief Primary template isn't defined on purpose. */
  7163. template<typename...>
  7164. struct type_list_diff;
  7165. /**
  7166. * @brief Computes the difference between two type lists.
  7167. * @tparam Type Types provided by the first type list.
  7168. * @tparam Other Types provided by the second type list.
  7169. */
  7170. template<typename... Type, typename... Other>
  7171. struct type_list_diff<type_list<Type...>, type_list<Other...>> {
  7172. /*! @brief A type list that is the difference between the two type lists. */
  7173. using type = type_list_cat_t<std::conditional_t<type_list_contains_v<type_list<Other...>, Type>, type_list<>, type_list<Type>>...>;
  7174. };
  7175. /**
  7176. * @brief Helper type.
  7177. * @tparam List Type lists between which to compute the difference.
  7178. */
  7179. template<typename... List>
  7180. using type_list_diff_t = typename type_list_diff<List...>::type;
  7181. /**
  7182. * @brief A class to use to push around lists of constant values, nothing more.
  7183. * @tparam Value Values provided by the value list.
  7184. */
  7185. template<auto... Value>
  7186. struct value_list {
  7187. /*! @brief Value list type. */
  7188. using type = value_list;
  7189. /*! @brief Compile-time number of elements in the value list. */
  7190. static constexpr auto size = sizeof...(Value);
  7191. };
  7192. /*! @brief Primary template isn't defined on purpose. */
  7193. template<std::size_t, typename>
  7194. struct value_list_element;
  7195. /**
  7196. * @brief Provides compile-time indexed access to the values of a value list.
  7197. * @tparam Index Index of the value to return.
  7198. * @tparam Value First value provided by the value list.
  7199. * @tparam Other Other values provided by the value list.
  7200. */
  7201. template<std::size_t Index, auto Value, auto... Other>
  7202. struct value_list_element<Index, value_list<Value, Other...>>
  7203. : value_list_element<Index - 1u, value_list<Other...>> {};
  7204. /**
  7205. * @brief Provides compile-time indexed access to the types of a type list.
  7206. * @tparam Value First value provided by the value list.
  7207. * @tparam Other Other values provided by the value list.
  7208. */
  7209. template<auto Value, auto... Other>
  7210. struct value_list_element<0u, value_list<Value, Other...>> {
  7211. /*! @brief Searched value. */
  7212. static constexpr auto value = Value;
  7213. };
  7214. /**
  7215. * @brief Helper type.
  7216. * @tparam Index Index of the value to return.
  7217. * @tparam List Value list to search into.
  7218. */
  7219. template<std::size_t Index, typename List>
  7220. inline constexpr auto value_list_element_v = value_list_element<Index, List>::value;
  7221. /**
  7222. * @brief Concatenates multiple value lists.
  7223. * @tparam Value Values provided by the first value list.
  7224. * @tparam Other Values provided by the second value list.
  7225. * @return A value list composed by the values of both the value lists.
  7226. */
  7227. template<auto... Value, auto... Other>
  7228. constexpr value_list<Value..., Other...> operator+(value_list<Value...>, value_list<Other...>) {
  7229. return {};
  7230. }
  7231. /*! @brief Primary template isn't defined on purpose. */
  7232. template<typename...>
  7233. struct value_list_cat;
  7234. /*! @brief Concatenates multiple value lists. */
  7235. template<>
  7236. struct value_list_cat<> {
  7237. /*! @brief A value list composed by the values of all the value lists. */
  7238. using type = value_list<>;
  7239. };
  7240. /**
  7241. * @brief Concatenates multiple value lists.
  7242. * @tparam Value Values provided by the first value list.
  7243. * @tparam Other Values provided by the second value list.
  7244. * @tparam List Other value lists, if any.
  7245. */
  7246. template<auto... Value, auto... Other, typename... List>
  7247. struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
  7248. /*! @brief A value list composed by the values of all the value lists. */
  7249. using type = typename value_list_cat<value_list<Value..., Other...>, List...>::type;
  7250. };
  7251. /**
  7252. * @brief Concatenates multiple value lists.
  7253. * @tparam Value Values provided by the value list.
  7254. */
  7255. template<auto... Value>
  7256. struct value_list_cat<value_list<Value...>> {
  7257. /*! @brief A value list composed by the values of all the value lists. */
  7258. using type = value_list<Value...>;
  7259. };
  7260. /**
  7261. * @brief Helper type.
  7262. * @tparam List Value lists to concatenate.
  7263. */
  7264. template<typename... List>
  7265. using value_list_cat_t = typename value_list_cat<List...>::type;
  7266. /*! @brief Same as std::is_invocable, but with tuples. */
  7267. template<typename, typename>
  7268. struct is_applicable: std::false_type {};
  7269. /**
  7270. * @copybrief is_applicable
  7271. * @tparam Func A valid function type.
  7272. * @tparam Tuple Tuple-like type.
  7273. * @tparam Args The list of arguments to use to probe the function type.
  7274. */
  7275. template<typename Func, template<typename...> class Tuple, typename... Args>
  7276. struct is_applicable<Func, Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  7277. /**
  7278. * @copybrief is_applicable
  7279. * @tparam Func A valid function type.
  7280. * @tparam Tuple Tuple-like type.
  7281. * @tparam Args The list of arguments to use to probe the function type.
  7282. */
  7283. template<typename Func, template<typename...> class Tuple, typename... Args>
  7284. struct is_applicable<Func, const Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  7285. /**
  7286. * @brief Helper variable template.
  7287. * @tparam Func A valid function type.
  7288. * @tparam Args The list of arguments to use to probe the function type.
  7289. */
  7290. template<typename Func, typename Args>
  7291. inline constexpr bool is_applicable_v = is_applicable<Func, Args>::value;
  7292. /*! @brief Same as std::is_invocable_r, but with tuples for arguments. */
  7293. template<typename, typename, typename>
  7294. struct is_applicable_r: std::false_type {};
  7295. /**
  7296. * @copybrief is_applicable_r
  7297. * @tparam Ret The type to which the return type of the function should be
  7298. * convertible.
  7299. * @tparam Func A valid function type.
  7300. * @tparam Args The list of arguments to use to probe the function type.
  7301. */
  7302. template<typename Ret, typename Func, typename... Args>
  7303. struct is_applicable_r<Ret, Func, std::tuple<Args...>>: std::is_invocable_r<Ret, Func, Args...> {};
  7304. /**
  7305. * @brief Helper variable template.
  7306. * @tparam Ret The type to which the return type of the function should be
  7307. * convertible.
  7308. * @tparam Func A valid function type.
  7309. * @tparam Args The list of arguments to use to probe the function type.
  7310. */
  7311. template<typename Ret, typename Func, typename Args>
  7312. inline constexpr bool is_applicable_r_v = is_applicable_r<Ret, Func, Args>::value;
  7313. /**
  7314. * @brief Provides the member constant `value` to true if a given type is
  7315. * complete, false otherwise.
  7316. * @tparam Type The type to test.
  7317. */
  7318. template<typename Type, typename = void>
  7319. struct is_complete: std::false_type {};
  7320. /*! @copydoc is_complete */
  7321. template<typename Type>
  7322. struct is_complete<Type, std::void_t<decltype(sizeof(Type))>>: std::true_type {};
  7323. /**
  7324. * @brief Helper variable template.
  7325. * @tparam Type The type to test.
  7326. */
  7327. template<typename Type>
  7328. inline constexpr bool is_complete_v = is_complete<Type>::value;
  7329. /**
  7330. * @brief Provides the member constant `value` to true if a given type is an
  7331. * iterator, false otherwise.
  7332. * @tparam Type The type to test.
  7333. */
  7334. template<typename Type, typename = void>
  7335. struct is_iterator: std::false_type {};
  7336. /**
  7337. * @cond TURN_OFF_DOXYGEN
  7338. * Internal details not to be documented.
  7339. */
  7340. namespace internal {
  7341. template<typename, typename = void>
  7342. struct has_iterator_category: std::false_type {};
  7343. template<typename Type>
  7344. struct has_iterator_category<Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>: std::true_type {};
  7345. } // namespace internal
  7346. /**
  7347. * Internal details not to be documented.
  7348. * @endcond
  7349. */
  7350. /*! @copydoc is_iterator */
  7351. template<typename Type>
  7352. struct is_iterator<Type, std::enable_if_t<!std::is_same_v<std::remove_const_t<std::remove_pointer_t<Type>>, void>>>
  7353. : internal::has_iterator_category<Type> {};
  7354. /**
  7355. * @brief Helper variable template.
  7356. * @tparam Type The type to test.
  7357. */
  7358. template<typename Type>
  7359. inline constexpr bool is_iterator_v = is_iterator<Type>::value;
  7360. /**
  7361. * @brief Provides the member constant `value` to true if a given type is both
  7362. * an empty and non-final class, false otherwise.
  7363. * @tparam Type The type to test
  7364. */
  7365. template<typename Type>
  7366. struct is_ebco_eligible
  7367. : std::conjunction<std::is_empty<Type>, std::negation<std::is_final<Type>>> {};
  7368. /**
  7369. * @brief Helper variable template.
  7370. * @tparam Type The type to test.
  7371. */
  7372. template<typename Type>
  7373. inline constexpr bool is_ebco_eligible_v = is_ebco_eligible<Type>::value;
  7374. /**
  7375. * @brief Provides the member constant `value` to true if `Type::is_transparent`
  7376. * is valid and denotes a type, false otherwise.
  7377. * @tparam Type The type to test.
  7378. */
  7379. template<typename Type, typename = void>
  7380. struct is_transparent: std::false_type {};
  7381. /*! @copydoc is_transparent */
  7382. template<typename Type>
  7383. struct is_transparent<Type, std::void_t<typename Type::is_transparent>>: std::true_type {};
  7384. /**
  7385. * @brief Helper variable template.
  7386. * @tparam Type The type to test.
  7387. */
  7388. template<typename Type>
  7389. inline constexpr bool is_transparent_v = is_transparent<Type>::value;
  7390. /**
  7391. * @brief Provides the member constant `value` to true if a given type is
  7392. * equality comparable, false otherwise.
  7393. * @tparam Type The type to test.
  7394. */
  7395. template<typename Type, typename = void>
  7396. struct is_equality_comparable: std::false_type {};
  7397. /**
  7398. * @cond TURN_OFF_DOXYGEN
  7399. * Internal details not to be documented.
  7400. */
  7401. namespace internal {
  7402. template<typename, typename = void>
  7403. struct has_tuple_size_value: std::false_type {};
  7404. template<typename Type>
  7405. struct has_tuple_size_value<Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>: std::true_type {};
  7406. template<typename Type, std::size_t... Index>
  7407. [[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
  7408. return (is_equality_comparable<std::tuple_element_t<Index, Type>>::value && ...);
  7409. }
  7410. template<typename>
  7411. [[nodiscard]] constexpr bool maybe_equality_comparable(choice_t<0>) {
  7412. return true;
  7413. }
  7414. template<typename Type>
  7415. [[nodiscard]] constexpr auto maybe_equality_comparable(choice_t<1>) -> decltype(std::declval<typename Type::value_type>(), bool{}) {
  7416. if constexpr(is_iterator_v<Type>) {
  7417. return true;
  7418. } else if constexpr(std::is_same_v<typename Type::value_type, Type>) {
  7419. return maybe_equality_comparable<Type>(choice<0>);
  7420. } else {
  7421. return is_equality_comparable<typename Type::value_type>::value;
  7422. }
  7423. }
  7424. template<typename Type>
  7425. [[nodiscard]] constexpr std::enable_if_t<is_complete_v<std::tuple_size<std::remove_const_t<Type>>>, bool> maybe_equality_comparable(choice_t<2>) {
  7426. if constexpr(has_tuple_size_value<Type>::value) {
  7427. return unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
  7428. } else {
  7429. return maybe_equality_comparable<Type>(choice<1>);
  7430. }
  7431. }
  7432. } // namespace internal
  7433. /**
  7434. * Internal details not to be documented.
  7435. * @endcond
  7436. */
  7437. /*! @copydoc is_equality_comparable */
  7438. template<typename Type>
  7439. struct is_equality_comparable<Type, std::void_t<decltype(std::declval<Type>() == std::declval<Type>())>>
  7440. : std::bool_constant<internal::maybe_equality_comparable<Type>(choice<2>)> {};
  7441. /**
  7442. * @brief Helper variable template.
  7443. * @tparam Type The type to test.
  7444. */
  7445. template<typename Type>
  7446. inline constexpr bool is_equality_comparable_v = is_equality_comparable<Type>::value;
  7447. /**
  7448. * @brief Transcribes the constness of a type to another type.
  7449. * @tparam To The type to which to transcribe the constness.
  7450. * @tparam From The type from which to transcribe the constness.
  7451. */
  7452. template<typename To, typename From>
  7453. struct constness_as {
  7454. /*! @brief The type resulting from the transcription of the constness. */
  7455. using type = std::remove_const_t<To>;
  7456. };
  7457. /*! @copydoc constness_as */
  7458. template<typename To, typename From>
  7459. struct constness_as<To, const From> {
  7460. /*! @brief The type resulting from the transcription of the constness. */
  7461. using type = std::add_const_t<To>;
  7462. };
  7463. /**
  7464. * @brief Alias template to facilitate the transcription of the constness.
  7465. * @tparam To The type to which to transcribe the constness.
  7466. * @tparam From The type from which to transcribe the constness.
  7467. */
  7468. template<typename To, typename From>
  7469. using constness_as_t = typename constness_as<To, From>::type;
  7470. /**
  7471. * @brief Extracts the class of a non-static member object or function.
  7472. * @tparam Member A pointer to a non-static member object or function.
  7473. */
  7474. template<typename Member>
  7475. class member_class {
  7476. static_assert(std::is_member_pointer_v<Member>, "Invalid pointer type to non-static member object or function");
  7477. template<typename Class, typename Ret, typename... Args>
  7478. static Class *clazz(Ret (Class::*)(Args...));
  7479. template<typename Class, typename Ret, typename... Args>
  7480. static Class *clazz(Ret (Class::*)(Args...) const);
  7481. template<typename Class, typename Type>
  7482. static Class *clazz(Type Class::*);
  7483. public:
  7484. /*! @brief The class of the given non-static member object or function. */
  7485. using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
  7486. };
  7487. /**
  7488. * @brief Helper type.
  7489. * @tparam Member A pointer to a non-static member object or function.
  7490. */
  7491. template<typename Member>
  7492. using member_class_t = typename member_class<Member>::type;
  7493. } // namespace entt
  7494. #endif
  7495. // #include "core/utility.hpp"
  7496. #ifndef ENTT_CORE_UTILITY_HPP
  7497. #define ENTT_CORE_UTILITY_HPP
  7498. #include <utility>
  7499. // #include "../config/config.h"
  7500. namespace entt {
  7501. /*! @brief Identity function object (waiting for C++20). */
  7502. struct identity {
  7503. /*! @brief Indicates that this is a transparent function object. */
  7504. using is_transparent = void;
  7505. /**
  7506. * @brief Returns its argument unchanged.
  7507. * @tparam Type Type of the argument.
  7508. * @param value The actual argument.
  7509. * @return The submitted value as-is.
  7510. */
  7511. template<class Type>
  7512. [[nodiscard]] constexpr Type &&operator()(Type &&value) const ENTT_NOEXCEPT {
  7513. return std::forward<Type>(value);
  7514. }
  7515. };
  7516. /**
  7517. * @brief Constant utility to disambiguate overloaded members of a class.
  7518. * @tparam Type Type of the desired overload.
  7519. * @tparam Class Type of class to which the member belongs.
  7520. * @param member A valid pointer to a member.
  7521. * @return Pointer to the member.
  7522. */
  7523. template<typename Type, typename Class>
  7524. [[nodiscard]] constexpr auto overload(Type Class::*member) ENTT_NOEXCEPT {
  7525. return member;
  7526. }
  7527. /**
  7528. * @brief Constant utility to disambiguate overloaded functions.
  7529. * @tparam Func Function type of the desired overload.
  7530. * @param func A valid pointer to a function.
  7531. * @return Pointer to the function.
  7532. */
  7533. template<typename Func>
  7534. [[nodiscard]] constexpr auto overload(Func *func) ENTT_NOEXCEPT {
  7535. return func;
  7536. }
  7537. /**
  7538. * @brief Helper type for visitors.
  7539. * @tparam Func Types of function objects.
  7540. */
  7541. template<class... Func>
  7542. struct overloaded: Func... {
  7543. using Func::operator()...;
  7544. };
  7545. /**
  7546. * @brief Deduction guide.
  7547. * @tparam Func Types of function objects.
  7548. */
  7549. template<class... Func>
  7550. overloaded(Func...) -> overloaded<Func...>;
  7551. /**
  7552. * @brief Basic implementation of a y-combinator.
  7553. * @tparam Func Type of a potentially recursive function.
  7554. */
  7555. template<class Func>
  7556. struct y_combinator {
  7557. /**
  7558. * @brief Constructs a y-combinator from a given function.
  7559. * @param recursive A potentially recursive function.
  7560. */
  7561. y_combinator(Func recursive)
  7562. : func{std::move(recursive)} {}
  7563. /**
  7564. * @brief Invokes a y-combinator and therefore its underlying function.
  7565. * @tparam Args Types of arguments to use to invoke the underlying function.
  7566. * @param args Parameters to use to invoke the underlying function.
  7567. * @return Return value of the underlying function, if any.
  7568. */
  7569. template<class... Args>
  7570. decltype(auto) operator()(Args &&...args) const {
  7571. return func(*this, std::forward<Args>(args)...);
  7572. }
  7573. /*! @copydoc operator()() */
  7574. template<class... Args>
  7575. decltype(auto) operator()(Args &&...args) {
  7576. return func(*this, std::forward<Args>(args)...);
  7577. }
  7578. private:
  7579. Func func;
  7580. };
  7581. } // namespace entt
  7582. #endif
  7583. // #include "entity/component.hpp"
  7584. #ifndef ENTT_ENTITY_COMPONENT_HPP
  7585. #define ENTT_ENTITY_COMPONENT_HPP
  7586. #include <cstddef>
  7587. #include <type_traits>
  7588. // #include "../config/config.h"
  7589. #ifndef ENTT_CONFIG_CONFIG_H
  7590. #define ENTT_CONFIG_CONFIG_H
  7591. // #include "version.h"
  7592. #ifndef ENTT_CONFIG_VERSION_H
  7593. #define ENTT_CONFIG_VERSION_H
  7594. // #include "macro.h"
  7595. #ifndef ENTT_CONFIG_MACRO_H
  7596. #define ENTT_CONFIG_MACRO_H
  7597. #define ENTT_STR(arg) #arg
  7598. #define ENTT_XSTR(arg) ENTT_STR(arg)
  7599. #endif
  7600. #define ENTT_VERSION_MAJOR 3
  7601. #define ENTT_VERSION_MINOR 10
  7602. #define ENTT_VERSION_PATCH 3
  7603. #define ENTT_VERSION \
  7604. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  7605. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  7606. #endif
  7607. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  7608. # define ENTT_THROW throw
  7609. # define ENTT_TRY try
  7610. # define ENTT_CATCH catch(...)
  7611. #else
  7612. # define ENTT_THROW
  7613. # define ENTT_TRY if(true)
  7614. # define ENTT_CATCH if(false)
  7615. #endif
  7616. #ifndef ENTT_NOEXCEPT
  7617. # define ENTT_NOEXCEPT noexcept
  7618. # define ENTT_NOEXCEPT_IF(expr) noexcept(expr)
  7619. # else
  7620. # define ENTT_NOEXCEPT_IF(...)
  7621. #endif
  7622. #ifdef ENTT_USE_ATOMIC
  7623. # include <atomic>
  7624. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  7625. #else
  7626. # define ENTT_MAYBE_ATOMIC(Type) Type
  7627. #endif
  7628. #ifndef ENTT_ID_TYPE
  7629. # include <cstdint>
  7630. # define ENTT_ID_TYPE std::uint32_t
  7631. #endif
  7632. #ifndef ENTT_SPARSE_PAGE
  7633. # define ENTT_SPARSE_PAGE 4096
  7634. #endif
  7635. #ifndef ENTT_PACKED_PAGE
  7636. # define ENTT_PACKED_PAGE 1024
  7637. #endif
  7638. #ifdef ENTT_DISABLE_ASSERT
  7639. # undef ENTT_ASSERT
  7640. # define ENTT_ASSERT(...) (void(0))
  7641. #elif !defined ENTT_ASSERT
  7642. # include <cassert>
  7643. # define ENTT_ASSERT(condition, ...) assert(condition)
  7644. #endif
  7645. #ifdef ENTT_NO_ETO
  7646. # define ENTT_IGNORE_IF_EMPTY false
  7647. #else
  7648. # define ENTT_IGNORE_IF_EMPTY true
  7649. #endif
  7650. #ifdef ENTT_STANDARD_CPP
  7651. # define ENTT_NONSTD false
  7652. #else
  7653. # define ENTT_NONSTD true
  7654. # if defined __clang__ || defined __GNUC__
  7655. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  7656. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  7657. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  7658. # elif defined _MSC_VER
  7659. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  7660. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  7661. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  7662. # endif
  7663. #endif
  7664. #if defined _MSC_VER
  7665. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  7666. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  7667. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  7668. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  7669. #endif
  7670. #endif
  7671. namespace entt {
  7672. /**
  7673. * @cond TURN_OFF_DOXYGEN
  7674. * Internal details not to be documented.
  7675. */
  7676. namespace internal {
  7677. template<typename, typename = void>
  7678. struct in_place_delete: std::false_type {};
  7679. template<typename Type>
  7680. struct in_place_delete<Type, std::enable_if_t<Type::in_place_delete>>
  7681. : std::true_type {};
  7682. template<typename Type, typename = void>
  7683. struct page_size: std::integral_constant<std::size_t, (ENTT_IGNORE_IF_EMPTY && std::is_empty_v<Type>) ? 0u : ENTT_PACKED_PAGE> {};
  7684. template<typename Type>
  7685. struct page_size<Type, std::enable_if_t<std::is_convertible_v<decltype(Type::page_size), std::size_t>>>
  7686. : std::integral_constant<std::size_t, Type::page_size> {};
  7687. } // namespace internal
  7688. /**
  7689. * Internal details not to be documented.
  7690. * @endcond
  7691. */
  7692. /**
  7693. * @brief Common way to access various properties of components.
  7694. * @tparam Type Type of component.
  7695. */
  7696. template<typename Type, typename = void>
  7697. struct component_traits {
  7698. static_assert(std::is_same_v<std::decay_t<Type>, Type>, "Unsupported type");
  7699. /*! @brief Pointer stability, default is `false`. */
  7700. static constexpr bool in_place_delete = internal::in_place_delete<Type>::value;
  7701. /*! @brief Page size, default is `ENTT_PACKED_PAGE` for non-empty types. */
  7702. static constexpr std::size_t page_size = internal::page_size<Type>::value;
  7703. };
  7704. /**
  7705. * @brief Helper variable template.
  7706. * @tparam Type Type of component.
  7707. */
  7708. template<class Type>
  7709. inline constexpr bool ignore_as_empty_v = (component_traits<Type>::page_size == 0u);
  7710. } // namespace entt
  7711. #endif
  7712. // #include "entity/entity.hpp"
  7713. #ifndef ENTT_ENTITY_ENTITY_HPP
  7714. #define ENTT_ENTITY_ENTITY_HPP
  7715. #include <cstddef>
  7716. #include <cstdint>
  7717. #include <type_traits>
  7718. // #include "../config/config.h"
  7719. // #include "fwd.hpp"
  7720. #ifndef ENTT_ENTITY_FWD_HPP
  7721. #define ENTT_ENTITY_FWD_HPP
  7722. #include <memory>
  7723. // #include "../core/fwd.hpp"
  7724. #ifndef ENTT_CORE_FWD_HPP
  7725. #define ENTT_CORE_FWD_HPP
  7726. #include <cstdint>
  7727. #include <type_traits>
  7728. // #include "../config/config.h"
  7729. #ifndef ENTT_CONFIG_CONFIG_H
  7730. #define ENTT_CONFIG_CONFIG_H
  7731. // #include "version.h"
  7732. #ifndef ENTT_CONFIG_VERSION_H
  7733. #define ENTT_CONFIG_VERSION_H
  7734. // #include "macro.h"
  7735. #ifndef ENTT_CONFIG_MACRO_H
  7736. #define ENTT_CONFIG_MACRO_H
  7737. #define ENTT_STR(arg) #arg
  7738. #define ENTT_XSTR(arg) ENTT_STR(arg)
  7739. #endif
  7740. #define ENTT_VERSION_MAJOR 3
  7741. #define ENTT_VERSION_MINOR 10
  7742. #define ENTT_VERSION_PATCH 3
  7743. #define ENTT_VERSION \
  7744. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  7745. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  7746. #endif
  7747. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  7748. # define ENTT_THROW throw
  7749. # define ENTT_TRY try
  7750. # define ENTT_CATCH catch(...)
  7751. #else
  7752. # define ENTT_THROW
  7753. # define ENTT_TRY if(true)
  7754. # define ENTT_CATCH if(false)
  7755. #endif
  7756. #ifndef ENTT_NOEXCEPT
  7757. # define ENTT_NOEXCEPT noexcept
  7758. # define ENTT_NOEXCEPT_IF(expr) noexcept(expr)
  7759. # else
  7760. # define ENTT_NOEXCEPT_IF(...)
  7761. #endif
  7762. #ifdef ENTT_USE_ATOMIC
  7763. # include <atomic>
  7764. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  7765. #else
  7766. # define ENTT_MAYBE_ATOMIC(Type) Type
  7767. #endif
  7768. #ifndef ENTT_ID_TYPE
  7769. # include <cstdint>
  7770. # define ENTT_ID_TYPE std::uint32_t
  7771. #endif
  7772. #ifndef ENTT_SPARSE_PAGE
  7773. # define ENTT_SPARSE_PAGE 4096
  7774. #endif
  7775. #ifndef ENTT_PACKED_PAGE
  7776. # define ENTT_PACKED_PAGE 1024
  7777. #endif
  7778. #ifdef ENTT_DISABLE_ASSERT
  7779. # undef ENTT_ASSERT
  7780. # define ENTT_ASSERT(...) (void(0))
  7781. #elif !defined ENTT_ASSERT
  7782. # include <cassert>
  7783. # define ENTT_ASSERT(condition, ...) assert(condition)
  7784. #endif
  7785. #ifdef ENTT_NO_ETO
  7786. # define ENTT_IGNORE_IF_EMPTY false
  7787. #else
  7788. # define ENTT_IGNORE_IF_EMPTY true
  7789. #endif
  7790. #ifdef ENTT_STANDARD_CPP
  7791. # define ENTT_NONSTD false
  7792. #else
  7793. # define ENTT_NONSTD true
  7794. # if defined __clang__ || defined __GNUC__
  7795. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  7796. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  7797. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  7798. # elif defined _MSC_VER
  7799. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  7800. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  7801. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  7802. # endif
  7803. #endif
  7804. #if defined _MSC_VER
  7805. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  7806. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  7807. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  7808. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  7809. #endif
  7810. #endif
  7811. namespace entt {
  7812. template<std::size_t Len = sizeof(double[2]), std::size_t = alignof(typename std::aligned_storage_t<Len + !Len>)>
  7813. class basic_any;
  7814. /*! @brief Alias declaration for type identifiers. */
  7815. using id_type = ENTT_ID_TYPE;
  7816. /*! @brief Alias declaration for the most common use case. */
  7817. using any = basic_any<>;
  7818. } // namespace entt
  7819. #endif
  7820. // #include "utility.hpp"
  7821. #ifndef ENTT_ENTITY_UTILITY_HPP
  7822. #define ENTT_ENTITY_UTILITY_HPP
  7823. // #include "../core/type_traits.hpp"
  7824. #ifndef ENTT_CORE_TYPE_TRAITS_HPP
  7825. #define ENTT_CORE_TYPE_TRAITS_HPP
  7826. #include <cstddef>
  7827. #include <iterator>
  7828. #include <type_traits>
  7829. #include <utility>
  7830. // #include "../config/config.h"
  7831. // #include "fwd.hpp"
  7832. #ifndef ENTT_CORE_FWD_HPP
  7833. #define ENTT_CORE_FWD_HPP
  7834. #include <cstdint>
  7835. #include <type_traits>
  7836. // #include "../config/config.h"
  7837. namespace entt {
  7838. template<std::size_t Len = sizeof(double[2]), std::size_t = alignof(typename std::aligned_storage_t<Len + !Len>)>
  7839. class basic_any;
  7840. /*! @brief Alias declaration for type identifiers. */
  7841. using id_type = ENTT_ID_TYPE;
  7842. /*! @brief Alias declaration for the most common use case. */
  7843. using any = basic_any<>;
  7844. } // namespace entt
  7845. #endif
  7846. namespace entt {
  7847. /**
  7848. * @brief Utility class to disambiguate overloaded functions.
  7849. * @tparam N Number of choices available.
  7850. */
  7851. template<std::size_t N>
  7852. struct choice_t
  7853. // Unfortunately, doxygen cannot parse such a construct.
  7854. : /*! @cond TURN_OFF_DOXYGEN */ choice_t<N - 1> /*! @endcond */
  7855. {};
  7856. /*! @copybrief choice_t */
  7857. template<>
  7858. struct choice_t<0> {};
  7859. /**
  7860. * @brief Variable template for the choice trick.
  7861. * @tparam N Number of choices available.
  7862. */
  7863. template<std::size_t N>
  7864. inline constexpr choice_t<N> choice{};
  7865. /**
  7866. * @brief Identity type trait.
  7867. *
  7868. * Useful to establish non-deduced contexts in template argument deduction
  7869. * (waiting for C++20) or to provide types through function arguments.
  7870. *
  7871. * @tparam Type A type.
  7872. */
  7873. template<typename Type>
  7874. struct type_identity {
  7875. /*! @brief Identity type. */
  7876. using type = Type;
  7877. };
  7878. /**
  7879. * @brief Helper type.
  7880. * @tparam Type A type.
  7881. */
  7882. template<typename Type>
  7883. using type_identity_t = typename type_identity<Type>::type;
  7884. /**
  7885. * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains.
  7886. * @tparam Type The type of which to return the size.
  7887. * @tparam The size of the type if `sizeof` accepts it, 0 otherwise.
  7888. */
  7889. template<typename Type, typename = void>
  7890. struct size_of: std::integral_constant<std::size_t, 0u> {};
  7891. /*! @copydoc size_of */
  7892. template<typename Type>
  7893. struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
  7894. : std::integral_constant<std::size_t, sizeof(Type)> {};
  7895. /**
  7896. * @brief Helper variable template.
  7897. * @tparam Type The type of which to return the size.
  7898. */
  7899. template<typename Type>
  7900. inline constexpr std::size_t size_of_v = size_of<Type>::value;
  7901. /**
  7902. * @brief Using declaration to be used to _repeat_ the same type a number of
  7903. * times equal to the size of a given parameter pack.
  7904. * @tparam Type A type to repeat.
  7905. */
  7906. template<typename Type, typename>
  7907. using unpack_as_type = Type;
  7908. /**
  7909. * @brief Helper variable template to be used to _repeat_ the same value a
  7910. * number of times equal to the size of a given parameter pack.
  7911. * @tparam Value A value to repeat.
  7912. */
  7913. template<auto Value, typename>
  7914. inline constexpr auto unpack_as_value = Value;
  7915. /**
  7916. * @brief Wraps a static constant.
  7917. * @tparam Value A static constant.
  7918. */
  7919. template<auto Value>
  7920. using integral_constant = std::integral_constant<decltype(Value), Value>;
  7921. /**
  7922. * @brief Alias template to facilitate the creation of named values.
  7923. * @tparam Value A constant value at least convertible to `id_type`.
  7924. */
  7925. template<id_type Value>
  7926. using tag = integral_constant<Value>;
  7927. /**
  7928. * @brief A class to use to push around lists of types, nothing more.
  7929. * @tparam Type Types provided by the type list.
  7930. */
  7931. template<typename... Type>
  7932. struct type_list {
  7933. /*! @brief Type list type. */
  7934. using type = type_list;
  7935. /*! @brief Compile-time number of elements in the type list. */
  7936. static constexpr auto size = sizeof...(Type);
  7937. };
  7938. /*! @brief Primary template isn't defined on purpose. */
  7939. template<std::size_t, typename>
  7940. struct type_list_element;
  7941. /**
  7942. * @brief Provides compile-time indexed access to the types of a type list.
  7943. * @tparam Index Index of the type to return.
  7944. * @tparam Type First type provided by the type list.
  7945. * @tparam Other Other types provided by the type list.
  7946. */
  7947. template<std::size_t Index, typename Type, typename... Other>
  7948. struct type_list_element<Index, type_list<Type, Other...>>
  7949. : type_list_element<Index - 1u, type_list<Other...>> {};
  7950. /**
  7951. * @brief Provides compile-time indexed access to the types of a type list.
  7952. * @tparam Type First type provided by the type list.
  7953. * @tparam Other Other types provided by the type list.
  7954. */
  7955. template<typename Type, typename... Other>
  7956. struct type_list_element<0u, type_list<Type, Other...>> {
  7957. /*! @brief Searched type. */
  7958. using type = Type;
  7959. };
  7960. /**
  7961. * @brief Helper type.
  7962. * @tparam Index Index of the type to return.
  7963. * @tparam List Type list to search into.
  7964. */
  7965. template<std::size_t Index, typename List>
  7966. using type_list_element_t = typename type_list_element<Index, List>::type;
  7967. /**
  7968. * @brief Concatenates multiple type lists.
  7969. * @tparam Type Types provided by the first type list.
  7970. * @tparam Other Types provided by the second type list.
  7971. * @return A type list composed by the types of both the type lists.
  7972. */
  7973. template<typename... Type, typename... Other>
  7974. constexpr type_list<Type..., Other...> operator+(type_list<Type...>, type_list<Other...>) {
  7975. return {};
  7976. }
  7977. /*! @brief Primary template isn't defined on purpose. */
  7978. template<typename...>
  7979. struct type_list_cat;
  7980. /*! @brief Concatenates multiple type lists. */
  7981. template<>
  7982. struct type_list_cat<> {
  7983. /*! @brief A type list composed by the types of all the type lists. */
  7984. using type = type_list<>;
  7985. };
  7986. /**
  7987. * @brief Concatenates multiple type lists.
  7988. * @tparam Type Types provided by the first type list.
  7989. * @tparam Other Types provided by the second type list.
  7990. * @tparam List Other type lists, if any.
  7991. */
  7992. template<typename... Type, typename... Other, typename... List>
  7993. struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
  7994. /*! @brief A type list composed by the types of all the type lists. */
  7995. using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
  7996. };
  7997. /**
  7998. * @brief Concatenates multiple type lists.
  7999. * @tparam Type Types provided by the type list.
  8000. */
  8001. template<typename... Type>
  8002. struct type_list_cat<type_list<Type...>> {
  8003. /*! @brief A type list composed by the types of all the type lists. */
  8004. using type = type_list<Type...>;
  8005. };
  8006. /**
  8007. * @brief Helper type.
  8008. * @tparam List Type lists to concatenate.
  8009. */
  8010. template<typename... List>
  8011. using type_list_cat_t = typename type_list_cat<List...>::type;
  8012. /*! @brief Primary template isn't defined on purpose. */
  8013. template<typename>
  8014. struct type_list_unique;
  8015. /**
  8016. * @brief Removes duplicates types from a type list.
  8017. * @tparam Type One of the types provided by the given type list.
  8018. * @tparam Other The other types provided by the given type list.
  8019. */
  8020. template<typename Type, typename... Other>
  8021. struct type_list_unique<type_list<Type, Other...>> {
  8022. /*! @brief A type list without duplicate types. */
  8023. using type = std::conditional_t<
  8024. (std::is_same_v<Type, Other> || ...),
  8025. typename type_list_unique<type_list<Other...>>::type,
  8026. type_list_cat_t<type_list<Type>, typename type_list_unique<type_list<Other...>>::type>>;
  8027. };
  8028. /*! @brief Removes duplicates types from a type list. */
  8029. template<>
  8030. struct type_list_unique<type_list<>> {
  8031. /*! @brief A type list without duplicate types. */
  8032. using type = type_list<>;
  8033. };
  8034. /**
  8035. * @brief Helper type.
  8036. * @tparam Type A type list.
  8037. */
  8038. template<typename Type>
  8039. using type_list_unique_t = typename type_list_unique<Type>::type;
  8040. /**
  8041. * @brief Provides the member constant `value` to true if a type list contains a
  8042. * given type, false otherwise.
  8043. * @tparam List Type list.
  8044. * @tparam Type Type to look for.
  8045. */
  8046. template<typename List, typename Type>
  8047. struct type_list_contains;
  8048. /**
  8049. * @copybrief type_list_contains
  8050. * @tparam Type Types provided by the type list.
  8051. * @tparam Other Type to look for.
  8052. */
  8053. template<typename... Type, typename Other>
  8054. struct type_list_contains<type_list<Type...>, Other>: std::disjunction<std::is_same<Type, Other>...> {};
  8055. /**
  8056. * @brief Helper variable template.
  8057. * @tparam List Type list.
  8058. * @tparam Type Type to look for.
  8059. */
  8060. template<typename List, typename Type>
  8061. inline constexpr bool type_list_contains_v = type_list_contains<List, Type>::value;
  8062. /*! @brief Primary template isn't defined on purpose. */
  8063. template<typename...>
  8064. struct type_list_diff;
  8065. /**
  8066. * @brief Computes the difference between two type lists.
  8067. * @tparam Type Types provided by the first type list.
  8068. * @tparam Other Types provided by the second type list.
  8069. */
  8070. template<typename... Type, typename... Other>
  8071. struct type_list_diff<type_list<Type...>, type_list<Other...>> {
  8072. /*! @brief A type list that is the difference between the two type lists. */
  8073. using type = type_list_cat_t<std::conditional_t<type_list_contains_v<type_list<Other...>, Type>, type_list<>, type_list<Type>>...>;
  8074. };
  8075. /**
  8076. * @brief Helper type.
  8077. * @tparam List Type lists between which to compute the difference.
  8078. */
  8079. template<typename... List>
  8080. using type_list_diff_t = typename type_list_diff<List...>::type;
  8081. /**
  8082. * @brief A class to use to push around lists of constant values, nothing more.
  8083. * @tparam Value Values provided by the value list.
  8084. */
  8085. template<auto... Value>
  8086. struct value_list {
  8087. /*! @brief Value list type. */
  8088. using type = value_list;
  8089. /*! @brief Compile-time number of elements in the value list. */
  8090. static constexpr auto size = sizeof...(Value);
  8091. };
  8092. /*! @brief Primary template isn't defined on purpose. */
  8093. template<std::size_t, typename>
  8094. struct value_list_element;
  8095. /**
  8096. * @brief Provides compile-time indexed access to the values of a value list.
  8097. * @tparam Index Index of the value to return.
  8098. * @tparam Value First value provided by the value list.
  8099. * @tparam Other Other values provided by the value list.
  8100. */
  8101. template<std::size_t Index, auto Value, auto... Other>
  8102. struct value_list_element<Index, value_list<Value, Other...>>
  8103. : value_list_element<Index - 1u, value_list<Other...>> {};
  8104. /**
  8105. * @brief Provides compile-time indexed access to the types of a type list.
  8106. * @tparam Value First value provided by the value list.
  8107. * @tparam Other Other values provided by the value list.
  8108. */
  8109. template<auto Value, auto... Other>
  8110. struct value_list_element<0u, value_list<Value, Other...>> {
  8111. /*! @brief Searched value. */
  8112. static constexpr auto value = Value;
  8113. };
  8114. /**
  8115. * @brief Helper type.
  8116. * @tparam Index Index of the value to return.
  8117. * @tparam List Value list to search into.
  8118. */
  8119. template<std::size_t Index, typename List>
  8120. inline constexpr auto value_list_element_v = value_list_element<Index, List>::value;
  8121. /**
  8122. * @brief Concatenates multiple value lists.
  8123. * @tparam Value Values provided by the first value list.
  8124. * @tparam Other Values provided by the second value list.
  8125. * @return A value list composed by the values of both the value lists.
  8126. */
  8127. template<auto... Value, auto... Other>
  8128. constexpr value_list<Value..., Other...> operator+(value_list<Value...>, value_list<Other...>) {
  8129. return {};
  8130. }
  8131. /*! @brief Primary template isn't defined on purpose. */
  8132. template<typename...>
  8133. struct value_list_cat;
  8134. /*! @brief Concatenates multiple value lists. */
  8135. template<>
  8136. struct value_list_cat<> {
  8137. /*! @brief A value list composed by the values of all the value lists. */
  8138. using type = value_list<>;
  8139. };
  8140. /**
  8141. * @brief Concatenates multiple value lists.
  8142. * @tparam Value Values provided by the first value list.
  8143. * @tparam Other Values provided by the second value list.
  8144. * @tparam List Other value lists, if any.
  8145. */
  8146. template<auto... Value, auto... Other, typename... List>
  8147. struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
  8148. /*! @brief A value list composed by the values of all the value lists. */
  8149. using type = typename value_list_cat<value_list<Value..., Other...>, List...>::type;
  8150. };
  8151. /**
  8152. * @brief Concatenates multiple value lists.
  8153. * @tparam Value Values provided by the value list.
  8154. */
  8155. template<auto... Value>
  8156. struct value_list_cat<value_list<Value...>> {
  8157. /*! @brief A value list composed by the values of all the value lists. */
  8158. using type = value_list<Value...>;
  8159. };
  8160. /**
  8161. * @brief Helper type.
  8162. * @tparam List Value lists to concatenate.
  8163. */
  8164. template<typename... List>
  8165. using value_list_cat_t = typename value_list_cat<List...>::type;
  8166. /*! @brief Same as std::is_invocable, but with tuples. */
  8167. template<typename, typename>
  8168. struct is_applicable: std::false_type {};
  8169. /**
  8170. * @copybrief is_applicable
  8171. * @tparam Func A valid function type.
  8172. * @tparam Tuple Tuple-like type.
  8173. * @tparam Args The list of arguments to use to probe the function type.
  8174. */
  8175. template<typename Func, template<typename...> class Tuple, typename... Args>
  8176. struct is_applicable<Func, Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  8177. /**
  8178. * @copybrief is_applicable
  8179. * @tparam Func A valid function type.
  8180. * @tparam Tuple Tuple-like type.
  8181. * @tparam Args The list of arguments to use to probe the function type.
  8182. */
  8183. template<typename Func, template<typename...> class Tuple, typename... Args>
  8184. struct is_applicable<Func, const Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  8185. /**
  8186. * @brief Helper variable template.
  8187. * @tparam Func A valid function type.
  8188. * @tparam Args The list of arguments to use to probe the function type.
  8189. */
  8190. template<typename Func, typename Args>
  8191. inline constexpr bool is_applicable_v = is_applicable<Func, Args>::value;
  8192. /*! @brief Same as std::is_invocable_r, but with tuples for arguments. */
  8193. template<typename, typename, typename>
  8194. struct is_applicable_r: std::false_type {};
  8195. /**
  8196. * @copybrief is_applicable_r
  8197. * @tparam Ret The type to which the return type of the function should be
  8198. * convertible.
  8199. * @tparam Func A valid function type.
  8200. * @tparam Args The list of arguments to use to probe the function type.
  8201. */
  8202. template<typename Ret, typename Func, typename... Args>
  8203. struct is_applicable_r<Ret, Func, std::tuple<Args...>>: std::is_invocable_r<Ret, Func, Args...> {};
  8204. /**
  8205. * @brief Helper variable template.
  8206. * @tparam Ret The type to which the return type of the function should be
  8207. * convertible.
  8208. * @tparam Func A valid function type.
  8209. * @tparam Args The list of arguments to use to probe the function type.
  8210. */
  8211. template<typename Ret, typename Func, typename Args>
  8212. inline constexpr bool is_applicable_r_v = is_applicable_r<Ret, Func, Args>::value;
  8213. /**
  8214. * @brief Provides the member constant `value` to true if a given type is
  8215. * complete, false otherwise.
  8216. * @tparam Type The type to test.
  8217. */
  8218. template<typename Type, typename = void>
  8219. struct is_complete: std::false_type {};
  8220. /*! @copydoc is_complete */
  8221. template<typename Type>
  8222. struct is_complete<Type, std::void_t<decltype(sizeof(Type))>>: std::true_type {};
  8223. /**
  8224. * @brief Helper variable template.
  8225. * @tparam Type The type to test.
  8226. */
  8227. template<typename Type>
  8228. inline constexpr bool is_complete_v = is_complete<Type>::value;
  8229. /**
  8230. * @brief Provides the member constant `value` to true if a given type is an
  8231. * iterator, false otherwise.
  8232. * @tparam Type The type to test.
  8233. */
  8234. template<typename Type, typename = void>
  8235. struct is_iterator: std::false_type {};
  8236. /**
  8237. * @cond TURN_OFF_DOXYGEN
  8238. * Internal details not to be documented.
  8239. */
  8240. namespace internal {
  8241. template<typename, typename = void>
  8242. struct has_iterator_category: std::false_type {};
  8243. template<typename Type>
  8244. struct has_iterator_category<Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>: std::true_type {};
  8245. } // namespace internal
  8246. /**
  8247. * Internal details not to be documented.
  8248. * @endcond
  8249. */
  8250. /*! @copydoc is_iterator */
  8251. template<typename Type>
  8252. struct is_iterator<Type, std::enable_if_t<!std::is_same_v<std::remove_const_t<std::remove_pointer_t<Type>>, void>>>
  8253. : internal::has_iterator_category<Type> {};
  8254. /**
  8255. * @brief Helper variable template.
  8256. * @tparam Type The type to test.
  8257. */
  8258. template<typename Type>
  8259. inline constexpr bool is_iterator_v = is_iterator<Type>::value;
  8260. /**
  8261. * @brief Provides the member constant `value` to true if a given type is both
  8262. * an empty and non-final class, false otherwise.
  8263. * @tparam Type The type to test
  8264. */
  8265. template<typename Type>
  8266. struct is_ebco_eligible
  8267. : std::conjunction<std::is_empty<Type>, std::negation<std::is_final<Type>>> {};
  8268. /**
  8269. * @brief Helper variable template.
  8270. * @tparam Type The type to test.
  8271. */
  8272. template<typename Type>
  8273. inline constexpr bool is_ebco_eligible_v = is_ebco_eligible<Type>::value;
  8274. /**
  8275. * @brief Provides the member constant `value` to true if `Type::is_transparent`
  8276. * is valid and denotes a type, false otherwise.
  8277. * @tparam Type The type to test.
  8278. */
  8279. template<typename Type, typename = void>
  8280. struct is_transparent: std::false_type {};
  8281. /*! @copydoc is_transparent */
  8282. template<typename Type>
  8283. struct is_transparent<Type, std::void_t<typename Type::is_transparent>>: std::true_type {};
  8284. /**
  8285. * @brief Helper variable template.
  8286. * @tparam Type The type to test.
  8287. */
  8288. template<typename Type>
  8289. inline constexpr bool is_transparent_v = is_transparent<Type>::value;
  8290. /**
  8291. * @brief Provides the member constant `value` to true if a given type is
  8292. * equality comparable, false otherwise.
  8293. * @tparam Type The type to test.
  8294. */
  8295. template<typename Type, typename = void>
  8296. struct is_equality_comparable: std::false_type {};
  8297. /**
  8298. * @cond TURN_OFF_DOXYGEN
  8299. * Internal details not to be documented.
  8300. */
  8301. namespace internal {
  8302. template<typename, typename = void>
  8303. struct has_tuple_size_value: std::false_type {};
  8304. template<typename Type>
  8305. struct has_tuple_size_value<Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>: std::true_type {};
  8306. template<typename Type, std::size_t... Index>
  8307. [[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
  8308. return (is_equality_comparable<std::tuple_element_t<Index, Type>>::value && ...);
  8309. }
  8310. template<typename>
  8311. [[nodiscard]] constexpr bool maybe_equality_comparable(choice_t<0>) {
  8312. return true;
  8313. }
  8314. template<typename Type>
  8315. [[nodiscard]] constexpr auto maybe_equality_comparable(choice_t<1>) -> decltype(std::declval<typename Type::value_type>(), bool{}) {
  8316. if constexpr(is_iterator_v<Type>) {
  8317. return true;
  8318. } else if constexpr(std::is_same_v<typename Type::value_type, Type>) {
  8319. return maybe_equality_comparable<Type>(choice<0>);
  8320. } else {
  8321. return is_equality_comparable<typename Type::value_type>::value;
  8322. }
  8323. }
  8324. template<typename Type>
  8325. [[nodiscard]] constexpr std::enable_if_t<is_complete_v<std::tuple_size<std::remove_const_t<Type>>>, bool> maybe_equality_comparable(choice_t<2>) {
  8326. if constexpr(has_tuple_size_value<Type>::value) {
  8327. return unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
  8328. } else {
  8329. return maybe_equality_comparable<Type>(choice<1>);
  8330. }
  8331. }
  8332. } // namespace internal
  8333. /**
  8334. * Internal details not to be documented.
  8335. * @endcond
  8336. */
  8337. /*! @copydoc is_equality_comparable */
  8338. template<typename Type>
  8339. struct is_equality_comparable<Type, std::void_t<decltype(std::declval<Type>() == std::declval<Type>())>>
  8340. : std::bool_constant<internal::maybe_equality_comparable<Type>(choice<2>)> {};
  8341. /**
  8342. * @brief Helper variable template.
  8343. * @tparam Type The type to test.
  8344. */
  8345. template<typename Type>
  8346. inline constexpr bool is_equality_comparable_v = is_equality_comparable<Type>::value;
  8347. /**
  8348. * @brief Transcribes the constness of a type to another type.
  8349. * @tparam To The type to which to transcribe the constness.
  8350. * @tparam From The type from which to transcribe the constness.
  8351. */
  8352. template<typename To, typename From>
  8353. struct constness_as {
  8354. /*! @brief The type resulting from the transcription of the constness. */
  8355. using type = std::remove_const_t<To>;
  8356. };
  8357. /*! @copydoc constness_as */
  8358. template<typename To, typename From>
  8359. struct constness_as<To, const From> {
  8360. /*! @brief The type resulting from the transcription of the constness. */
  8361. using type = std::add_const_t<To>;
  8362. };
  8363. /**
  8364. * @brief Alias template to facilitate the transcription of the constness.
  8365. * @tparam To The type to which to transcribe the constness.
  8366. * @tparam From The type from which to transcribe the constness.
  8367. */
  8368. template<typename To, typename From>
  8369. using constness_as_t = typename constness_as<To, From>::type;
  8370. /**
  8371. * @brief Extracts the class of a non-static member object or function.
  8372. * @tparam Member A pointer to a non-static member object or function.
  8373. */
  8374. template<typename Member>
  8375. class member_class {
  8376. static_assert(std::is_member_pointer_v<Member>, "Invalid pointer type to non-static member object or function");
  8377. template<typename Class, typename Ret, typename... Args>
  8378. static Class *clazz(Ret (Class::*)(Args...));
  8379. template<typename Class, typename Ret, typename... Args>
  8380. static Class *clazz(Ret (Class::*)(Args...) const);
  8381. template<typename Class, typename Type>
  8382. static Class *clazz(Type Class::*);
  8383. public:
  8384. /*! @brief The class of the given non-static member object or function. */
  8385. using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
  8386. };
  8387. /**
  8388. * @brief Helper type.
  8389. * @tparam Member A pointer to a non-static member object or function.
  8390. */
  8391. template<typename Member>
  8392. using member_class_t = typename member_class<Member>::type;
  8393. } // namespace entt
  8394. #endif
  8395. namespace entt {
  8396. /**
  8397. * @brief Alias for exclusion lists.
  8398. * @tparam Type List of types.
  8399. */
  8400. template<typename... Type>
  8401. struct exclude_t: type_list<Type...> {};
  8402. /**
  8403. * @brief Variable template for exclusion lists.
  8404. * @tparam Type List of types.
  8405. */
  8406. template<typename... Type>
  8407. inline constexpr exclude_t<Type...> exclude{};
  8408. /**
  8409. * @brief Alias for lists of observed components.
  8410. * @tparam Type List of types.
  8411. */
  8412. template<typename... Type>
  8413. struct get_t: type_list<Type...> {};
  8414. /**
  8415. * @brief Variable template for lists of observed components.
  8416. * @tparam Type List of types.
  8417. */
  8418. template<typename... Type>
  8419. inline constexpr get_t<Type...> get{};
  8420. /**
  8421. * @brief Alias for lists of owned components.
  8422. * @tparam Type List of types.
  8423. */
  8424. template<typename... Type>
  8425. struct owned_t: type_list<Type...> {};
  8426. /**
  8427. * @brief Variable template for lists of owned components.
  8428. * @tparam Type List of types.
  8429. */
  8430. template<typename... Type>
  8431. inline constexpr owned_t<Type...> owned{};
  8432. } // namespace entt
  8433. #endif
  8434. namespace entt {
  8435. template<typename Entity, typename = std::allocator<Entity>>
  8436. class basic_sparse_set;
  8437. template<typename, typename Type, typename = std::allocator<Type>, typename = void>
  8438. class basic_storage;
  8439. template<typename>
  8440. class basic_registry;
  8441. template<typename, typename, typename, typename = void>
  8442. class basic_view;
  8443. template<typename>
  8444. struct basic_runtime_view;
  8445. template<typename, typename, typename, typename>
  8446. class basic_group;
  8447. template<typename>
  8448. class basic_observer;
  8449. template<typename>
  8450. class basic_organizer;
  8451. template<typename, typename...>
  8452. struct basic_handle;
  8453. template<typename>
  8454. class basic_snapshot;
  8455. template<typename>
  8456. class basic_snapshot_loader;
  8457. template<typename>
  8458. class basic_continuous_loader;
  8459. /*! @brief Default entity identifier. */
  8460. enum class entity : id_type {};
  8461. /*! @brief Alias declaration for the most common use case. */
  8462. using sparse_set = basic_sparse_set<entity>;
  8463. /**
  8464. * @brief Alias declaration for the most common use case.
  8465. * @tparam Args Other template parameters.
  8466. */
  8467. template<typename... Args>
  8468. using storage = basic_storage<entity, Args...>;
  8469. /*! @brief Alias declaration for the most common use case. */
  8470. using registry = basic_registry<entity>;
  8471. /*! @brief Alias declaration for the most common use case. */
  8472. using observer = basic_observer<entity>;
  8473. /*! @brief Alias declaration for the most common use case. */
  8474. using organizer = basic_organizer<entity>;
  8475. /*! @brief Alias declaration for the most common use case. */
  8476. using handle = basic_handle<entity>;
  8477. /*! @brief Alias declaration for the most common use case. */
  8478. using const_handle = basic_handle<const entity>;
  8479. /**
  8480. * @brief Alias declaration for the most common use case.
  8481. * @tparam Args Other template parameters.
  8482. */
  8483. template<typename... Args>
  8484. using handle_view = basic_handle<entity, Args...>;
  8485. /**
  8486. * @brief Alias declaration for the most common use case.
  8487. * @tparam Args Other template parameters.
  8488. */
  8489. template<typename... Args>
  8490. using const_handle_view = basic_handle<const entity, Args...>;
  8491. /*! @brief Alias declaration for the most common use case. */
  8492. using snapshot = basic_snapshot<entity>;
  8493. /*! @brief Alias declaration for the most common use case. */
  8494. using snapshot_loader = basic_snapshot_loader<entity>;
  8495. /*! @brief Alias declaration for the most common use case. */
  8496. using continuous_loader = basic_continuous_loader<entity>;
  8497. /**
  8498. * @brief Alias declaration for the most common use case.
  8499. * @tparam Get Types of components iterated by the view.
  8500. * @tparam Exclude Types of components used to filter the view.
  8501. */
  8502. template<typename Get, typename Exclude = exclude_t<>>
  8503. using view = basic_view<entity, Get, Exclude>;
  8504. /*! @brief Alias declaration for the most common use case. */
  8505. using runtime_view = basic_runtime_view<sparse_set>;
  8506. /**
  8507. * @brief Alias declaration for the most common use case.
  8508. * @tparam Args Other template parameters.
  8509. */
  8510. template<typename... Args>
  8511. using group = basic_group<entity, Args...>;
  8512. } // namespace entt
  8513. #endif
  8514. namespace entt {
  8515. /**
  8516. * @cond TURN_OFF_DOXYGEN
  8517. * Internal details not to be documented.
  8518. */
  8519. namespace internal {
  8520. template<typename, typename = void>
  8521. struct entt_traits;
  8522. template<typename Type>
  8523. struct entt_traits<Type, std::enable_if_t<std::is_enum_v<Type>>>
  8524. : entt_traits<std::underlying_type_t<Type>> {};
  8525. template<typename Type>
  8526. struct entt_traits<Type, std::enable_if_t<std::is_class_v<Type>>>
  8527. : entt_traits<typename Type::entity_type> {};
  8528. template<>
  8529. struct entt_traits<std::uint32_t> {
  8530. using entity_type = std::uint32_t;
  8531. using version_type = std::uint16_t;
  8532. static constexpr entity_type entity_mask = 0xFFFFF;
  8533. static constexpr entity_type version_mask = 0xFFF;
  8534. static constexpr std::size_t entity_shift = 20u;
  8535. };
  8536. template<>
  8537. struct entt_traits<std::uint64_t> {
  8538. using entity_type = std::uint64_t;
  8539. using version_type = std::uint32_t;
  8540. static constexpr entity_type entity_mask = 0xFFFFFFFF;
  8541. static constexpr entity_type version_mask = 0xFFFFFFFF;
  8542. static constexpr std::size_t entity_shift = 32u;
  8543. };
  8544. } // namespace internal
  8545. /**
  8546. * Internal details not to be documented.
  8547. * @endcond
  8548. */
  8549. /**
  8550. * @brief Entity traits.
  8551. * @tparam Type Type of identifier.
  8552. */
  8553. template<typename Type>
  8554. class entt_traits: internal::entt_traits<Type> {
  8555. using base_type = internal::entt_traits<Type>;
  8556. public:
  8557. /*! @brief Value type. */
  8558. using value_type = Type;
  8559. /*! @brief Underlying entity type. */
  8560. using entity_type = typename base_type::entity_type;
  8561. /*! @brief Underlying version type. */
  8562. using version_type = typename base_type::version_type;
  8563. /*! @brief Reserved identifier. */
  8564. static constexpr entity_type reserved = base_type::entity_mask | (base_type::version_mask << base_type::entity_shift);
  8565. /*! @brief Page size, default is `ENTT_SPARSE_PAGE`. */
  8566. static constexpr auto page_size = ENTT_SPARSE_PAGE;
  8567. /**
  8568. * @brief Converts an entity to its underlying type.
  8569. * @param value The value to convert.
  8570. * @return The integral representation of the given value.
  8571. */
  8572. [[nodiscard]] static constexpr entity_type to_integral(const value_type value) ENTT_NOEXCEPT {
  8573. return static_cast<entity_type>(value);
  8574. }
  8575. /**
  8576. * @brief Returns the entity part once converted to the underlying type.
  8577. * @param value The value to convert.
  8578. * @return The integral representation of the entity part.
  8579. */
  8580. [[nodiscard]] static constexpr entity_type to_entity(const value_type value) ENTT_NOEXCEPT {
  8581. return (to_integral(value) & base_type::entity_mask);
  8582. }
  8583. /**
  8584. * @brief Returns the version part once converted to the underlying type.
  8585. * @param value The value to convert.
  8586. * @return The integral representation of the version part.
  8587. */
  8588. [[nodiscard]] static constexpr version_type to_version(const value_type value) ENTT_NOEXCEPT {
  8589. return (to_integral(value) >> base_type::entity_shift);
  8590. }
  8591. /**
  8592. * @brief Constructs an identifier from its parts.
  8593. *
  8594. * If the version part is not provided, a tombstone is returned.<br/>
  8595. * If the entity part is not provided, a null identifier is returned.
  8596. *
  8597. * @param entity The entity part of the identifier.
  8598. * @param version The version part of the identifier.
  8599. * @return A properly constructed identifier.
  8600. */
  8601. [[nodiscard]] static constexpr value_type construct(const entity_type entity, const version_type version) ENTT_NOEXCEPT {
  8602. return value_type{(entity & base_type::entity_mask) | (static_cast<entity_type>(version) << base_type::entity_shift)};
  8603. }
  8604. /**
  8605. * @brief Combines two identifiers in a single one.
  8606. *
  8607. * The returned identifier is a copy of the first element except for its
  8608. * version, which is taken from the second element.
  8609. *
  8610. * @param lhs The identifier from which to take the entity part.
  8611. * @param rhs The identifier from which to take the version part.
  8612. * @return A properly constructed identifier.
  8613. */
  8614. [[nodiscard]] static constexpr value_type combine(const entity_type lhs, const entity_type rhs) ENTT_NOEXCEPT {
  8615. constexpr auto mask = (base_type::version_mask << base_type::entity_shift);
  8616. return value_type{(lhs & base_type::entity_mask) | (rhs & mask)};
  8617. }
  8618. };
  8619. /**
  8620. * @copydoc entt_traits<Entity>::to_integral
  8621. * @tparam Entity The value type.
  8622. */
  8623. template<typename Entity>
  8624. [[nodiscard]] constexpr typename entt_traits<Entity>::entity_type to_integral(const Entity value) ENTT_NOEXCEPT {
  8625. return entt_traits<Entity>::to_integral(value);
  8626. }
  8627. /**
  8628. * @copydoc entt_traits<Entity>::to_entity
  8629. * @tparam Entity The value type.
  8630. */
  8631. template<typename Entity>
  8632. [[nodiscard]] constexpr typename entt_traits<Entity>::entity_type to_entity(const Entity value) ENTT_NOEXCEPT {
  8633. return entt_traits<Entity>::to_entity(value);
  8634. }
  8635. /**
  8636. * @copydoc entt_traits<Entity>::to_version
  8637. * @tparam Entity The value type.
  8638. */
  8639. template<typename Entity>
  8640. [[nodiscard]] constexpr typename entt_traits<Entity>::version_type to_version(const Entity value) ENTT_NOEXCEPT {
  8641. return entt_traits<Entity>::to_version(value);
  8642. }
  8643. /*! @brief Null object for all identifiers. */
  8644. struct null_t {
  8645. /**
  8646. * @brief Converts the null object to identifiers of any type.
  8647. * @tparam Entity Type of identifier.
  8648. * @return The null representation for the given type.
  8649. */
  8650. template<typename Entity>
  8651. [[nodiscard]] constexpr operator Entity() const ENTT_NOEXCEPT {
  8652. using entity_traits = entt_traits<Entity>;
  8653. return entity_traits::combine(entity_traits::reserved, entity_traits::reserved);
  8654. }
  8655. /**
  8656. * @brief Compares two null objects.
  8657. * @param other A null object.
  8658. * @return True in all cases.
  8659. */
  8660. [[nodiscard]] constexpr bool operator==([[maybe_unused]] const null_t other) const ENTT_NOEXCEPT {
  8661. return true;
  8662. }
  8663. /**
  8664. * @brief Compares two null objects.
  8665. * @param other A null object.
  8666. * @return False in all cases.
  8667. */
  8668. [[nodiscard]] constexpr bool operator!=([[maybe_unused]] const null_t other) const ENTT_NOEXCEPT {
  8669. return false;
  8670. }
  8671. /**
  8672. * @brief Compares a null object and an identifier of any type.
  8673. * @tparam Entity Type of identifier.
  8674. * @param entity Identifier with which to compare.
  8675. * @return False if the two elements differ, true otherwise.
  8676. */
  8677. template<typename Entity>
  8678. [[nodiscard]] constexpr bool operator==(const Entity entity) const ENTT_NOEXCEPT {
  8679. using entity_traits = entt_traits<Entity>;
  8680. return entity_traits::to_entity(entity) == entity_traits::to_entity(*this);
  8681. }
  8682. /**
  8683. * @brief Compares a null object and an identifier of any type.
  8684. * @tparam Entity Type of identifier.
  8685. * @param entity Identifier with which to compare.
  8686. * @return True if the two elements differ, false otherwise.
  8687. */
  8688. template<typename Entity>
  8689. [[nodiscard]] constexpr bool operator!=(const Entity entity) const ENTT_NOEXCEPT {
  8690. return !(entity == *this);
  8691. }
  8692. };
  8693. /**
  8694. * @brief Compares a null object and an identifier of any type.
  8695. * @tparam Entity Type of identifier.
  8696. * @param entity Identifier with which to compare.
  8697. * @param other A null object yet to be converted.
  8698. * @return False if the two elements differ, true otherwise.
  8699. */
  8700. template<typename Entity>
  8701. [[nodiscard]] constexpr bool operator==(const Entity entity, const null_t other) ENTT_NOEXCEPT {
  8702. return other.operator==(entity);
  8703. }
  8704. /**
  8705. * @brief Compares a null object and an identifier of any type.
  8706. * @tparam Entity Type of identifier.
  8707. * @param entity Identifier with which to compare.
  8708. * @param other A null object yet to be converted.
  8709. * @return True if the two elements differ, false otherwise.
  8710. */
  8711. template<typename Entity>
  8712. [[nodiscard]] constexpr bool operator!=(const Entity entity, const null_t other) ENTT_NOEXCEPT {
  8713. return !(other == entity);
  8714. }
  8715. /*! @brief Tombstone object for all identifiers. */
  8716. struct tombstone_t {
  8717. /**
  8718. * @brief Converts the tombstone object to identifiers of any type.
  8719. * @tparam Entity Type of identifier.
  8720. * @return The tombstone representation for the given type.
  8721. */
  8722. template<typename Entity>
  8723. [[nodiscard]] constexpr operator Entity() const ENTT_NOEXCEPT {
  8724. using entity_traits = entt_traits<Entity>;
  8725. return entity_traits::combine(entity_traits::reserved, entity_traits::reserved);
  8726. }
  8727. /**
  8728. * @brief Compares two tombstone objects.
  8729. * @param other A tombstone object.
  8730. * @return True in all cases.
  8731. */
  8732. [[nodiscard]] constexpr bool operator==([[maybe_unused]] const tombstone_t other) const ENTT_NOEXCEPT {
  8733. return true;
  8734. }
  8735. /**
  8736. * @brief Compares two tombstone objects.
  8737. * @param other A tombstone object.
  8738. * @return False in all cases.
  8739. */
  8740. [[nodiscard]] constexpr bool operator!=([[maybe_unused]] const tombstone_t other) const ENTT_NOEXCEPT {
  8741. return false;
  8742. }
  8743. /**
  8744. * @brief Compares a tombstone object and an identifier of any type.
  8745. * @tparam Entity Type of identifier.
  8746. * @param entity Identifier with which to compare.
  8747. * @return False if the two elements differ, true otherwise.
  8748. */
  8749. template<typename Entity>
  8750. [[nodiscard]] constexpr bool operator==(const Entity entity) const ENTT_NOEXCEPT {
  8751. using entity_traits = entt_traits<Entity>;
  8752. return entity_traits::to_version(entity) == entity_traits::to_version(*this);
  8753. }
  8754. /**
  8755. * @brief Compares a tombstone object and an identifier of any type.
  8756. * @tparam Entity Type of identifier.
  8757. * @param entity Identifier with which to compare.
  8758. * @return True if the two elements differ, false otherwise.
  8759. */
  8760. template<typename Entity>
  8761. [[nodiscard]] constexpr bool operator!=(const Entity entity) const ENTT_NOEXCEPT {
  8762. return !(entity == *this);
  8763. }
  8764. };
  8765. /**
  8766. * @brief Compares a tombstone object and an identifier of any type.
  8767. * @tparam Entity Type of identifier.
  8768. * @param entity Identifier with which to compare.
  8769. * @param other A tombstone object yet to be converted.
  8770. * @return False if the two elements differ, true otherwise.
  8771. */
  8772. template<typename Entity>
  8773. [[nodiscard]] constexpr bool operator==(const Entity entity, const tombstone_t other) ENTT_NOEXCEPT {
  8774. return other.operator==(entity);
  8775. }
  8776. /**
  8777. * @brief Compares a tombstone object and an identifier of any type.
  8778. * @tparam Entity Type of identifier.
  8779. * @param entity Identifier with which to compare.
  8780. * @param other A tombstone object yet to be converted.
  8781. * @return True if the two elements differ, false otherwise.
  8782. */
  8783. template<typename Entity>
  8784. [[nodiscard]] constexpr bool operator!=(const Entity entity, const tombstone_t other) ENTT_NOEXCEPT {
  8785. return !(other == entity);
  8786. }
  8787. /**
  8788. * @brief Compile-time constant for null entities.
  8789. *
  8790. * There exist implicit conversions from this variable to identifiers of any
  8791. * allowed type. Similarly, there exist comparison operators between the null
  8792. * entity and any other identifier.
  8793. */
  8794. inline constexpr null_t null{};
  8795. /**
  8796. * @brief Compile-time constant for tombstone entities.
  8797. *
  8798. * There exist implicit conversions from this variable to identifiers of any
  8799. * allowed type. Similarly, there exist comparison operators between the
  8800. * tombstone entity and any other identifier.
  8801. */
  8802. inline constexpr tombstone_t tombstone{};
  8803. } // namespace entt
  8804. #endif
  8805. // #include "entity/group.hpp"
  8806. #ifndef ENTT_ENTITY_GROUP_HPP
  8807. #define ENTT_ENTITY_GROUP_HPP
  8808. #include <tuple>
  8809. #include <type_traits>
  8810. #include <utility>
  8811. // #include "../config/config.h"
  8812. // #include "../core/iterator.hpp"
  8813. #ifndef ENTT_CORE_ITERATOR_HPP
  8814. #define ENTT_CORE_ITERATOR_HPP
  8815. #include <iterator>
  8816. #include <memory>
  8817. #include <utility>
  8818. // #include "../config/config.h"
  8819. namespace entt {
  8820. /**
  8821. * @brief Helper type to use as pointer with input iterators.
  8822. * @tparam Type of wrapped value.
  8823. */
  8824. template<typename Type>
  8825. struct input_iterator_pointer final {
  8826. /*! @brief Pointer type. */
  8827. using pointer = Type *;
  8828. /*! @brief Default copy constructor, deleted on purpose. */
  8829. input_iterator_pointer(const input_iterator_pointer &) = delete;
  8830. /*! @brief Default move constructor. */
  8831. input_iterator_pointer(input_iterator_pointer &&) = default;
  8832. /**
  8833. * @brief Constructs a proxy object by move.
  8834. * @param val Value to use to initialize the proxy object.
  8835. */
  8836. input_iterator_pointer(Type &&val)
  8837. : value{std::move(val)} {}
  8838. /**
  8839. * @brief Default copy assignment operator, deleted on purpose.
  8840. * @return This proxy object.
  8841. */
  8842. input_iterator_pointer &operator=(const input_iterator_pointer &) = delete;
  8843. /**
  8844. * @brief Default move assignment operator.
  8845. * @return This proxy object.
  8846. */
  8847. input_iterator_pointer &operator=(input_iterator_pointer &&) = default;
  8848. /**
  8849. * @brief Access operator for accessing wrapped values.
  8850. * @return A pointer to the wrapped value.
  8851. */
  8852. [[nodiscard]] pointer operator->() ENTT_NOEXCEPT {
  8853. return std::addressof(value);
  8854. }
  8855. private:
  8856. Type value;
  8857. };
  8858. /**
  8859. * @brief Utility class to create an iterable object from a pair of iterators.
  8860. * @tparam It Type of iterator.
  8861. * @tparam Sentinel Type of sentinel.
  8862. */
  8863. template<typename It, typename Sentinel = It>
  8864. struct iterable_adaptor final {
  8865. /*! @brief Value type. */
  8866. using value_type = typename std::iterator_traits<It>::value_type;
  8867. /*! @brief Iterator type. */
  8868. using iterator = It;
  8869. /*! @brief Sentinel type. */
  8870. using sentinel = Sentinel;
  8871. /*! @brief Default constructor. */
  8872. iterable_adaptor() = default;
  8873. /**
  8874. * @brief Creates an iterable object from a pair of iterators.
  8875. * @param from Begin iterator.
  8876. * @param to End iterator.
  8877. */
  8878. iterable_adaptor(iterator from, sentinel to)
  8879. : first{from},
  8880. last{to} {}
  8881. /**
  8882. * @brief Returns an iterator to the beginning.
  8883. * @return An iterator to the first element of the range.
  8884. */
  8885. [[nodiscard]] iterator begin() const ENTT_NOEXCEPT {
  8886. return first;
  8887. }
  8888. /**
  8889. * @brief Returns an iterator to the end.
  8890. * @return An iterator to the element following the last element of the
  8891. * range.
  8892. */
  8893. [[nodiscard]] sentinel end() const ENTT_NOEXCEPT {
  8894. return last;
  8895. }
  8896. /*! @copydoc begin */
  8897. [[nodiscard]] iterator cbegin() const ENTT_NOEXCEPT {
  8898. return begin();
  8899. }
  8900. /*! @copydoc end */
  8901. [[nodiscard]] sentinel cend() const ENTT_NOEXCEPT {
  8902. return end();
  8903. }
  8904. private:
  8905. It first;
  8906. Sentinel last;
  8907. };
  8908. } // namespace entt
  8909. #endif
  8910. // #include "../core/type_traits.hpp"
  8911. // #include "component.hpp"
  8912. #ifndef ENTT_ENTITY_COMPONENT_HPP
  8913. #define ENTT_ENTITY_COMPONENT_HPP
  8914. #include <cstddef>
  8915. #include <type_traits>
  8916. // #include "../config/config.h"
  8917. namespace entt {
  8918. /**
  8919. * @cond TURN_OFF_DOXYGEN
  8920. * Internal details not to be documented.
  8921. */
  8922. namespace internal {
  8923. template<typename, typename = void>
  8924. struct in_place_delete: std::false_type {};
  8925. template<typename Type>
  8926. struct in_place_delete<Type, std::enable_if_t<Type::in_place_delete>>
  8927. : std::true_type {};
  8928. template<typename Type, typename = void>
  8929. struct page_size: std::integral_constant<std::size_t, (ENTT_IGNORE_IF_EMPTY && std::is_empty_v<Type>) ? 0u : ENTT_PACKED_PAGE> {};
  8930. template<typename Type>
  8931. struct page_size<Type, std::enable_if_t<std::is_convertible_v<decltype(Type::page_size), std::size_t>>>
  8932. : std::integral_constant<std::size_t, Type::page_size> {};
  8933. } // namespace internal
  8934. /**
  8935. * Internal details not to be documented.
  8936. * @endcond
  8937. */
  8938. /**
  8939. * @brief Common way to access various properties of components.
  8940. * @tparam Type Type of component.
  8941. */
  8942. template<typename Type, typename = void>
  8943. struct component_traits {
  8944. static_assert(std::is_same_v<std::decay_t<Type>, Type>, "Unsupported type");
  8945. /*! @brief Pointer stability, default is `false`. */
  8946. static constexpr bool in_place_delete = internal::in_place_delete<Type>::value;
  8947. /*! @brief Page size, default is `ENTT_PACKED_PAGE` for non-empty types. */
  8948. static constexpr std::size_t page_size = internal::page_size<Type>::value;
  8949. };
  8950. /**
  8951. * @brief Helper variable template.
  8952. * @tparam Type Type of component.
  8953. */
  8954. template<class Type>
  8955. inline constexpr bool ignore_as_empty_v = (component_traits<Type>::page_size == 0u);
  8956. } // namespace entt
  8957. #endif
  8958. // #include "entity.hpp"
  8959. #ifndef ENTT_ENTITY_ENTITY_HPP
  8960. #define ENTT_ENTITY_ENTITY_HPP
  8961. #include <cstddef>
  8962. #include <cstdint>
  8963. #include <type_traits>
  8964. // #include "../config/config.h"
  8965. // #include "fwd.hpp"
  8966. namespace entt {
  8967. /**
  8968. * @cond TURN_OFF_DOXYGEN
  8969. * Internal details not to be documented.
  8970. */
  8971. namespace internal {
  8972. template<typename, typename = void>
  8973. struct entt_traits;
  8974. template<typename Type>
  8975. struct entt_traits<Type, std::enable_if_t<std::is_enum_v<Type>>>
  8976. : entt_traits<std::underlying_type_t<Type>> {};
  8977. template<typename Type>
  8978. struct entt_traits<Type, std::enable_if_t<std::is_class_v<Type>>>
  8979. : entt_traits<typename Type::entity_type> {};
  8980. template<>
  8981. struct entt_traits<std::uint32_t> {
  8982. using entity_type = std::uint32_t;
  8983. using version_type = std::uint16_t;
  8984. static constexpr entity_type entity_mask = 0xFFFFF;
  8985. static constexpr entity_type version_mask = 0xFFF;
  8986. static constexpr std::size_t entity_shift = 20u;
  8987. };
  8988. template<>
  8989. struct entt_traits<std::uint64_t> {
  8990. using entity_type = std::uint64_t;
  8991. using version_type = std::uint32_t;
  8992. static constexpr entity_type entity_mask = 0xFFFFFFFF;
  8993. static constexpr entity_type version_mask = 0xFFFFFFFF;
  8994. static constexpr std::size_t entity_shift = 32u;
  8995. };
  8996. } // namespace internal
  8997. /**
  8998. * Internal details not to be documented.
  8999. * @endcond
  9000. */
  9001. /**
  9002. * @brief Entity traits.
  9003. * @tparam Type Type of identifier.
  9004. */
  9005. template<typename Type>
  9006. class entt_traits: internal::entt_traits<Type> {
  9007. using base_type = internal::entt_traits<Type>;
  9008. public:
  9009. /*! @brief Value type. */
  9010. using value_type = Type;
  9011. /*! @brief Underlying entity type. */
  9012. using entity_type = typename base_type::entity_type;
  9013. /*! @brief Underlying version type. */
  9014. using version_type = typename base_type::version_type;
  9015. /*! @brief Reserved identifier. */
  9016. static constexpr entity_type reserved = base_type::entity_mask | (base_type::version_mask << base_type::entity_shift);
  9017. /*! @brief Page size, default is `ENTT_SPARSE_PAGE`. */
  9018. static constexpr auto page_size = ENTT_SPARSE_PAGE;
  9019. /**
  9020. * @brief Converts an entity to its underlying type.
  9021. * @param value The value to convert.
  9022. * @return The integral representation of the given value.
  9023. */
  9024. [[nodiscard]] static constexpr entity_type to_integral(const value_type value) ENTT_NOEXCEPT {
  9025. return static_cast<entity_type>(value);
  9026. }
  9027. /**
  9028. * @brief Returns the entity part once converted to the underlying type.
  9029. * @param value The value to convert.
  9030. * @return The integral representation of the entity part.
  9031. */
  9032. [[nodiscard]] static constexpr entity_type to_entity(const value_type value) ENTT_NOEXCEPT {
  9033. return (to_integral(value) & base_type::entity_mask);
  9034. }
  9035. /**
  9036. * @brief Returns the version part once converted to the underlying type.
  9037. * @param value The value to convert.
  9038. * @return The integral representation of the version part.
  9039. */
  9040. [[nodiscard]] static constexpr version_type to_version(const value_type value) ENTT_NOEXCEPT {
  9041. return (to_integral(value) >> base_type::entity_shift);
  9042. }
  9043. /**
  9044. * @brief Constructs an identifier from its parts.
  9045. *
  9046. * If the version part is not provided, a tombstone is returned.<br/>
  9047. * If the entity part is not provided, a null identifier is returned.
  9048. *
  9049. * @param entity The entity part of the identifier.
  9050. * @param version The version part of the identifier.
  9051. * @return A properly constructed identifier.
  9052. */
  9053. [[nodiscard]] static constexpr value_type construct(const entity_type entity, const version_type version) ENTT_NOEXCEPT {
  9054. return value_type{(entity & base_type::entity_mask) | (static_cast<entity_type>(version) << base_type::entity_shift)};
  9055. }
  9056. /**
  9057. * @brief Combines two identifiers in a single one.
  9058. *
  9059. * The returned identifier is a copy of the first element except for its
  9060. * version, which is taken from the second element.
  9061. *
  9062. * @param lhs The identifier from which to take the entity part.
  9063. * @param rhs The identifier from which to take the version part.
  9064. * @return A properly constructed identifier.
  9065. */
  9066. [[nodiscard]] static constexpr value_type combine(const entity_type lhs, const entity_type rhs) ENTT_NOEXCEPT {
  9067. constexpr auto mask = (base_type::version_mask << base_type::entity_shift);
  9068. return value_type{(lhs & base_type::entity_mask) | (rhs & mask)};
  9069. }
  9070. };
  9071. /**
  9072. * @copydoc entt_traits<Entity>::to_integral
  9073. * @tparam Entity The value type.
  9074. */
  9075. template<typename Entity>
  9076. [[nodiscard]] constexpr typename entt_traits<Entity>::entity_type to_integral(const Entity value) ENTT_NOEXCEPT {
  9077. return entt_traits<Entity>::to_integral(value);
  9078. }
  9079. /**
  9080. * @copydoc entt_traits<Entity>::to_entity
  9081. * @tparam Entity The value type.
  9082. */
  9083. template<typename Entity>
  9084. [[nodiscard]] constexpr typename entt_traits<Entity>::entity_type to_entity(const Entity value) ENTT_NOEXCEPT {
  9085. return entt_traits<Entity>::to_entity(value);
  9086. }
  9087. /**
  9088. * @copydoc entt_traits<Entity>::to_version
  9089. * @tparam Entity The value type.
  9090. */
  9091. template<typename Entity>
  9092. [[nodiscard]] constexpr typename entt_traits<Entity>::version_type to_version(const Entity value) ENTT_NOEXCEPT {
  9093. return entt_traits<Entity>::to_version(value);
  9094. }
  9095. /*! @brief Null object for all identifiers. */
  9096. struct null_t {
  9097. /**
  9098. * @brief Converts the null object to identifiers of any type.
  9099. * @tparam Entity Type of identifier.
  9100. * @return The null representation for the given type.
  9101. */
  9102. template<typename Entity>
  9103. [[nodiscard]] constexpr operator Entity() const ENTT_NOEXCEPT {
  9104. using entity_traits = entt_traits<Entity>;
  9105. return entity_traits::combine(entity_traits::reserved, entity_traits::reserved);
  9106. }
  9107. /**
  9108. * @brief Compares two null objects.
  9109. * @param other A null object.
  9110. * @return True in all cases.
  9111. */
  9112. [[nodiscard]] constexpr bool operator==([[maybe_unused]] const null_t other) const ENTT_NOEXCEPT {
  9113. return true;
  9114. }
  9115. /**
  9116. * @brief Compares two null objects.
  9117. * @param other A null object.
  9118. * @return False in all cases.
  9119. */
  9120. [[nodiscard]] constexpr bool operator!=([[maybe_unused]] const null_t other) const ENTT_NOEXCEPT {
  9121. return false;
  9122. }
  9123. /**
  9124. * @brief Compares a null object and an identifier of any type.
  9125. * @tparam Entity Type of identifier.
  9126. * @param entity Identifier with which to compare.
  9127. * @return False if the two elements differ, true otherwise.
  9128. */
  9129. template<typename Entity>
  9130. [[nodiscard]] constexpr bool operator==(const Entity entity) const ENTT_NOEXCEPT {
  9131. using entity_traits = entt_traits<Entity>;
  9132. return entity_traits::to_entity(entity) == entity_traits::to_entity(*this);
  9133. }
  9134. /**
  9135. * @brief Compares a null object and an identifier of any type.
  9136. * @tparam Entity Type of identifier.
  9137. * @param entity Identifier with which to compare.
  9138. * @return True if the two elements differ, false otherwise.
  9139. */
  9140. template<typename Entity>
  9141. [[nodiscard]] constexpr bool operator!=(const Entity entity) const ENTT_NOEXCEPT {
  9142. return !(entity == *this);
  9143. }
  9144. };
  9145. /**
  9146. * @brief Compares a null object and an identifier of any type.
  9147. * @tparam Entity Type of identifier.
  9148. * @param entity Identifier with which to compare.
  9149. * @param other A null object yet to be converted.
  9150. * @return False if the two elements differ, true otherwise.
  9151. */
  9152. template<typename Entity>
  9153. [[nodiscard]] constexpr bool operator==(const Entity entity, const null_t other) ENTT_NOEXCEPT {
  9154. return other.operator==(entity);
  9155. }
  9156. /**
  9157. * @brief Compares a null object and an identifier of any type.
  9158. * @tparam Entity Type of identifier.
  9159. * @param entity Identifier with which to compare.
  9160. * @param other A null object yet to be converted.
  9161. * @return True if the two elements differ, false otherwise.
  9162. */
  9163. template<typename Entity>
  9164. [[nodiscard]] constexpr bool operator!=(const Entity entity, const null_t other) ENTT_NOEXCEPT {
  9165. return !(other == entity);
  9166. }
  9167. /*! @brief Tombstone object for all identifiers. */
  9168. struct tombstone_t {
  9169. /**
  9170. * @brief Converts the tombstone object to identifiers of any type.
  9171. * @tparam Entity Type of identifier.
  9172. * @return The tombstone representation for the given type.
  9173. */
  9174. template<typename Entity>
  9175. [[nodiscard]] constexpr operator Entity() const ENTT_NOEXCEPT {
  9176. using entity_traits = entt_traits<Entity>;
  9177. return entity_traits::combine(entity_traits::reserved, entity_traits::reserved);
  9178. }
  9179. /**
  9180. * @brief Compares two tombstone objects.
  9181. * @param other A tombstone object.
  9182. * @return True in all cases.
  9183. */
  9184. [[nodiscard]] constexpr bool operator==([[maybe_unused]] const tombstone_t other) const ENTT_NOEXCEPT {
  9185. return true;
  9186. }
  9187. /**
  9188. * @brief Compares two tombstone objects.
  9189. * @param other A tombstone object.
  9190. * @return False in all cases.
  9191. */
  9192. [[nodiscard]] constexpr bool operator!=([[maybe_unused]] const tombstone_t other) const ENTT_NOEXCEPT {
  9193. return false;
  9194. }
  9195. /**
  9196. * @brief Compares a tombstone object and an identifier of any type.
  9197. * @tparam Entity Type of identifier.
  9198. * @param entity Identifier with which to compare.
  9199. * @return False if the two elements differ, true otherwise.
  9200. */
  9201. template<typename Entity>
  9202. [[nodiscard]] constexpr bool operator==(const Entity entity) const ENTT_NOEXCEPT {
  9203. using entity_traits = entt_traits<Entity>;
  9204. return entity_traits::to_version(entity) == entity_traits::to_version(*this);
  9205. }
  9206. /**
  9207. * @brief Compares a tombstone object and an identifier of any type.
  9208. * @tparam Entity Type of identifier.
  9209. * @param entity Identifier with which to compare.
  9210. * @return True if the two elements differ, false otherwise.
  9211. */
  9212. template<typename Entity>
  9213. [[nodiscard]] constexpr bool operator!=(const Entity entity) const ENTT_NOEXCEPT {
  9214. return !(entity == *this);
  9215. }
  9216. };
  9217. /**
  9218. * @brief Compares a tombstone object and an identifier of any type.
  9219. * @tparam Entity Type of identifier.
  9220. * @param entity Identifier with which to compare.
  9221. * @param other A tombstone object yet to be converted.
  9222. * @return False if the two elements differ, true otherwise.
  9223. */
  9224. template<typename Entity>
  9225. [[nodiscard]] constexpr bool operator==(const Entity entity, const tombstone_t other) ENTT_NOEXCEPT {
  9226. return other.operator==(entity);
  9227. }
  9228. /**
  9229. * @brief Compares a tombstone object and an identifier of any type.
  9230. * @tparam Entity Type of identifier.
  9231. * @param entity Identifier with which to compare.
  9232. * @param other A tombstone object yet to be converted.
  9233. * @return True if the two elements differ, false otherwise.
  9234. */
  9235. template<typename Entity>
  9236. [[nodiscard]] constexpr bool operator!=(const Entity entity, const tombstone_t other) ENTT_NOEXCEPT {
  9237. return !(other == entity);
  9238. }
  9239. /**
  9240. * @brief Compile-time constant for null entities.
  9241. *
  9242. * There exist implicit conversions from this variable to identifiers of any
  9243. * allowed type. Similarly, there exist comparison operators between the null
  9244. * entity and any other identifier.
  9245. */
  9246. inline constexpr null_t null{};
  9247. /**
  9248. * @brief Compile-time constant for tombstone entities.
  9249. *
  9250. * There exist implicit conversions from this variable to identifiers of any
  9251. * allowed type. Similarly, there exist comparison operators between the
  9252. * tombstone entity and any other identifier.
  9253. */
  9254. inline constexpr tombstone_t tombstone{};
  9255. } // namespace entt
  9256. #endif
  9257. // #include "fwd.hpp"
  9258. // #include "sparse_set.hpp"
  9259. #ifndef ENTT_ENTITY_SPARSE_SET_HPP
  9260. #define ENTT_ENTITY_SPARSE_SET_HPP
  9261. #include <cstddef>
  9262. #include <iterator>
  9263. #include <memory>
  9264. #include <type_traits>
  9265. #include <utility>
  9266. #include <vector>
  9267. // #include "../config/config.h"
  9268. // #include "../core/algorithm.hpp"
  9269. #ifndef ENTT_CORE_ALGORITHM_HPP
  9270. #define ENTT_CORE_ALGORITHM_HPP
  9271. #include <algorithm>
  9272. #include <functional>
  9273. #include <iterator>
  9274. #include <utility>
  9275. #include <vector>
  9276. // #include "utility.hpp"
  9277. #ifndef ENTT_CORE_UTILITY_HPP
  9278. #define ENTT_CORE_UTILITY_HPP
  9279. #include <utility>
  9280. // #include "../config/config.h"
  9281. namespace entt {
  9282. /*! @brief Identity function object (waiting for C++20). */
  9283. struct identity {
  9284. /*! @brief Indicates that this is a transparent function object. */
  9285. using is_transparent = void;
  9286. /**
  9287. * @brief Returns its argument unchanged.
  9288. * @tparam Type Type of the argument.
  9289. * @param value The actual argument.
  9290. * @return The submitted value as-is.
  9291. */
  9292. template<class Type>
  9293. [[nodiscard]] constexpr Type &&operator()(Type &&value) const ENTT_NOEXCEPT {
  9294. return std::forward<Type>(value);
  9295. }
  9296. };
  9297. /**
  9298. * @brief Constant utility to disambiguate overloaded members of a class.
  9299. * @tparam Type Type of the desired overload.
  9300. * @tparam Class Type of class to which the member belongs.
  9301. * @param member A valid pointer to a member.
  9302. * @return Pointer to the member.
  9303. */
  9304. template<typename Type, typename Class>
  9305. [[nodiscard]] constexpr auto overload(Type Class::*member) ENTT_NOEXCEPT {
  9306. return member;
  9307. }
  9308. /**
  9309. * @brief Constant utility to disambiguate overloaded functions.
  9310. * @tparam Func Function type of the desired overload.
  9311. * @param func A valid pointer to a function.
  9312. * @return Pointer to the function.
  9313. */
  9314. template<typename Func>
  9315. [[nodiscard]] constexpr auto overload(Func *func) ENTT_NOEXCEPT {
  9316. return func;
  9317. }
  9318. /**
  9319. * @brief Helper type for visitors.
  9320. * @tparam Func Types of function objects.
  9321. */
  9322. template<class... Func>
  9323. struct overloaded: Func... {
  9324. using Func::operator()...;
  9325. };
  9326. /**
  9327. * @brief Deduction guide.
  9328. * @tparam Func Types of function objects.
  9329. */
  9330. template<class... Func>
  9331. overloaded(Func...) -> overloaded<Func...>;
  9332. /**
  9333. * @brief Basic implementation of a y-combinator.
  9334. * @tparam Func Type of a potentially recursive function.
  9335. */
  9336. template<class Func>
  9337. struct y_combinator {
  9338. /**
  9339. * @brief Constructs a y-combinator from a given function.
  9340. * @param recursive A potentially recursive function.
  9341. */
  9342. y_combinator(Func recursive)
  9343. : func{std::move(recursive)} {}
  9344. /**
  9345. * @brief Invokes a y-combinator and therefore its underlying function.
  9346. * @tparam Args Types of arguments to use to invoke the underlying function.
  9347. * @param args Parameters to use to invoke the underlying function.
  9348. * @return Return value of the underlying function, if any.
  9349. */
  9350. template<class... Args>
  9351. decltype(auto) operator()(Args &&...args) const {
  9352. return func(*this, std::forward<Args>(args)...);
  9353. }
  9354. /*! @copydoc operator()() */
  9355. template<class... Args>
  9356. decltype(auto) operator()(Args &&...args) {
  9357. return func(*this, std::forward<Args>(args)...);
  9358. }
  9359. private:
  9360. Func func;
  9361. };
  9362. } // namespace entt
  9363. #endif
  9364. namespace entt {
  9365. /**
  9366. * @brief Function object to wrap `std::sort` in a class type.
  9367. *
  9368. * Unfortunately, `std::sort` cannot be passed as template argument to a class
  9369. * template or a function template.<br/>
  9370. * This class fills the gap by wrapping some flavors of `std::sort` in a
  9371. * function object.
  9372. */
  9373. struct std_sort {
  9374. /**
  9375. * @brief Sorts the elements in a range.
  9376. *
  9377. * Sorts the elements in a range using the given binary comparison function.
  9378. *
  9379. * @tparam It Type of random access iterator.
  9380. * @tparam Compare Type of comparison function object.
  9381. * @tparam Args Types of arguments to forward to the sort function.
  9382. * @param first An iterator to the first element of the range to sort.
  9383. * @param last An iterator past the last element of the range to sort.
  9384. * @param compare A valid comparison function object.
  9385. * @param args Arguments to forward to the sort function, if any.
  9386. */
  9387. template<typename It, typename Compare = std::less<>, typename... Args>
  9388. void operator()(It first, It last, Compare compare = Compare{}, Args &&...args) const {
  9389. std::sort(std::forward<Args>(args)..., std::move(first), std::move(last), std::move(compare));
  9390. }
  9391. };
  9392. /*! @brief Function object for performing insertion sort. */
  9393. struct insertion_sort {
  9394. /**
  9395. * @brief Sorts the elements in a range.
  9396. *
  9397. * Sorts the elements in a range using the given binary comparison function.
  9398. *
  9399. * @tparam It Type of random access iterator.
  9400. * @tparam Compare Type of comparison function object.
  9401. * @param first An iterator to the first element of the range to sort.
  9402. * @param last An iterator past the last element of the range to sort.
  9403. * @param compare A valid comparison function object.
  9404. */
  9405. template<typename It, typename Compare = std::less<>>
  9406. void operator()(It first, It last, Compare compare = Compare{}) const {
  9407. if(first < last) {
  9408. for(auto it = first + 1; it < last; ++it) {
  9409. auto value = std::move(*it);
  9410. auto pre = it;
  9411. for(; pre > first && compare(value, *(pre - 1)); --pre) {
  9412. *pre = std::move(*(pre - 1));
  9413. }
  9414. *pre = std::move(value);
  9415. }
  9416. }
  9417. }
  9418. };
  9419. /**
  9420. * @brief Function object for performing LSD radix sort.
  9421. * @tparam Bit Number of bits processed per pass.
  9422. * @tparam N Maximum number of bits to sort.
  9423. */
  9424. template<std::size_t Bit, std::size_t N>
  9425. struct radix_sort {
  9426. static_assert((N % Bit) == 0, "The maximum number of bits to sort must be a multiple of the number of bits processed per pass");
  9427. /**
  9428. * @brief Sorts the elements in a range.
  9429. *
  9430. * Sorts the elements in a range using the given _getter_ to access the
  9431. * actual data to be sorted.
  9432. *
  9433. * This implementation is inspired by the online book
  9434. * [Physically Based Rendering](http://www.pbr-book.org/3ed-2018/Primitives_and_Intersection_Acceleration/Bounding_Volume_Hierarchies.html#RadixSort).
  9435. *
  9436. * @tparam It Type of random access iterator.
  9437. * @tparam Getter Type of _getter_ function object.
  9438. * @param first An iterator to the first element of the range to sort.
  9439. * @param last An iterator past the last element of the range to sort.
  9440. * @param getter A valid _getter_ function object.
  9441. */
  9442. template<typename It, typename Getter = identity>
  9443. void operator()(It first, It last, Getter getter = Getter{}) const {
  9444. if(first < last) {
  9445. static constexpr auto mask = (1 << Bit) - 1;
  9446. static constexpr auto buckets = 1 << Bit;
  9447. static constexpr auto passes = N / Bit;
  9448. using value_type = typename std::iterator_traits<It>::value_type;
  9449. std::vector<value_type> aux(std::distance(first, last));
  9450. auto part = [getter = std::move(getter)](auto from, auto to, auto out, auto start) {
  9451. std::size_t index[buckets]{};
  9452. std::size_t count[buckets]{};
  9453. for(auto it = from; it != to; ++it) {
  9454. ++count[(getter(*it) >> start) & mask];
  9455. }
  9456. for(std::size_t pos{}, end = buckets - 1u; pos < end; ++pos) {
  9457. index[pos + 1u] = index[pos] + count[pos];
  9458. }
  9459. for(auto it = from; it != to; ++it) {
  9460. out[index[(getter(*it) >> start) & mask]++] = std::move(*it);
  9461. }
  9462. };
  9463. for(std::size_t pass = 0; pass < (passes & ~1); pass += 2) {
  9464. part(first, last, aux.begin(), pass * Bit);
  9465. part(aux.begin(), aux.end(), first, (pass + 1) * Bit);
  9466. }
  9467. if constexpr(passes & 1) {
  9468. part(first, last, aux.begin(), (passes - 1) * Bit);
  9469. std::move(aux.begin(), aux.end(), first);
  9470. }
  9471. }
  9472. }
  9473. };
  9474. } // namespace entt
  9475. #endif
  9476. // #include "../core/any.hpp"
  9477. #ifndef ENTT_CORE_ANY_HPP
  9478. #define ENTT_CORE_ANY_HPP
  9479. #include <cstddef>
  9480. #include <memory>
  9481. #include <type_traits>
  9482. #include <utility>
  9483. // #include "../config/config.h"
  9484. // #include "../core/utility.hpp"
  9485. #ifndef ENTT_CORE_UTILITY_HPP
  9486. #define ENTT_CORE_UTILITY_HPP
  9487. #include <utility>
  9488. // #include "../config/config.h"
  9489. #ifndef ENTT_CONFIG_CONFIG_H
  9490. #define ENTT_CONFIG_CONFIG_H
  9491. // #include "version.h"
  9492. #ifndef ENTT_CONFIG_VERSION_H
  9493. #define ENTT_CONFIG_VERSION_H
  9494. // #include "macro.h"
  9495. #ifndef ENTT_CONFIG_MACRO_H
  9496. #define ENTT_CONFIG_MACRO_H
  9497. #define ENTT_STR(arg) #arg
  9498. #define ENTT_XSTR(arg) ENTT_STR(arg)
  9499. #endif
  9500. #define ENTT_VERSION_MAJOR 3
  9501. #define ENTT_VERSION_MINOR 10
  9502. #define ENTT_VERSION_PATCH 3
  9503. #define ENTT_VERSION \
  9504. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  9505. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  9506. #endif
  9507. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  9508. # define ENTT_THROW throw
  9509. # define ENTT_TRY try
  9510. # define ENTT_CATCH catch(...)
  9511. #else
  9512. # define ENTT_THROW
  9513. # define ENTT_TRY if(true)
  9514. # define ENTT_CATCH if(false)
  9515. #endif
  9516. #ifndef ENTT_NOEXCEPT
  9517. # define ENTT_NOEXCEPT noexcept
  9518. # define ENTT_NOEXCEPT_IF(expr) noexcept(expr)
  9519. # else
  9520. # define ENTT_NOEXCEPT_IF(...)
  9521. #endif
  9522. #ifdef ENTT_USE_ATOMIC
  9523. # include <atomic>
  9524. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  9525. #else
  9526. # define ENTT_MAYBE_ATOMIC(Type) Type
  9527. #endif
  9528. #ifndef ENTT_ID_TYPE
  9529. # include <cstdint>
  9530. # define ENTT_ID_TYPE std::uint32_t
  9531. #endif
  9532. #ifndef ENTT_SPARSE_PAGE
  9533. # define ENTT_SPARSE_PAGE 4096
  9534. #endif
  9535. #ifndef ENTT_PACKED_PAGE
  9536. # define ENTT_PACKED_PAGE 1024
  9537. #endif
  9538. #ifdef ENTT_DISABLE_ASSERT
  9539. # undef ENTT_ASSERT
  9540. # define ENTT_ASSERT(...) (void(0))
  9541. #elif !defined ENTT_ASSERT
  9542. # include <cassert>
  9543. # define ENTT_ASSERT(condition, ...) assert(condition)
  9544. #endif
  9545. #ifdef ENTT_NO_ETO
  9546. # define ENTT_IGNORE_IF_EMPTY false
  9547. #else
  9548. # define ENTT_IGNORE_IF_EMPTY true
  9549. #endif
  9550. #ifdef ENTT_STANDARD_CPP
  9551. # define ENTT_NONSTD false
  9552. #else
  9553. # define ENTT_NONSTD true
  9554. # if defined __clang__ || defined __GNUC__
  9555. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  9556. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  9557. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  9558. # elif defined _MSC_VER
  9559. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  9560. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  9561. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  9562. # endif
  9563. #endif
  9564. #if defined _MSC_VER
  9565. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  9566. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  9567. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  9568. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  9569. #endif
  9570. #endif
  9571. namespace entt {
  9572. /*! @brief Identity function object (waiting for C++20). */
  9573. struct identity {
  9574. /*! @brief Indicates that this is a transparent function object. */
  9575. using is_transparent = void;
  9576. /**
  9577. * @brief Returns its argument unchanged.
  9578. * @tparam Type Type of the argument.
  9579. * @param value The actual argument.
  9580. * @return The submitted value as-is.
  9581. */
  9582. template<class Type>
  9583. [[nodiscard]] constexpr Type &&operator()(Type &&value) const ENTT_NOEXCEPT {
  9584. return std::forward<Type>(value);
  9585. }
  9586. };
  9587. /**
  9588. * @brief Constant utility to disambiguate overloaded members of a class.
  9589. * @tparam Type Type of the desired overload.
  9590. * @tparam Class Type of class to which the member belongs.
  9591. * @param member A valid pointer to a member.
  9592. * @return Pointer to the member.
  9593. */
  9594. template<typename Type, typename Class>
  9595. [[nodiscard]] constexpr auto overload(Type Class::*member) ENTT_NOEXCEPT {
  9596. return member;
  9597. }
  9598. /**
  9599. * @brief Constant utility to disambiguate overloaded functions.
  9600. * @tparam Func Function type of the desired overload.
  9601. * @param func A valid pointer to a function.
  9602. * @return Pointer to the function.
  9603. */
  9604. template<typename Func>
  9605. [[nodiscard]] constexpr auto overload(Func *func) ENTT_NOEXCEPT {
  9606. return func;
  9607. }
  9608. /**
  9609. * @brief Helper type for visitors.
  9610. * @tparam Func Types of function objects.
  9611. */
  9612. template<class... Func>
  9613. struct overloaded: Func... {
  9614. using Func::operator()...;
  9615. };
  9616. /**
  9617. * @brief Deduction guide.
  9618. * @tparam Func Types of function objects.
  9619. */
  9620. template<class... Func>
  9621. overloaded(Func...) -> overloaded<Func...>;
  9622. /**
  9623. * @brief Basic implementation of a y-combinator.
  9624. * @tparam Func Type of a potentially recursive function.
  9625. */
  9626. template<class Func>
  9627. struct y_combinator {
  9628. /**
  9629. * @brief Constructs a y-combinator from a given function.
  9630. * @param recursive A potentially recursive function.
  9631. */
  9632. y_combinator(Func recursive)
  9633. : func{std::move(recursive)} {}
  9634. /**
  9635. * @brief Invokes a y-combinator and therefore its underlying function.
  9636. * @tparam Args Types of arguments to use to invoke the underlying function.
  9637. * @param args Parameters to use to invoke the underlying function.
  9638. * @return Return value of the underlying function, if any.
  9639. */
  9640. template<class... Args>
  9641. decltype(auto) operator()(Args &&...args) const {
  9642. return func(*this, std::forward<Args>(args)...);
  9643. }
  9644. /*! @copydoc operator()() */
  9645. template<class... Args>
  9646. decltype(auto) operator()(Args &&...args) {
  9647. return func(*this, std::forward<Args>(args)...);
  9648. }
  9649. private:
  9650. Func func;
  9651. };
  9652. } // namespace entt
  9653. #endif
  9654. // #include "fwd.hpp"
  9655. // #include "type_info.hpp"
  9656. #ifndef ENTT_CORE_TYPE_INFO_HPP
  9657. #define ENTT_CORE_TYPE_INFO_HPP
  9658. #include <string_view>
  9659. #include <type_traits>
  9660. #include <utility>
  9661. // #include "../config/config.h"
  9662. // #include "../core/attribute.h"
  9663. #ifndef ENTT_CORE_ATTRIBUTE_H
  9664. #define ENTT_CORE_ATTRIBUTE_H
  9665. #ifndef ENTT_EXPORT
  9666. # if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER
  9667. # define ENTT_EXPORT __declspec(dllexport)
  9668. # define ENTT_IMPORT __declspec(dllimport)
  9669. # define ENTT_HIDDEN
  9670. # elif defined __GNUC__ && __GNUC__ >= 4
  9671. # define ENTT_EXPORT __attribute__((visibility("default")))
  9672. # define ENTT_IMPORT __attribute__((visibility("default")))
  9673. # define ENTT_HIDDEN __attribute__((visibility("hidden")))
  9674. # else /* Unsupported compiler */
  9675. # define ENTT_EXPORT
  9676. # define ENTT_IMPORT
  9677. # define ENTT_HIDDEN
  9678. # endif
  9679. #endif
  9680. #ifndef ENTT_API
  9681. # if defined ENTT_API_EXPORT
  9682. # define ENTT_API ENTT_EXPORT
  9683. # elif defined ENTT_API_IMPORT
  9684. # define ENTT_API ENTT_IMPORT
  9685. # else /* No API */
  9686. # define ENTT_API
  9687. # endif
  9688. #endif
  9689. #endif
  9690. // #include "fwd.hpp"
  9691. // #include "hashed_string.hpp"
  9692. #ifndef ENTT_CORE_HASHED_STRING_HPP
  9693. #define ENTT_CORE_HASHED_STRING_HPP
  9694. #include <cstddef>
  9695. #include <cstdint>
  9696. // #include "../config/config.h"
  9697. // #include "fwd.hpp"
  9698. namespace entt {
  9699. /**
  9700. * @cond TURN_OFF_DOXYGEN
  9701. * Internal details not to be documented.
  9702. */
  9703. namespace internal {
  9704. template<typename>
  9705. struct fnv1a_traits;
  9706. template<>
  9707. struct fnv1a_traits<std::uint32_t> {
  9708. using type = std::uint32_t;
  9709. static constexpr std::uint32_t offset = 2166136261;
  9710. static constexpr std::uint32_t prime = 16777619;
  9711. };
  9712. template<>
  9713. struct fnv1a_traits<std::uint64_t> {
  9714. using type = std::uint64_t;
  9715. static constexpr std::uint64_t offset = 14695981039346656037ull;
  9716. static constexpr std::uint64_t prime = 1099511628211ull;
  9717. };
  9718. template<typename Char>
  9719. struct basic_hashed_string {
  9720. using value_type = Char;
  9721. using size_type = std::size_t;
  9722. using hash_type = id_type;
  9723. const value_type *repr;
  9724. size_type length;
  9725. hash_type hash;
  9726. };
  9727. } // namespace internal
  9728. /**
  9729. * Internal details not to be documented.
  9730. * @endcond
  9731. */
  9732. /**
  9733. * @brief Zero overhead unique identifier.
  9734. *
  9735. * A hashed string is a compile-time tool that allows users to use
  9736. * human-readable identifiers in the codebase while using their numeric
  9737. * counterparts at runtime.<br/>
  9738. * Because of that, a hashed string can also be used in constant expressions if
  9739. * required.
  9740. *
  9741. * @warning
  9742. * This class doesn't take ownership of user-supplied strings nor does it make a
  9743. * copy of them.
  9744. *
  9745. * @tparam Char Character type.
  9746. */
  9747. template<typename Char>
  9748. class basic_hashed_string: internal::basic_hashed_string<Char> {
  9749. using base_type = internal::basic_hashed_string<Char>;
  9750. using hs_traits = internal::fnv1a_traits<id_type>;
  9751. struct const_wrapper {
  9752. // non-explicit constructor on purpose
  9753. constexpr const_wrapper(const Char *str) ENTT_NOEXCEPT: repr{str} {}
  9754. const Char *repr;
  9755. };
  9756. // Fowler–Noll–Vo hash function v. 1a - the good
  9757. [[nodiscard]] static constexpr auto helper(const Char *str) ENTT_NOEXCEPT {
  9758. base_type base{str, 0u, hs_traits::offset};
  9759. for(; str[base.length]; ++base.length) {
  9760. base.hash = (base.hash ^ static_cast<hs_traits::type>(str[base.length])) * hs_traits::prime;
  9761. }
  9762. return base;
  9763. }
  9764. // Fowler–Noll–Vo hash function v. 1a - the good
  9765. [[nodiscard]] static constexpr auto helper(const Char *str, const std::size_t len) ENTT_NOEXCEPT {
  9766. base_type base{str, len, hs_traits::offset};
  9767. for(size_type pos{}; pos < len; ++pos) {
  9768. base.hash = (base.hash ^ static_cast<hs_traits::type>(str[pos])) * hs_traits::prime;
  9769. }
  9770. return base;
  9771. }
  9772. public:
  9773. /*! @brief Character type. */
  9774. using value_type = typename base_type::value_type;
  9775. /*! @brief Unsigned integer type. */
  9776. using size_type = typename base_type::size_type;
  9777. /*! @brief Unsigned integer type. */
  9778. using hash_type = typename base_type::hash_type;
  9779. /**
  9780. * @brief Returns directly the numeric representation of a string view.
  9781. * @param str Human-readable identifier.
  9782. * @param len Length of the string to hash.
  9783. * @return The numeric representation of the string.
  9784. */
  9785. [[nodiscard]] static constexpr hash_type value(const value_type *str, const size_type len) ENTT_NOEXCEPT {
  9786. return basic_hashed_string{str, len};
  9787. }
  9788. /**
  9789. * @brief Returns directly the numeric representation of a string.
  9790. * @tparam N Number of characters of the identifier.
  9791. * @param str Human-readable identifier.
  9792. * @return The numeric representation of the string.
  9793. */
  9794. template<std::size_t N>
  9795. [[nodiscard]] static constexpr hash_type value(const value_type (&str)[N]) ENTT_NOEXCEPT {
  9796. return basic_hashed_string{str};
  9797. }
  9798. /**
  9799. * @brief Returns directly the numeric representation of a string.
  9800. * @param wrapper Helps achieving the purpose by relying on overloading.
  9801. * @return The numeric representation of the string.
  9802. */
  9803. [[nodiscard]] static constexpr hash_type value(const_wrapper wrapper) ENTT_NOEXCEPT {
  9804. return basic_hashed_string{wrapper};
  9805. }
  9806. /*! @brief Constructs an empty hashed string. */
  9807. constexpr basic_hashed_string() ENTT_NOEXCEPT
  9808. : base_type{} {}
  9809. /**
  9810. * @brief Constructs a hashed string from a string view.
  9811. * @param str Human-readable identifier.
  9812. * @param len Length of the string to hash.
  9813. */
  9814. constexpr basic_hashed_string(const value_type *str, const size_type len) ENTT_NOEXCEPT
  9815. : base_type{helper(str, len)} {}
  9816. /**
  9817. * @brief Constructs a hashed string from an array of const characters.
  9818. * @tparam N Number of characters of the identifier.
  9819. * @param str Human-readable identifier.
  9820. */
  9821. template<std::size_t N>
  9822. constexpr basic_hashed_string(const value_type (&str)[N]) ENTT_NOEXCEPT
  9823. : base_type{helper(str)} {}
  9824. /**
  9825. * @brief Explicit constructor on purpose to avoid constructing a hashed
  9826. * string directly from a `const value_type *`.
  9827. *
  9828. * @warning
  9829. * The lifetime of the string is not extended nor is it copied.
  9830. *
  9831. * @param wrapper Helps achieving the purpose by relying on overloading.
  9832. */
  9833. explicit constexpr basic_hashed_string(const_wrapper wrapper) ENTT_NOEXCEPT
  9834. : base_type{helper(wrapper.repr)} {}
  9835. /**
  9836. * @brief Returns the size a hashed string.
  9837. * @return The size of the hashed string.
  9838. */
  9839. [[nodiscard]] constexpr size_type size() const ENTT_NOEXCEPT {
  9840. return base_type::length;
  9841. }
  9842. /**
  9843. * @brief Returns the human-readable representation of a hashed string.
  9844. * @return The string used to initialize the hashed string.
  9845. */
  9846. [[nodiscard]] constexpr const value_type *data() const ENTT_NOEXCEPT {
  9847. return base_type::repr;
  9848. }
  9849. /**
  9850. * @brief Returns the numeric representation of a hashed string.
  9851. * @return The numeric representation of the hashed string.
  9852. */
  9853. [[nodiscard]] constexpr hash_type value() const ENTT_NOEXCEPT {
  9854. return base_type::hash;
  9855. }
  9856. /*! @copydoc data */
  9857. [[nodiscard]] constexpr operator const value_type *() const ENTT_NOEXCEPT {
  9858. return data();
  9859. }
  9860. /**
  9861. * @brief Returns the numeric representation of a hashed string.
  9862. * @return The numeric representation of the hashed string.
  9863. */
  9864. [[nodiscard]] constexpr operator hash_type() const ENTT_NOEXCEPT {
  9865. return value();
  9866. }
  9867. };
  9868. /**
  9869. * @brief Deduction guide.
  9870. * @tparam Char Character type.
  9871. * @param str Human-readable identifier.
  9872. * @param len Length of the string to hash.
  9873. */
  9874. template<typename Char>
  9875. basic_hashed_string(const Char *str, const std::size_t len) -> basic_hashed_string<Char>;
  9876. /**
  9877. * @brief Deduction guide.
  9878. * @tparam Char Character type.
  9879. * @tparam N Number of characters of the identifier.
  9880. * @param str Human-readable identifier.
  9881. */
  9882. template<typename Char, std::size_t N>
  9883. basic_hashed_string(const Char (&str)[N]) -> basic_hashed_string<Char>;
  9884. /**
  9885. * @brief Compares two hashed strings.
  9886. * @tparam Char Character type.
  9887. * @param lhs A valid hashed string.
  9888. * @param rhs A valid hashed string.
  9889. * @return True if the two hashed strings are identical, false otherwise.
  9890. */
  9891. template<typename Char>
  9892. [[nodiscard]] constexpr bool operator==(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) ENTT_NOEXCEPT {
  9893. return lhs.value() == rhs.value();
  9894. }
  9895. /**
  9896. * @brief Compares two hashed strings.
  9897. * @tparam Char Character type.
  9898. * @param lhs A valid hashed string.
  9899. * @param rhs A valid hashed string.
  9900. * @return True if the two hashed strings differ, false otherwise.
  9901. */
  9902. template<typename Char>
  9903. [[nodiscard]] constexpr bool operator!=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) ENTT_NOEXCEPT {
  9904. return !(lhs == rhs);
  9905. }
  9906. /**
  9907. * @brief Compares two hashed strings.
  9908. * @tparam Char Character type.
  9909. * @param lhs A valid hashed string.
  9910. * @param rhs A valid hashed string.
  9911. * @return True if the first element is less than the second, false otherwise.
  9912. */
  9913. template<typename Char>
  9914. [[nodiscard]] constexpr bool operator<(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) ENTT_NOEXCEPT {
  9915. return lhs.value() < rhs.value();
  9916. }
  9917. /**
  9918. * @brief Compares two hashed strings.
  9919. * @tparam Char Character type.
  9920. * @param lhs A valid hashed string.
  9921. * @param rhs A valid hashed string.
  9922. * @return True if the first element is less than or equal to the second, false
  9923. * otherwise.
  9924. */
  9925. template<typename Char>
  9926. [[nodiscard]] constexpr bool operator<=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) ENTT_NOEXCEPT {
  9927. return !(rhs < lhs);
  9928. }
  9929. /**
  9930. * @brief Compares two hashed strings.
  9931. * @tparam Char Character type.
  9932. * @param lhs A valid hashed string.
  9933. * @param rhs A valid hashed string.
  9934. * @return True if the first element is greater than the second, false
  9935. * otherwise.
  9936. */
  9937. template<typename Char>
  9938. [[nodiscard]] constexpr bool operator>(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) ENTT_NOEXCEPT {
  9939. return rhs < lhs;
  9940. }
  9941. /**
  9942. * @brief Compares two hashed strings.
  9943. * @tparam Char Character type.
  9944. * @param lhs A valid hashed string.
  9945. * @param rhs A valid hashed string.
  9946. * @return True if the first element is greater than or equal to the second,
  9947. * false otherwise.
  9948. */
  9949. template<typename Char>
  9950. [[nodiscard]] constexpr bool operator>=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) ENTT_NOEXCEPT {
  9951. return !(lhs < rhs);
  9952. }
  9953. /*! @brief Aliases for common character types. */
  9954. using hashed_string = basic_hashed_string<char>;
  9955. /*! @brief Aliases for common character types. */
  9956. using hashed_wstring = basic_hashed_string<wchar_t>;
  9957. inline namespace literals {
  9958. /**
  9959. * @brief User defined literal for hashed strings.
  9960. * @param str The literal without its suffix.
  9961. * @return A properly initialized hashed string.
  9962. */
  9963. [[nodiscard]] constexpr hashed_string operator"" _hs(const char *str, std::size_t) ENTT_NOEXCEPT {
  9964. return hashed_string{str};
  9965. }
  9966. /**
  9967. * @brief User defined literal for hashed wstrings.
  9968. * @param str The literal without its suffix.
  9969. * @return A properly initialized hashed wstring.
  9970. */
  9971. [[nodiscard]] constexpr hashed_wstring operator"" _hws(const wchar_t *str, std::size_t) ENTT_NOEXCEPT {
  9972. return hashed_wstring{str};
  9973. }
  9974. } // namespace literals
  9975. } // namespace entt
  9976. #endif
  9977. namespace entt {
  9978. /**
  9979. * @cond TURN_OFF_DOXYGEN
  9980. * Internal details not to be documented.
  9981. */
  9982. namespace internal {
  9983. struct ENTT_API type_index final {
  9984. [[nodiscard]] static id_type next() ENTT_NOEXCEPT {
  9985. static ENTT_MAYBE_ATOMIC(id_type) value{};
  9986. return value++;
  9987. }
  9988. };
  9989. template<typename Type>
  9990. [[nodiscard]] constexpr auto stripped_type_name() ENTT_NOEXCEPT {
  9991. #if defined ENTT_PRETTY_FUNCTION
  9992. std::string_view pretty_function{ENTT_PRETTY_FUNCTION};
  9993. auto first = pretty_function.find_first_not_of(' ', pretty_function.find_first_of(ENTT_PRETTY_FUNCTION_PREFIX) + 1);
  9994. auto value = pretty_function.substr(first, pretty_function.find_last_of(ENTT_PRETTY_FUNCTION_SUFFIX) - first);
  9995. return value;
  9996. #else
  9997. return std::string_view{""};
  9998. #endif
  9999. }
  10000. template<typename Type, auto = stripped_type_name<Type>().find_first_of('.')>
  10001. [[nodiscard]] static constexpr std::string_view type_name(int) ENTT_NOEXCEPT {
  10002. constexpr auto value = stripped_type_name<Type>();
  10003. return value;
  10004. }
  10005. template<typename Type>
  10006. [[nodiscard]] static std::string_view type_name(char) ENTT_NOEXCEPT {
  10007. static const auto value = stripped_type_name<Type>();
  10008. return value;
  10009. }
  10010. template<typename Type, auto = stripped_type_name<Type>().find_first_of('.')>
  10011. [[nodiscard]] static constexpr id_type type_hash(int) ENTT_NOEXCEPT {
  10012. constexpr auto stripped = stripped_type_name<Type>();
  10013. constexpr auto value = hashed_string::value(stripped.data(), stripped.size());
  10014. return value;
  10015. }
  10016. template<typename Type>
  10017. [[nodiscard]] static id_type type_hash(char) ENTT_NOEXCEPT {
  10018. static const auto value = [](const auto stripped) {
  10019. return hashed_string::value(stripped.data(), stripped.size());
  10020. }(stripped_type_name<Type>());
  10021. return value;
  10022. }
  10023. } // namespace internal
  10024. /**
  10025. * Internal details not to be documented.
  10026. * @endcond
  10027. */
  10028. /**
  10029. * @brief Type sequential identifier.
  10030. * @tparam Type Type for which to generate a sequential identifier.
  10031. */
  10032. template<typename Type, typename = void>
  10033. struct ENTT_API type_index final {
  10034. /**
  10035. * @brief Returns the sequential identifier of a given type.
  10036. * @return The sequential identifier of a given type.
  10037. */
  10038. [[nodiscard]] static id_type value() ENTT_NOEXCEPT {
  10039. static const id_type value = internal::type_index::next();
  10040. return value;
  10041. }
  10042. /*! @copydoc value */
  10043. [[nodiscard]] constexpr operator id_type() const ENTT_NOEXCEPT {
  10044. return value();
  10045. }
  10046. };
  10047. /**
  10048. * @brief Type hash.
  10049. * @tparam Type Type for which to generate a hash value.
  10050. */
  10051. template<typename Type, typename = void>
  10052. struct type_hash final {
  10053. /**
  10054. * @brief Returns the numeric representation of a given type.
  10055. * @return The numeric representation of the given type.
  10056. */
  10057. #if defined ENTT_PRETTY_FUNCTION
  10058. [[nodiscard]] static constexpr id_type value() ENTT_NOEXCEPT {
  10059. return internal::type_hash<Type>(0);
  10060. #else
  10061. [[nodiscard]] static constexpr id_type value() ENTT_NOEXCEPT {
  10062. return type_index<Type>::value();
  10063. #endif
  10064. }
  10065. /*! @copydoc value */
  10066. [[nodiscard]] constexpr operator id_type() const ENTT_NOEXCEPT {
  10067. return value();
  10068. }
  10069. };
  10070. /**
  10071. * @brief Type name.
  10072. * @tparam Type Type for which to generate a name.
  10073. */
  10074. template<typename Type, typename = void>
  10075. struct type_name final {
  10076. /**
  10077. * @brief Returns the name of a given type.
  10078. * @return The name of the given type.
  10079. */
  10080. [[nodiscard]] static constexpr std::string_view value() ENTT_NOEXCEPT {
  10081. return internal::type_name<Type>(0);
  10082. }
  10083. /*! @copydoc value */
  10084. [[nodiscard]] constexpr operator std::string_view() const ENTT_NOEXCEPT {
  10085. return value();
  10086. }
  10087. };
  10088. /*! @brief Implementation specific information about a type. */
  10089. struct type_info final {
  10090. /**
  10091. * @brief Constructs a type info object for a given type.
  10092. * @tparam Type Type for which to construct a type info object.
  10093. */
  10094. template<typename Type>
  10095. constexpr type_info(std::in_place_type_t<Type>) ENTT_NOEXCEPT
  10096. : seq{type_index<std::remove_cv_t<std::remove_reference_t<Type>>>::value()},
  10097. identifier{type_hash<std::remove_cv_t<std::remove_reference_t<Type>>>::value()},
  10098. alias{type_name<std::remove_cv_t<std::remove_reference_t<Type>>>::value()} {}
  10099. /**
  10100. * @brief Type index.
  10101. * @return Type index.
  10102. */
  10103. [[nodiscard]] constexpr id_type index() const ENTT_NOEXCEPT {
  10104. return seq;
  10105. }
  10106. /**
  10107. * @brief Type hash.
  10108. * @return Type hash.
  10109. */
  10110. [[nodiscard]] constexpr id_type hash() const ENTT_NOEXCEPT {
  10111. return identifier;
  10112. }
  10113. /**
  10114. * @brief Type name.
  10115. * @return Type name.
  10116. */
  10117. [[nodiscard]] constexpr std::string_view name() const ENTT_NOEXCEPT {
  10118. return alias;
  10119. }
  10120. private:
  10121. id_type seq;
  10122. id_type identifier;
  10123. std::string_view alias;
  10124. };
  10125. /**
  10126. * @brief Compares the contents of two type info objects.
  10127. * @param lhs A type info object.
  10128. * @param rhs A type info object.
  10129. * @return True if the two type info objects are identical, false otherwise.
  10130. */
  10131. [[nodiscard]] inline constexpr bool operator==(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT {
  10132. return lhs.hash() == rhs.hash();
  10133. }
  10134. /**
  10135. * @brief Compares the contents of two type info objects.
  10136. * @param lhs A type info object.
  10137. * @param rhs A type info object.
  10138. * @return True if the two type info objects differ, false otherwise.
  10139. */
  10140. [[nodiscard]] inline constexpr bool operator!=(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT {
  10141. return !(lhs == rhs);
  10142. }
  10143. /**
  10144. * @brief Compares two type info objects.
  10145. * @param lhs A valid type info object.
  10146. * @param rhs A valid type info object.
  10147. * @return True if the first element is less than the second, false otherwise.
  10148. */
  10149. [[nodiscard]] constexpr bool operator<(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT {
  10150. return lhs.index() < rhs.index();
  10151. }
  10152. /**
  10153. * @brief Compares two type info objects.
  10154. * @param lhs A valid type info object.
  10155. * @param rhs A valid type info object.
  10156. * @return True if the first element is less than or equal to the second, false
  10157. * otherwise.
  10158. */
  10159. [[nodiscard]] constexpr bool operator<=(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT {
  10160. return !(rhs < lhs);
  10161. }
  10162. /**
  10163. * @brief Compares two type info objects.
  10164. * @param lhs A valid type info object.
  10165. * @param rhs A valid type info object.
  10166. * @return True if the first element is greater than the second, false
  10167. * otherwise.
  10168. */
  10169. [[nodiscard]] constexpr bool operator>(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT {
  10170. return rhs < lhs;
  10171. }
  10172. /**
  10173. * @brief Compares two type info objects.
  10174. * @param lhs A valid type info object.
  10175. * @param rhs A valid type info object.
  10176. * @return True if the first element is greater than or equal to the second,
  10177. * false otherwise.
  10178. */
  10179. [[nodiscard]] constexpr bool operator>=(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT {
  10180. return !(lhs < rhs);
  10181. }
  10182. /**
  10183. * @brief Returns the type info object associated to a given type.
  10184. *
  10185. * The returned element refers to an object with static storage duration.<br/>
  10186. * The type doesn't need to be a complete type. If the type is a reference, the
  10187. * result refers to the referenced type. In all cases, top-level cv-qualifiers
  10188. * are ignored.
  10189. *
  10190. * @tparam Type Type for which to generate a type info object.
  10191. * @return A reference to a properly initialized type info object.
  10192. */
  10193. template<typename Type>
  10194. [[nodiscard]] const type_info &type_id() ENTT_NOEXCEPT {
  10195. if constexpr(std::is_same_v<Type, std::remove_cv_t<std::remove_reference_t<Type>>>) {
  10196. static type_info instance{std::in_place_type<Type>};
  10197. return instance;
  10198. } else {
  10199. return type_id<std::remove_cv_t<std::remove_reference_t<Type>>>();
  10200. }
  10201. }
  10202. /*! @copydoc type_id */
  10203. template<typename Type>
  10204. [[nodiscard]] const type_info &type_id(Type &&) ENTT_NOEXCEPT {
  10205. return type_id<std::remove_cv_t<std::remove_reference_t<Type>>>();
  10206. }
  10207. } // namespace entt
  10208. #endif
  10209. // #include "type_traits.hpp"
  10210. #ifndef ENTT_CORE_TYPE_TRAITS_HPP
  10211. #define ENTT_CORE_TYPE_TRAITS_HPP
  10212. #include <cstddef>
  10213. #include <iterator>
  10214. #include <type_traits>
  10215. #include <utility>
  10216. // #include "../config/config.h"
  10217. // #include "fwd.hpp"
  10218. namespace entt {
  10219. /**
  10220. * @brief Utility class to disambiguate overloaded functions.
  10221. * @tparam N Number of choices available.
  10222. */
  10223. template<std::size_t N>
  10224. struct choice_t
  10225. // Unfortunately, doxygen cannot parse such a construct.
  10226. : /*! @cond TURN_OFF_DOXYGEN */ choice_t<N - 1> /*! @endcond */
  10227. {};
  10228. /*! @copybrief choice_t */
  10229. template<>
  10230. struct choice_t<0> {};
  10231. /**
  10232. * @brief Variable template for the choice trick.
  10233. * @tparam N Number of choices available.
  10234. */
  10235. template<std::size_t N>
  10236. inline constexpr choice_t<N> choice{};
  10237. /**
  10238. * @brief Identity type trait.
  10239. *
  10240. * Useful to establish non-deduced contexts in template argument deduction
  10241. * (waiting for C++20) or to provide types through function arguments.
  10242. *
  10243. * @tparam Type A type.
  10244. */
  10245. template<typename Type>
  10246. struct type_identity {
  10247. /*! @brief Identity type. */
  10248. using type = Type;
  10249. };
  10250. /**
  10251. * @brief Helper type.
  10252. * @tparam Type A type.
  10253. */
  10254. template<typename Type>
  10255. using type_identity_t = typename type_identity<Type>::type;
  10256. /**
  10257. * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains.
  10258. * @tparam Type The type of which to return the size.
  10259. * @tparam The size of the type if `sizeof` accepts it, 0 otherwise.
  10260. */
  10261. template<typename Type, typename = void>
  10262. struct size_of: std::integral_constant<std::size_t, 0u> {};
  10263. /*! @copydoc size_of */
  10264. template<typename Type>
  10265. struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
  10266. : std::integral_constant<std::size_t, sizeof(Type)> {};
  10267. /**
  10268. * @brief Helper variable template.
  10269. * @tparam Type The type of which to return the size.
  10270. */
  10271. template<typename Type>
  10272. inline constexpr std::size_t size_of_v = size_of<Type>::value;
  10273. /**
  10274. * @brief Using declaration to be used to _repeat_ the same type a number of
  10275. * times equal to the size of a given parameter pack.
  10276. * @tparam Type A type to repeat.
  10277. */
  10278. template<typename Type, typename>
  10279. using unpack_as_type = Type;
  10280. /**
  10281. * @brief Helper variable template to be used to _repeat_ the same value a
  10282. * number of times equal to the size of a given parameter pack.
  10283. * @tparam Value A value to repeat.
  10284. */
  10285. template<auto Value, typename>
  10286. inline constexpr auto unpack_as_value = Value;
  10287. /**
  10288. * @brief Wraps a static constant.
  10289. * @tparam Value A static constant.
  10290. */
  10291. template<auto Value>
  10292. using integral_constant = std::integral_constant<decltype(Value), Value>;
  10293. /**
  10294. * @brief Alias template to facilitate the creation of named values.
  10295. * @tparam Value A constant value at least convertible to `id_type`.
  10296. */
  10297. template<id_type Value>
  10298. using tag = integral_constant<Value>;
  10299. /**
  10300. * @brief A class to use to push around lists of types, nothing more.
  10301. * @tparam Type Types provided by the type list.
  10302. */
  10303. template<typename... Type>
  10304. struct type_list {
  10305. /*! @brief Type list type. */
  10306. using type = type_list;
  10307. /*! @brief Compile-time number of elements in the type list. */
  10308. static constexpr auto size = sizeof...(Type);
  10309. };
  10310. /*! @brief Primary template isn't defined on purpose. */
  10311. template<std::size_t, typename>
  10312. struct type_list_element;
  10313. /**
  10314. * @brief Provides compile-time indexed access to the types of a type list.
  10315. * @tparam Index Index of the type to return.
  10316. * @tparam Type First type provided by the type list.
  10317. * @tparam Other Other types provided by the type list.
  10318. */
  10319. template<std::size_t Index, typename Type, typename... Other>
  10320. struct type_list_element<Index, type_list<Type, Other...>>
  10321. : type_list_element<Index - 1u, type_list<Other...>> {};
  10322. /**
  10323. * @brief Provides compile-time indexed access to the types of a type list.
  10324. * @tparam Type First type provided by the type list.
  10325. * @tparam Other Other types provided by the type list.
  10326. */
  10327. template<typename Type, typename... Other>
  10328. struct type_list_element<0u, type_list<Type, Other...>> {
  10329. /*! @brief Searched type. */
  10330. using type = Type;
  10331. };
  10332. /**
  10333. * @brief Helper type.
  10334. * @tparam Index Index of the type to return.
  10335. * @tparam List Type list to search into.
  10336. */
  10337. template<std::size_t Index, typename List>
  10338. using type_list_element_t = typename type_list_element<Index, List>::type;
  10339. /**
  10340. * @brief Concatenates multiple type lists.
  10341. * @tparam Type Types provided by the first type list.
  10342. * @tparam Other Types provided by the second type list.
  10343. * @return A type list composed by the types of both the type lists.
  10344. */
  10345. template<typename... Type, typename... Other>
  10346. constexpr type_list<Type..., Other...> operator+(type_list<Type...>, type_list<Other...>) {
  10347. return {};
  10348. }
  10349. /*! @brief Primary template isn't defined on purpose. */
  10350. template<typename...>
  10351. struct type_list_cat;
  10352. /*! @brief Concatenates multiple type lists. */
  10353. template<>
  10354. struct type_list_cat<> {
  10355. /*! @brief A type list composed by the types of all the type lists. */
  10356. using type = type_list<>;
  10357. };
  10358. /**
  10359. * @brief Concatenates multiple type lists.
  10360. * @tparam Type Types provided by the first type list.
  10361. * @tparam Other Types provided by the second type list.
  10362. * @tparam List Other type lists, if any.
  10363. */
  10364. template<typename... Type, typename... Other, typename... List>
  10365. struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
  10366. /*! @brief A type list composed by the types of all the type lists. */
  10367. using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
  10368. };
  10369. /**
  10370. * @brief Concatenates multiple type lists.
  10371. * @tparam Type Types provided by the type list.
  10372. */
  10373. template<typename... Type>
  10374. struct type_list_cat<type_list<Type...>> {
  10375. /*! @brief A type list composed by the types of all the type lists. */
  10376. using type = type_list<Type...>;
  10377. };
  10378. /**
  10379. * @brief Helper type.
  10380. * @tparam List Type lists to concatenate.
  10381. */
  10382. template<typename... List>
  10383. using type_list_cat_t = typename type_list_cat<List...>::type;
  10384. /*! @brief Primary template isn't defined on purpose. */
  10385. template<typename>
  10386. struct type_list_unique;
  10387. /**
  10388. * @brief Removes duplicates types from a type list.
  10389. * @tparam Type One of the types provided by the given type list.
  10390. * @tparam Other The other types provided by the given type list.
  10391. */
  10392. template<typename Type, typename... Other>
  10393. struct type_list_unique<type_list<Type, Other...>> {
  10394. /*! @brief A type list without duplicate types. */
  10395. using type = std::conditional_t<
  10396. (std::is_same_v<Type, Other> || ...),
  10397. typename type_list_unique<type_list<Other...>>::type,
  10398. type_list_cat_t<type_list<Type>, typename type_list_unique<type_list<Other...>>::type>>;
  10399. };
  10400. /*! @brief Removes duplicates types from a type list. */
  10401. template<>
  10402. struct type_list_unique<type_list<>> {
  10403. /*! @brief A type list without duplicate types. */
  10404. using type = type_list<>;
  10405. };
  10406. /**
  10407. * @brief Helper type.
  10408. * @tparam Type A type list.
  10409. */
  10410. template<typename Type>
  10411. using type_list_unique_t = typename type_list_unique<Type>::type;
  10412. /**
  10413. * @brief Provides the member constant `value` to true if a type list contains a
  10414. * given type, false otherwise.
  10415. * @tparam List Type list.
  10416. * @tparam Type Type to look for.
  10417. */
  10418. template<typename List, typename Type>
  10419. struct type_list_contains;
  10420. /**
  10421. * @copybrief type_list_contains
  10422. * @tparam Type Types provided by the type list.
  10423. * @tparam Other Type to look for.
  10424. */
  10425. template<typename... Type, typename Other>
  10426. struct type_list_contains<type_list<Type...>, Other>: std::disjunction<std::is_same<Type, Other>...> {};
  10427. /**
  10428. * @brief Helper variable template.
  10429. * @tparam List Type list.
  10430. * @tparam Type Type to look for.
  10431. */
  10432. template<typename List, typename Type>
  10433. inline constexpr bool type_list_contains_v = type_list_contains<List, Type>::value;
  10434. /*! @brief Primary template isn't defined on purpose. */
  10435. template<typename...>
  10436. struct type_list_diff;
  10437. /**
  10438. * @brief Computes the difference between two type lists.
  10439. * @tparam Type Types provided by the first type list.
  10440. * @tparam Other Types provided by the second type list.
  10441. */
  10442. template<typename... Type, typename... Other>
  10443. struct type_list_diff<type_list<Type...>, type_list<Other...>> {
  10444. /*! @brief A type list that is the difference between the two type lists. */
  10445. using type = type_list_cat_t<std::conditional_t<type_list_contains_v<type_list<Other...>, Type>, type_list<>, type_list<Type>>...>;
  10446. };
  10447. /**
  10448. * @brief Helper type.
  10449. * @tparam List Type lists between which to compute the difference.
  10450. */
  10451. template<typename... List>
  10452. using type_list_diff_t = typename type_list_diff<List...>::type;
  10453. /**
  10454. * @brief A class to use to push around lists of constant values, nothing more.
  10455. * @tparam Value Values provided by the value list.
  10456. */
  10457. template<auto... Value>
  10458. struct value_list {
  10459. /*! @brief Value list type. */
  10460. using type = value_list;
  10461. /*! @brief Compile-time number of elements in the value list. */
  10462. static constexpr auto size = sizeof...(Value);
  10463. };
  10464. /*! @brief Primary template isn't defined on purpose. */
  10465. template<std::size_t, typename>
  10466. struct value_list_element;
  10467. /**
  10468. * @brief Provides compile-time indexed access to the values of a value list.
  10469. * @tparam Index Index of the value to return.
  10470. * @tparam Value First value provided by the value list.
  10471. * @tparam Other Other values provided by the value list.
  10472. */
  10473. template<std::size_t Index, auto Value, auto... Other>
  10474. struct value_list_element<Index, value_list<Value, Other...>>
  10475. : value_list_element<Index - 1u, value_list<Other...>> {};
  10476. /**
  10477. * @brief Provides compile-time indexed access to the types of a type list.
  10478. * @tparam Value First value provided by the value list.
  10479. * @tparam Other Other values provided by the value list.
  10480. */
  10481. template<auto Value, auto... Other>
  10482. struct value_list_element<0u, value_list<Value, Other...>> {
  10483. /*! @brief Searched value. */
  10484. static constexpr auto value = Value;
  10485. };
  10486. /**
  10487. * @brief Helper type.
  10488. * @tparam Index Index of the value to return.
  10489. * @tparam List Value list to search into.
  10490. */
  10491. template<std::size_t Index, typename List>
  10492. inline constexpr auto value_list_element_v = value_list_element<Index, List>::value;
  10493. /**
  10494. * @brief Concatenates multiple value lists.
  10495. * @tparam Value Values provided by the first value list.
  10496. * @tparam Other Values provided by the second value list.
  10497. * @return A value list composed by the values of both the value lists.
  10498. */
  10499. template<auto... Value, auto... Other>
  10500. constexpr value_list<Value..., Other...> operator+(value_list<Value...>, value_list<Other...>) {
  10501. return {};
  10502. }
  10503. /*! @brief Primary template isn't defined on purpose. */
  10504. template<typename...>
  10505. struct value_list_cat;
  10506. /*! @brief Concatenates multiple value lists. */
  10507. template<>
  10508. struct value_list_cat<> {
  10509. /*! @brief A value list composed by the values of all the value lists. */
  10510. using type = value_list<>;
  10511. };
  10512. /**
  10513. * @brief Concatenates multiple value lists.
  10514. * @tparam Value Values provided by the first value list.
  10515. * @tparam Other Values provided by the second value list.
  10516. * @tparam List Other value lists, if any.
  10517. */
  10518. template<auto... Value, auto... Other, typename... List>
  10519. struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
  10520. /*! @brief A value list composed by the values of all the value lists. */
  10521. using type = typename value_list_cat<value_list<Value..., Other...>, List...>::type;
  10522. };
  10523. /**
  10524. * @brief Concatenates multiple value lists.
  10525. * @tparam Value Values provided by the value list.
  10526. */
  10527. template<auto... Value>
  10528. struct value_list_cat<value_list<Value...>> {
  10529. /*! @brief A value list composed by the values of all the value lists. */
  10530. using type = value_list<Value...>;
  10531. };
  10532. /**
  10533. * @brief Helper type.
  10534. * @tparam List Value lists to concatenate.
  10535. */
  10536. template<typename... List>
  10537. using value_list_cat_t = typename value_list_cat<List...>::type;
  10538. /*! @brief Same as std::is_invocable, but with tuples. */
  10539. template<typename, typename>
  10540. struct is_applicable: std::false_type {};
  10541. /**
  10542. * @copybrief is_applicable
  10543. * @tparam Func A valid function type.
  10544. * @tparam Tuple Tuple-like type.
  10545. * @tparam Args The list of arguments to use to probe the function type.
  10546. */
  10547. template<typename Func, template<typename...> class Tuple, typename... Args>
  10548. struct is_applicable<Func, Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  10549. /**
  10550. * @copybrief is_applicable
  10551. * @tparam Func A valid function type.
  10552. * @tparam Tuple Tuple-like type.
  10553. * @tparam Args The list of arguments to use to probe the function type.
  10554. */
  10555. template<typename Func, template<typename...> class Tuple, typename... Args>
  10556. struct is_applicable<Func, const Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  10557. /**
  10558. * @brief Helper variable template.
  10559. * @tparam Func A valid function type.
  10560. * @tparam Args The list of arguments to use to probe the function type.
  10561. */
  10562. template<typename Func, typename Args>
  10563. inline constexpr bool is_applicable_v = is_applicable<Func, Args>::value;
  10564. /*! @brief Same as std::is_invocable_r, but with tuples for arguments. */
  10565. template<typename, typename, typename>
  10566. struct is_applicable_r: std::false_type {};
  10567. /**
  10568. * @copybrief is_applicable_r
  10569. * @tparam Ret The type to which the return type of the function should be
  10570. * convertible.
  10571. * @tparam Func A valid function type.
  10572. * @tparam Args The list of arguments to use to probe the function type.
  10573. */
  10574. template<typename Ret, typename Func, typename... Args>
  10575. struct is_applicable_r<Ret, Func, std::tuple<Args...>>: std::is_invocable_r<Ret, Func, Args...> {};
  10576. /**
  10577. * @brief Helper variable template.
  10578. * @tparam Ret The type to which the return type of the function should be
  10579. * convertible.
  10580. * @tparam Func A valid function type.
  10581. * @tparam Args The list of arguments to use to probe the function type.
  10582. */
  10583. template<typename Ret, typename Func, typename Args>
  10584. inline constexpr bool is_applicable_r_v = is_applicable_r<Ret, Func, Args>::value;
  10585. /**
  10586. * @brief Provides the member constant `value` to true if a given type is
  10587. * complete, false otherwise.
  10588. * @tparam Type The type to test.
  10589. */
  10590. template<typename Type, typename = void>
  10591. struct is_complete: std::false_type {};
  10592. /*! @copydoc is_complete */
  10593. template<typename Type>
  10594. struct is_complete<Type, std::void_t<decltype(sizeof(Type))>>: std::true_type {};
  10595. /**
  10596. * @brief Helper variable template.
  10597. * @tparam Type The type to test.
  10598. */
  10599. template<typename Type>
  10600. inline constexpr bool is_complete_v = is_complete<Type>::value;
  10601. /**
  10602. * @brief Provides the member constant `value` to true if a given type is an
  10603. * iterator, false otherwise.
  10604. * @tparam Type The type to test.
  10605. */
  10606. template<typename Type, typename = void>
  10607. struct is_iterator: std::false_type {};
  10608. /**
  10609. * @cond TURN_OFF_DOXYGEN
  10610. * Internal details not to be documented.
  10611. */
  10612. namespace internal {
  10613. template<typename, typename = void>
  10614. struct has_iterator_category: std::false_type {};
  10615. template<typename Type>
  10616. struct has_iterator_category<Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>: std::true_type {};
  10617. } // namespace internal
  10618. /**
  10619. * Internal details not to be documented.
  10620. * @endcond
  10621. */
  10622. /*! @copydoc is_iterator */
  10623. template<typename Type>
  10624. struct is_iterator<Type, std::enable_if_t<!std::is_same_v<std::remove_const_t<std::remove_pointer_t<Type>>, void>>>
  10625. : internal::has_iterator_category<Type> {};
  10626. /**
  10627. * @brief Helper variable template.
  10628. * @tparam Type The type to test.
  10629. */
  10630. template<typename Type>
  10631. inline constexpr bool is_iterator_v = is_iterator<Type>::value;
  10632. /**
  10633. * @brief Provides the member constant `value` to true if a given type is both
  10634. * an empty and non-final class, false otherwise.
  10635. * @tparam Type The type to test
  10636. */
  10637. template<typename Type>
  10638. struct is_ebco_eligible
  10639. : std::conjunction<std::is_empty<Type>, std::negation<std::is_final<Type>>> {};
  10640. /**
  10641. * @brief Helper variable template.
  10642. * @tparam Type The type to test.
  10643. */
  10644. template<typename Type>
  10645. inline constexpr bool is_ebco_eligible_v = is_ebco_eligible<Type>::value;
  10646. /**
  10647. * @brief Provides the member constant `value` to true if `Type::is_transparent`
  10648. * is valid and denotes a type, false otherwise.
  10649. * @tparam Type The type to test.
  10650. */
  10651. template<typename Type, typename = void>
  10652. struct is_transparent: std::false_type {};
  10653. /*! @copydoc is_transparent */
  10654. template<typename Type>
  10655. struct is_transparent<Type, std::void_t<typename Type::is_transparent>>: std::true_type {};
  10656. /**
  10657. * @brief Helper variable template.
  10658. * @tparam Type The type to test.
  10659. */
  10660. template<typename Type>
  10661. inline constexpr bool is_transparent_v = is_transparent<Type>::value;
  10662. /**
  10663. * @brief Provides the member constant `value` to true if a given type is
  10664. * equality comparable, false otherwise.
  10665. * @tparam Type The type to test.
  10666. */
  10667. template<typename Type, typename = void>
  10668. struct is_equality_comparable: std::false_type {};
  10669. /**
  10670. * @cond TURN_OFF_DOXYGEN
  10671. * Internal details not to be documented.
  10672. */
  10673. namespace internal {
  10674. template<typename, typename = void>
  10675. struct has_tuple_size_value: std::false_type {};
  10676. template<typename Type>
  10677. struct has_tuple_size_value<Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>: std::true_type {};
  10678. template<typename Type, std::size_t... Index>
  10679. [[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
  10680. return (is_equality_comparable<std::tuple_element_t<Index, Type>>::value && ...);
  10681. }
  10682. template<typename>
  10683. [[nodiscard]] constexpr bool maybe_equality_comparable(choice_t<0>) {
  10684. return true;
  10685. }
  10686. template<typename Type>
  10687. [[nodiscard]] constexpr auto maybe_equality_comparable(choice_t<1>) -> decltype(std::declval<typename Type::value_type>(), bool{}) {
  10688. if constexpr(is_iterator_v<Type>) {
  10689. return true;
  10690. } else if constexpr(std::is_same_v<typename Type::value_type, Type>) {
  10691. return maybe_equality_comparable<Type>(choice<0>);
  10692. } else {
  10693. return is_equality_comparable<typename Type::value_type>::value;
  10694. }
  10695. }
  10696. template<typename Type>
  10697. [[nodiscard]] constexpr std::enable_if_t<is_complete_v<std::tuple_size<std::remove_const_t<Type>>>, bool> maybe_equality_comparable(choice_t<2>) {
  10698. if constexpr(has_tuple_size_value<Type>::value) {
  10699. return unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
  10700. } else {
  10701. return maybe_equality_comparable<Type>(choice<1>);
  10702. }
  10703. }
  10704. } // namespace internal
  10705. /**
  10706. * Internal details not to be documented.
  10707. * @endcond
  10708. */
  10709. /*! @copydoc is_equality_comparable */
  10710. template<typename Type>
  10711. struct is_equality_comparable<Type, std::void_t<decltype(std::declval<Type>() == std::declval<Type>())>>
  10712. : std::bool_constant<internal::maybe_equality_comparable<Type>(choice<2>)> {};
  10713. /**
  10714. * @brief Helper variable template.
  10715. * @tparam Type The type to test.
  10716. */
  10717. template<typename Type>
  10718. inline constexpr bool is_equality_comparable_v = is_equality_comparable<Type>::value;
  10719. /**
  10720. * @brief Transcribes the constness of a type to another type.
  10721. * @tparam To The type to which to transcribe the constness.
  10722. * @tparam From The type from which to transcribe the constness.
  10723. */
  10724. template<typename To, typename From>
  10725. struct constness_as {
  10726. /*! @brief The type resulting from the transcription of the constness. */
  10727. using type = std::remove_const_t<To>;
  10728. };
  10729. /*! @copydoc constness_as */
  10730. template<typename To, typename From>
  10731. struct constness_as<To, const From> {
  10732. /*! @brief The type resulting from the transcription of the constness. */
  10733. using type = std::add_const_t<To>;
  10734. };
  10735. /**
  10736. * @brief Alias template to facilitate the transcription of the constness.
  10737. * @tparam To The type to which to transcribe the constness.
  10738. * @tparam From The type from which to transcribe the constness.
  10739. */
  10740. template<typename To, typename From>
  10741. using constness_as_t = typename constness_as<To, From>::type;
  10742. /**
  10743. * @brief Extracts the class of a non-static member object or function.
  10744. * @tparam Member A pointer to a non-static member object or function.
  10745. */
  10746. template<typename Member>
  10747. class member_class {
  10748. static_assert(std::is_member_pointer_v<Member>, "Invalid pointer type to non-static member object or function");
  10749. template<typename Class, typename Ret, typename... Args>
  10750. static Class *clazz(Ret (Class::*)(Args...));
  10751. template<typename Class, typename Ret, typename... Args>
  10752. static Class *clazz(Ret (Class::*)(Args...) const);
  10753. template<typename Class, typename Type>
  10754. static Class *clazz(Type Class::*);
  10755. public:
  10756. /*! @brief The class of the given non-static member object or function. */
  10757. using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
  10758. };
  10759. /**
  10760. * @brief Helper type.
  10761. * @tparam Member A pointer to a non-static member object or function.
  10762. */
  10763. template<typename Member>
  10764. using member_class_t = typename member_class<Member>::type;
  10765. } // namespace entt
  10766. #endif
  10767. namespace entt {
  10768. /**
  10769. * @brief A SBO friendly, type-safe container for single values of any type.
  10770. * @tparam Len Size of the storage reserved for the small buffer optimization.
  10771. * @tparam Align Optional alignment requirement.
  10772. */
  10773. template<std::size_t Len, std::size_t Align>
  10774. class basic_any {
  10775. enum class operation : std::uint8_t {
  10776. copy,
  10777. move,
  10778. transfer,
  10779. assign,
  10780. destroy,
  10781. compare,
  10782. get
  10783. };
  10784. enum class policy : std::uint8_t {
  10785. owner,
  10786. ref,
  10787. cref
  10788. };
  10789. using storage_type = std::aligned_storage_t<Len + !Len, Align>;
  10790. using vtable_type = const void *(const operation, const basic_any &, const void *);
  10791. template<typename Type>
  10792. static constexpr bool in_situ = Len && alignof(Type) <= alignof(storage_type) && sizeof(Type) <= sizeof(storage_type) && std::is_nothrow_move_constructible_v<Type>;
  10793. template<typename Type>
  10794. static const void *basic_vtable([[maybe_unused]] const operation op, [[maybe_unused]] const basic_any &value, [[maybe_unused]] const void *other) {
  10795. static_assert(!std::is_same_v<Type, void> && std::is_same_v<std::remove_cv_t<std::remove_reference_t<Type>>, Type>, "Invalid type");
  10796. const Type *element = nullptr;
  10797. if constexpr(in_situ<Type>) {
  10798. element = value.owner() ? reinterpret_cast<const Type *>(&value.storage) : static_cast<const Type *>(value.instance);
  10799. } else {
  10800. element = static_cast<const Type *>(value.instance);
  10801. }
  10802. switch(op) {
  10803. case operation::copy:
  10804. if constexpr(std::is_copy_constructible_v<Type>) {
  10805. static_cast<basic_any *>(const_cast<void *>(other))->initialize<Type>(*element);
  10806. }
  10807. break;
  10808. case operation::move:
  10809. if constexpr(in_situ<Type>) {
  10810. if(value.owner()) {
  10811. return new(&static_cast<basic_any *>(const_cast<void *>(other))->storage) Type{std::move(*const_cast<Type *>(element))};
  10812. }
  10813. }
  10814. return (static_cast<basic_any *>(const_cast<void *>(other))->instance = std::exchange(const_cast<basic_any &>(value).instance, nullptr));
  10815. case operation::transfer:
  10816. if constexpr(std::is_move_assignable_v<Type>) {
  10817. *const_cast<Type *>(element) = std::move(*static_cast<Type *>(const_cast<void *>(other)));
  10818. return other;
  10819. }
  10820. [[fallthrough]];
  10821. case operation::assign:
  10822. if constexpr(std::is_copy_assignable_v<Type>) {
  10823. *const_cast<Type *>(element) = *static_cast<const Type *>(other);
  10824. return other;
  10825. }
  10826. break;
  10827. case operation::destroy:
  10828. if constexpr(in_situ<Type>) {
  10829. element->~Type();
  10830. } else if constexpr(std::is_array_v<Type>) {
  10831. delete[] element;
  10832. } else {
  10833. delete element;
  10834. }
  10835. break;
  10836. case operation::compare:
  10837. if constexpr(!std::is_function_v<Type> && !std::is_array_v<Type> && is_equality_comparable_v<Type>) {
  10838. return *static_cast<const Type *>(element) == *static_cast<const Type *>(other) ? other : nullptr;
  10839. } else {
  10840. return (element == other) ? other : nullptr;
  10841. }
  10842. case operation::get:
  10843. return element;
  10844. }
  10845. return nullptr;
  10846. }
  10847. template<typename Type, typename... Args>
  10848. void initialize([[maybe_unused]] Args &&...args) {
  10849. if constexpr(!std::is_void_v<Type>) {
  10850. info = &type_id<std::remove_cv_t<std::remove_reference_t<Type>>>();
  10851. vtable = basic_vtable<std::remove_cv_t<std::remove_reference_t<Type>>>;
  10852. if constexpr(std::is_lvalue_reference_v<Type>) {
  10853. static_assert(sizeof...(Args) == 1u && (std::is_lvalue_reference_v<Args> && ...), "Invalid arguments");
  10854. mode = std::is_const_v<std::remove_reference_t<Type>> ? policy::cref : policy::ref;
  10855. instance = (std::addressof(args), ...);
  10856. } else if constexpr(in_situ<Type>) {
  10857. if constexpr(sizeof...(Args) != 0u && std::is_aggregate_v<Type>) {
  10858. new(&storage) Type{std::forward<Args>(args)...};
  10859. } else {
  10860. new(&storage) Type(std::forward<Args>(args)...);
  10861. }
  10862. } else {
  10863. if constexpr(sizeof...(Args) != 0u && std::is_aggregate_v<Type>) {
  10864. instance = new Type{std::forward<Args>(args)...};
  10865. } else {
  10866. instance = new Type(std::forward<Args>(args)...);
  10867. }
  10868. }
  10869. }
  10870. }
  10871. basic_any(const basic_any &other, const policy pol) ENTT_NOEXCEPT
  10872. : instance{other.data()},
  10873. info{other.info},
  10874. vtable{other.vtable},
  10875. mode{pol} {}
  10876. public:
  10877. /*! @brief Size of the internal storage. */
  10878. static constexpr auto length = Len;
  10879. /*! @brief Alignment requirement. */
  10880. static constexpr auto alignment = Align;
  10881. /*! @brief Default constructor. */
  10882. constexpr basic_any() ENTT_NOEXCEPT
  10883. : instance{},
  10884. info{&type_id<void>()},
  10885. vtable{},
  10886. mode{policy::owner} {}
  10887. /**
  10888. * @brief Constructs a wrapper by directly initializing the new object.
  10889. * @tparam Type Type of object to use to initialize the wrapper.
  10890. * @tparam Args Types of arguments to use to construct the new instance.
  10891. * @param args Parameters to use to construct the instance.
  10892. */
  10893. template<typename Type, typename... Args>
  10894. explicit basic_any(std::in_place_type_t<Type>, Args &&...args)
  10895. : basic_any{} {
  10896. initialize<Type>(std::forward<Args>(args)...);
  10897. }
  10898. /**
  10899. * @brief Constructs a wrapper from a given value.
  10900. * @tparam Type Type of object to use to initialize the wrapper.
  10901. * @param value An instance of an object to use to initialize the wrapper.
  10902. */
  10903. template<typename Type, typename = std::enable_if_t<!std::is_same_v<std::decay_t<Type>, basic_any>>>
  10904. basic_any(Type &&value)
  10905. : basic_any{} {
  10906. initialize<std::decay_t<Type>>(std::forward<Type>(value));
  10907. }
  10908. /**
  10909. * @brief Copy constructor.
  10910. * @param other The instance to copy from.
  10911. */
  10912. basic_any(const basic_any &other)
  10913. : basic_any{} {
  10914. if(other.vtable) {
  10915. other.vtable(operation::copy, other, this);
  10916. }
  10917. }
  10918. /**
  10919. * @brief Move constructor.
  10920. * @param other The instance to move from.
  10921. */
  10922. basic_any(basic_any &&other) ENTT_NOEXCEPT
  10923. : instance{},
  10924. info{other.info},
  10925. vtable{other.vtable},
  10926. mode{other.mode} {
  10927. if(other.vtable) {
  10928. other.vtable(operation::move, other, this);
  10929. }
  10930. }
  10931. /*! @brief Frees the internal storage, whatever it means. */
  10932. ~basic_any() {
  10933. if(vtable && owner()) {
  10934. vtable(operation::destroy, *this, nullptr);
  10935. }
  10936. }
  10937. /**
  10938. * @brief Copy assignment operator.
  10939. * @param other The instance to copy from.
  10940. * @return This any object.
  10941. */
  10942. basic_any &operator=(const basic_any &other) {
  10943. reset();
  10944. if(other.vtable) {
  10945. other.vtable(operation::copy, other, this);
  10946. }
  10947. return *this;
  10948. }
  10949. /**
  10950. * @brief Move assignment operator.
  10951. * @param other The instance to move from.
  10952. * @return This any object.
  10953. */
  10954. basic_any &operator=(basic_any &&other) ENTT_NOEXCEPT {
  10955. reset();
  10956. if(other.vtable) {
  10957. other.vtable(operation::move, other, this);
  10958. info = other.info;
  10959. vtable = other.vtable;
  10960. mode = other.mode;
  10961. }
  10962. return *this;
  10963. }
  10964. /**
  10965. * @brief Value assignment operator.
  10966. * @tparam Type Type of object to use to initialize the wrapper.
  10967. * @param value An instance of an object to use to initialize the wrapper.
  10968. * @return This any object.
  10969. */
  10970. template<typename Type>
  10971. std::enable_if_t<!std::is_same_v<std::decay_t<Type>, basic_any>, basic_any &>
  10972. operator=(Type &&value) {
  10973. emplace<std::decay_t<Type>>(std::forward<Type>(value));
  10974. return *this;
  10975. }
  10976. /**
  10977. * @brief Returns the object type if any, `type_id<void>()` otherwise.
  10978. * @return The object type if any, `type_id<void>()` otherwise.
  10979. */
  10980. [[nodiscard]] const type_info &type() const ENTT_NOEXCEPT {
  10981. return *info;
  10982. }
  10983. /**
  10984. * @brief Returns an opaque pointer to the contained instance.
  10985. * @return An opaque pointer the contained instance, if any.
  10986. */
  10987. [[nodiscard]] const void *data() const ENTT_NOEXCEPT {
  10988. return vtable ? vtable(operation::get, *this, nullptr) : nullptr;
  10989. }
  10990. /**
  10991. * @brief Returns an opaque pointer to the contained instance.
  10992. * @param req Expected type.
  10993. * @return An opaque pointer the contained instance, if any.
  10994. */
  10995. [[nodiscard]] const void *data(const type_info &req) const ENTT_NOEXCEPT {
  10996. return *info == req ? data() : nullptr;
  10997. }
  10998. /**
  10999. * @brief Returns an opaque pointer to the contained instance.
  11000. * @return An opaque pointer the contained instance, if any.
  11001. */
  11002. [[nodiscard]] void *data() ENTT_NOEXCEPT {
  11003. return (!vtable || mode == policy::cref) ? nullptr : const_cast<void *>(vtable(operation::get, *this, nullptr));
  11004. }
  11005. /**
  11006. * @brief Returns an opaque pointer to the contained instance.
  11007. * @param req Expected type.
  11008. * @return An opaque pointer the contained instance, if any.
  11009. */
  11010. [[nodiscard]] void *data(const type_info &req) ENTT_NOEXCEPT {
  11011. return *info == req ? data() : nullptr;
  11012. }
  11013. /**
  11014. * @brief Replaces the contained object by creating a new instance directly.
  11015. * @tparam Type Type of object to use to initialize the wrapper.
  11016. * @tparam Args Types of arguments to use to construct the new instance.
  11017. * @param args Parameters to use to construct the instance.
  11018. */
  11019. template<typename Type, typename... Args>
  11020. void emplace(Args &&...args) {
  11021. reset();
  11022. initialize<Type>(std::forward<Args>(args)...);
  11023. }
  11024. /**
  11025. * @brief Assigns a value to the contained object without replacing it.
  11026. * @param other The value to assign to the contained object.
  11027. * @return True in case of success, false otherwise.
  11028. */
  11029. bool assign(const any &other) {
  11030. if(vtable && mode != policy::cref && *info == *other.info) {
  11031. return (vtable(operation::assign, *this, other.data()) != nullptr);
  11032. }
  11033. return false;
  11034. }
  11035. /*! @copydoc assign */
  11036. bool assign(any &&other) {
  11037. if(vtable && mode != policy::cref && *info == *other.info) {
  11038. if(auto *val = other.data(); val) {
  11039. return (vtable(operation::transfer, *this, val) != nullptr);
  11040. } else {
  11041. return (vtable(operation::assign, *this, std::as_const(other).data()) != nullptr);
  11042. }
  11043. }
  11044. return false;
  11045. }
  11046. /*! @brief Destroys contained object */
  11047. void reset() {
  11048. if(vtable && owner()) {
  11049. vtable(operation::destroy, *this, nullptr);
  11050. }
  11051. info = &type_id<void>();
  11052. vtable = nullptr;
  11053. mode = policy::owner;
  11054. }
  11055. /**
  11056. * @brief Returns false if a wrapper is empty, true otherwise.
  11057. * @return False if the wrapper is empty, true otherwise.
  11058. */
  11059. [[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
  11060. return vtable != nullptr;
  11061. }
  11062. /**
  11063. * @brief Checks if two wrappers differ in their content.
  11064. * @param other Wrapper with which to compare.
  11065. * @return False if the two objects differ in their content, true otherwise.
  11066. */
  11067. bool operator==(const basic_any &other) const ENTT_NOEXCEPT {
  11068. if(vtable && *info == *other.info) {
  11069. return (vtable(operation::compare, *this, other.data()) != nullptr);
  11070. }
  11071. return (!vtable && !other.vtable);
  11072. }
  11073. /**
  11074. * @brief Aliasing constructor.
  11075. * @return A wrapper that shares a reference to an unmanaged object.
  11076. */
  11077. [[nodiscard]] basic_any as_ref() ENTT_NOEXCEPT {
  11078. return basic_any{*this, (mode == policy::cref ? policy::cref : policy::ref)};
  11079. }
  11080. /*! @copydoc as_ref */
  11081. [[nodiscard]] basic_any as_ref() const ENTT_NOEXCEPT {
  11082. return basic_any{*this, policy::cref};
  11083. }
  11084. /**
  11085. * @brief Returns true if a wrapper owns its object, false otherwise.
  11086. * @return True if the wrapper owns its object, false otherwise.
  11087. */
  11088. [[nodiscard]] bool owner() const ENTT_NOEXCEPT {
  11089. return (mode == policy::owner);
  11090. }
  11091. private:
  11092. union {
  11093. const void *instance;
  11094. storage_type storage;
  11095. };
  11096. const type_info *info;
  11097. vtable_type *vtable;
  11098. policy mode;
  11099. };
  11100. /**
  11101. * @brief Checks if two wrappers differ in their content.
  11102. * @tparam Len Size of the storage reserved for the small buffer optimization.
  11103. * @tparam Align Alignment requirement.
  11104. * @param lhs A wrapper, either empty or not.
  11105. * @param rhs A wrapper, either empty or not.
  11106. * @return True if the two wrappers differ in their content, false otherwise.
  11107. */
  11108. template<std::size_t Len, std::size_t Align>
  11109. [[nodiscard]] inline bool operator!=(const basic_any<Len, Align> &lhs, const basic_any<Len, Align> &rhs) ENTT_NOEXCEPT {
  11110. return !(lhs == rhs);
  11111. }
  11112. /**
  11113. * @brief Performs type-safe access to the contained object.
  11114. * @tparam Type Type to which conversion is required.
  11115. * @tparam Len Size of the storage reserved for the small buffer optimization.
  11116. * @tparam Align Alignment requirement.
  11117. * @param data Target any object.
  11118. * @return The element converted to the requested type.
  11119. */
  11120. template<typename Type, std::size_t Len, std::size_t Align>
  11121. Type any_cast(const basic_any<Len, Align> &data) ENTT_NOEXCEPT {
  11122. const auto *const instance = any_cast<std::remove_reference_t<Type>>(&data);
  11123. ENTT_ASSERT(instance, "Invalid instance");
  11124. return static_cast<Type>(*instance);
  11125. }
  11126. /*! @copydoc any_cast */
  11127. template<typename Type, std::size_t Len, std::size_t Align>
  11128. Type any_cast(basic_any<Len, Align> &data) ENTT_NOEXCEPT {
  11129. // forces const on non-reference types to make them work also with wrappers for const references
  11130. auto *const instance = any_cast<std::remove_reference_t<const Type>>(&data);
  11131. ENTT_ASSERT(instance, "Invalid instance");
  11132. return static_cast<Type>(*instance);
  11133. }
  11134. /*! @copydoc any_cast */
  11135. template<typename Type, std::size_t Len, std::size_t Align>
  11136. Type any_cast(basic_any<Len, Align> &&data) ENTT_NOEXCEPT {
  11137. if constexpr(std::is_copy_constructible_v<std::remove_cv_t<std::remove_reference_t<Type>>>) {
  11138. if(auto *const instance = any_cast<std::remove_reference_t<Type>>(&data); instance) {
  11139. return static_cast<Type>(std::move(*instance));
  11140. } else {
  11141. return any_cast<Type>(data);
  11142. }
  11143. } else {
  11144. auto *const instance = any_cast<std::remove_reference_t<Type>>(&data);
  11145. ENTT_ASSERT(instance, "Invalid instance");
  11146. return static_cast<Type>(std::move(*instance));
  11147. }
  11148. }
  11149. /*! @copydoc any_cast */
  11150. template<typename Type, std::size_t Len, std::size_t Align>
  11151. const Type *any_cast(const basic_any<Len, Align> *data) ENTT_NOEXCEPT {
  11152. const auto &info = type_id<std::remove_cv_t<std::remove_reference_t<Type>>>();
  11153. return static_cast<const Type *>(data->data(info));
  11154. }
  11155. /*! @copydoc any_cast */
  11156. template<typename Type, std::size_t Len, std::size_t Align>
  11157. Type *any_cast(basic_any<Len, Align> *data) ENTT_NOEXCEPT {
  11158. const auto &info = type_id<std::remove_cv_t<std::remove_reference_t<Type>>>();
  11159. // last attempt to make wrappers for const references return their values
  11160. return static_cast<Type *>(static_cast<constness_as_t<basic_any<Len, Align>, Type> *>(data)->data(info));
  11161. }
  11162. /**
  11163. * @brief Constructs a wrapper from a given type, passing it all arguments.
  11164. * @tparam Type Type of object to use to initialize the wrapper.
  11165. * @tparam Len Size of the storage reserved for the small buffer optimization.
  11166. * @tparam Align Optional alignment requirement.
  11167. * @tparam Args Types of arguments to use to construct the new instance.
  11168. * @param args Parameters to use to construct the instance.
  11169. * @return A properly initialized wrapper for an object of the given type.
  11170. */
  11171. template<typename Type, std::size_t Len = basic_any<>::length, std::size_t Align = basic_any<Len>::alignment, typename... Args>
  11172. basic_any<Len, Align> make_any(Args &&...args) {
  11173. return basic_any<Len, Align>{std::in_place_type<Type>, std::forward<Args>(args)...};
  11174. }
  11175. /**
  11176. * @brief Forwards its argument and avoids copies for lvalue references.
  11177. * @tparam Len Size of the storage reserved for the small buffer optimization.
  11178. * @tparam Align Optional alignment requirement.
  11179. * @tparam Type Type of argument to use to construct the new instance.
  11180. * @param value Parameter to use to construct the instance.
  11181. * @return A properly initialized and not necessarily owning wrapper.
  11182. */
  11183. template<std::size_t Len = basic_any<>::length, std::size_t Align = basic_any<Len>::alignment, typename Type>
  11184. basic_any<Len, Align> forward_as_any(Type &&value) {
  11185. return basic_any<Len, Align>{std::in_place_type<std::conditional_t<std::is_rvalue_reference_v<Type>, std::decay_t<Type>, Type>>, std::forward<Type>(value)};
  11186. }
  11187. } // namespace entt
  11188. #endif
  11189. // #include "../core/memory.hpp"
  11190. #ifndef ENTT_CORE_MEMORY_HPP
  11191. #define ENTT_CORE_MEMORY_HPP
  11192. #include <cstddef>
  11193. #include <limits>
  11194. #include <memory>
  11195. #include <tuple>
  11196. #include <type_traits>
  11197. #include <utility>
  11198. // #include "../config/config.h"
  11199. namespace entt {
  11200. /**
  11201. * @brief Unwraps fancy pointers, does nothing otherwise (waiting for C++20).
  11202. * @tparam Type Pointer type.
  11203. * @param ptr Fancy or raw pointer.
  11204. * @return A raw pointer that represents the address of the original pointer.
  11205. */
  11206. template<typename Type>
  11207. [[nodiscard]] constexpr auto to_address(Type &&ptr) ENTT_NOEXCEPT {
  11208. if constexpr(std::is_pointer_v<std::remove_cv_t<std::remove_reference_t<Type>>>) {
  11209. return ptr;
  11210. } else {
  11211. return to_address(std::forward<Type>(ptr).operator->());
  11212. }
  11213. }
  11214. /**
  11215. * @brief Utility function to design allocation-aware containers.
  11216. * @tparam Allocator Type of allocator.
  11217. * @param lhs A valid allocator.
  11218. * @param rhs Another valid allocator.
  11219. */
  11220. template<typename Allocator>
  11221. constexpr void propagate_on_container_copy_assignment([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) ENTT_NOEXCEPT {
  11222. if constexpr(std::allocator_traits<Allocator>::propagate_on_container_copy_assignment::value) {
  11223. lhs = rhs;
  11224. }
  11225. }
  11226. /**
  11227. * @brief Utility function to design allocation-aware containers.
  11228. * @tparam Allocator Type of allocator.
  11229. * @param lhs A valid allocator.
  11230. * @param rhs Another valid allocator.
  11231. */
  11232. template<typename Allocator>
  11233. constexpr void propagate_on_container_move_assignment([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) ENTT_NOEXCEPT {
  11234. if constexpr(std::allocator_traits<Allocator>::propagate_on_container_move_assignment::value) {
  11235. lhs = std::move(rhs);
  11236. }
  11237. }
  11238. /**
  11239. * @brief Utility function to design allocation-aware containers.
  11240. * @tparam Allocator Type of allocator.
  11241. * @param lhs A valid allocator.
  11242. * @param rhs Another valid allocator.
  11243. */
  11244. template<typename Allocator>
  11245. constexpr void propagate_on_container_swap([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) ENTT_NOEXCEPT {
  11246. ENTT_ASSERT(std::allocator_traits<Allocator>::propagate_on_container_swap::value || lhs == rhs, "Cannot swap the containers");
  11247. if constexpr(std::allocator_traits<Allocator>::propagate_on_container_swap::value) {
  11248. using std::swap;
  11249. swap(lhs, rhs);
  11250. }
  11251. }
  11252. /**
  11253. * @brief Checks whether a value is a power of two or not.
  11254. * @param value A value that may or may not be a power of two.
  11255. * @return True if the value is a power of two, false otherwise.
  11256. */
  11257. [[nodiscard]] inline constexpr bool is_power_of_two(const std::size_t value) ENTT_NOEXCEPT {
  11258. return value && ((value & (value - 1)) == 0);
  11259. }
  11260. /**
  11261. * @brief Computes the smallest power of two greater than or equal to a value.
  11262. * @param value The value to use.
  11263. * @return The smallest power of two greater than or equal to the given value.
  11264. */
  11265. [[nodiscard]] inline constexpr std::size_t next_power_of_two(const std::size_t value) ENTT_NOEXCEPT {
  11266. ENTT_ASSERT(value < (std::size_t{1u} << (std::numeric_limits<std::size_t>::digits - 1)), "Numeric limits exceeded");
  11267. std::size_t curr = value - (value != 0u);
  11268. for(int next = 1; next < std::numeric_limits<std::size_t>::digits; next = next * 2) {
  11269. curr |= curr >> next;
  11270. }
  11271. return ++curr;
  11272. }
  11273. /**
  11274. * @brief Fast module utility function (powers of two only).
  11275. * @param value A value for which to calculate the modulus.
  11276. * @param mod _Modulus_, it must be a power of two.
  11277. * @return The common remainder.
  11278. */
  11279. [[nodiscard]] inline constexpr std::size_t fast_mod(const std::size_t value, const std::size_t mod) ENTT_NOEXCEPT {
  11280. ENTT_ASSERT(is_power_of_two(mod), "Value must be a power of two");
  11281. return value & (mod - 1u);
  11282. }
  11283. /**
  11284. * @brief Deleter for allocator-aware unique pointers (waiting for C++20).
  11285. * @tparam Args Types of arguments to use to construct the object.
  11286. */
  11287. template<typename Allocator>
  11288. struct allocation_deleter: private Allocator {
  11289. /*! @brief Allocator type. */
  11290. using allocator_type = Allocator;
  11291. /*! @brief Pointer type. */
  11292. using pointer = typename std::allocator_traits<Allocator>::pointer;
  11293. /**
  11294. * @brief Inherited constructors.
  11295. * @param alloc The allocator to use.
  11296. */
  11297. allocation_deleter(const allocator_type &alloc)
  11298. : Allocator{alloc} {}
  11299. /**
  11300. * @brief Destroys the pointed object and deallocates its memory.
  11301. * @param ptr A valid pointer to an object of the given type.
  11302. */
  11303. void operator()(pointer ptr) {
  11304. using alloc_traits = typename std::allocator_traits<Allocator>;
  11305. alloc_traits::destroy(*this, to_address(ptr));
  11306. alloc_traits::deallocate(*this, ptr, 1u);
  11307. }
  11308. };
  11309. /**
  11310. * @brief Allows `std::unique_ptr` to use allocators (waiting for C++20).
  11311. * @tparam Type Type of object to allocate for and to construct.
  11312. * @tparam Allocator Type of allocator used to manage memory and elements.
  11313. * @tparam Args Types of arguments to use to construct the object.
  11314. * @param allocator The allocator to use.
  11315. * @param args Parameters to use to construct the object.
  11316. * @return A properly initialized unique pointer with a custom deleter.
  11317. */
  11318. template<typename Type, typename Allocator, typename... Args>
  11319. auto allocate_unique(Allocator &allocator, Args &&...args) {
  11320. static_assert(!std::is_array_v<Type>, "Array types are not supported");
  11321. using alloc_traits = typename std::allocator_traits<Allocator>::template rebind_traits<Type>;
  11322. using allocator_type = typename alloc_traits::allocator_type;
  11323. allocator_type alloc{allocator};
  11324. auto ptr = alloc_traits::allocate(alloc, 1u);
  11325. ENTT_TRY {
  11326. alloc_traits::construct(alloc, to_address(ptr), std::forward<Args>(args)...);
  11327. }
  11328. ENTT_CATCH {
  11329. alloc_traits::deallocate(alloc, ptr, 1u);
  11330. ENTT_THROW;
  11331. }
  11332. return std::unique_ptr<Type, allocation_deleter<allocator_type>>{ptr, alloc};
  11333. }
  11334. /**
  11335. * @cond TURN_OFF_DOXYGEN
  11336. * Internal details not to be documented.
  11337. */
  11338. namespace internal {
  11339. template<typename Type>
  11340. struct uses_allocator_construction {
  11341. template<typename Allocator, typename... Params>
  11342. static constexpr auto args([[maybe_unused]] const Allocator &allocator, Params &&...params) ENTT_NOEXCEPT {
  11343. if constexpr(!std::uses_allocator_v<Type, Allocator> && std::is_constructible_v<Type, Params...>) {
  11344. return std::forward_as_tuple(std::forward<Params>(params)...);
  11345. } else {
  11346. static_assert(std::uses_allocator_v<Type, Allocator>, "Ill-formed request");
  11347. if constexpr(std::is_constructible_v<Type, std::allocator_arg_t, const Allocator &, Params...>) {
  11348. return std::tuple<std::allocator_arg_t, const Allocator &, Params &&...>(std::allocator_arg, allocator, std::forward<Params>(params)...);
  11349. } else {
  11350. static_assert(std::is_constructible_v<Type, Params..., const Allocator &>, "Ill-formed request");
  11351. return std::forward_as_tuple(std::forward<Params>(params)..., allocator);
  11352. }
  11353. }
  11354. }
  11355. };
  11356. template<typename Type, typename Other>
  11357. struct uses_allocator_construction<std::pair<Type, Other>> {
  11358. using type = std::pair<Type, Other>;
  11359. template<typename Allocator, typename First, typename Second>
  11360. static constexpr auto args(const Allocator &allocator, std::piecewise_construct_t, First &&first, Second &&second) ENTT_NOEXCEPT {
  11361. return std::make_tuple(
  11362. std::piecewise_construct,
  11363. std::apply([&allocator](auto &&...curr) { return uses_allocator_construction<Type>::args(allocator, std::forward<decltype(curr)>(curr)...); }, std::forward<First>(first)),
  11364. std::apply([&allocator](auto &&...curr) { return uses_allocator_construction<Other>::args(allocator, std::forward<decltype(curr)>(curr)...); }, std::forward<Second>(second)));
  11365. }
  11366. template<typename Allocator>
  11367. static constexpr auto args(const Allocator &allocator) ENTT_NOEXCEPT {
  11368. return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::tuple<>{}, std::tuple<>{});
  11369. }
  11370. template<typename Allocator, typename First, typename Second>
  11371. static constexpr auto args(const Allocator &allocator, First &&first, Second &&second) ENTT_NOEXCEPT {
  11372. 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)));
  11373. }
  11374. template<typename Allocator, typename First, typename Second>
  11375. static constexpr auto args(const Allocator &allocator, const std::pair<First, Second> &value) ENTT_NOEXCEPT {
  11376. return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::forward_as_tuple(value.first), std::forward_as_tuple(value.second));
  11377. }
  11378. template<typename Allocator, typename First, typename Second>
  11379. static constexpr auto args(const Allocator &allocator, std::pair<First, Second> &&value) ENTT_NOEXCEPT {
  11380. 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)));
  11381. }
  11382. };
  11383. } // namespace internal
  11384. /**
  11385. * Internal details not to be documented.
  11386. * @endcond
  11387. */
  11388. /**
  11389. * @brief Uses-allocator construction utility (waiting for C++20).
  11390. *
  11391. * Primarily intended for internal use. Prepares the argument list needed to
  11392. * create an object of a given type by means of uses-allocator construction.
  11393. *
  11394. * @tparam Type Type to return arguments for.
  11395. * @tparam Allocator Type of allocator used to manage memory and elements.
  11396. * @tparam Args Types of arguments to use to construct the object.
  11397. * @param allocator The allocator to use.
  11398. * @param args Parameters to use to construct the object.
  11399. * @return The arguments needed to create an object of the given type.
  11400. */
  11401. template<typename Type, typename Allocator, typename... Args>
  11402. constexpr auto uses_allocator_construction_args(const Allocator &allocator, Args &&...args) ENTT_NOEXCEPT {
  11403. return internal::uses_allocator_construction<Type>::args(allocator, std::forward<Args>(args)...);
  11404. }
  11405. /**
  11406. * @brief Uses-allocator construction utility (waiting for C++20).
  11407. *
  11408. * Primarily intended for internal use. Creates an object of a given type by
  11409. * means of uses-allocator construction.
  11410. *
  11411. * @tparam Type Type of object to create.
  11412. * @tparam Allocator Type of allocator used to manage memory and elements.
  11413. * @tparam Args Types of arguments to use to construct the object.
  11414. * @param allocator The allocator to use.
  11415. * @param args Parameters to use to construct the object.
  11416. * @return A newly created object of the given type.
  11417. */
  11418. template<typename Type, typename Allocator, typename... Args>
  11419. constexpr Type make_obj_using_allocator(const Allocator &allocator, Args &&...args) {
  11420. return std::make_from_tuple<Type>(internal::uses_allocator_construction<Type>::args(allocator, std::forward<Args>(args)...));
  11421. }
  11422. /**
  11423. * @brief Uses-allocator construction utility (waiting for C++20).
  11424. *
  11425. * Primarily intended for internal use. Creates an object of a given type by
  11426. * means of uses-allocator construction at an uninitialized memory location.
  11427. *
  11428. * @tparam Type Type of object to create.
  11429. * @tparam Allocator Type of allocator used to manage memory and elements.
  11430. * @tparam Args Types of arguments to use to construct the object.
  11431. * @param value Memory location in which to place the object.
  11432. * @param allocator The allocator to use.
  11433. * @param args Parameters to use to construct the object.
  11434. * @return A pointer to the newly created object of the given type.
  11435. */
  11436. template<typename Type, typename Allocator, typename... Args>
  11437. constexpr Type *uninitialized_construct_using_allocator(Type *value, const Allocator &allocator, Args &&...args) {
  11438. return std::apply([&](auto &&...curr) { return new(value) Type(std::forward<decltype(curr)>(curr)...); }, internal::uses_allocator_construction<Type>::args(allocator, std::forward<Args>(args)...));
  11439. }
  11440. } // namespace entt
  11441. #endif
  11442. // #include "../core/type_info.hpp"
  11443. #ifndef ENTT_CORE_TYPE_INFO_HPP
  11444. #define ENTT_CORE_TYPE_INFO_HPP
  11445. #include <string_view>
  11446. #include <type_traits>
  11447. #include <utility>
  11448. // #include "../config/config.h"
  11449. // #include "../core/attribute.h"
  11450. // #include "fwd.hpp"
  11451. // #include "hashed_string.hpp"
  11452. namespace entt {
  11453. /**
  11454. * @cond TURN_OFF_DOXYGEN
  11455. * Internal details not to be documented.
  11456. */
  11457. namespace internal {
  11458. struct ENTT_API type_index final {
  11459. [[nodiscard]] static id_type next() ENTT_NOEXCEPT {
  11460. static ENTT_MAYBE_ATOMIC(id_type) value{};
  11461. return value++;
  11462. }
  11463. };
  11464. template<typename Type>
  11465. [[nodiscard]] constexpr auto stripped_type_name() ENTT_NOEXCEPT {
  11466. #if defined ENTT_PRETTY_FUNCTION
  11467. std::string_view pretty_function{ENTT_PRETTY_FUNCTION};
  11468. auto first = pretty_function.find_first_not_of(' ', pretty_function.find_first_of(ENTT_PRETTY_FUNCTION_PREFIX) + 1);
  11469. auto value = pretty_function.substr(first, pretty_function.find_last_of(ENTT_PRETTY_FUNCTION_SUFFIX) - first);
  11470. return value;
  11471. #else
  11472. return std::string_view{""};
  11473. #endif
  11474. }
  11475. template<typename Type, auto = stripped_type_name<Type>().find_first_of('.')>
  11476. [[nodiscard]] static constexpr std::string_view type_name(int) ENTT_NOEXCEPT {
  11477. constexpr auto value = stripped_type_name<Type>();
  11478. return value;
  11479. }
  11480. template<typename Type>
  11481. [[nodiscard]] static std::string_view type_name(char) ENTT_NOEXCEPT {
  11482. static const auto value = stripped_type_name<Type>();
  11483. return value;
  11484. }
  11485. template<typename Type, auto = stripped_type_name<Type>().find_first_of('.')>
  11486. [[nodiscard]] static constexpr id_type type_hash(int) ENTT_NOEXCEPT {
  11487. constexpr auto stripped = stripped_type_name<Type>();
  11488. constexpr auto value = hashed_string::value(stripped.data(), stripped.size());
  11489. return value;
  11490. }
  11491. template<typename Type>
  11492. [[nodiscard]] static id_type type_hash(char) ENTT_NOEXCEPT {
  11493. static const auto value = [](const auto stripped) {
  11494. return hashed_string::value(stripped.data(), stripped.size());
  11495. }(stripped_type_name<Type>());
  11496. return value;
  11497. }
  11498. } // namespace internal
  11499. /**
  11500. * Internal details not to be documented.
  11501. * @endcond
  11502. */
  11503. /**
  11504. * @brief Type sequential identifier.
  11505. * @tparam Type Type for which to generate a sequential identifier.
  11506. */
  11507. template<typename Type, typename = void>
  11508. struct ENTT_API type_index final {
  11509. /**
  11510. * @brief Returns the sequential identifier of a given type.
  11511. * @return The sequential identifier of a given type.
  11512. */
  11513. [[nodiscard]] static id_type value() ENTT_NOEXCEPT {
  11514. static const id_type value = internal::type_index::next();
  11515. return value;
  11516. }
  11517. /*! @copydoc value */
  11518. [[nodiscard]] constexpr operator id_type() const ENTT_NOEXCEPT {
  11519. return value();
  11520. }
  11521. };
  11522. /**
  11523. * @brief Type hash.
  11524. * @tparam Type Type for which to generate a hash value.
  11525. */
  11526. template<typename Type, typename = void>
  11527. struct type_hash final {
  11528. /**
  11529. * @brief Returns the numeric representation of a given type.
  11530. * @return The numeric representation of the given type.
  11531. */
  11532. #if defined ENTT_PRETTY_FUNCTION
  11533. [[nodiscard]] static constexpr id_type value() ENTT_NOEXCEPT {
  11534. return internal::type_hash<Type>(0);
  11535. #else
  11536. [[nodiscard]] static constexpr id_type value() ENTT_NOEXCEPT {
  11537. return type_index<Type>::value();
  11538. #endif
  11539. }
  11540. /*! @copydoc value */
  11541. [[nodiscard]] constexpr operator id_type() const ENTT_NOEXCEPT {
  11542. return value();
  11543. }
  11544. };
  11545. /**
  11546. * @brief Type name.
  11547. * @tparam Type Type for which to generate a name.
  11548. */
  11549. template<typename Type, typename = void>
  11550. struct type_name final {
  11551. /**
  11552. * @brief Returns the name of a given type.
  11553. * @return The name of the given type.
  11554. */
  11555. [[nodiscard]] static constexpr std::string_view value() ENTT_NOEXCEPT {
  11556. return internal::type_name<Type>(0);
  11557. }
  11558. /*! @copydoc value */
  11559. [[nodiscard]] constexpr operator std::string_view() const ENTT_NOEXCEPT {
  11560. return value();
  11561. }
  11562. };
  11563. /*! @brief Implementation specific information about a type. */
  11564. struct type_info final {
  11565. /**
  11566. * @brief Constructs a type info object for a given type.
  11567. * @tparam Type Type for which to construct a type info object.
  11568. */
  11569. template<typename Type>
  11570. constexpr type_info(std::in_place_type_t<Type>) ENTT_NOEXCEPT
  11571. : seq{type_index<std::remove_cv_t<std::remove_reference_t<Type>>>::value()},
  11572. identifier{type_hash<std::remove_cv_t<std::remove_reference_t<Type>>>::value()},
  11573. alias{type_name<std::remove_cv_t<std::remove_reference_t<Type>>>::value()} {}
  11574. /**
  11575. * @brief Type index.
  11576. * @return Type index.
  11577. */
  11578. [[nodiscard]] constexpr id_type index() const ENTT_NOEXCEPT {
  11579. return seq;
  11580. }
  11581. /**
  11582. * @brief Type hash.
  11583. * @return Type hash.
  11584. */
  11585. [[nodiscard]] constexpr id_type hash() const ENTT_NOEXCEPT {
  11586. return identifier;
  11587. }
  11588. /**
  11589. * @brief Type name.
  11590. * @return Type name.
  11591. */
  11592. [[nodiscard]] constexpr std::string_view name() const ENTT_NOEXCEPT {
  11593. return alias;
  11594. }
  11595. private:
  11596. id_type seq;
  11597. id_type identifier;
  11598. std::string_view alias;
  11599. };
  11600. /**
  11601. * @brief Compares the contents of two type info objects.
  11602. * @param lhs A type info object.
  11603. * @param rhs A type info object.
  11604. * @return True if the two type info objects are identical, false otherwise.
  11605. */
  11606. [[nodiscard]] inline constexpr bool operator==(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT {
  11607. return lhs.hash() == rhs.hash();
  11608. }
  11609. /**
  11610. * @brief Compares the contents of two type info objects.
  11611. * @param lhs A type info object.
  11612. * @param rhs A type info object.
  11613. * @return True if the two type info objects differ, false otherwise.
  11614. */
  11615. [[nodiscard]] inline constexpr bool operator!=(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT {
  11616. return !(lhs == rhs);
  11617. }
  11618. /**
  11619. * @brief Compares two type info objects.
  11620. * @param lhs A valid type info object.
  11621. * @param rhs A valid type info object.
  11622. * @return True if the first element is less than the second, false otherwise.
  11623. */
  11624. [[nodiscard]] constexpr bool operator<(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT {
  11625. return lhs.index() < rhs.index();
  11626. }
  11627. /**
  11628. * @brief Compares two type info objects.
  11629. * @param lhs A valid type info object.
  11630. * @param rhs A valid type info object.
  11631. * @return True if the first element is less than or equal to the second, false
  11632. * otherwise.
  11633. */
  11634. [[nodiscard]] constexpr bool operator<=(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT {
  11635. return !(rhs < lhs);
  11636. }
  11637. /**
  11638. * @brief Compares two type info objects.
  11639. * @param lhs A valid type info object.
  11640. * @param rhs A valid type info object.
  11641. * @return True if the first element is greater than the second, false
  11642. * otherwise.
  11643. */
  11644. [[nodiscard]] constexpr bool operator>(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT {
  11645. return rhs < lhs;
  11646. }
  11647. /**
  11648. * @brief Compares two type info objects.
  11649. * @param lhs A valid type info object.
  11650. * @param rhs A valid type info object.
  11651. * @return True if the first element is greater than or equal to the second,
  11652. * false otherwise.
  11653. */
  11654. [[nodiscard]] constexpr bool operator>=(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT {
  11655. return !(lhs < rhs);
  11656. }
  11657. /**
  11658. * @brief Returns the type info object associated to a given type.
  11659. *
  11660. * The returned element refers to an object with static storage duration.<br/>
  11661. * The type doesn't need to be a complete type. If the type is a reference, the
  11662. * result refers to the referenced type. In all cases, top-level cv-qualifiers
  11663. * are ignored.
  11664. *
  11665. * @tparam Type Type for which to generate a type info object.
  11666. * @return A reference to a properly initialized type info object.
  11667. */
  11668. template<typename Type>
  11669. [[nodiscard]] const type_info &type_id() ENTT_NOEXCEPT {
  11670. if constexpr(std::is_same_v<Type, std::remove_cv_t<std::remove_reference_t<Type>>>) {
  11671. static type_info instance{std::in_place_type<Type>};
  11672. return instance;
  11673. } else {
  11674. return type_id<std::remove_cv_t<std::remove_reference_t<Type>>>();
  11675. }
  11676. }
  11677. /*! @copydoc type_id */
  11678. template<typename Type>
  11679. [[nodiscard]] const type_info &type_id(Type &&) ENTT_NOEXCEPT {
  11680. return type_id<std::remove_cv_t<std::remove_reference_t<Type>>>();
  11681. }
  11682. } // namespace entt
  11683. #endif
  11684. // #include "entity.hpp"
  11685. // #include "fwd.hpp"
  11686. namespace entt {
  11687. /**
  11688. * @cond TURN_OFF_DOXYGEN
  11689. * Internal details not to be documented.
  11690. */
  11691. namespace internal {
  11692. template<typename Container>
  11693. struct sparse_set_iterator final {
  11694. using value_type = typename Container::value_type;
  11695. using pointer = typename Container::const_pointer;
  11696. using reference = typename Container::const_reference;
  11697. using difference_type = typename Container::difference_type;
  11698. using iterator_category = std::random_access_iterator_tag;
  11699. sparse_set_iterator() ENTT_NOEXCEPT
  11700. : packed{},
  11701. offset{} {}
  11702. sparse_set_iterator(const Container &ref, const difference_type idx) ENTT_NOEXCEPT
  11703. : packed{std::addressof(ref)},
  11704. offset{idx} {}
  11705. sparse_set_iterator &operator++() ENTT_NOEXCEPT {
  11706. return --offset, *this;
  11707. }
  11708. sparse_set_iterator operator++(int) ENTT_NOEXCEPT {
  11709. sparse_set_iterator orig = *this;
  11710. return ++(*this), orig;
  11711. }
  11712. sparse_set_iterator &operator--() ENTT_NOEXCEPT {
  11713. return ++offset, *this;
  11714. }
  11715. sparse_set_iterator operator--(int) ENTT_NOEXCEPT {
  11716. sparse_set_iterator orig = *this;
  11717. return operator--(), orig;
  11718. }
  11719. sparse_set_iterator &operator+=(const difference_type value) ENTT_NOEXCEPT {
  11720. offset -= value;
  11721. return *this;
  11722. }
  11723. sparse_set_iterator operator+(const difference_type value) const ENTT_NOEXCEPT {
  11724. sparse_set_iterator copy = *this;
  11725. return (copy += value);
  11726. }
  11727. sparse_set_iterator &operator-=(const difference_type value) ENTT_NOEXCEPT {
  11728. return (*this += -value);
  11729. }
  11730. sparse_set_iterator operator-(const difference_type value) const ENTT_NOEXCEPT {
  11731. return (*this + -value);
  11732. }
  11733. [[nodiscard]] reference operator[](const difference_type value) const ENTT_NOEXCEPT {
  11734. return packed->data()[index() - value];
  11735. }
  11736. [[nodiscard]] pointer operator->() const ENTT_NOEXCEPT {
  11737. return packed->data() + index();
  11738. }
  11739. [[nodiscard]] reference operator*() const ENTT_NOEXCEPT {
  11740. return *operator->();
  11741. }
  11742. [[nodiscard]] difference_type index() const ENTT_NOEXCEPT {
  11743. return offset - 1;
  11744. }
  11745. private:
  11746. const Container *packed;
  11747. difference_type offset;
  11748. };
  11749. template<typename Type, typename Other>
  11750. [[nodiscard]] std::ptrdiff_t operator-(const sparse_set_iterator<Type> &lhs, const sparse_set_iterator<Other> &rhs) ENTT_NOEXCEPT {
  11751. return rhs.index() - lhs.index();
  11752. }
  11753. template<typename Type, typename Other>
  11754. [[nodiscard]] bool operator==(const sparse_set_iterator<Type> &lhs, const sparse_set_iterator<Other> &rhs) ENTT_NOEXCEPT {
  11755. return lhs.index() == rhs.index();
  11756. }
  11757. template<typename Type, typename Other>
  11758. [[nodiscard]] bool operator!=(const sparse_set_iterator<Type> &lhs, const sparse_set_iterator<Other> &rhs) ENTT_NOEXCEPT {
  11759. return !(lhs == rhs);
  11760. }
  11761. template<typename Type, typename Other>
  11762. [[nodiscard]] bool operator<(const sparse_set_iterator<Type> &lhs, const sparse_set_iterator<Other> &rhs) ENTT_NOEXCEPT {
  11763. return lhs.index() > rhs.index();
  11764. }
  11765. template<typename Type, typename Other>
  11766. [[nodiscard]] bool operator>(const sparse_set_iterator<Type> &lhs, const sparse_set_iterator<Other> &rhs) ENTT_NOEXCEPT {
  11767. return lhs.index() < rhs.index();
  11768. }
  11769. template<typename Type, typename Other>
  11770. [[nodiscard]] bool operator<=(const sparse_set_iterator<Type> &lhs, const sparse_set_iterator<Other> &rhs) ENTT_NOEXCEPT {
  11771. return !(lhs > rhs);
  11772. }
  11773. template<typename Type, typename Other>
  11774. [[nodiscard]] bool operator>=(const sparse_set_iterator<Type> &lhs, const sparse_set_iterator<Other> &rhs) ENTT_NOEXCEPT {
  11775. return !(lhs < rhs);
  11776. }
  11777. } // namespace internal
  11778. /**
  11779. * Internal details not to be documented.
  11780. * @endcond
  11781. */
  11782. /*! @brief Sparse set deletion policy. */
  11783. enum class deletion_policy : std::uint8_t {
  11784. /*! @brief Swap-and-pop deletion policy. */
  11785. swap_and_pop = 0u,
  11786. /*! @brief In-place deletion policy. */
  11787. in_place = 1u
  11788. };
  11789. /**
  11790. * @brief Basic sparse set implementation.
  11791. *
  11792. * Sparse set or packed array or whatever is the name users give it.<br/>
  11793. * Two arrays: an _external_ one and an _internal_ one; a _sparse_ one and a
  11794. * _packed_ one; one used for direct access through contiguous memory, the other
  11795. * one used to get the data through an extra level of indirection.<br/>
  11796. * This is largely used by the registry to offer users the fastest access ever
  11797. * to the components. Views and groups in general are almost entirely designed
  11798. * around sparse sets.
  11799. *
  11800. * This type of data structure is widely documented in the literature and on the
  11801. * web. This is nothing more than a customized implementation suitable for the
  11802. * purpose of the framework.
  11803. *
  11804. * @note
  11805. * Internal data structures arrange elements to maximize performance. There are
  11806. * no guarantees that entities are returned in the insertion order when iterate
  11807. * a sparse set. Do not make assumption on the order in any case.
  11808. *
  11809. * @tparam Entity A valid entity type (see entt_traits for more details).
  11810. * @tparam Allocator Type of allocator used to manage memory and elements.
  11811. */
  11812. template<typename Entity, typename Allocator>
  11813. class basic_sparse_set {
  11814. using alloc_traits = std::allocator_traits<Allocator>;
  11815. static_assert(std::is_same_v<typename alloc_traits::value_type, Entity>, "Invalid value type");
  11816. using sparse_container_type = std::vector<typename alloc_traits::pointer, typename alloc_traits::template rebind_alloc<typename alloc_traits::pointer>>;
  11817. using packed_container_type = std::vector<Entity, Allocator>;
  11818. using entity_traits = entt_traits<Entity>;
  11819. [[nodiscard]] auto sparse_ptr(const Entity entt) const {
  11820. const auto pos = static_cast<size_type>(entity_traits::to_entity(entt));
  11821. const auto page = pos / entity_traits::page_size;
  11822. return (page < sparse.size() && sparse[page]) ? (sparse[page] + fast_mod(pos, entity_traits::page_size)) : nullptr;
  11823. }
  11824. [[nodiscard]] auto &sparse_ref(const Entity entt) const {
  11825. ENTT_ASSERT(sparse_ptr(entt), "Invalid element");
  11826. const auto pos = static_cast<size_type>(entity_traits::to_entity(entt));
  11827. return sparse[pos / entity_traits::page_size][fast_mod(pos, entity_traits::page_size)];
  11828. }
  11829. [[nodiscard]] auto &assure_at_least(const Entity entt) {
  11830. const auto pos = static_cast<size_type>(entity_traits::to_entity(entt));
  11831. const auto page = pos / entity_traits::page_size;
  11832. if(!(page < sparse.size())) {
  11833. sparse.resize(page + 1u, nullptr);
  11834. }
  11835. if(!sparse[page]) {
  11836. auto page_allocator{packed.get_allocator()};
  11837. sparse[page] = alloc_traits::allocate(page_allocator, entity_traits::page_size);
  11838. std::uninitialized_fill(sparse[page], sparse[page] + entity_traits::page_size, null);
  11839. }
  11840. auto &elem = sparse[page][fast_mod(pos, entity_traits::page_size)];
  11841. ENTT_ASSERT(entity_traits::to_version(elem) == entity_traits::to_version(tombstone), "Slot not available");
  11842. return elem;
  11843. }
  11844. void release_sparse_pages() {
  11845. auto page_allocator{packed.get_allocator()};
  11846. for(auto &&page: sparse) {
  11847. if(page != nullptr) {
  11848. std::destroy(page, page + entity_traits::page_size);
  11849. alloc_traits::deallocate(page_allocator, page, entity_traits::page_size);
  11850. page = nullptr;
  11851. }
  11852. }
  11853. }
  11854. private:
  11855. virtual const void *get_at(const std::size_t) const {
  11856. return nullptr;
  11857. }
  11858. virtual void swap_at(const std::size_t, const std::size_t) {}
  11859. virtual void move_element(const std::size_t, const std::size_t) {}
  11860. protected:
  11861. /*! @brief Random access iterator type. */
  11862. using basic_iterator = internal::sparse_set_iterator<packed_container_type>;
  11863. /**
  11864. * @brief Erases entities from a sparse set.
  11865. * @param first An iterator to the first element of the range of entities.
  11866. * @param last An iterator past the last element of the range of entities.
  11867. */
  11868. virtual void swap_and_pop(basic_iterator first, basic_iterator last) {
  11869. for(; first != last; ++first) {
  11870. auto &self = sparse_ref(*first);
  11871. const auto entt = entity_traits::to_entity(self);
  11872. sparse_ref(packed.back()) = entity_traits::combine(entt, entity_traits::to_integral(packed.back()));
  11873. packed[static_cast<size_type>(entt)] = packed.back();
  11874. // unnecessary but it helps to detect nasty bugs
  11875. ENTT_ASSERT((packed.back() = tombstone, true), "");
  11876. // lazy self-assignment guard
  11877. self = null;
  11878. packed.pop_back();
  11879. }
  11880. }
  11881. /**
  11882. * @brief Erases entities from a sparse set.
  11883. * @param first An iterator to the first element of the range of entities.
  11884. * @param last An iterator past the last element of the range of entities.
  11885. */
  11886. virtual void in_place_pop(basic_iterator first, basic_iterator last) {
  11887. for(; first != last; ++first) {
  11888. const auto entt = entity_traits::to_entity(std::exchange(sparse_ref(*first), null));
  11889. packed[static_cast<size_type>(entt)] = std::exchange(free_list, entity_traits::combine(entt, entity_traits::reserved));
  11890. }
  11891. }
  11892. /**
  11893. * @brief Assigns an entity to a sparse set.
  11894. * @param entt A valid identifier.
  11895. * @param force_back Force back insertion.
  11896. * @return Iterator pointing to the emplaced element.
  11897. */
  11898. virtual basic_iterator try_emplace(const Entity entt, const bool force_back, const void * = nullptr) {
  11899. ENTT_ASSERT(!contains(entt), "Set already contains entity");
  11900. if(auto &elem = assure_at_least(entt); free_list == null || force_back) {
  11901. packed.push_back(entt);
  11902. elem = entity_traits::combine(static_cast<typename entity_traits::entity_type>(packed.size() - 1u), entity_traits::to_integral(entt));
  11903. return begin();
  11904. } else {
  11905. const auto pos = static_cast<size_type>(entity_traits::to_entity(free_list));
  11906. elem = entity_traits::combine(entity_traits::to_integral(free_list), entity_traits::to_integral(entt));
  11907. free_list = std::exchange(packed[pos], entt);
  11908. return --(end() - pos);
  11909. }
  11910. }
  11911. public:
  11912. /*! @brief Allocator type. */
  11913. using allocator_type = Allocator;
  11914. /*! @brief Underlying entity identifier. */
  11915. using entity_type = Entity;
  11916. /*! @brief Underlying version type. */
  11917. using version_type = typename entity_traits::version_type;
  11918. /*! @brief Unsigned integer type. */
  11919. using size_type = typename packed_container_type::size_type;
  11920. /*! @brief Pointer type to contained entities. */
  11921. using pointer = typename packed_container_type::const_pointer;
  11922. /*! @brief Random access iterator type. */
  11923. using iterator = basic_iterator;
  11924. /*! @brief Constant random access iterator type. */
  11925. using const_iterator = iterator;
  11926. /*! @brief Reverse iterator type. */
  11927. using reverse_iterator = std::reverse_iterator<iterator>;
  11928. /*! @brief Constant reverse iterator type. */
  11929. using const_reverse_iterator = reverse_iterator;
  11930. /*! @brief Default constructor. */
  11931. basic_sparse_set()
  11932. : basic_sparse_set{type_id<void>()} {}
  11933. /**
  11934. * @brief Constructs an empty container with a given allocator.
  11935. * @param allocator The allocator to use.
  11936. */
  11937. explicit basic_sparse_set(const allocator_type &allocator)
  11938. : basic_sparse_set{type_id<void>(), deletion_policy::swap_and_pop, allocator} {}
  11939. /**
  11940. * @brief Constructs an empty container with the given policy and allocator.
  11941. * @param pol Type of deletion policy.
  11942. * @param allocator The allocator to use (possibly default-constructed).
  11943. */
  11944. explicit basic_sparse_set(deletion_policy pol, const allocator_type &allocator = {})
  11945. : basic_sparse_set{type_id<void>(), pol, allocator} {}
  11946. /**
  11947. * @brief Constructs an empty container with the given value type, policy
  11948. * and allocator.
  11949. * @param value Returned value type, if any.
  11950. * @param pol Type of deletion policy.
  11951. * @param allocator The allocator to use (possibly default-constructed).
  11952. */
  11953. explicit basic_sparse_set(const type_info &value, deletion_policy pol = deletion_policy::swap_and_pop, const allocator_type &allocator = {})
  11954. : sparse{allocator},
  11955. packed{allocator},
  11956. info{&value},
  11957. free_list{tombstone},
  11958. mode{pol} {}
  11959. /**
  11960. * @brief Move constructor.
  11961. * @param other The instance to move from.
  11962. */
  11963. basic_sparse_set(basic_sparse_set &&other) ENTT_NOEXCEPT
  11964. : sparse{std::move(other.sparse)},
  11965. packed{std::move(other.packed)},
  11966. info{other.info},
  11967. free_list{std::exchange(other.free_list, tombstone)},
  11968. mode{other.mode} {}
  11969. /**
  11970. * @brief Allocator-extended move constructor.
  11971. * @param other The instance to move from.
  11972. * @param allocator The allocator to use.
  11973. */
  11974. basic_sparse_set(basic_sparse_set &&other, const allocator_type &allocator) ENTT_NOEXCEPT
  11975. : sparse{std::move(other.sparse), allocator},
  11976. packed{std::move(other.packed), allocator},
  11977. info{other.info},
  11978. free_list{std::exchange(other.free_list, tombstone)},
  11979. mode{other.mode} {
  11980. ENTT_ASSERT(alloc_traits::is_always_equal::value || packed.get_allocator() == other.packed.get_allocator(), "Copying a sparse set is not allowed");
  11981. }
  11982. /*! @brief Default destructor. */
  11983. virtual ~basic_sparse_set() {
  11984. release_sparse_pages();
  11985. }
  11986. /**
  11987. * @brief Move assignment operator.
  11988. * @param other The instance to move from.
  11989. * @return This sparse set.
  11990. */
  11991. basic_sparse_set &operator=(basic_sparse_set &&other) ENTT_NOEXCEPT {
  11992. ENTT_ASSERT(alloc_traits::is_always_equal::value || packed.get_allocator() == other.packed.get_allocator(), "Copying a sparse set is not allowed");
  11993. release_sparse_pages();
  11994. sparse = std::move(other.sparse);
  11995. packed = std::move(other.packed);
  11996. info = other.info;
  11997. free_list = std::exchange(other.free_list, tombstone);
  11998. mode = other.mode;
  11999. return *this;
  12000. }
  12001. /**
  12002. * @brief Exchanges the contents with those of a given sparse set.
  12003. * @param other Sparse set to exchange the content with.
  12004. */
  12005. void swap(basic_sparse_set &other) {
  12006. using std::swap;
  12007. swap(sparse, other.sparse);
  12008. swap(packed, other.packed);
  12009. swap(info, other.info);
  12010. swap(free_list, other.free_list);
  12011. swap(mode, other.mode);
  12012. }
  12013. /**
  12014. * @brief Returns the associated allocator.
  12015. * @return The associated allocator.
  12016. */
  12017. [[nodiscard]] constexpr allocator_type get_allocator() const ENTT_NOEXCEPT {
  12018. return packed.get_allocator();
  12019. }
  12020. /**
  12021. * @brief Returns the deletion policy of a sparse set.
  12022. * @return The deletion policy of the sparse set.
  12023. */
  12024. [[nodiscard]] deletion_policy policy() const ENTT_NOEXCEPT {
  12025. return mode;
  12026. }
  12027. /**
  12028. * @brief Increases the capacity of a sparse set.
  12029. *
  12030. * If the new capacity is greater than the current capacity, new storage is
  12031. * allocated, otherwise the method does nothing.
  12032. *
  12033. * @param cap Desired capacity.
  12034. */
  12035. virtual void reserve(const size_type cap) {
  12036. packed.reserve(cap);
  12037. }
  12038. /**
  12039. * @brief Returns the number of elements that a sparse set has currently
  12040. * allocated space for.
  12041. * @return Capacity of the sparse set.
  12042. */
  12043. [[nodiscard]] virtual size_type capacity() const ENTT_NOEXCEPT {
  12044. return packed.capacity();
  12045. }
  12046. /*! @brief Requests the removal of unused capacity. */
  12047. virtual void shrink_to_fit() {
  12048. packed.shrink_to_fit();
  12049. }
  12050. /**
  12051. * @brief Returns the extent of a sparse set.
  12052. *
  12053. * The extent of a sparse set is also the size of the internal sparse array.
  12054. * There is no guarantee that the internal packed array has the same size.
  12055. * Usually the size of the internal sparse array is equal or greater than
  12056. * the one of the internal packed array.
  12057. *
  12058. * @return Extent of the sparse set.
  12059. */
  12060. [[nodiscard]] size_type extent() const ENTT_NOEXCEPT {
  12061. return sparse.size() * entity_traits::page_size;
  12062. }
  12063. /**
  12064. * @brief Returns the number of elements in a sparse set.
  12065. *
  12066. * The number of elements is also the size of the internal packed array.
  12067. * There is no guarantee that the internal sparse array has the same size.
  12068. * Usually the size of the internal sparse array is equal or greater than
  12069. * the one of the internal packed array.
  12070. *
  12071. * @return Number of elements.
  12072. */
  12073. [[nodiscard]] size_type size() const ENTT_NOEXCEPT {
  12074. return packed.size();
  12075. }
  12076. /**
  12077. * @brief Checks whether a sparse set is empty.
  12078. * @return True if the sparse set is empty, false otherwise.
  12079. */
  12080. [[nodiscard]] bool empty() const ENTT_NOEXCEPT {
  12081. return packed.empty();
  12082. }
  12083. /**
  12084. * @brief Direct access to the internal packed array.
  12085. * @return A pointer to the internal packed array.
  12086. */
  12087. [[nodiscard]] pointer data() const ENTT_NOEXCEPT {
  12088. return packed.data();
  12089. }
  12090. /**
  12091. * @brief Returns an iterator to the beginning.
  12092. *
  12093. * The returned iterator points to the first entity of the internal packed
  12094. * array. If the sparse set is empty, the returned iterator will be equal to
  12095. * `end()`.
  12096. *
  12097. * @return An iterator to the first entity of the sparse set.
  12098. */
  12099. [[nodiscard]] const_iterator begin() const ENTT_NOEXCEPT {
  12100. const auto pos = static_cast<typename iterator::difference_type>(packed.size());
  12101. return iterator{packed, pos};
  12102. }
  12103. /*! @copydoc begin */
  12104. [[nodiscard]] const_iterator cbegin() const ENTT_NOEXCEPT {
  12105. return begin();
  12106. }
  12107. /**
  12108. * @brief Returns an iterator to the end.
  12109. *
  12110. * The returned iterator points to the element following the last entity in
  12111. * a sparse set. Attempting to dereference the returned iterator results in
  12112. * undefined behavior.
  12113. *
  12114. * @return An iterator to the element following the last entity of a sparse
  12115. * set.
  12116. */
  12117. [[nodiscard]] iterator end() const ENTT_NOEXCEPT {
  12118. return iterator{packed, {}};
  12119. }
  12120. /*! @copydoc end */
  12121. [[nodiscard]] const_iterator cend() const ENTT_NOEXCEPT {
  12122. return end();
  12123. }
  12124. /**
  12125. * @brief Returns a reverse iterator to the beginning.
  12126. *
  12127. * The returned iterator points to the first entity of the reversed internal
  12128. * packed array. If the sparse set is empty, the returned iterator will be
  12129. * equal to `rend()`.
  12130. *
  12131. * @return An iterator to the first entity of the reversed internal packed
  12132. * array.
  12133. */
  12134. [[nodiscard]] const_reverse_iterator rbegin() const ENTT_NOEXCEPT {
  12135. return std::make_reverse_iterator(end());
  12136. }
  12137. /*! @copydoc rbegin */
  12138. [[nodiscard]] const_reverse_iterator crbegin() const ENTT_NOEXCEPT {
  12139. return rbegin();
  12140. }
  12141. /**
  12142. * @brief Returns a reverse iterator to the end.
  12143. *
  12144. * The returned iterator points to the element following the last entity in
  12145. * the reversed sparse set. Attempting to dereference the returned iterator
  12146. * results in undefined behavior.
  12147. *
  12148. * @return An iterator to the element following the last entity of the
  12149. * reversed sparse set.
  12150. */
  12151. [[nodiscard]] reverse_iterator rend() const ENTT_NOEXCEPT {
  12152. return std::make_reverse_iterator(begin());
  12153. }
  12154. /*! @copydoc rend */
  12155. [[nodiscard]] const_reverse_iterator crend() const ENTT_NOEXCEPT {
  12156. return rend();
  12157. }
  12158. /**
  12159. * @brief Finds an entity.
  12160. * @param entt A valid identifier.
  12161. * @return An iterator to the given entity if it's found, past the end
  12162. * iterator otherwise.
  12163. */
  12164. [[nodiscard]] iterator find(const entity_type entt) const ENTT_NOEXCEPT {
  12165. return contains(entt) ? --(end() - index(entt)) : end();
  12166. }
  12167. /**
  12168. * @brief Checks if a sparse set contains an entity.
  12169. * @param entt A valid identifier.
  12170. * @return True if the sparse set contains the entity, false otherwise.
  12171. */
  12172. [[nodiscard]] bool contains(const entity_type entt) const ENTT_NOEXCEPT {
  12173. const auto elem = sparse_ptr(entt);
  12174. constexpr auto cap = entity_traits::to_entity(null);
  12175. // testing versions permits to avoid accessing the packed array
  12176. return elem && (((~cap & entity_traits::to_integral(entt)) ^ entity_traits::to_integral(*elem)) < cap);
  12177. }
  12178. /**
  12179. * @brief Returns the contained version for an identifier.
  12180. * @param entt A valid identifier.
  12181. * @return The version for the given identifier if present, the tombstone
  12182. * version otherwise.
  12183. */
  12184. [[nodiscard]] version_type current(const entity_type entt) const ENTT_NOEXCEPT {
  12185. const auto elem = sparse_ptr(entt);
  12186. constexpr auto fallback = entity_traits::to_version(tombstone);
  12187. return elem ? entity_traits::to_version(*elem) : fallback;
  12188. }
  12189. /**
  12190. * @brief Returns the position of an entity in a sparse set.
  12191. *
  12192. * @warning
  12193. * Attempting to get the position of an entity that doesn't belong to the
  12194. * sparse set results in undefined behavior.
  12195. *
  12196. * @param entt A valid identifier.
  12197. * @return The position of the entity in the sparse set.
  12198. */
  12199. [[nodiscard]] size_type index(const entity_type entt) const ENTT_NOEXCEPT {
  12200. ENTT_ASSERT(contains(entt), "Set does not contain entity");
  12201. return static_cast<size_type>(entity_traits::to_entity(sparse_ref(entt)));
  12202. }
  12203. /**
  12204. * @brief Returns the entity at specified location, with bounds checking.
  12205. * @param pos The position for which to return the entity.
  12206. * @return The entity at specified location if any, a null entity otherwise.
  12207. */
  12208. [[nodiscard]] entity_type at(const size_type pos) const ENTT_NOEXCEPT {
  12209. return pos < packed.size() ? packed[pos] : null;
  12210. }
  12211. /**
  12212. * @brief Returns the entity at specified location, without bounds checking.
  12213. * @param pos The position for which to return the entity.
  12214. * @return The entity at specified location.
  12215. */
  12216. [[nodiscard]] entity_type operator[](const size_type pos) const ENTT_NOEXCEPT {
  12217. ENTT_ASSERT(pos < packed.size(), "Position is out of bounds");
  12218. return packed[pos];
  12219. }
  12220. /**
  12221. * @brief Returns the element assigned to an entity, if any.
  12222. *
  12223. * @warning
  12224. * Attempting to use an entity that doesn't belong to the sparse set results
  12225. * in undefined behavior.
  12226. *
  12227. * @param entt A valid identifier.
  12228. * @return An opaque pointer to the element assigned to the entity, if any.
  12229. */
  12230. const void *get(const entity_type entt) const ENTT_NOEXCEPT {
  12231. return get_at(index(entt));
  12232. }
  12233. /*! @copydoc get */
  12234. void *get(const entity_type entt) ENTT_NOEXCEPT {
  12235. return const_cast<void *>(std::as_const(*this).get(entt));
  12236. }
  12237. /**
  12238. * @brief Assigns an entity to a sparse set.
  12239. *
  12240. * @warning
  12241. * Attempting to assign an entity that already belongs to the sparse set
  12242. * results in undefined behavior.
  12243. *
  12244. * @param entt A valid identifier.
  12245. * @param value Optional opaque value to forward to mixins, if any.
  12246. * @return Iterator pointing to the emplaced element in case of success, the
  12247. * `end()` iterator otherwise.
  12248. */
  12249. iterator emplace(const entity_type entt, const void *value = nullptr) {
  12250. return try_emplace(entt, false, value);
  12251. }
  12252. /**
  12253. * @brief Bump the version number of an entity.
  12254. *
  12255. * @warning
  12256. * Attempting to bump the version of an entity that doesn't belong to the
  12257. * sparse set results in undefined behavior.
  12258. *
  12259. * @param entt A valid identifier.
  12260. */
  12261. void bump(const entity_type entt) {
  12262. auto &entity = sparse_ref(entt);
  12263. entity = entity_traits::combine(entity_traits::to_integral(entity), entity_traits::to_integral(entt));
  12264. packed[static_cast<size_type>(entity_traits::to_entity(entity))] = entt;
  12265. }
  12266. /**
  12267. * @brief Assigns one or more entities to a sparse set.
  12268. *
  12269. * @warning
  12270. * Attempting to assign an entity that already belongs to the sparse set
  12271. * results in undefined behavior.
  12272. *
  12273. * @tparam It Type of input iterator.
  12274. * @param first An iterator to the first element of the range of entities.
  12275. * @param last An iterator past the last element of the range of entities.
  12276. * @return Iterator pointing to the first element inserted in case of
  12277. * success, the `end()` iterator otherwise.
  12278. */
  12279. template<typename It>
  12280. iterator insert(It first, It last) {
  12281. for(auto it = first; it != last; ++it) {
  12282. try_emplace(*it, true);
  12283. }
  12284. return first == last ? end() : find(*first);
  12285. }
  12286. /**
  12287. * @brief Erases an entity from a sparse set.
  12288. *
  12289. * @warning
  12290. * Attempting to erase an entity that doesn't belong to the sparse set
  12291. * results in undefined behavior.
  12292. *
  12293. * @param entt A valid identifier.
  12294. */
  12295. void erase(const entity_type entt) {
  12296. const auto it = --(end() - index(entt));
  12297. (mode == deletion_policy::in_place) ? in_place_pop(it, it + 1u) : swap_and_pop(it, it + 1u);
  12298. }
  12299. /**
  12300. * @brief Erases entities from a set.
  12301. *
  12302. * @sa erase
  12303. *
  12304. * @tparam It Type of input iterator.
  12305. * @param first An iterator to the first element of the range of entities.
  12306. * @param last An iterator past the last element of the range of entities.
  12307. */
  12308. template<typename It>
  12309. void erase(It first, It last) {
  12310. if constexpr(std::is_same_v<It, basic_iterator>) {
  12311. (mode == deletion_policy::in_place) ? in_place_pop(first, last) : swap_and_pop(first, last);
  12312. } else {
  12313. for(; first != last; ++first) {
  12314. erase(*first);
  12315. }
  12316. }
  12317. }
  12318. /**
  12319. * @brief Removes an entity from a sparse set if it exists.
  12320. * @param entt A valid identifier.
  12321. * @return True if the entity is actually removed, false otherwise.
  12322. */
  12323. bool remove(const entity_type entt) {
  12324. return contains(entt) && (erase(entt), true);
  12325. }
  12326. /**
  12327. * @brief Removes entities from a sparse set if they exist.
  12328. * @tparam It Type of input iterator.
  12329. * @param first An iterator to the first element of the range of entities.
  12330. * @param last An iterator past the last element of the range of entities.
  12331. * @return The number of entities actually removed.
  12332. */
  12333. template<typename It>
  12334. size_type remove(It first, It last) {
  12335. size_type count{};
  12336. for(; first != last; ++first) {
  12337. count += remove(*first);
  12338. }
  12339. return count;
  12340. }
  12341. /*! @brief Removes all tombstones from the packed array of a sparse set. */
  12342. void compact() {
  12343. size_type from = packed.size();
  12344. for(; from && packed[from - 1u] == tombstone; --from) {}
  12345. for(auto *it = &free_list; *it != null && from; it = std::addressof(packed[entity_traits::to_entity(*it)])) {
  12346. if(const size_type to = entity_traits::to_entity(*it); to < from) {
  12347. --from;
  12348. move_element(from, to);
  12349. using std::swap;
  12350. swap(packed[from], packed[to]);
  12351. const auto entity = static_cast<typename entity_traits::entity_type>(to);
  12352. sparse_ref(packed[to]) = entity_traits::combine(entity, entity_traits::to_integral(packed[to]));
  12353. *it = entity_traits::combine(static_cast<typename entity_traits::entity_type>(from), entity_traits::reserved);
  12354. for(; from && packed[from - 1u] == tombstone; --from) {}
  12355. }
  12356. }
  12357. free_list = tombstone;
  12358. packed.resize(from);
  12359. }
  12360. /**
  12361. * @brief Swaps two entities in a sparse set.
  12362. *
  12363. * For what it's worth, this function affects both the internal sparse array
  12364. * and the internal packed array. Users should not care of that anyway.
  12365. *
  12366. * @warning
  12367. * Attempting to swap entities that don't belong to the sparse set results
  12368. * in undefined behavior.
  12369. *
  12370. * @param lhs A valid identifier.
  12371. * @param rhs A valid identifier.
  12372. */
  12373. void swap_elements(const entity_type lhs, const entity_type rhs) {
  12374. ENTT_ASSERT(contains(lhs) && contains(rhs), "Set does not contain entities");
  12375. auto &entt = sparse_ref(lhs);
  12376. auto &other = sparse_ref(rhs);
  12377. const auto from = entity_traits::to_entity(entt);
  12378. const auto to = entity_traits::to_entity(other);
  12379. // basic no-leak guarantee (with invalid state) if swapping throws
  12380. swap_at(static_cast<size_type>(from), static_cast<size_type>(to));
  12381. entt = entity_traits::combine(to, entity_traits::to_integral(packed[from]));
  12382. other = entity_traits::combine(from, entity_traits::to_integral(packed[to]));
  12383. using std::swap;
  12384. swap(packed[from], packed[to]);
  12385. }
  12386. /**
  12387. * @brief Sort the first count elements according to the given comparison
  12388. * function.
  12389. *
  12390. * The comparison function object must return `true` if the first element
  12391. * is _less_ than the second one, `false` otherwise. The signature of the
  12392. * comparison function should be equivalent to the following:
  12393. *
  12394. * @code{.cpp}
  12395. * bool(const Entity, const Entity);
  12396. * @endcode
  12397. *
  12398. * Moreover, the comparison function object shall induce a
  12399. * _strict weak ordering_ on the values.
  12400. *
  12401. * The sort function object must offer a member function template
  12402. * `operator()` that accepts three arguments:
  12403. *
  12404. * * An iterator to the first element of the range to sort.
  12405. * * An iterator past the last element of the range to sort.
  12406. * * A comparison function to use to compare the elements.
  12407. *
  12408. * @tparam Compare Type of comparison function object.
  12409. * @tparam Sort Type of sort function object.
  12410. * @tparam Args Types of arguments to forward to the sort function object.
  12411. * @param length Number of elements to sort.
  12412. * @param compare A valid comparison function object.
  12413. * @param algo A valid sort function object.
  12414. * @param args Arguments to forward to the sort function object, if any.
  12415. */
  12416. template<typename Compare, typename Sort = std_sort, typename... Args>
  12417. void sort_n(const size_type length, Compare compare, Sort algo = Sort{}, Args &&...args) {
  12418. ENTT_ASSERT(!(length > packed.size()), "Length exceeds the number of elements");
  12419. ENTT_ASSERT(free_list == null, "Partial sorting with tombstones is not supported");
  12420. algo(packed.rend() - length, packed.rend(), std::move(compare), std::forward<Args>(args)...);
  12421. for(size_type pos{}; pos < length; ++pos) {
  12422. auto curr = pos;
  12423. auto next = index(packed[curr]);
  12424. while(curr != next) {
  12425. const auto idx = index(packed[next]);
  12426. const auto entt = packed[curr];
  12427. swap_at(next, idx);
  12428. const auto entity = static_cast<typename entity_traits::entity_type>(curr);
  12429. sparse_ref(entt) = entity_traits::combine(entity, entity_traits::to_integral(packed[curr]));
  12430. curr = std::exchange(next, idx);
  12431. }
  12432. }
  12433. }
  12434. /**
  12435. * @brief Sort all elements according to the given comparison function.
  12436. *
  12437. * @sa sort_n
  12438. *
  12439. * @tparam Compare Type of comparison function object.
  12440. * @tparam Sort Type of sort function object.
  12441. * @tparam Args Types of arguments to forward to the sort function object.
  12442. * @param compare A valid comparison function object.
  12443. * @param algo A valid sort function object.
  12444. * @param args Arguments to forward to the sort function object, if any.
  12445. */
  12446. template<typename Compare, typename Sort = std_sort, typename... Args>
  12447. void sort(Compare compare, Sort algo = Sort{}, Args &&...args) {
  12448. compact();
  12449. sort_n(packed.size(), std::move(compare), std::move(algo), std::forward<Args>(args)...);
  12450. }
  12451. /**
  12452. * @brief Sort entities according to their order in another sparse set.
  12453. *
  12454. * Entities that are part of both the sparse sets are ordered internally
  12455. * according to the order they have in `other`. All the other entities goes
  12456. * to the end of the list and there are no guarantees on their order.<br/>
  12457. * In other terms, this function can be used to impose the same order on two
  12458. * sets by using one of them as a master and the other one as a slave.
  12459. *
  12460. * Iterating the sparse set with a couple of iterators returns elements in
  12461. * the expected order after a call to `respect`. See `begin` and `end` for
  12462. * more details.
  12463. *
  12464. * @param other The sparse sets that imposes the order of the entities.
  12465. */
  12466. void respect(const basic_sparse_set &other) {
  12467. compact();
  12468. const auto to = other.end();
  12469. auto from = other.begin();
  12470. for(size_type pos = packed.size() - 1; pos && from != to; ++from) {
  12471. if(contains(*from)) {
  12472. if(*from != packed[pos]) {
  12473. // basic no-leak guarantee (with invalid state) if swapping throws
  12474. swap_elements(packed[pos], *from);
  12475. }
  12476. --pos;
  12477. }
  12478. }
  12479. }
  12480. /*! @brief Clears a sparse set. */
  12481. void clear() {
  12482. if(const auto last = end(); free_list == null) {
  12483. in_place_pop(begin(), last);
  12484. } else {
  12485. for(auto &&entity: *this) {
  12486. // tombstone filter on itself
  12487. if(const auto it = find(entity); it != last) {
  12488. in_place_pop(it, it + 1u);
  12489. }
  12490. }
  12491. }
  12492. free_list = tombstone;
  12493. packed.clear();
  12494. }
  12495. /**
  12496. * @brief Returned value type, if any.
  12497. * @return Returned value type, if any.
  12498. */
  12499. const type_info &type() const ENTT_NOEXCEPT {
  12500. return *info;
  12501. }
  12502. /*! @brief Forwards variables to mixins, if any. */
  12503. virtual void bind(any) ENTT_NOEXCEPT {}
  12504. private:
  12505. sparse_container_type sparse;
  12506. packed_container_type packed;
  12507. const type_info *info;
  12508. entity_type free_list;
  12509. deletion_policy mode;
  12510. };
  12511. } // namespace entt
  12512. #endif
  12513. // #include "storage.hpp"
  12514. #ifndef ENTT_ENTITY_STORAGE_HPP
  12515. #define ENTT_ENTITY_STORAGE_HPP
  12516. #include <cstddef>
  12517. #include <iterator>
  12518. #include <memory>
  12519. #include <tuple>
  12520. #include <type_traits>
  12521. #include <utility>
  12522. #include <vector>
  12523. // #include "../config/config.h"
  12524. // #include "../core/compressed_pair.hpp"
  12525. #ifndef ENTT_CORE_COMPRESSED_PAIR_HPP
  12526. #define ENTT_CORE_COMPRESSED_PAIR_HPP
  12527. #include <cstddef>
  12528. #include <tuple>
  12529. #include <type_traits>
  12530. #include <utility>
  12531. // #include "../config/config.h"
  12532. // #include "type_traits.hpp"
  12533. namespace entt {
  12534. /**
  12535. * @cond TURN_OFF_DOXYGEN
  12536. * Internal details not to be documented.
  12537. */
  12538. namespace internal {
  12539. template<typename Type, std::size_t, typename = void>
  12540. struct compressed_pair_element {
  12541. using reference = Type &;
  12542. using const_reference = const Type &;
  12543. template<bool Dummy = true, typename = std::enable_if_t<Dummy && std::is_default_constructible_v<Type>>>
  12544. compressed_pair_element()
  12545. : value{} {}
  12546. template<typename Args, typename = std::enable_if_t<!std::is_same_v<std::remove_cv_t<std::remove_reference_t<Args>>, compressed_pair_element>>>
  12547. compressed_pair_element(Args &&args)
  12548. : value{std::forward<Args>(args)} {}
  12549. template<typename... Args, std::size_t... Index>
  12550. compressed_pair_element(std::tuple<Args...> args, std::index_sequence<Index...>)
  12551. : value{std::forward<Args>(std::get<Index>(args))...} {}
  12552. [[nodiscard]] reference get() ENTT_NOEXCEPT {
  12553. return value;
  12554. }
  12555. [[nodiscard]] const_reference get() const ENTT_NOEXCEPT {
  12556. return value;
  12557. }
  12558. private:
  12559. Type value;
  12560. };
  12561. template<typename Type, std::size_t Tag>
  12562. struct compressed_pair_element<Type, Tag, std::enable_if_t<is_ebco_eligible_v<Type>>>: Type {
  12563. using reference = Type &;
  12564. using const_reference = const Type &;
  12565. using base_type = Type;
  12566. template<bool Dummy = true, typename = std::enable_if_t<Dummy && std::is_default_constructible_v<base_type>>>
  12567. compressed_pair_element()
  12568. : base_type{} {}
  12569. template<typename Args, typename = std::enable_if_t<!std::is_same_v<std::remove_cv_t<std::remove_reference_t<Args>>, compressed_pair_element>>>
  12570. compressed_pair_element(Args &&args)
  12571. : base_type{std::forward<Args>(args)} {}
  12572. template<typename... Args, std::size_t... Index>
  12573. compressed_pair_element(std::tuple<Args...> args, std::index_sequence<Index...>)
  12574. : base_type{std::forward<Args>(std::get<Index>(args))...} {}
  12575. [[nodiscard]] reference get() ENTT_NOEXCEPT {
  12576. return *this;
  12577. }
  12578. [[nodiscard]] const_reference get() const ENTT_NOEXCEPT {
  12579. return *this;
  12580. }
  12581. };
  12582. } // namespace internal
  12583. /**
  12584. * Internal details not to be documented.
  12585. * @endcond
  12586. */
  12587. /**
  12588. * @brief A compressed pair.
  12589. *
  12590. * A pair that exploits the _Empty Base Class Optimization_ (or _EBCO_) to
  12591. * reduce its final size to a minimum.
  12592. *
  12593. * @tparam First The type of the first element that the pair stores.
  12594. * @tparam Second The type of the second element that the pair stores.
  12595. */
  12596. template<typename First, typename Second>
  12597. class compressed_pair final
  12598. : internal::compressed_pair_element<First, 0u>,
  12599. internal::compressed_pair_element<Second, 1u> {
  12600. using first_base = internal::compressed_pair_element<First, 0u>;
  12601. using second_base = internal::compressed_pair_element<Second, 1u>;
  12602. public:
  12603. /*! @brief The type of the first element that the pair stores. */
  12604. using first_type = First;
  12605. /*! @brief The type of the second element that the pair stores. */
  12606. using second_type = Second;
  12607. /**
  12608. * @brief Default constructor, conditionally enabled.
  12609. *
  12610. * This constructor is only available when the types that the pair stores
  12611. * are both at least default constructible.
  12612. *
  12613. * @tparam Dummy Dummy template parameter used for internal purposes.
  12614. */
  12615. template<bool Dummy = true, typename = std::enable_if_t<Dummy && std::is_default_constructible_v<first_type> && std::is_default_constructible_v<second_type>>>
  12616. constexpr compressed_pair()
  12617. : first_base{},
  12618. second_base{} {}
  12619. /**
  12620. * @brief Copy constructor.
  12621. * @param other The instance to copy from.
  12622. */
  12623. constexpr compressed_pair(const compressed_pair &other) = default;
  12624. /**
  12625. * @brief Move constructor.
  12626. * @param other The instance to move from.
  12627. */
  12628. constexpr compressed_pair(compressed_pair &&other) = default;
  12629. /**
  12630. * @brief Constructs a pair from its values.
  12631. * @tparam Arg Type of value to use to initialize the first element.
  12632. * @tparam Other Type of value to use to initialize the second element.
  12633. * @param arg Value to use to initialize the first element.
  12634. * @param other Value to use to initialize the second element.
  12635. */
  12636. template<typename Arg, typename Other>
  12637. constexpr compressed_pair(Arg &&arg, Other &&other)
  12638. : first_base{std::forward<Arg>(arg)},
  12639. second_base{std::forward<Other>(other)} {}
  12640. /**
  12641. * @brief Constructs a pair by forwarding the arguments to its parts.
  12642. * @tparam Args Types of arguments to use to initialize the first element.
  12643. * @tparam Other Types of arguments to use to initialize the second element.
  12644. * @param args Arguments to use to initialize the first element.
  12645. * @param other Arguments to use to initialize the second element.
  12646. */
  12647. template<typename... Args, typename... Other>
  12648. constexpr compressed_pair(std::piecewise_construct_t, std::tuple<Args...> args, std::tuple<Other...> other)
  12649. : first_base{std::move(args), std::index_sequence_for<Args...>{}},
  12650. second_base{std::move(other), std::index_sequence_for<Other...>{}} {}
  12651. /**
  12652. * @brief Copy assignment operator.
  12653. * @param other The instance to copy from.
  12654. * @return This compressed pair object.
  12655. */
  12656. constexpr compressed_pair &operator=(const compressed_pair &other) = default;
  12657. /**
  12658. * @brief Move assignment operator.
  12659. * @param other The instance to move from.
  12660. * @return This compressed pair object.
  12661. */
  12662. constexpr compressed_pair &operator=(compressed_pair &&other) = default;
  12663. /**
  12664. * @brief Returns the first element that a pair stores.
  12665. * @return The first element that a pair stores.
  12666. */
  12667. [[nodiscard]] first_type &first() ENTT_NOEXCEPT {
  12668. return static_cast<first_base &>(*this).get();
  12669. }
  12670. /*! @copydoc first */
  12671. [[nodiscard]] const first_type &first() const ENTT_NOEXCEPT {
  12672. return static_cast<const first_base &>(*this).get();
  12673. }
  12674. /**
  12675. * @brief Returns the second element that a pair stores.
  12676. * @return The second element that a pair stores.
  12677. */
  12678. [[nodiscard]] second_type &second() ENTT_NOEXCEPT {
  12679. return static_cast<second_base &>(*this).get();
  12680. }
  12681. /*! @copydoc second */
  12682. [[nodiscard]] const second_type &second() const ENTT_NOEXCEPT {
  12683. return static_cast<const second_base &>(*this).get();
  12684. }
  12685. /**
  12686. * @brief Swaps two compressed pair objects.
  12687. * @param other The compressed pair to swap with.
  12688. */
  12689. void swap(compressed_pair &other) {
  12690. using std::swap;
  12691. swap(first(), other.first());
  12692. swap(second(), other.second());
  12693. }
  12694. /**
  12695. * @brief Extracts an element from the compressed pair.
  12696. * @tparam Index An integer value that is either 0 or 1.
  12697. * @return Returns a reference to the first element if `Index` is 0 and a
  12698. * reference to the second element if `Index` is 1.
  12699. */
  12700. template<std::size_t Index>
  12701. decltype(auto) get() ENTT_NOEXCEPT {
  12702. if constexpr(Index == 0u) {
  12703. return first();
  12704. } else {
  12705. static_assert(Index == 1u, "Index out of bounds");
  12706. return second();
  12707. }
  12708. }
  12709. /*! @copydoc get */
  12710. template<std::size_t Index>
  12711. decltype(auto) get() const ENTT_NOEXCEPT {
  12712. if constexpr(Index == 0u) {
  12713. return first();
  12714. } else {
  12715. static_assert(Index == 1u, "Index out of bounds");
  12716. return second();
  12717. }
  12718. }
  12719. };
  12720. /**
  12721. * @brief Deduction guide.
  12722. * @tparam Type Type of value to use to initialize the first element.
  12723. * @tparam Other Type of value to use to initialize the second element.
  12724. */
  12725. template<typename Type, typename Other>
  12726. compressed_pair(Type &&, Other &&) -> compressed_pair<std::decay_t<Type>, std::decay_t<Other>>;
  12727. /**
  12728. * @brief Swaps two compressed pair objects.
  12729. * @tparam First The type of the first element that the pairs store.
  12730. * @tparam Second The type of the second element that the pairs store.
  12731. * @param lhs A valid compressed pair object.
  12732. * @param rhs A valid compressed pair object.
  12733. */
  12734. template<typename First, typename Second>
  12735. inline void swap(compressed_pair<First, Second> &lhs, compressed_pair<First, Second> &rhs) {
  12736. lhs.swap(rhs);
  12737. }
  12738. } // namespace entt
  12739. // disable structured binding support for clang 6, it messes when specializing tuple_size
  12740. #if !defined __clang_major__ || __clang_major__ > 6
  12741. namespace std {
  12742. /**
  12743. * @brief `std::tuple_size` specialization for `compressed_pair`s.
  12744. * @tparam First The type of the first element that the pair stores.
  12745. * @tparam Second The type of the second element that the pair stores.
  12746. */
  12747. template<typename First, typename Second>
  12748. struct tuple_size<entt::compressed_pair<First, Second>>: integral_constant<size_t, 2u> {};
  12749. /**
  12750. * @brief `std::tuple_element` specialization for `compressed_pair`s.
  12751. * @tparam Index The index of the type to return.
  12752. * @tparam First The type of the first element that the pair stores.
  12753. * @tparam Second The type of the second element that the pair stores.
  12754. */
  12755. template<size_t Index, typename First, typename Second>
  12756. struct tuple_element<Index, entt::compressed_pair<First, Second>>: conditional<Index == 0u, First, Second> {
  12757. static_assert(Index < 2u, "Index out of bounds");
  12758. };
  12759. } // namespace std
  12760. #endif
  12761. #endif
  12762. // #include "../core/iterator.hpp"
  12763. // #include "../core/memory.hpp"
  12764. // #include "../core/type_info.hpp"
  12765. // #include "component.hpp"
  12766. // #include "entity.hpp"
  12767. // #include "fwd.hpp"
  12768. // #include "sigh_storage_mixin.hpp"
  12769. #ifndef ENTT_ENTITY_SIGH_STORAGE_MIXIN_HPP
  12770. #define ENTT_ENTITY_SIGH_STORAGE_MIXIN_HPP
  12771. #include <utility>
  12772. // #include "../config/config.h"
  12773. // #include "../core/any.hpp"
  12774. // #include "../signal/sigh.hpp"
  12775. #ifndef ENTT_SIGNAL_SIGH_HPP
  12776. #define ENTT_SIGNAL_SIGH_HPP
  12777. #include <algorithm>
  12778. #include <functional>
  12779. #include <type_traits>
  12780. #include <utility>
  12781. #include <vector>
  12782. // #include "../config/config.h"
  12783. #ifndef ENTT_CONFIG_CONFIG_H
  12784. #define ENTT_CONFIG_CONFIG_H
  12785. // #include "version.h"
  12786. #ifndef ENTT_CONFIG_VERSION_H
  12787. #define ENTT_CONFIG_VERSION_H
  12788. // #include "macro.h"
  12789. #ifndef ENTT_CONFIG_MACRO_H
  12790. #define ENTT_CONFIG_MACRO_H
  12791. #define ENTT_STR(arg) #arg
  12792. #define ENTT_XSTR(arg) ENTT_STR(arg)
  12793. #endif
  12794. #define ENTT_VERSION_MAJOR 3
  12795. #define ENTT_VERSION_MINOR 10
  12796. #define ENTT_VERSION_PATCH 3
  12797. #define ENTT_VERSION \
  12798. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  12799. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  12800. #endif
  12801. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  12802. # define ENTT_THROW throw
  12803. # define ENTT_TRY try
  12804. # define ENTT_CATCH catch(...)
  12805. #else
  12806. # define ENTT_THROW
  12807. # define ENTT_TRY if(true)
  12808. # define ENTT_CATCH if(false)
  12809. #endif
  12810. #ifndef ENTT_NOEXCEPT
  12811. # define ENTT_NOEXCEPT noexcept
  12812. # define ENTT_NOEXCEPT_IF(expr) noexcept(expr)
  12813. # else
  12814. # define ENTT_NOEXCEPT_IF(...)
  12815. #endif
  12816. #ifdef ENTT_USE_ATOMIC
  12817. # include <atomic>
  12818. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  12819. #else
  12820. # define ENTT_MAYBE_ATOMIC(Type) Type
  12821. #endif
  12822. #ifndef ENTT_ID_TYPE
  12823. # include <cstdint>
  12824. # define ENTT_ID_TYPE std::uint32_t
  12825. #endif
  12826. #ifndef ENTT_SPARSE_PAGE
  12827. # define ENTT_SPARSE_PAGE 4096
  12828. #endif
  12829. #ifndef ENTT_PACKED_PAGE
  12830. # define ENTT_PACKED_PAGE 1024
  12831. #endif
  12832. #ifdef ENTT_DISABLE_ASSERT
  12833. # undef ENTT_ASSERT
  12834. # define ENTT_ASSERT(...) (void(0))
  12835. #elif !defined ENTT_ASSERT
  12836. # include <cassert>
  12837. # define ENTT_ASSERT(condition, ...) assert(condition)
  12838. #endif
  12839. #ifdef ENTT_NO_ETO
  12840. # define ENTT_IGNORE_IF_EMPTY false
  12841. #else
  12842. # define ENTT_IGNORE_IF_EMPTY true
  12843. #endif
  12844. #ifdef ENTT_STANDARD_CPP
  12845. # define ENTT_NONSTD false
  12846. #else
  12847. # define ENTT_NONSTD true
  12848. # if defined __clang__ || defined __GNUC__
  12849. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  12850. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  12851. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  12852. # elif defined _MSC_VER
  12853. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  12854. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  12855. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  12856. # endif
  12857. #endif
  12858. #if defined _MSC_VER
  12859. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  12860. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  12861. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  12862. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  12863. #endif
  12864. #endif
  12865. // #include "delegate.hpp"
  12866. #ifndef ENTT_SIGNAL_DELEGATE_HPP
  12867. #define ENTT_SIGNAL_DELEGATE_HPP
  12868. #include <cstddef>
  12869. #include <functional>
  12870. #include <tuple>
  12871. #include <type_traits>
  12872. #include <utility>
  12873. // #include "../config/config.h"
  12874. // #include "../core/type_traits.hpp"
  12875. #ifndef ENTT_CORE_TYPE_TRAITS_HPP
  12876. #define ENTT_CORE_TYPE_TRAITS_HPP
  12877. #include <cstddef>
  12878. #include <iterator>
  12879. #include <type_traits>
  12880. #include <utility>
  12881. // #include "../config/config.h"
  12882. #ifndef ENTT_CONFIG_CONFIG_H
  12883. #define ENTT_CONFIG_CONFIG_H
  12884. // #include "version.h"
  12885. #ifndef ENTT_CONFIG_VERSION_H
  12886. #define ENTT_CONFIG_VERSION_H
  12887. // #include "macro.h"
  12888. #ifndef ENTT_CONFIG_MACRO_H
  12889. #define ENTT_CONFIG_MACRO_H
  12890. #define ENTT_STR(arg) #arg
  12891. #define ENTT_XSTR(arg) ENTT_STR(arg)
  12892. #endif
  12893. #define ENTT_VERSION_MAJOR 3
  12894. #define ENTT_VERSION_MINOR 10
  12895. #define ENTT_VERSION_PATCH 3
  12896. #define ENTT_VERSION \
  12897. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  12898. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  12899. #endif
  12900. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  12901. # define ENTT_THROW throw
  12902. # define ENTT_TRY try
  12903. # define ENTT_CATCH catch(...)
  12904. #else
  12905. # define ENTT_THROW
  12906. # define ENTT_TRY if(true)
  12907. # define ENTT_CATCH if(false)
  12908. #endif
  12909. #ifndef ENTT_NOEXCEPT
  12910. # define ENTT_NOEXCEPT noexcept
  12911. # define ENTT_NOEXCEPT_IF(expr) noexcept(expr)
  12912. # else
  12913. # define ENTT_NOEXCEPT_IF(...)
  12914. #endif
  12915. #ifdef ENTT_USE_ATOMIC
  12916. # include <atomic>
  12917. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  12918. #else
  12919. # define ENTT_MAYBE_ATOMIC(Type) Type
  12920. #endif
  12921. #ifndef ENTT_ID_TYPE
  12922. # include <cstdint>
  12923. # define ENTT_ID_TYPE std::uint32_t
  12924. #endif
  12925. #ifndef ENTT_SPARSE_PAGE
  12926. # define ENTT_SPARSE_PAGE 4096
  12927. #endif
  12928. #ifndef ENTT_PACKED_PAGE
  12929. # define ENTT_PACKED_PAGE 1024
  12930. #endif
  12931. #ifdef ENTT_DISABLE_ASSERT
  12932. # undef ENTT_ASSERT
  12933. # define ENTT_ASSERT(...) (void(0))
  12934. #elif !defined ENTT_ASSERT
  12935. # include <cassert>
  12936. # define ENTT_ASSERT(condition, ...) assert(condition)
  12937. #endif
  12938. #ifdef ENTT_NO_ETO
  12939. # define ENTT_IGNORE_IF_EMPTY false
  12940. #else
  12941. # define ENTT_IGNORE_IF_EMPTY true
  12942. #endif
  12943. #ifdef ENTT_STANDARD_CPP
  12944. # define ENTT_NONSTD false
  12945. #else
  12946. # define ENTT_NONSTD true
  12947. # if defined __clang__ || defined __GNUC__
  12948. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  12949. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  12950. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  12951. # elif defined _MSC_VER
  12952. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  12953. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  12954. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  12955. # endif
  12956. #endif
  12957. #if defined _MSC_VER
  12958. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  12959. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  12960. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  12961. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  12962. #endif
  12963. #endif
  12964. // #include "fwd.hpp"
  12965. #ifndef ENTT_CORE_FWD_HPP
  12966. #define ENTT_CORE_FWD_HPP
  12967. #include <cstdint>
  12968. #include <type_traits>
  12969. // #include "../config/config.h"
  12970. namespace entt {
  12971. template<std::size_t Len = sizeof(double[2]), std::size_t = alignof(typename std::aligned_storage_t<Len + !Len>)>
  12972. class basic_any;
  12973. /*! @brief Alias declaration for type identifiers. */
  12974. using id_type = ENTT_ID_TYPE;
  12975. /*! @brief Alias declaration for the most common use case. */
  12976. using any = basic_any<>;
  12977. } // namespace entt
  12978. #endif
  12979. namespace entt {
  12980. /**
  12981. * @brief Utility class to disambiguate overloaded functions.
  12982. * @tparam N Number of choices available.
  12983. */
  12984. template<std::size_t N>
  12985. struct choice_t
  12986. // Unfortunately, doxygen cannot parse such a construct.
  12987. : /*! @cond TURN_OFF_DOXYGEN */ choice_t<N - 1> /*! @endcond */
  12988. {};
  12989. /*! @copybrief choice_t */
  12990. template<>
  12991. struct choice_t<0> {};
  12992. /**
  12993. * @brief Variable template for the choice trick.
  12994. * @tparam N Number of choices available.
  12995. */
  12996. template<std::size_t N>
  12997. inline constexpr choice_t<N> choice{};
  12998. /**
  12999. * @brief Identity type trait.
  13000. *
  13001. * Useful to establish non-deduced contexts in template argument deduction
  13002. * (waiting for C++20) or to provide types through function arguments.
  13003. *
  13004. * @tparam Type A type.
  13005. */
  13006. template<typename Type>
  13007. struct type_identity {
  13008. /*! @brief Identity type. */
  13009. using type = Type;
  13010. };
  13011. /**
  13012. * @brief Helper type.
  13013. * @tparam Type A type.
  13014. */
  13015. template<typename Type>
  13016. using type_identity_t = typename type_identity<Type>::type;
  13017. /**
  13018. * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains.
  13019. * @tparam Type The type of which to return the size.
  13020. * @tparam The size of the type if `sizeof` accepts it, 0 otherwise.
  13021. */
  13022. template<typename Type, typename = void>
  13023. struct size_of: std::integral_constant<std::size_t, 0u> {};
  13024. /*! @copydoc size_of */
  13025. template<typename Type>
  13026. struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
  13027. : std::integral_constant<std::size_t, sizeof(Type)> {};
  13028. /**
  13029. * @brief Helper variable template.
  13030. * @tparam Type The type of which to return the size.
  13031. */
  13032. template<typename Type>
  13033. inline constexpr std::size_t size_of_v = size_of<Type>::value;
  13034. /**
  13035. * @brief Using declaration to be used to _repeat_ the same type a number of
  13036. * times equal to the size of a given parameter pack.
  13037. * @tparam Type A type to repeat.
  13038. */
  13039. template<typename Type, typename>
  13040. using unpack_as_type = Type;
  13041. /**
  13042. * @brief Helper variable template to be used to _repeat_ the same value a
  13043. * number of times equal to the size of a given parameter pack.
  13044. * @tparam Value A value to repeat.
  13045. */
  13046. template<auto Value, typename>
  13047. inline constexpr auto unpack_as_value = Value;
  13048. /**
  13049. * @brief Wraps a static constant.
  13050. * @tparam Value A static constant.
  13051. */
  13052. template<auto Value>
  13053. using integral_constant = std::integral_constant<decltype(Value), Value>;
  13054. /**
  13055. * @brief Alias template to facilitate the creation of named values.
  13056. * @tparam Value A constant value at least convertible to `id_type`.
  13057. */
  13058. template<id_type Value>
  13059. using tag = integral_constant<Value>;
  13060. /**
  13061. * @brief A class to use to push around lists of types, nothing more.
  13062. * @tparam Type Types provided by the type list.
  13063. */
  13064. template<typename... Type>
  13065. struct type_list {
  13066. /*! @brief Type list type. */
  13067. using type = type_list;
  13068. /*! @brief Compile-time number of elements in the type list. */
  13069. static constexpr auto size = sizeof...(Type);
  13070. };
  13071. /*! @brief Primary template isn't defined on purpose. */
  13072. template<std::size_t, typename>
  13073. struct type_list_element;
  13074. /**
  13075. * @brief Provides compile-time indexed access to the types of a type list.
  13076. * @tparam Index Index of the type to return.
  13077. * @tparam Type First type provided by the type list.
  13078. * @tparam Other Other types provided by the type list.
  13079. */
  13080. template<std::size_t Index, typename Type, typename... Other>
  13081. struct type_list_element<Index, type_list<Type, Other...>>
  13082. : type_list_element<Index - 1u, type_list<Other...>> {};
  13083. /**
  13084. * @brief Provides compile-time indexed access to the types of a type list.
  13085. * @tparam Type First type provided by the type list.
  13086. * @tparam Other Other types provided by the type list.
  13087. */
  13088. template<typename Type, typename... Other>
  13089. struct type_list_element<0u, type_list<Type, Other...>> {
  13090. /*! @brief Searched type. */
  13091. using type = Type;
  13092. };
  13093. /**
  13094. * @brief Helper type.
  13095. * @tparam Index Index of the type to return.
  13096. * @tparam List Type list to search into.
  13097. */
  13098. template<std::size_t Index, typename List>
  13099. using type_list_element_t = typename type_list_element<Index, List>::type;
  13100. /**
  13101. * @brief Concatenates multiple type lists.
  13102. * @tparam Type Types provided by the first type list.
  13103. * @tparam Other Types provided by the second type list.
  13104. * @return A type list composed by the types of both the type lists.
  13105. */
  13106. template<typename... Type, typename... Other>
  13107. constexpr type_list<Type..., Other...> operator+(type_list<Type...>, type_list<Other...>) {
  13108. return {};
  13109. }
  13110. /*! @brief Primary template isn't defined on purpose. */
  13111. template<typename...>
  13112. struct type_list_cat;
  13113. /*! @brief Concatenates multiple type lists. */
  13114. template<>
  13115. struct type_list_cat<> {
  13116. /*! @brief A type list composed by the types of all the type lists. */
  13117. using type = type_list<>;
  13118. };
  13119. /**
  13120. * @brief Concatenates multiple type lists.
  13121. * @tparam Type Types provided by the first type list.
  13122. * @tparam Other Types provided by the second type list.
  13123. * @tparam List Other type lists, if any.
  13124. */
  13125. template<typename... Type, typename... Other, typename... List>
  13126. struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
  13127. /*! @brief A type list composed by the types of all the type lists. */
  13128. using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
  13129. };
  13130. /**
  13131. * @brief Concatenates multiple type lists.
  13132. * @tparam Type Types provided by the type list.
  13133. */
  13134. template<typename... Type>
  13135. struct type_list_cat<type_list<Type...>> {
  13136. /*! @brief A type list composed by the types of all the type lists. */
  13137. using type = type_list<Type...>;
  13138. };
  13139. /**
  13140. * @brief Helper type.
  13141. * @tparam List Type lists to concatenate.
  13142. */
  13143. template<typename... List>
  13144. using type_list_cat_t = typename type_list_cat<List...>::type;
  13145. /*! @brief Primary template isn't defined on purpose. */
  13146. template<typename>
  13147. struct type_list_unique;
  13148. /**
  13149. * @brief Removes duplicates types from a type list.
  13150. * @tparam Type One of the types provided by the given type list.
  13151. * @tparam Other The other types provided by the given type list.
  13152. */
  13153. template<typename Type, typename... Other>
  13154. struct type_list_unique<type_list<Type, Other...>> {
  13155. /*! @brief A type list without duplicate types. */
  13156. using type = std::conditional_t<
  13157. (std::is_same_v<Type, Other> || ...),
  13158. typename type_list_unique<type_list<Other...>>::type,
  13159. type_list_cat_t<type_list<Type>, typename type_list_unique<type_list<Other...>>::type>>;
  13160. };
  13161. /*! @brief Removes duplicates types from a type list. */
  13162. template<>
  13163. struct type_list_unique<type_list<>> {
  13164. /*! @brief A type list without duplicate types. */
  13165. using type = type_list<>;
  13166. };
  13167. /**
  13168. * @brief Helper type.
  13169. * @tparam Type A type list.
  13170. */
  13171. template<typename Type>
  13172. using type_list_unique_t = typename type_list_unique<Type>::type;
  13173. /**
  13174. * @brief Provides the member constant `value` to true if a type list contains a
  13175. * given type, false otherwise.
  13176. * @tparam List Type list.
  13177. * @tparam Type Type to look for.
  13178. */
  13179. template<typename List, typename Type>
  13180. struct type_list_contains;
  13181. /**
  13182. * @copybrief type_list_contains
  13183. * @tparam Type Types provided by the type list.
  13184. * @tparam Other Type to look for.
  13185. */
  13186. template<typename... Type, typename Other>
  13187. struct type_list_contains<type_list<Type...>, Other>: std::disjunction<std::is_same<Type, Other>...> {};
  13188. /**
  13189. * @brief Helper variable template.
  13190. * @tparam List Type list.
  13191. * @tparam Type Type to look for.
  13192. */
  13193. template<typename List, typename Type>
  13194. inline constexpr bool type_list_contains_v = type_list_contains<List, Type>::value;
  13195. /*! @brief Primary template isn't defined on purpose. */
  13196. template<typename...>
  13197. struct type_list_diff;
  13198. /**
  13199. * @brief Computes the difference between two type lists.
  13200. * @tparam Type Types provided by the first type list.
  13201. * @tparam Other Types provided by the second type list.
  13202. */
  13203. template<typename... Type, typename... Other>
  13204. struct type_list_diff<type_list<Type...>, type_list<Other...>> {
  13205. /*! @brief A type list that is the difference between the two type lists. */
  13206. using type = type_list_cat_t<std::conditional_t<type_list_contains_v<type_list<Other...>, Type>, type_list<>, type_list<Type>>...>;
  13207. };
  13208. /**
  13209. * @brief Helper type.
  13210. * @tparam List Type lists between which to compute the difference.
  13211. */
  13212. template<typename... List>
  13213. using type_list_diff_t = typename type_list_diff<List...>::type;
  13214. /**
  13215. * @brief A class to use to push around lists of constant values, nothing more.
  13216. * @tparam Value Values provided by the value list.
  13217. */
  13218. template<auto... Value>
  13219. struct value_list {
  13220. /*! @brief Value list type. */
  13221. using type = value_list;
  13222. /*! @brief Compile-time number of elements in the value list. */
  13223. static constexpr auto size = sizeof...(Value);
  13224. };
  13225. /*! @brief Primary template isn't defined on purpose. */
  13226. template<std::size_t, typename>
  13227. struct value_list_element;
  13228. /**
  13229. * @brief Provides compile-time indexed access to the values of a value list.
  13230. * @tparam Index Index of the value to return.
  13231. * @tparam Value First value provided by the value list.
  13232. * @tparam Other Other values provided by the value list.
  13233. */
  13234. template<std::size_t Index, auto Value, auto... Other>
  13235. struct value_list_element<Index, value_list<Value, Other...>>
  13236. : value_list_element<Index - 1u, value_list<Other...>> {};
  13237. /**
  13238. * @brief Provides compile-time indexed access to the types of a type list.
  13239. * @tparam Value First value provided by the value list.
  13240. * @tparam Other Other values provided by the value list.
  13241. */
  13242. template<auto Value, auto... Other>
  13243. struct value_list_element<0u, value_list<Value, Other...>> {
  13244. /*! @brief Searched value. */
  13245. static constexpr auto value = Value;
  13246. };
  13247. /**
  13248. * @brief Helper type.
  13249. * @tparam Index Index of the value to return.
  13250. * @tparam List Value list to search into.
  13251. */
  13252. template<std::size_t Index, typename List>
  13253. inline constexpr auto value_list_element_v = value_list_element<Index, List>::value;
  13254. /**
  13255. * @brief Concatenates multiple value lists.
  13256. * @tparam Value Values provided by the first value list.
  13257. * @tparam Other Values provided by the second value list.
  13258. * @return A value list composed by the values of both the value lists.
  13259. */
  13260. template<auto... Value, auto... Other>
  13261. constexpr value_list<Value..., Other...> operator+(value_list<Value...>, value_list<Other...>) {
  13262. return {};
  13263. }
  13264. /*! @brief Primary template isn't defined on purpose. */
  13265. template<typename...>
  13266. struct value_list_cat;
  13267. /*! @brief Concatenates multiple value lists. */
  13268. template<>
  13269. struct value_list_cat<> {
  13270. /*! @brief A value list composed by the values of all the value lists. */
  13271. using type = value_list<>;
  13272. };
  13273. /**
  13274. * @brief Concatenates multiple value lists.
  13275. * @tparam Value Values provided by the first value list.
  13276. * @tparam Other Values provided by the second value list.
  13277. * @tparam List Other value lists, if any.
  13278. */
  13279. template<auto... Value, auto... Other, typename... List>
  13280. struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
  13281. /*! @brief A value list composed by the values of all the value lists. */
  13282. using type = typename value_list_cat<value_list<Value..., Other...>, List...>::type;
  13283. };
  13284. /**
  13285. * @brief Concatenates multiple value lists.
  13286. * @tparam Value Values provided by the value list.
  13287. */
  13288. template<auto... Value>
  13289. struct value_list_cat<value_list<Value...>> {
  13290. /*! @brief A value list composed by the values of all the value lists. */
  13291. using type = value_list<Value...>;
  13292. };
  13293. /**
  13294. * @brief Helper type.
  13295. * @tparam List Value lists to concatenate.
  13296. */
  13297. template<typename... List>
  13298. using value_list_cat_t = typename value_list_cat<List...>::type;
  13299. /*! @brief Same as std::is_invocable, but with tuples. */
  13300. template<typename, typename>
  13301. struct is_applicable: std::false_type {};
  13302. /**
  13303. * @copybrief is_applicable
  13304. * @tparam Func A valid function type.
  13305. * @tparam Tuple Tuple-like type.
  13306. * @tparam Args The list of arguments to use to probe the function type.
  13307. */
  13308. template<typename Func, template<typename...> class Tuple, typename... Args>
  13309. struct is_applicable<Func, Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  13310. /**
  13311. * @copybrief is_applicable
  13312. * @tparam Func A valid function type.
  13313. * @tparam Tuple Tuple-like type.
  13314. * @tparam Args The list of arguments to use to probe the function type.
  13315. */
  13316. template<typename Func, template<typename...> class Tuple, typename... Args>
  13317. struct is_applicable<Func, const Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  13318. /**
  13319. * @brief Helper variable template.
  13320. * @tparam Func A valid function type.
  13321. * @tparam Args The list of arguments to use to probe the function type.
  13322. */
  13323. template<typename Func, typename Args>
  13324. inline constexpr bool is_applicable_v = is_applicable<Func, Args>::value;
  13325. /*! @brief Same as std::is_invocable_r, but with tuples for arguments. */
  13326. template<typename, typename, typename>
  13327. struct is_applicable_r: std::false_type {};
  13328. /**
  13329. * @copybrief is_applicable_r
  13330. * @tparam Ret The type to which the return type of the function should be
  13331. * convertible.
  13332. * @tparam Func A valid function type.
  13333. * @tparam Args The list of arguments to use to probe the function type.
  13334. */
  13335. template<typename Ret, typename Func, typename... Args>
  13336. struct is_applicable_r<Ret, Func, std::tuple<Args...>>: std::is_invocable_r<Ret, Func, Args...> {};
  13337. /**
  13338. * @brief Helper variable template.
  13339. * @tparam Ret The type to which the return type of the function should be
  13340. * convertible.
  13341. * @tparam Func A valid function type.
  13342. * @tparam Args The list of arguments to use to probe the function type.
  13343. */
  13344. template<typename Ret, typename Func, typename Args>
  13345. inline constexpr bool is_applicable_r_v = is_applicable_r<Ret, Func, Args>::value;
  13346. /**
  13347. * @brief Provides the member constant `value` to true if a given type is
  13348. * complete, false otherwise.
  13349. * @tparam Type The type to test.
  13350. */
  13351. template<typename Type, typename = void>
  13352. struct is_complete: std::false_type {};
  13353. /*! @copydoc is_complete */
  13354. template<typename Type>
  13355. struct is_complete<Type, std::void_t<decltype(sizeof(Type))>>: std::true_type {};
  13356. /**
  13357. * @brief Helper variable template.
  13358. * @tparam Type The type to test.
  13359. */
  13360. template<typename Type>
  13361. inline constexpr bool is_complete_v = is_complete<Type>::value;
  13362. /**
  13363. * @brief Provides the member constant `value` to true if a given type is an
  13364. * iterator, false otherwise.
  13365. * @tparam Type The type to test.
  13366. */
  13367. template<typename Type, typename = void>
  13368. struct is_iterator: std::false_type {};
  13369. /**
  13370. * @cond TURN_OFF_DOXYGEN
  13371. * Internal details not to be documented.
  13372. */
  13373. namespace internal {
  13374. template<typename, typename = void>
  13375. struct has_iterator_category: std::false_type {};
  13376. template<typename Type>
  13377. struct has_iterator_category<Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>: std::true_type {};
  13378. } // namespace internal
  13379. /**
  13380. * Internal details not to be documented.
  13381. * @endcond
  13382. */
  13383. /*! @copydoc is_iterator */
  13384. template<typename Type>
  13385. struct is_iterator<Type, std::enable_if_t<!std::is_same_v<std::remove_const_t<std::remove_pointer_t<Type>>, void>>>
  13386. : internal::has_iterator_category<Type> {};
  13387. /**
  13388. * @brief Helper variable template.
  13389. * @tparam Type The type to test.
  13390. */
  13391. template<typename Type>
  13392. inline constexpr bool is_iterator_v = is_iterator<Type>::value;
  13393. /**
  13394. * @brief Provides the member constant `value` to true if a given type is both
  13395. * an empty and non-final class, false otherwise.
  13396. * @tparam Type The type to test
  13397. */
  13398. template<typename Type>
  13399. struct is_ebco_eligible
  13400. : std::conjunction<std::is_empty<Type>, std::negation<std::is_final<Type>>> {};
  13401. /**
  13402. * @brief Helper variable template.
  13403. * @tparam Type The type to test.
  13404. */
  13405. template<typename Type>
  13406. inline constexpr bool is_ebco_eligible_v = is_ebco_eligible<Type>::value;
  13407. /**
  13408. * @brief Provides the member constant `value` to true if `Type::is_transparent`
  13409. * is valid and denotes a type, false otherwise.
  13410. * @tparam Type The type to test.
  13411. */
  13412. template<typename Type, typename = void>
  13413. struct is_transparent: std::false_type {};
  13414. /*! @copydoc is_transparent */
  13415. template<typename Type>
  13416. struct is_transparent<Type, std::void_t<typename Type::is_transparent>>: std::true_type {};
  13417. /**
  13418. * @brief Helper variable template.
  13419. * @tparam Type The type to test.
  13420. */
  13421. template<typename Type>
  13422. inline constexpr bool is_transparent_v = is_transparent<Type>::value;
  13423. /**
  13424. * @brief Provides the member constant `value` to true if a given type is
  13425. * equality comparable, false otherwise.
  13426. * @tparam Type The type to test.
  13427. */
  13428. template<typename Type, typename = void>
  13429. struct is_equality_comparable: std::false_type {};
  13430. /**
  13431. * @cond TURN_OFF_DOXYGEN
  13432. * Internal details not to be documented.
  13433. */
  13434. namespace internal {
  13435. template<typename, typename = void>
  13436. struct has_tuple_size_value: std::false_type {};
  13437. template<typename Type>
  13438. struct has_tuple_size_value<Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>: std::true_type {};
  13439. template<typename Type, std::size_t... Index>
  13440. [[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
  13441. return (is_equality_comparable<std::tuple_element_t<Index, Type>>::value && ...);
  13442. }
  13443. template<typename>
  13444. [[nodiscard]] constexpr bool maybe_equality_comparable(choice_t<0>) {
  13445. return true;
  13446. }
  13447. template<typename Type>
  13448. [[nodiscard]] constexpr auto maybe_equality_comparable(choice_t<1>) -> decltype(std::declval<typename Type::value_type>(), bool{}) {
  13449. if constexpr(is_iterator_v<Type>) {
  13450. return true;
  13451. } else if constexpr(std::is_same_v<typename Type::value_type, Type>) {
  13452. return maybe_equality_comparable<Type>(choice<0>);
  13453. } else {
  13454. return is_equality_comparable<typename Type::value_type>::value;
  13455. }
  13456. }
  13457. template<typename Type>
  13458. [[nodiscard]] constexpr std::enable_if_t<is_complete_v<std::tuple_size<std::remove_const_t<Type>>>, bool> maybe_equality_comparable(choice_t<2>) {
  13459. if constexpr(has_tuple_size_value<Type>::value) {
  13460. return unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
  13461. } else {
  13462. return maybe_equality_comparable<Type>(choice<1>);
  13463. }
  13464. }
  13465. } // namespace internal
  13466. /**
  13467. * Internal details not to be documented.
  13468. * @endcond
  13469. */
  13470. /*! @copydoc is_equality_comparable */
  13471. template<typename Type>
  13472. struct is_equality_comparable<Type, std::void_t<decltype(std::declval<Type>() == std::declval<Type>())>>
  13473. : std::bool_constant<internal::maybe_equality_comparable<Type>(choice<2>)> {};
  13474. /**
  13475. * @brief Helper variable template.
  13476. * @tparam Type The type to test.
  13477. */
  13478. template<typename Type>
  13479. inline constexpr bool is_equality_comparable_v = is_equality_comparable<Type>::value;
  13480. /**
  13481. * @brief Transcribes the constness of a type to another type.
  13482. * @tparam To The type to which to transcribe the constness.
  13483. * @tparam From The type from which to transcribe the constness.
  13484. */
  13485. template<typename To, typename From>
  13486. struct constness_as {
  13487. /*! @brief The type resulting from the transcription of the constness. */
  13488. using type = std::remove_const_t<To>;
  13489. };
  13490. /*! @copydoc constness_as */
  13491. template<typename To, typename From>
  13492. struct constness_as<To, const From> {
  13493. /*! @brief The type resulting from the transcription of the constness. */
  13494. using type = std::add_const_t<To>;
  13495. };
  13496. /**
  13497. * @brief Alias template to facilitate the transcription of the constness.
  13498. * @tparam To The type to which to transcribe the constness.
  13499. * @tparam From The type from which to transcribe the constness.
  13500. */
  13501. template<typename To, typename From>
  13502. using constness_as_t = typename constness_as<To, From>::type;
  13503. /**
  13504. * @brief Extracts the class of a non-static member object or function.
  13505. * @tparam Member A pointer to a non-static member object or function.
  13506. */
  13507. template<typename Member>
  13508. class member_class {
  13509. static_assert(std::is_member_pointer_v<Member>, "Invalid pointer type to non-static member object or function");
  13510. template<typename Class, typename Ret, typename... Args>
  13511. static Class *clazz(Ret (Class::*)(Args...));
  13512. template<typename Class, typename Ret, typename... Args>
  13513. static Class *clazz(Ret (Class::*)(Args...) const);
  13514. template<typename Class, typename Type>
  13515. static Class *clazz(Type Class::*);
  13516. public:
  13517. /*! @brief The class of the given non-static member object or function. */
  13518. using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
  13519. };
  13520. /**
  13521. * @brief Helper type.
  13522. * @tparam Member A pointer to a non-static member object or function.
  13523. */
  13524. template<typename Member>
  13525. using member_class_t = typename member_class<Member>::type;
  13526. } // namespace entt
  13527. #endif
  13528. // #include "fwd.hpp"
  13529. #ifndef ENTT_SIGNAL_FWD_HPP
  13530. #define ENTT_SIGNAL_FWD_HPP
  13531. #include <memory>
  13532. namespace entt {
  13533. template<typename>
  13534. class delegate;
  13535. template<typename = std::allocator<char>>
  13536. class basic_dispatcher;
  13537. template<typename>
  13538. class emitter;
  13539. class connection;
  13540. struct scoped_connection;
  13541. template<typename>
  13542. class sink;
  13543. template<typename Type, typename = std::allocator<Type *>>
  13544. class sigh;
  13545. /*! @brief Alias declaration for the most common use case. */
  13546. using dispatcher = basic_dispatcher<>;
  13547. } // namespace entt
  13548. #endif
  13549. namespace entt {
  13550. /**
  13551. * @cond TURN_OFF_DOXYGEN
  13552. * Internal details not to be documented.
  13553. */
  13554. namespace internal {
  13555. template<typename Ret, typename... Args>
  13556. auto function_pointer(Ret (*)(Args...)) -> Ret (*)(Args...);
  13557. template<typename Ret, typename Type, typename... Args, typename Other>
  13558. auto function_pointer(Ret (*)(Type, Args...), Other &&) -> Ret (*)(Args...);
  13559. template<typename Class, typename Ret, typename... Args, typename... Other>
  13560. auto function_pointer(Ret (Class::*)(Args...), Other &&...) -> Ret (*)(Args...);
  13561. template<typename Class, typename Ret, typename... Args, typename... Other>
  13562. auto function_pointer(Ret (Class::*)(Args...) const, Other &&...) -> Ret (*)(Args...);
  13563. template<typename Class, typename Type, typename... Other>
  13564. auto function_pointer(Type Class::*, Other &&...) -> Type (*)();
  13565. template<typename... Type>
  13566. using function_pointer_t = decltype(internal::function_pointer(std::declval<Type>()...));
  13567. template<typename... Class, typename Ret, typename... Args>
  13568. [[nodiscard]] constexpr auto index_sequence_for(Ret (*)(Args...)) {
  13569. return std::index_sequence_for<Class..., Args...>{};
  13570. }
  13571. } // namespace internal
  13572. /**
  13573. * Internal details not to be documented.
  13574. * @endcond
  13575. */
  13576. /*! @brief Used to wrap a function or a member of a specified type. */
  13577. template<auto>
  13578. struct connect_arg_t {};
  13579. /*! @brief Constant of type connect_arg_t used to disambiguate calls. */
  13580. template<auto Func>
  13581. inline constexpr connect_arg_t<Func> connect_arg{};
  13582. /**
  13583. * @brief Basic delegate implementation.
  13584. *
  13585. * Primary template isn't defined on purpose. All the specializations give a
  13586. * compile-time error unless the template parameter is a function type.
  13587. */
  13588. template<typename>
  13589. class delegate;
  13590. /**
  13591. * @brief Utility class to use to send around functions and members.
  13592. *
  13593. * Unmanaged delegate for function pointers and members. Users of this class are
  13594. * in charge of disconnecting instances before deleting them.
  13595. *
  13596. * A delegate can be used as a general purpose invoker without memory overhead
  13597. * for free functions possibly with payloads and bound or unbound members.
  13598. *
  13599. * @tparam Ret Return type of a function type.
  13600. * @tparam Args Types of arguments of a function type.
  13601. */
  13602. template<typename Ret, typename... Args>
  13603. class delegate<Ret(Args...)> {
  13604. template<auto Candidate, std::size_t... Index>
  13605. [[nodiscard]] auto wrap(std::index_sequence<Index...>) ENTT_NOEXCEPT {
  13606. return [](const void *, Args... args) -> Ret {
  13607. [[maybe_unused]] const auto arguments = std::forward_as_tuple(std::forward<Args>(args)...);
  13608. return static_cast<Ret>(std::invoke(Candidate, std::forward<type_list_element_t<Index, type_list<Args...>>>(std::get<Index>(arguments))...));
  13609. };
  13610. }
  13611. template<auto Candidate, typename Type, std::size_t... Index>
  13612. [[nodiscard]] auto wrap(Type &, std::index_sequence<Index...>) ENTT_NOEXCEPT {
  13613. return [](const void *payload, Args... args) -> Ret {
  13614. [[maybe_unused]] const auto arguments = std::forward_as_tuple(std::forward<Args>(args)...);
  13615. Type *curr = static_cast<Type *>(const_cast<constness_as_t<void, Type> *>(payload));
  13616. return static_cast<Ret>(std::invoke(Candidate, *curr, std::forward<type_list_element_t<Index, type_list<Args...>>>(std::get<Index>(arguments))...));
  13617. };
  13618. }
  13619. template<auto Candidate, typename Type, std::size_t... Index>
  13620. [[nodiscard]] auto wrap(Type *, std::index_sequence<Index...>) ENTT_NOEXCEPT {
  13621. return [](const void *payload, Args... args) -> Ret {
  13622. [[maybe_unused]] const auto arguments = std::forward_as_tuple(std::forward<Args>(args)...);
  13623. Type *curr = static_cast<Type *>(const_cast<constness_as_t<void, Type> *>(payload));
  13624. return static_cast<Ret>(std::invoke(Candidate, curr, std::forward<type_list_element_t<Index, type_list<Args...>>>(std::get<Index>(arguments))...));
  13625. };
  13626. }
  13627. public:
  13628. /*! @brief Function type of the contained target. */
  13629. using function_type = Ret(const void *, Args...);
  13630. /*! @brief Function type of the delegate. */
  13631. using type = Ret(Args...);
  13632. /*! @brief Return type of the delegate. */
  13633. using result_type = Ret;
  13634. /*! @brief Default constructor. */
  13635. delegate() ENTT_NOEXCEPT
  13636. : instance{nullptr},
  13637. fn{nullptr} {}
  13638. /**
  13639. * @brief Constructs a delegate and connects a free function or an unbound
  13640. * member.
  13641. * @tparam Candidate Function or member to connect to the delegate.
  13642. */
  13643. template<auto Candidate>
  13644. delegate(connect_arg_t<Candidate>) ENTT_NOEXCEPT {
  13645. connect<Candidate>();
  13646. }
  13647. /**
  13648. * @brief Constructs a delegate and connects a free function with payload or
  13649. * a bound member.
  13650. * @tparam Candidate Function or member to connect to the delegate.
  13651. * @tparam Type Type of class or type of payload.
  13652. * @param value_or_instance A valid object that fits the purpose.
  13653. */
  13654. template<auto Candidate, typename Type>
  13655. delegate(connect_arg_t<Candidate>, Type &&value_or_instance) ENTT_NOEXCEPT {
  13656. connect<Candidate>(std::forward<Type>(value_or_instance));
  13657. }
  13658. /**
  13659. * @brief Constructs a delegate and connects an user defined function with
  13660. * optional payload.
  13661. * @param function Function to connect to the delegate.
  13662. * @param payload User defined arbitrary data.
  13663. */
  13664. delegate(function_type *function, const void *payload = nullptr) ENTT_NOEXCEPT {
  13665. connect(function, payload);
  13666. }
  13667. /**
  13668. * @brief Connects a free function or an unbound member to a delegate.
  13669. * @tparam Candidate Function or member to connect to the delegate.
  13670. */
  13671. template<auto Candidate>
  13672. void connect() ENTT_NOEXCEPT {
  13673. instance = nullptr;
  13674. if constexpr(std::is_invocable_r_v<Ret, decltype(Candidate), Args...>) {
  13675. fn = [](const void *, Args... args) -> Ret {
  13676. return Ret(std::invoke(Candidate, std::forward<Args>(args)...));
  13677. };
  13678. } else if constexpr(std::is_member_pointer_v<decltype(Candidate)>) {
  13679. fn = wrap<Candidate>(internal::index_sequence_for<type_list_element_t<0, type_list<Args...>>>(internal::function_pointer_t<decltype(Candidate)>{}));
  13680. } else {
  13681. fn = wrap<Candidate>(internal::index_sequence_for(internal::function_pointer_t<decltype(Candidate)>{}));
  13682. }
  13683. }
  13684. /**
  13685. * @brief Connects a free function with payload or a bound member to a
  13686. * delegate.
  13687. *
  13688. * The delegate isn't responsible for the connected object or the payload.
  13689. * Users must always guarantee that the lifetime of the instance overcomes
  13690. * the one of the delegate.<br/>
  13691. * When used to connect a free function with payload, its signature must be
  13692. * such that the instance is the first argument before the ones used to
  13693. * define the delegate itself.
  13694. *
  13695. * @tparam Candidate Function or member to connect to the delegate.
  13696. * @tparam Type Type of class or type of payload.
  13697. * @param value_or_instance A valid reference that fits the purpose.
  13698. */
  13699. template<auto Candidate, typename Type>
  13700. void connect(Type &value_or_instance) ENTT_NOEXCEPT {
  13701. instance = &value_or_instance;
  13702. if constexpr(std::is_invocable_r_v<Ret, decltype(Candidate), Type &, Args...>) {
  13703. fn = [](const void *payload, Args... args) -> Ret {
  13704. Type *curr = static_cast<Type *>(const_cast<constness_as_t<void, Type> *>(payload));
  13705. return Ret(std::invoke(Candidate, *curr, std::forward<Args>(args)...));
  13706. };
  13707. } else {
  13708. fn = wrap<Candidate>(value_or_instance, internal::index_sequence_for(internal::function_pointer_t<decltype(Candidate), Type>{}));
  13709. }
  13710. }
  13711. /**
  13712. * @brief Connects a free function with payload or a bound member to a
  13713. * delegate.
  13714. *
  13715. * @sa connect(Type &)
  13716. *
  13717. * @tparam Candidate Function or member to connect to the delegate.
  13718. * @tparam Type Type of class or type of payload.
  13719. * @param value_or_instance A valid pointer that fits the purpose.
  13720. */
  13721. template<auto Candidate, typename Type>
  13722. void connect(Type *value_or_instance) ENTT_NOEXCEPT {
  13723. instance = value_or_instance;
  13724. if constexpr(std::is_invocable_r_v<Ret, decltype(Candidate), Type *, Args...>) {
  13725. fn = [](const void *payload, Args... args) -> Ret {
  13726. Type *curr = static_cast<Type *>(const_cast<constness_as_t<void, Type> *>(payload));
  13727. return Ret(std::invoke(Candidate, curr, std::forward<Args>(args)...));
  13728. };
  13729. } else {
  13730. fn = wrap<Candidate>(value_or_instance, internal::index_sequence_for(internal::function_pointer_t<decltype(Candidate), Type>{}));
  13731. }
  13732. }
  13733. /**
  13734. * @brief Connects an user defined function with optional payload to a
  13735. * delegate.
  13736. *
  13737. * The delegate isn't responsible for the connected object or the payload.
  13738. * Users must always guarantee that the lifetime of an instance overcomes
  13739. * the one of the delegate.<br/>
  13740. * The payload is returned as the first argument to the target function in
  13741. * all cases.
  13742. *
  13743. * @param function Function to connect to the delegate.
  13744. * @param payload User defined arbitrary data.
  13745. */
  13746. void connect(function_type *function, const void *payload = nullptr) ENTT_NOEXCEPT {
  13747. instance = payload;
  13748. fn = function;
  13749. }
  13750. /**
  13751. * @brief Resets a delegate.
  13752. *
  13753. * After a reset, a delegate cannot be invoked anymore.
  13754. */
  13755. void reset() ENTT_NOEXCEPT {
  13756. instance = nullptr;
  13757. fn = nullptr;
  13758. }
  13759. /**
  13760. * @brief Returns the instance or the payload linked to a delegate, if any.
  13761. * @return An opaque pointer to the underlying data.
  13762. */
  13763. [[nodiscard]] const void *data() const ENTT_NOEXCEPT {
  13764. return instance;
  13765. }
  13766. /**
  13767. * @brief Triggers a delegate.
  13768. *
  13769. * The delegate invokes the underlying function and returns the result.
  13770. *
  13771. * @warning
  13772. * Attempting to trigger an invalid delegate results in undefined
  13773. * behavior.
  13774. *
  13775. * @param args Arguments to use to invoke the underlying function.
  13776. * @return The value returned by the underlying function.
  13777. */
  13778. Ret operator()(Args... args) const {
  13779. ENTT_ASSERT(static_cast<bool>(*this), "Uninitialized delegate");
  13780. return fn(instance, std::forward<Args>(args)...);
  13781. }
  13782. /**
  13783. * @brief Checks whether a delegate actually stores a listener.
  13784. * @return False if the delegate is empty, true otherwise.
  13785. */
  13786. [[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
  13787. // no need to also test instance
  13788. return !(fn == nullptr);
  13789. }
  13790. /**
  13791. * @brief Compares the contents of two delegates.
  13792. * @param other Delegate with which to compare.
  13793. * @return False if the two contents differ, true otherwise.
  13794. */
  13795. [[nodiscard]] bool operator==(const delegate<Ret(Args...)> &other) const ENTT_NOEXCEPT {
  13796. return fn == other.fn && instance == other.instance;
  13797. }
  13798. private:
  13799. const void *instance;
  13800. function_type *fn;
  13801. };
  13802. /**
  13803. * @brief Compares the contents of two delegates.
  13804. * @tparam Ret Return type of a function type.
  13805. * @tparam Args Types of arguments of a function type.
  13806. * @param lhs A valid delegate object.
  13807. * @param rhs A valid delegate object.
  13808. * @return True if the two contents differ, false otherwise.
  13809. */
  13810. template<typename Ret, typename... Args>
  13811. [[nodiscard]] bool operator!=(const delegate<Ret(Args...)> &lhs, const delegate<Ret(Args...)> &rhs) ENTT_NOEXCEPT {
  13812. return !(lhs == rhs);
  13813. }
  13814. /**
  13815. * @brief Deduction guide.
  13816. * @tparam Candidate Function or member to connect to the delegate.
  13817. */
  13818. template<auto Candidate>
  13819. delegate(connect_arg_t<Candidate>) -> delegate<std::remove_pointer_t<internal::function_pointer_t<decltype(Candidate)>>>;
  13820. /**
  13821. * @brief Deduction guide.
  13822. * @tparam Candidate Function or member to connect to the delegate.
  13823. * @tparam Type Type of class or type of payload.
  13824. */
  13825. template<auto Candidate, typename Type>
  13826. delegate(connect_arg_t<Candidate>, Type &&) -> delegate<std::remove_pointer_t<internal::function_pointer_t<decltype(Candidate), Type>>>;
  13827. /**
  13828. * @brief Deduction guide.
  13829. * @tparam Ret Return type of a function type.
  13830. * @tparam Args Types of arguments of a function type.
  13831. */
  13832. template<typename Ret, typename... Args>
  13833. delegate(Ret (*)(const void *, Args...), const void * = nullptr) -> delegate<Ret(Args...)>;
  13834. } // namespace entt
  13835. #endif
  13836. // #include "fwd.hpp"
  13837. namespace entt {
  13838. /**
  13839. * @brief Sink class.
  13840. *
  13841. * Primary template isn't defined on purpose. All the specializations give a
  13842. * compile-time error unless the template parameter is a function type.
  13843. *
  13844. * @tparam Type A valid signal handler type.
  13845. */
  13846. template<typename Type>
  13847. class sink;
  13848. /**
  13849. * @brief Unmanaged signal handler.
  13850. *
  13851. * Primary template isn't defined on purpose. All the specializations give a
  13852. * compile-time error unless the template parameter is a function type.
  13853. *
  13854. * @tparam Type A valid function type.
  13855. * @tparam Allocator Type of allocator used to manage memory and elements.
  13856. */
  13857. template<typename Type, typename Allocator>
  13858. class sigh;
  13859. /**
  13860. * @brief Unmanaged signal handler.
  13861. *
  13862. * It works directly with references to classes and pointers to member functions
  13863. * as well as pointers to free functions. Users of this class are in charge of
  13864. * disconnecting instances before deleting them.
  13865. *
  13866. * This class serves mainly two purposes:
  13867. *
  13868. * * Creating signals to use later to notify a bunch of listeners.
  13869. * * Collecting results from a set of functions like in a voting system.
  13870. *
  13871. * @tparam Ret Return type of a function type.
  13872. * @tparam Args Types of arguments of a function type.
  13873. * @tparam Allocator Type of allocator used to manage memory and elements.
  13874. */
  13875. template<typename Ret, typename... Args, typename Allocator>
  13876. class sigh<Ret(Args...), Allocator> {
  13877. /*! @brief A sink is allowed to modify a signal. */
  13878. friend class sink<sigh<Ret(Args...), Allocator>>;
  13879. using alloc_traits = std::allocator_traits<Allocator>;
  13880. static_assert(std::is_same_v<typename alloc_traits::value_type, Ret (*)(Args...)>, "Invalid value type");
  13881. using container_type = std::vector<delegate<Ret(Args...)>, typename alloc_traits::template rebind_alloc<delegate<Ret(Args...)>>>;
  13882. public:
  13883. /*! @brief Allocator type. */
  13884. using allocator_type = Allocator;
  13885. /*! @brief Unsigned integer type. */
  13886. using size_type = std::size_t;
  13887. /*! @brief Sink type. */
  13888. using sink_type = sink<sigh<Ret(Args...), Allocator>>;
  13889. /*! @brief Default constructor. */
  13890. sigh()
  13891. : sigh{allocator_type{}} {}
  13892. /**
  13893. * @brief Constructs a signal handler with a given allocator.
  13894. * @param allocator The allocator to use.
  13895. */
  13896. explicit sigh(const allocator_type &allocator)
  13897. : calls{allocator} {}
  13898. /**
  13899. * @brief Copy constructor.
  13900. * @param other The instance to copy from.
  13901. */
  13902. sigh(const sigh &other)
  13903. : calls{other.calls} {}
  13904. /**
  13905. * @brief Allocator-extended copy constructor.
  13906. * @param other The instance to copy from.
  13907. * @param allocator The allocator to use.
  13908. */
  13909. sigh(const sigh &other, const allocator_type &allocator)
  13910. : calls{other.calls, allocator} {}
  13911. /**
  13912. * @brief Move constructor.
  13913. * @param other The instance to move from.
  13914. */
  13915. sigh(sigh &&other) ENTT_NOEXCEPT
  13916. : calls{std::move(other.calls)} {}
  13917. /**
  13918. * @brief Allocator-extended move constructor.
  13919. * @param other The instance to move from.
  13920. * @param allocator The allocator to use.
  13921. */
  13922. sigh(sigh &&other, const allocator_type &allocator) ENTT_NOEXCEPT
  13923. : calls{std::move(other.calls), allocator} {}
  13924. /**
  13925. * @brief Copy assignment operator.
  13926. * @param other The instance to copy from.
  13927. * @return This signal handler.
  13928. */
  13929. sigh &operator=(const sigh &other) {
  13930. calls = other.calls;
  13931. return *this;
  13932. }
  13933. /**
  13934. * @brief Move assignment operator.
  13935. * @param other The instance to move from.
  13936. * @return This signal handler.
  13937. */
  13938. sigh &operator=(sigh &&other) ENTT_NOEXCEPT {
  13939. calls = std::move(other.calls);
  13940. return *this;
  13941. }
  13942. /**
  13943. * @brief Exchanges the contents with those of a given signal handler.
  13944. * @param other Signal handler to exchange the content with.
  13945. */
  13946. void swap(sigh &other) {
  13947. using std::swap;
  13948. swap(calls, other.calls);
  13949. }
  13950. /**
  13951. * @brief Returns the associated allocator.
  13952. * @return The associated allocator.
  13953. */
  13954. [[nodiscard]] constexpr allocator_type get_allocator() const ENTT_NOEXCEPT {
  13955. return calls.get_allocator();
  13956. }
  13957. /**
  13958. * @brief Instance type when it comes to connecting member functions.
  13959. * @tparam Class Type of class to which the member function belongs.
  13960. */
  13961. template<typename Class>
  13962. using instance_type = Class *;
  13963. /**
  13964. * @brief Number of listeners connected to the signal.
  13965. * @return Number of listeners currently connected.
  13966. */
  13967. [[nodiscard]] size_type size() const ENTT_NOEXCEPT {
  13968. return calls.size();
  13969. }
  13970. /**
  13971. * @brief Returns false if at least a listener is connected to the signal.
  13972. * @return True if the signal has no listeners connected, false otherwise.
  13973. */
  13974. [[nodiscard]] bool empty() const ENTT_NOEXCEPT {
  13975. return calls.empty();
  13976. }
  13977. /**
  13978. * @brief Triggers a signal.
  13979. *
  13980. * All the listeners are notified. Order isn't guaranteed.
  13981. *
  13982. * @param args Arguments to use to invoke listeners.
  13983. */
  13984. void publish(Args... args) const {
  13985. for(auto &&call: std::as_const(calls)) {
  13986. call(args...);
  13987. }
  13988. }
  13989. /**
  13990. * @brief Collects return values from the listeners.
  13991. *
  13992. * The collector must expose a call operator with the following properties:
  13993. *
  13994. * * The return type is either `void` or such that it's convertible to
  13995. * `bool`. In the second case, a true value will stop the iteration.
  13996. * * The list of parameters is empty if `Ret` is `void`, otherwise it
  13997. * contains a single element such that `Ret` is convertible to it.
  13998. *
  13999. * @tparam Func Type of collector to use, if any.
  14000. * @param func A valid function object.
  14001. * @param args Arguments to use to invoke listeners.
  14002. */
  14003. template<typename Func>
  14004. void collect(Func func, Args... args) const {
  14005. for(auto &&call: calls) {
  14006. if constexpr(std::is_void_v<Ret>) {
  14007. if constexpr(std::is_invocable_r_v<bool, Func>) {
  14008. call(args...);
  14009. if(func()) { break; }
  14010. } else {
  14011. call(args...);
  14012. func();
  14013. }
  14014. } else {
  14015. if constexpr(std::is_invocable_r_v<bool, Func, Ret>) {
  14016. if(func(call(args...))) { break; }
  14017. } else {
  14018. func(call(args...));
  14019. }
  14020. }
  14021. }
  14022. }
  14023. private:
  14024. container_type calls;
  14025. };
  14026. /**
  14027. * @brief Connection class.
  14028. *
  14029. * Opaque object the aim of which is to allow users to release an already
  14030. * estabilished connection without having to keep a reference to the signal or
  14031. * the sink that generated it.
  14032. */
  14033. class connection {
  14034. /*! @brief A sink is allowed to create connection objects. */
  14035. template<typename>
  14036. friend class sink;
  14037. connection(delegate<void(void *)> fn, void *ref)
  14038. : disconnect{fn}, signal{ref} {}
  14039. public:
  14040. /*! @brief Default constructor. */
  14041. connection() = default;
  14042. /**
  14043. * @brief Checks whether a connection is properly initialized.
  14044. * @return True if the connection is properly initialized, false otherwise.
  14045. */
  14046. [[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
  14047. return static_cast<bool>(disconnect);
  14048. }
  14049. /*! @brief Breaks the connection. */
  14050. void release() {
  14051. if(disconnect) {
  14052. disconnect(signal);
  14053. disconnect.reset();
  14054. }
  14055. }
  14056. private:
  14057. delegate<void(void *)> disconnect;
  14058. void *signal{};
  14059. };
  14060. /**
  14061. * @brief Scoped connection class.
  14062. *
  14063. * Opaque object the aim of which is to allow users to release an already
  14064. * estabilished connection without having to keep a reference to the signal or
  14065. * the sink that generated it.<br/>
  14066. * A scoped connection automatically breaks the link between the two objects
  14067. * when it goes out of scope.
  14068. */
  14069. struct scoped_connection {
  14070. /*! @brief Default constructor. */
  14071. scoped_connection() = default;
  14072. /**
  14073. * @brief Constructs a scoped connection from a basic connection.
  14074. * @param other A valid connection object.
  14075. */
  14076. scoped_connection(const connection &other)
  14077. : conn{other} {}
  14078. /*! @brief Default copy constructor, deleted on purpose. */
  14079. scoped_connection(const scoped_connection &) = delete;
  14080. /**
  14081. * @brief Move constructor.
  14082. * @param other The scoped connection to move from.
  14083. */
  14084. scoped_connection(scoped_connection &&other) ENTT_NOEXCEPT
  14085. : conn{std::exchange(other.conn, {})} {}
  14086. /*! @brief Automatically breaks the link on destruction. */
  14087. ~scoped_connection() {
  14088. conn.release();
  14089. }
  14090. /**
  14091. * @brief Default copy assignment operator, deleted on purpose.
  14092. * @return This scoped connection.
  14093. */
  14094. scoped_connection &operator=(const scoped_connection &) = delete;
  14095. /**
  14096. * @brief Move assignment operator.
  14097. * @param other The scoped connection to move from.
  14098. * @return This scoped connection.
  14099. */
  14100. scoped_connection &operator=(scoped_connection &&other) ENTT_NOEXCEPT {
  14101. conn = std::exchange(other.conn, {});
  14102. return *this;
  14103. }
  14104. /**
  14105. * @brief Acquires a connection.
  14106. * @param other The connection object to acquire.
  14107. * @return This scoped connection.
  14108. */
  14109. scoped_connection &operator=(connection other) {
  14110. conn = std::move(other);
  14111. return *this;
  14112. }
  14113. /**
  14114. * @brief Checks whether a scoped connection is properly initialized.
  14115. * @return True if the connection is properly initialized, false otherwise.
  14116. */
  14117. [[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
  14118. return static_cast<bool>(conn);
  14119. }
  14120. /*! @brief Breaks the connection. */
  14121. void release() {
  14122. conn.release();
  14123. }
  14124. private:
  14125. connection conn;
  14126. };
  14127. /**
  14128. * @brief Sink class.
  14129. *
  14130. * A sink is used to connect listeners to signals and to disconnect them.<br/>
  14131. * The function type for a listener is the one of the signal to which it
  14132. * belongs.
  14133. *
  14134. * The clear separation between a signal and a sink permits to store the former
  14135. * as private data member without exposing the publish functionality to the
  14136. * users of the class.
  14137. *
  14138. * @warning
  14139. * Lifetime of a sink must not overcome that of the signal to which it refers.
  14140. * In any other case, attempting to use a sink results in undefined behavior.
  14141. *
  14142. * @tparam Ret Return type of a function type.
  14143. * @tparam Args Types of arguments of a function type.
  14144. * @tparam Allocator Type of allocator used to manage memory and elements.
  14145. */
  14146. template<typename Ret, typename... Args, typename Allocator>
  14147. class sink<sigh<Ret(Args...), Allocator>> {
  14148. using signal_type = sigh<Ret(Args...), Allocator>;
  14149. using difference_type = typename signal_type::container_type::difference_type;
  14150. template<auto Candidate, typename Type>
  14151. static void release(Type value_or_instance, void *signal) {
  14152. sink{*static_cast<signal_type *>(signal)}.disconnect<Candidate>(value_or_instance);
  14153. }
  14154. template<auto Candidate>
  14155. static void release(void *signal) {
  14156. sink{*static_cast<signal_type *>(signal)}.disconnect<Candidate>();
  14157. }
  14158. public:
  14159. /**
  14160. * @brief Constructs a sink that is allowed to modify a given signal.
  14161. * @param ref A valid reference to a signal object.
  14162. */
  14163. sink(sigh<Ret(Args...), Allocator> &ref) ENTT_NOEXCEPT
  14164. : offset{},
  14165. signal{&ref} {}
  14166. /**
  14167. * @brief Returns false if at least a listener is connected to the sink.
  14168. * @return True if the sink has no listeners connected, false otherwise.
  14169. */
  14170. [[nodiscard]] bool empty() const ENTT_NOEXCEPT {
  14171. return signal->calls.empty();
  14172. }
  14173. /**
  14174. * @brief Returns a sink that connects before a given free function or an
  14175. * unbound member.
  14176. * @tparam Function A valid free function pointer.
  14177. * @return A properly initialized sink object.
  14178. */
  14179. template<auto Function>
  14180. [[nodiscard]] sink before() {
  14181. delegate<Ret(Args...)> call{};
  14182. call.template connect<Function>();
  14183. const auto &calls = signal->calls;
  14184. const auto it = std::find(calls.cbegin(), calls.cend(), std::move(call));
  14185. sink other{*this};
  14186. other.offset = calls.cend() - it;
  14187. return other;
  14188. }
  14189. /**
  14190. * @brief Returns a sink that connects before a free function with payload
  14191. * or a bound member.
  14192. * @tparam Candidate Member or free function to look for.
  14193. * @tparam Type Type of class or type of payload.
  14194. * @param value_or_instance A valid object that fits the purpose.
  14195. * @return A properly initialized sink object.
  14196. */
  14197. template<auto Candidate, typename Type>
  14198. [[nodiscard]] sink before(Type &&value_or_instance) {
  14199. delegate<Ret(Args...)> call{};
  14200. call.template connect<Candidate>(value_or_instance);
  14201. const auto &calls = signal->calls;
  14202. const auto it = std::find(calls.cbegin(), calls.cend(), std::move(call));
  14203. sink other{*this};
  14204. other.offset = calls.cend() - it;
  14205. return other;
  14206. }
  14207. /**
  14208. * @brief Returns a sink that connects before a given instance or specific
  14209. * payload.
  14210. * @tparam Type Type of class or type of payload.
  14211. * @param value_or_instance A valid object that fits the purpose.
  14212. * @return A properly initialized sink object.
  14213. */
  14214. template<typename Type>
  14215. [[nodiscard]] sink before(Type &value_or_instance) {
  14216. return before(&value_or_instance);
  14217. }
  14218. /**
  14219. * @brief Returns a sink that connects before a given instance or specific
  14220. * payload.
  14221. * @tparam Type Type of class or type of payload.
  14222. * @param value_or_instance A valid pointer that fits the purpose.
  14223. * @return A properly initialized sink object.
  14224. */
  14225. template<typename Type>
  14226. [[nodiscard]] sink before(Type *value_or_instance) {
  14227. sink other{*this};
  14228. if(value_or_instance) {
  14229. const auto &calls = signal->calls;
  14230. const auto it = std::find_if(calls.cbegin(), calls.cend(), [value_or_instance](const auto &delegate) {
  14231. return delegate.data() == value_or_instance;
  14232. });
  14233. other.offset = calls.cend() - it;
  14234. }
  14235. return other;
  14236. }
  14237. /**
  14238. * @brief Returns a sink that connects before anything else.
  14239. * @return A properly initialized sink object.
  14240. */
  14241. [[nodiscard]] sink before() {
  14242. sink other{*this};
  14243. other.offset = signal->calls.size();
  14244. return other;
  14245. }
  14246. /**
  14247. * @brief Connects a free function or an unbound member to a signal.
  14248. *
  14249. * The signal handler performs checks to avoid multiple connections for the
  14250. * same function.
  14251. *
  14252. * @tparam Candidate Function or member to connect to the signal.
  14253. * @return A properly initialized connection object.
  14254. */
  14255. template<auto Candidate>
  14256. connection connect() {
  14257. disconnect<Candidate>();
  14258. delegate<Ret(Args...)> call{};
  14259. call.template connect<Candidate>();
  14260. signal->calls.insert(signal->calls.end() - offset, std::move(call));
  14261. delegate<void(void *)> conn{};
  14262. conn.template connect<&release<Candidate>>();
  14263. return {std::move(conn), signal};
  14264. }
  14265. /**
  14266. * @brief Connects a free function with payload or a bound member to a
  14267. * signal.
  14268. *
  14269. * The signal isn't responsible for the connected object or the payload.
  14270. * Users must always guarantee that the lifetime of the instance overcomes
  14271. * the one of the signal. On the other side, the signal handler performs
  14272. * checks to avoid multiple connections for the same function.<br/>
  14273. * When used to connect a free function with payload, its signature must be
  14274. * such that the instance is the first argument before the ones used to
  14275. * define the signal itself.
  14276. *
  14277. * @tparam Candidate Function or member to connect to the signal.
  14278. * @tparam Type Type of class or type of payload.
  14279. * @param value_or_instance A valid object that fits the purpose.
  14280. * @return A properly initialized connection object.
  14281. */
  14282. template<auto Candidate, typename Type>
  14283. connection connect(Type &&value_or_instance) {
  14284. disconnect<Candidate>(value_or_instance);
  14285. delegate<Ret(Args...)> call{};
  14286. call.template connect<Candidate>(value_or_instance);
  14287. signal->calls.insert(signal->calls.end() - offset, std::move(call));
  14288. delegate<void(void *)> conn{};
  14289. conn.template connect<&release<Candidate, Type>>(value_or_instance);
  14290. return {std::move(conn), signal};
  14291. }
  14292. /**
  14293. * @brief Disconnects a free function or an unbound member from a signal.
  14294. * @tparam Candidate Function or member to disconnect from the signal.
  14295. */
  14296. template<auto Candidate>
  14297. void disconnect() {
  14298. auto &calls = signal->calls;
  14299. delegate<Ret(Args...)> call{};
  14300. call.template connect<Candidate>();
  14301. calls.erase(std::remove(calls.begin(), calls.end(), std::move(call)), calls.end());
  14302. }
  14303. /**
  14304. * @brief Disconnects a free function with payload or a bound member from a
  14305. * signal.
  14306. * @tparam Candidate Function or member to disconnect from the signal.
  14307. * @tparam Type Type of class or type of payload.
  14308. * @param value_or_instance A valid object that fits the purpose.
  14309. */
  14310. template<auto Candidate, typename Type>
  14311. void disconnect(Type &&value_or_instance) {
  14312. auto &calls = signal->calls;
  14313. delegate<Ret(Args...)> call{};
  14314. call.template connect<Candidate>(value_or_instance);
  14315. calls.erase(std::remove(calls.begin(), calls.end(), std::move(call)), calls.end());
  14316. }
  14317. /**
  14318. * @brief Disconnects free functions with payload or bound members from a
  14319. * signal.
  14320. * @tparam Type Type of class or type of payload.
  14321. * @param value_or_instance A valid object that fits the purpose.
  14322. */
  14323. template<typename Type>
  14324. void disconnect(Type &value_or_instance) {
  14325. disconnect(&value_or_instance);
  14326. }
  14327. /**
  14328. * @brief Disconnects free functions with payload or bound members from a
  14329. * signal.
  14330. * @tparam Type Type of class or type of payload.
  14331. * @param value_or_instance A valid object that fits the purpose.
  14332. */
  14333. template<typename Type>
  14334. void disconnect(Type *value_or_instance) {
  14335. if(value_or_instance) {
  14336. auto &calls = signal->calls;
  14337. auto predicate = [value_or_instance](const auto &delegate) { return delegate.data() == value_or_instance; };
  14338. calls.erase(std::remove_if(calls.begin(), calls.end(), std::move(predicate)), calls.end());
  14339. }
  14340. }
  14341. /*! @brief Disconnects all the listeners from a signal. */
  14342. void disconnect() {
  14343. signal->calls.clear();
  14344. }
  14345. private:
  14346. difference_type offset;
  14347. signal_type *signal;
  14348. };
  14349. /**
  14350. * @brief Deduction guide.
  14351. *
  14352. * It allows to deduce the signal handler type of a sink directly from the
  14353. * signal it refers to.
  14354. *
  14355. * @tparam Ret Return type of a function type.
  14356. * @tparam Args Types of arguments of a function type.
  14357. * @tparam Allocator Type of allocator used to manage memory and elements.
  14358. */
  14359. template<typename Ret, typename... Args, typename Allocator>
  14360. sink(sigh<Ret(Args...), Allocator> &) -> sink<sigh<Ret(Args...), Allocator>>;
  14361. } // namespace entt
  14362. #endif
  14363. // #include "fwd.hpp"
  14364. namespace entt {
  14365. /**
  14366. * @brief Mixin type used to add signal support to storage types.
  14367. *
  14368. * The function type of a listener is equivalent to:
  14369. *
  14370. * @code{.cpp}
  14371. * void(basic_registry<entity_type> &, entity_type);
  14372. * @endcode
  14373. *
  14374. * This applies to all signals made available.
  14375. *
  14376. * @tparam Type The type of the underlying storage.
  14377. */
  14378. template<typename Type>
  14379. class sigh_storage_mixin final: public Type {
  14380. using basic_iterator = typename Type::basic_iterator;
  14381. template<typename Func>
  14382. void notify_destruction(basic_iterator first, basic_iterator last, Func func) {
  14383. ENTT_ASSERT(owner != nullptr, "Invalid pointer to registry");
  14384. for(; first != last; ++first) {
  14385. const auto entt = *first;
  14386. destruction.publish(*owner, entt);
  14387. const auto it = Type::find(entt);
  14388. func(it, it + 1u);
  14389. }
  14390. }
  14391. void swap_and_pop(basic_iterator first, basic_iterator last) final {
  14392. notify_destruction(std::move(first), std::move(last), [this](auto... args) { Type::swap_and_pop(args...); });
  14393. }
  14394. void in_place_pop(basic_iterator first, basic_iterator last) final {
  14395. notify_destruction(std::move(first), std::move(last), [this](auto... args) { Type::in_place_pop(args...); });
  14396. }
  14397. basic_iterator try_emplace(const typename Type::entity_type entt, const bool force_back, const void *value) final {
  14398. ENTT_ASSERT(owner != nullptr, "Invalid pointer to registry");
  14399. Type::try_emplace(entt, force_back, value);
  14400. construction.publish(*owner, entt);
  14401. return Type::find(entt);
  14402. }
  14403. public:
  14404. /*! @brief Underlying entity identifier. */
  14405. using entity_type = typename Type::entity_type;
  14406. /*! @brief Inherited constructors. */
  14407. using Type::Type;
  14408. /**
  14409. * @brief Returns a sink object.
  14410. *
  14411. * The sink returned by this function can be used to receive notifications
  14412. * whenever a new instance is created and assigned to an entity.<br/>
  14413. * Listeners are invoked after the object has been assigned to the entity.
  14414. *
  14415. * @sa sink
  14416. *
  14417. * @return A temporary sink object.
  14418. */
  14419. [[nodiscard]] auto on_construct() ENTT_NOEXCEPT {
  14420. return sink{construction};
  14421. }
  14422. /**
  14423. * @brief Returns a sink object.
  14424. *
  14425. * The sink returned by this function can be used to receive notifications
  14426. * whenever an instance is explicitly updated.<br/>
  14427. * Listeners are invoked after the object has been updated.
  14428. *
  14429. * @sa sink
  14430. *
  14431. * @return A temporary sink object.
  14432. */
  14433. [[nodiscard]] auto on_update() ENTT_NOEXCEPT {
  14434. return sink{update};
  14435. }
  14436. /**
  14437. * @brief Returns a sink object.
  14438. *
  14439. * The sink returned by this function can be used to receive notifications
  14440. * whenever an instance is removed from an entity and thus destroyed.<br/>
  14441. * Listeners are invoked before the object has been removed from the entity.
  14442. *
  14443. * @sa sink
  14444. *
  14445. * @return A temporary sink object.
  14446. */
  14447. [[nodiscard]] auto on_destroy() ENTT_NOEXCEPT {
  14448. return sink{destruction};
  14449. }
  14450. /**
  14451. * @brief Assigns entities to a storage.
  14452. * @tparam Args Types of arguments to use to construct the object.
  14453. * @param entt A valid identifier.
  14454. * @param args Parameters to use to initialize the object.
  14455. * @return A reference to the newly created object.
  14456. */
  14457. template<typename... Args>
  14458. decltype(auto) emplace(const entity_type entt, Args &&...args) {
  14459. ENTT_ASSERT(owner != nullptr, "Invalid pointer to registry");
  14460. Type::emplace(entt, std::forward<Args>(args)...);
  14461. construction.publish(*owner, entt);
  14462. return this->get(entt);
  14463. }
  14464. /**
  14465. * @brief Patches the given instance for an entity.
  14466. * @tparam Func Types of the function objects to invoke.
  14467. * @param entt A valid identifier.
  14468. * @param func Valid function objects.
  14469. * @return A reference to the patched instance.
  14470. */
  14471. template<typename... Func>
  14472. decltype(auto) patch(const entity_type entt, Func &&...func) {
  14473. ENTT_ASSERT(owner != nullptr, "Invalid pointer to registry");
  14474. Type::patch(entt, std::forward<Func>(func)...);
  14475. update.publish(*owner, entt);
  14476. return this->get(entt);
  14477. }
  14478. /**
  14479. * @brief Assigns entities to a storage.
  14480. * @tparam It Type of input iterator.
  14481. * @tparam Args Types of arguments to use to construct the objects assigned
  14482. * to the entities.
  14483. * @param first An iterator to the first element of the range of entities.
  14484. * @param last An iterator past the last element of the range of entities.
  14485. * @param args Parameters to use to initialize the objects assigned to the
  14486. * entities.
  14487. */
  14488. template<typename It, typename... Args>
  14489. void insert(It first, It last, Args &&...args) {
  14490. ENTT_ASSERT(owner != nullptr, "Invalid pointer to registry");
  14491. Type::insert(first, last, std::forward<Args>(args)...);
  14492. for(auto it = construction.empty() ? last : first; it != last; ++it) {
  14493. construction.publish(*owner, *it);
  14494. }
  14495. }
  14496. /**
  14497. * @brief Forwards variables to mixins, if any.
  14498. * @param value A variable wrapped in an opaque container.
  14499. */
  14500. void bind(any value) ENTT_NOEXCEPT final {
  14501. auto *reg = any_cast<basic_registry<entity_type>>(&value);
  14502. owner = reg ? reg : owner;
  14503. Type::bind(std::move(value));
  14504. }
  14505. private:
  14506. sigh<void(basic_registry<entity_type> &, const entity_type)> construction{};
  14507. sigh<void(basic_registry<entity_type> &, const entity_type)> destruction{};
  14508. sigh<void(basic_registry<entity_type> &, const entity_type)> update{};
  14509. basic_registry<entity_type> *owner{};
  14510. };
  14511. } // namespace entt
  14512. #endif
  14513. // #include "sparse_set.hpp"
  14514. namespace entt {
  14515. /**
  14516. * @cond TURN_OFF_DOXYGEN
  14517. * Internal details not to be documented.
  14518. */
  14519. namespace internal {
  14520. template<typename Container>
  14521. class storage_iterator final {
  14522. friend storage_iterator<const Container>;
  14523. using container_type = std::remove_const_t<Container>;
  14524. using alloc_traits = std::allocator_traits<typename container_type::allocator_type>;
  14525. using comp_traits = component_traits<typename container_type::value_type>;
  14526. using iterator_traits = std::iterator_traits<std::conditional_t<
  14527. std::is_const_v<Container>,
  14528. typename alloc_traits::template rebind_traits<typename std::pointer_traits<typename container_type::value_type>::element_type>::const_pointer,
  14529. typename alloc_traits::template rebind_traits<typename std::pointer_traits<typename container_type::value_type>::element_type>::pointer>>;
  14530. public:
  14531. using value_type = typename iterator_traits::value_type;
  14532. using pointer = typename iterator_traits::pointer;
  14533. using reference = typename iterator_traits::reference;
  14534. using difference_type = typename iterator_traits::difference_type;
  14535. using iterator_category = std::random_access_iterator_tag;
  14536. storage_iterator() ENTT_NOEXCEPT = default;
  14537. storage_iterator(Container *ref, difference_type idx) ENTT_NOEXCEPT
  14538. : packed{ref},
  14539. offset{idx} {}
  14540. template<bool Const = std::is_const_v<Container>, typename = std::enable_if_t<Const>>
  14541. storage_iterator(const storage_iterator<std::remove_const_t<Container>> &other) ENTT_NOEXCEPT
  14542. : packed{other.packed},
  14543. offset{other.offset} {}
  14544. storage_iterator &operator++() ENTT_NOEXCEPT {
  14545. return --offset, *this;
  14546. }
  14547. storage_iterator operator++(int) ENTT_NOEXCEPT {
  14548. storage_iterator orig = *this;
  14549. return ++(*this), orig;
  14550. }
  14551. storage_iterator &operator--() ENTT_NOEXCEPT {
  14552. return ++offset, *this;
  14553. }
  14554. storage_iterator operator--(int) ENTT_NOEXCEPT {
  14555. storage_iterator orig = *this;
  14556. return operator--(), orig;
  14557. }
  14558. storage_iterator &operator+=(const difference_type value) ENTT_NOEXCEPT {
  14559. offset -= value;
  14560. return *this;
  14561. }
  14562. storage_iterator operator+(const difference_type value) const ENTT_NOEXCEPT {
  14563. storage_iterator copy = *this;
  14564. return (copy += value);
  14565. }
  14566. storage_iterator &operator-=(const difference_type value) ENTT_NOEXCEPT {
  14567. return (*this += -value);
  14568. }
  14569. storage_iterator operator-(const difference_type value) const ENTT_NOEXCEPT {
  14570. return (*this + -value);
  14571. }
  14572. [[nodiscard]] reference operator[](const difference_type value) const ENTT_NOEXCEPT {
  14573. const auto pos = index() - value;
  14574. return (*packed)[pos / comp_traits::page_size][fast_mod(pos, comp_traits::page_size)];
  14575. }
  14576. [[nodiscard]] pointer operator->() const ENTT_NOEXCEPT {
  14577. const auto pos = index();
  14578. return (*packed)[pos / comp_traits::page_size] + fast_mod(pos, comp_traits::page_size);
  14579. }
  14580. [[nodiscard]] reference operator*() const ENTT_NOEXCEPT {
  14581. return *operator->();
  14582. }
  14583. [[nodiscard]] difference_type index() const ENTT_NOEXCEPT {
  14584. return offset - 1;
  14585. }
  14586. private:
  14587. Container *packed;
  14588. difference_type offset;
  14589. };
  14590. template<typename CLhs, typename CRhs>
  14591. [[nodiscard]] std::ptrdiff_t operator-(const storage_iterator<CLhs> &lhs, const storage_iterator<CRhs> &rhs) ENTT_NOEXCEPT {
  14592. return rhs.index() - lhs.index();
  14593. }
  14594. template<typename CLhs, typename CRhs>
  14595. [[nodiscard]] bool operator==(const storage_iterator<CLhs> &lhs, const storage_iterator<CRhs> &rhs) ENTT_NOEXCEPT {
  14596. return lhs.index() == rhs.index();
  14597. }
  14598. template<typename CLhs, typename CRhs>
  14599. [[nodiscard]] bool operator!=(const storage_iterator<CLhs> &lhs, const storage_iterator<CRhs> &rhs) ENTT_NOEXCEPT {
  14600. return !(lhs == rhs);
  14601. }
  14602. template<typename CLhs, typename CRhs>
  14603. [[nodiscard]] bool operator<(const storage_iterator<CLhs> &lhs, const storage_iterator<CRhs> &rhs) ENTT_NOEXCEPT {
  14604. return lhs.index() > rhs.index();
  14605. }
  14606. template<typename CLhs, typename CRhs>
  14607. [[nodiscard]] bool operator>(const storage_iterator<CLhs> &lhs, const storage_iterator<CRhs> &rhs) ENTT_NOEXCEPT {
  14608. return lhs.index() < rhs.index();
  14609. }
  14610. template<typename CLhs, typename CRhs>
  14611. [[nodiscard]] bool operator<=(const storage_iterator<CLhs> &lhs, const storage_iterator<CRhs> &rhs) ENTT_NOEXCEPT {
  14612. return !(lhs > rhs);
  14613. }
  14614. template<typename CLhs, typename CRhs>
  14615. [[nodiscard]] bool operator>=(const storage_iterator<CLhs> &lhs, const storage_iterator<CRhs> &rhs) ENTT_NOEXCEPT {
  14616. return !(lhs < rhs);
  14617. }
  14618. template<typename It, typename... Other>
  14619. class extended_storage_iterator final {
  14620. template<typename Iter, typename... Args>
  14621. friend class extended_storage_iterator;
  14622. public:
  14623. using value_type = decltype(std::tuple_cat(std::make_tuple(*std::declval<It>()), std::forward_as_tuple(*std::declval<Other>()...)));
  14624. using pointer = input_iterator_pointer<value_type>;
  14625. using reference = value_type;
  14626. using difference_type = std::ptrdiff_t;
  14627. using iterator_category = std::input_iterator_tag;
  14628. extended_storage_iterator() = default;
  14629. extended_storage_iterator(It base, Other... other)
  14630. : it{base, other...} {}
  14631. template<typename... Args, typename = std::enable_if_t<(!std::is_same_v<Other, Args> && ...) && (std::is_constructible_v<Other, Args> && ...)>>
  14632. extended_storage_iterator(const extended_storage_iterator<It, Args...> &other)
  14633. : it{other.it} {}
  14634. extended_storage_iterator &operator++() ENTT_NOEXCEPT {
  14635. return ++std::get<It>(it), (++std::get<Other>(it), ...), *this;
  14636. }
  14637. extended_storage_iterator operator++(int) ENTT_NOEXCEPT {
  14638. extended_storage_iterator orig = *this;
  14639. return ++(*this), orig;
  14640. }
  14641. [[nodiscard]] pointer operator->() const ENTT_NOEXCEPT {
  14642. return operator*();
  14643. }
  14644. [[nodiscard]] reference operator*() const ENTT_NOEXCEPT {
  14645. return {*std::get<It>(it), *std::get<Other>(it)...};
  14646. }
  14647. template<typename... CLhs, typename... CRhs>
  14648. friend bool operator==(const extended_storage_iterator<CLhs...> &, const extended_storage_iterator<CRhs...> &) ENTT_NOEXCEPT;
  14649. private:
  14650. std::tuple<It, Other...> it;
  14651. };
  14652. template<typename... CLhs, typename... CRhs>
  14653. [[nodiscard]] bool operator==(const extended_storage_iterator<CLhs...> &lhs, const extended_storage_iterator<CRhs...> &rhs) ENTT_NOEXCEPT {
  14654. return std::get<0>(lhs.it) == std::get<0>(rhs.it);
  14655. }
  14656. template<typename... CLhs, typename... CRhs>
  14657. [[nodiscard]] bool operator!=(const extended_storage_iterator<CLhs...> &lhs, const extended_storage_iterator<CRhs...> &rhs) ENTT_NOEXCEPT {
  14658. return !(lhs == rhs);
  14659. }
  14660. } // namespace internal
  14661. /**
  14662. * Internal details not to be documented.
  14663. * @endcond
  14664. */
  14665. /**
  14666. * @brief Basic storage implementation.
  14667. *
  14668. * Internal data structures arrange elements to maximize performance. There are
  14669. * no guarantees that objects are returned in the insertion order when iterate
  14670. * a storage. Do not make assumption on the order in any case.
  14671. *
  14672. * @warning
  14673. * Empty types aren't explicitly instantiated. Therefore, many of the functions
  14674. * normally available for non-empty types will not be available for empty ones.
  14675. *
  14676. * @tparam Entity A valid entity type (see entt_traits for more details).
  14677. * @tparam Type Type of objects assigned to the entities.
  14678. * @tparam Allocator Type of allocator used to manage memory and elements.
  14679. */
  14680. template<typename Entity, typename Type, typename Allocator, typename>
  14681. class basic_storage: public basic_sparse_set<Entity, typename std::allocator_traits<Allocator>::template rebind_alloc<Entity>> {
  14682. static_assert(std::is_move_constructible_v<Type> && std::is_move_assignable_v<Type>, "The type must be at least move constructible/assignable");
  14683. using alloc_traits = std::allocator_traits<Allocator>;
  14684. static_assert(std::is_same_v<typename alloc_traits::value_type, Type>, "Invalid value type");
  14685. using underlying_type = basic_sparse_set<Entity, typename alloc_traits::template rebind_alloc<Entity>>;
  14686. using container_type = std::vector<typename alloc_traits::pointer, typename alloc_traits::template rebind_alloc<typename alloc_traits::pointer>>;
  14687. using comp_traits = component_traits<Type>;
  14688. [[nodiscard]] auto &element_at(const std::size_t pos) const {
  14689. return packed.first()[pos / comp_traits::page_size][fast_mod(pos, comp_traits::page_size)];
  14690. }
  14691. auto assure_at_least(const std::size_t pos) {
  14692. auto &&container = packed.first();
  14693. const auto idx = pos / comp_traits::page_size;
  14694. if(!(idx < container.size())) {
  14695. auto curr = container.size();
  14696. container.resize(idx + 1u, nullptr);
  14697. ENTT_TRY {
  14698. for(const auto last = container.size(); curr < last; ++curr) {
  14699. container[curr] = alloc_traits::allocate(packed.second(), comp_traits::page_size);
  14700. }
  14701. }
  14702. ENTT_CATCH {
  14703. container.resize(curr);
  14704. ENTT_THROW;
  14705. }
  14706. }
  14707. return container[idx] + fast_mod(pos, comp_traits::page_size);
  14708. }
  14709. template<typename... Args>
  14710. auto emplace_element(const Entity entt, const bool force_back, Args &&...args) {
  14711. const auto it = base_type::try_emplace(entt, force_back);
  14712. ENTT_TRY {
  14713. auto elem = assure_at_least(static_cast<size_type>(it.index()));
  14714. entt::uninitialized_construct_using_allocator(to_address(elem), packed.second(), std::forward<Args>(args)...);
  14715. }
  14716. ENTT_CATCH {
  14717. if constexpr(comp_traits::in_place_delete) {
  14718. base_type::in_place_pop(it, it + 1u);
  14719. } else {
  14720. base_type::swap_and_pop(it, it + 1u);
  14721. }
  14722. ENTT_THROW;
  14723. }
  14724. return it;
  14725. }
  14726. void shrink_to_size(const std::size_t sz) {
  14727. for(auto pos = sz, length = base_type::size(); pos < length; ++pos) {
  14728. if constexpr(comp_traits::in_place_delete) {
  14729. if(base_type::at(pos) != tombstone) {
  14730. std::destroy_at(std::addressof(element_at(pos)));
  14731. }
  14732. } else {
  14733. std::destroy_at(std::addressof(element_at(pos)));
  14734. }
  14735. }
  14736. auto &&container = packed.first();
  14737. auto page_allocator{packed.second()};
  14738. const auto from = (sz + comp_traits::page_size - 1u) / comp_traits::page_size;
  14739. for(auto pos = from, last = container.size(); pos < last; ++pos) {
  14740. alloc_traits::deallocate(page_allocator, container[pos], comp_traits::page_size);
  14741. }
  14742. container.resize(from);
  14743. }
  14744. private:
  14745. const void *get_at(const std::size_t pos) const final {
  14746. return std::addressof(element_at(pos));
  14747. }
  14748. void swap_at(const std::size_t lhs, const std::size_t rhs) final {
  14749. using std::swap;
  14750. swap(element_at(lhs), element_at(rhs));
  14751. }
  14752. void move_element(const std::size_t from, const std::size_t to) final {
  14753. auto &elem = element_at(from);
  14754. entt::uninitialized_construct_using_allocator(to_address(assure_at_least(to)), packed.second(), std::move(elem));
  14755. std::destroy_at(std::addressof(elem));
  14756. }
  14757. protected:
  14758. /**
  14759. * @brief Erases elements from a storage.
  14760. * @param first An iterator to the first element to erase.
  14761. * @param last An iterator past the last element to erase.
  14762. */
  14763. void swap_and_pop(typename underlying_type::basic_iterator first, typename underlying_type::basic_iterator last) override {
  14764. for(; first != last; ++first) {
  14765. // cannot use first::index() because it would break with cross iterators
  14766. const auto pos = base_type::index(*first);
  14767. auto &elem = element_at(base_type::size() - 1u);
  14768. // destroying on exit allows reentrant destructors
  14769. [[maybe_unused]] auto unused = std::exchange(element_at(pos), std::move(elem));
  14770. std::destroy_at(std::addressof(elem));
  14771. base_type::swap_and_pop(first, first + 1u);
  14772. }
  14773. }
  14774. /**
  14775. * @brief Erases elements from a storage.
  14776. * @param first An iterator to the first element to erase.
  14777. * @param last An iterator past the last element to erase.
  14778. */
  14779. void in_place_pop(typename underlying_type::basic_iterator first, typename underlying_type::basic_iterator last) override {
  14780. for(; first != last; ++first) {
  14781. // cannot use first::index() because it would break with cross iterators
  14782. const auto pos = base_type::index(*first);
  14783. base_type::in_place_pop(first, first + 1u);
  14784. std::destroy_at(std::addressof(element_at(pos)));
  14785. }
  14786. }
  14787. /**
  14788. * @brief Assigns an entity to a storage.
  14789. * @param entt A valid identifier.
  14790. * @param value Optional opaque value.
  14791. * @param force_back Force back insertion.
  14792. * @return Iterator pointing to the emplaced element.
  14793. */
  14794. typename underlying_type::basic_iterator try_emplace([[maybe_unused]] const Entity entt, const bool force_back, const void *value) override {
  14795. if(value) {
  14796. if constexpr(std::is_copy_constructible_v<value_type>) {
  14797. return emplace_element(entt, force_back, *static_cast<const value_type *>(value));
  14798. } else {
  14799. return base_type::end();
  14800. }
  14801. } else {
  14802. if constexpr(std::is_default_constructible_v<value_type>) {
  14803. return emplace_element(entt, force_back);
  14804. } else {
  14805. return base_type::end();
  14806. }
  14807. }
  14808. }
  14809. public:
  14810. /*! @brief Base type. */
  14811. using base_type = underlying_type;
  14812. /*! @brief Allocator type. */
  14813. using allocator_type = Allocator;
  14814. /*! @brief Type of the objects assigned to entities. */
  14815. using value_type = Type;
  14816. /*! @brief Underlying entity identifier. */
  14817. using entity_type = Entity;
  14818. /*! @brief Unsigned integer type. */
  14819. using size_type = std::size_t;
  14820. /*! @brief Pointer type to contained elements. */
  14821. using pointer = typename container_type::pointer;
  14822. /*! @brief Constant pointer type to contained elements. */
  14823. using const_pointer = typename alloc_traits::template rebind_traits<typename alloc_traits::const_pointer>::const_pointer;
  14824. /*! @brief Random access iterator type. */
  14825. using iterator = internal::storage_iterator<container_type>;
  14826. /*! @brief Constant random access iterator type. */
  14827. using const_iterator = internal::storage_iterator<const container_type>;
  14828. /*! @brief Reverse iterator type. */
  14829. using reverse_iterator = std::reverse_iterator<iterator>;
  14830. /*! @brief Constant reverse iterator type. */
  14831. using const_reverse_iterator = std::reverse_iterator<const_iterator>;
  14832. /*! @brief Extended iterable storage proxy. */
  14833. using iterable = iterable_adaptor<internal::extended_storage_iterator<typename base_type::iterator, iterator>>;
  14834. /*! @brief Constant extended iterable storage proxy. */
  14835. using const_iterable = iterable_adaptor<internal::extended_storage_iterator<typename base_type::const_iterator, const_iterator>>;
  14836. /*! @brief Default constructor. */
  14837. basic_storage()
  14838. : basic_storage{allocator_type{}} {}
  14839. /**
  14840. * @brief Constructs an empty storage with a given allocator.
  14841. * @param allocator The allocator to use.
  14842. */
  14843. explicit basic_storage(const allocator_type &allocator)
  14844. : base_type{type_id<value_type>(), deletion_policy{comp_traits::in_place_delete}, allocator},
  14845. packed{container_type{allocator}, allocator} {}
  14846. /**
  14847. * @brief Move constructor.
  14848. * @param other The instance to move from.
  14849. */
  14850. basic_storage(basic_storage &&other) ENTT_NOEXCEPT
  14851. : base_type{std::move(other)},
  14852. packed{std::move(other.packed)} {}
  14853. /**
  14854. * @brief Allocator-extended move constructor.
  14855. * @param other The instance to move from.
  14856. * @param allocator The allocator to use.
  14857. */
  14858. basic_storage(basic_storage &&other, const allocator_type &allocator) ENTT_NOEXCEPT
  14859. : base_type{std::move(other), allocator},
  14860. packed{container_type{std::move(other.packed.first()), allocator}, allocator} {
  14861. ENTT_ASSERT(alloc_traits::is_always_equal::value || packed.second() == other.packed.second(), "Copying a storage is not allowed");
  14862. }
  14863. /*! @brief Default destructor. */
  14864. ~basic_storage() override {
  14865. shrink_to_size(0u);
  14866. }
  14867. /**
  14868. * @brief Move assignment operator.
  14869. * @param other The instance to move from.
  14870. * @return This storage.
  14871. */
  14872. basic_storage &operator=(basic_storage &&other) ENTT_NOEXCEPT {
  14873. ENTT_ASSERT(alloc_traits::is_always_equal::value || packed.second() == other.packed.second(), "Copying a storage is not allowed");
  14874. shrink_to_size(0u);
  14875. base_type::operator=(std::move(other));
  14876. packed.first() = std::move(other.packed.first());
  14877. propagate_on_container_move_assignment(packed.second(), other.packed.second());
  14878. return *this;
  14879. }
  14880. /**
  14881. * @brief Exchanges the contents with those of a given storage.
  14882. * @param other Storage to exchange the content with.
  14883. */
  14884. void swap(basic_storage &other) {
  14885. using std::swap;
  14886. underlying_type::swap(other);
  14887. propagate_on_container_swap(packed.second(), other.packed.second());
  14888. swap(packed.first(), other.packed.first());
  14889. }
  14890. /**
  14891. * @brief Returns the associated allocator.
  14892. * @return The associated allocator.
  14893. */
  14894. [[nodiscard]] constexpr allocator_type get_allocator() const ENTT_NOEXCEPT {
  14895. return allocator_type{packed.second()};
  14896. }
  14897. /**
  14898. * @brief Increases the capacity of a storage.
  14899. *
  14900. * If the new capacity is greater than the current capacity, new storage is
  14901. * allocated, otherwise the method does nothing.
  14902. *
  14903. * @param cap Desired capacity.
  14904. */
  14905. void reserve(const size_type cap) override {
  14906. if(cap != 0u) {
  14907. base_type::reserve(cap);
  14908. assure_at_least(cap - 1u);
  14909. }
  14910. }
  14911. /**
  14912. * @brief Returns the number of elements that a storage has currently
  14913. * allocated space for.
  14914. * @return Capacity of the storage.
  14915. */
  14916. [[nodiscard]] size_type capacity() const ENTT_NOEXCEPT override {
  14917. return packed.first().size() * comp_traits::page_size;
  14918. }
  14919. /*! @brief Requests the removal of unused capacity. */
  14920. void shrink_to_fit() override {
  14921. base_type::shrink_to_fit();
  14922. shrink_to_size(base_type::size());
  14923. }
  14924. /**
  14925. * @brief Direct access to the array of objects.
  14926. * @return A pointer to the array of objects.
  14927. */
  14928. [[nodiscard]] const_pointer raw() const ENTT_NOEXCEPT {
  14929. return packed.first().data();
  14930. }
  14931. /*! @copydoc raw */
  14932. [[nodiscard]] pointer raw() ENTT_NOEXCEPT {
  14933. return packed.first().data();
  14934. }
  14935. /**
  14936. * @brief Returns an iterator to the beginning.
  14937. *
  14938. * The returned iterator points to the first instance of the internal array.
  14939. * If the storage is empty, the returned iterator will be equal to `end()`.
  14940. *
  14941. * @return An iterator to the first instance of the internal array.
  14942. */
  14943. [[nodiscard]] const_iterator cbegin() const ENTT_NOEXCEPT {
  14944. const auto pos = static_cast<typename iterator::difference_type>(base_type::size());
  14945. return const_iterator{&packed.first(), pos};
  14946. }
  14947. /*! @copydoc cbegin */
  14948. [[nodiscard]] const_iterator begin() const ENTT_NOEXCEPT {
  14949. return cbegin();
  14950. }
  14951. /*! @copydoc begin */
  14952. [[nodiscard]] iterator begin() ENTT_NOEXCEPT {
  14953. const auto pos = static_cast<typename iterator::difference_type>(base_type::size());
  14954. return iterator{&packed.first(), pos};
  14955. }
  14956. /**
  14957. * @brief Returns an iterator to the end.
  14958. *
  14959. * The returned iterator points to the element following the last instance
  14960. * of the internal array. Attempting to dereference the returned iterator
  14961. * results in undefined behavior.
  14962. *
  14963. * @return An iterator to the element following the last instance of the
  14964. * internal array.
  14965. */
  14966. [[nodiscard]] const_iterator cend() const ENTT_NOEXCEPT {
  14967. return const_iterator{&packed.first(), {}};
  14968. }
  14969. /*! @copydoc cend */
  14970. [[nodiscard]] const_iterator end() const ENTT_NOEXCEPT {
  14971. return cend();
  14972. }
  14973. /*! @copydoc end */
  14974. [[nodiscard]] iterator end() ENTT_NOEXCEPT {
  14975. return iterator{&packed.first(), {}};
  14976. }
  14977. /**
  14978. * @brief Returns a reverse iterator to the beginning.
  14979. *
  14980. * The returned iterator points to the first instance of the reversed
  14981. * internal array. If the storage is empty, the returned iterator will be
  14982. * equal to `rend()`.
  14983. *
  14984. * @return An iterator to the first instance of the reversed internal array.
  14985. */
  14986. [[nodiscard]] const_reverse_iterator crbegin() const ENTT_NOEXCEPT {
  14987. return std::make_reverse_iterator(cend());
  14988. }
  14989. /*! @copydoc crbegin */
  14990. [[nodiscard]] const_reverse_iterator rbegin() const ENTT_NOEXCEPT {
  14991. return crbegin();
  14992. }
  14993. /*! @copydoc rbegin */
  14994. [[nodiscard]] reverse_iterator rbegin() ENTT_NOEXCEPT {
  14995. return std::make_reverse_iterator(end());
  14996. }
  14997. /**
  14998. * @brief Returns a reverse iterator to the end.
  14999. *
  15000. * The returned iterator points to the element following the last instance
  15001. * of the reversed internal array. Attempting to dereference the returned
  15002. * iterator results in undefined behavior.
  15003. *
  15004. * @return An iterator to the element following the last instance of the
  15005. * reversed internal array.
  15006. */
  15007. [[nodiscard]] const_reverse_iterator crend() const ENTT_NOEXCEPT {
  15008. return std::make_reverse_iterator(cbegin());
  15009. }
  15010. /*! @copydoc crend */
  15011. [[nodiscard]] const_reverse_iterator rend() const ENTT_NOEXCEPT {
  15012. return crend();
  15013. }
  15014. /*! @copydoc rend */
  15015. [[nodiscard]] reverse_iterator rend() ENTT_NOEXCEPT {
  15016. return std::make_reverse_iterator(begin());
  15017. }
  15018. /**
  15019. * @brief Returns the object assigned to an entity.
  15020. *
  15021. * @warning
  15022. * Attempting to use an entity that doesn't belong to the storage results in
  15023. * undefined behavior.
  15024. *
  15025. * @param entt A valid identifier.
  15026. * @return The object assigned to the entity.
  15027. */
  15028. [[nodiscard]] const value_type &get(const entity_type entt) const ENTT_NOEXCEPT {
  15029. return element_at(base_type::index(entt));
  15030. }
  15031. /*! @copydoc get */
  15032. [[nodiscard]] value_type &get(const entity_type entt) ENTT_NOEXCEPT {
  15033. return const_cast<value_type &>(std::as_const(*this).get(entt));
  15034. }
  15035. /**
  15036. * @brief Returns the object assigned to an entity as a tuple.
  15037. * @param entt A valid identifier.
  15038. * @return The object assigned to the entity as a tuple.
  15039. */
  15040. [[nodiscard]] std::tuple<const value_type &> get_as_tuple(const entity_type entt) const ENTT_NOEXCEPT {
  15041. return std::forward_as_tuple(get(entt));
  15042. }
  15043. /*! @copydoc get_as_tuple */
  15044. [[nodiscard]] std::tuple<value_type &> get_as_tuple(const entity_type entt) ENTT_NOEXCEPT {
  15045. return std::forward_as_tuple(get(entt));
  15046. }
  15047. /**
  15048. * @brief Assigns an entity to a storage and constructs its object.
  15049. *
  15050. * @warning
  15051. * Attempting to use an entity that already belongs to the storage results
  15052. * in undefined behavior.
  15053. *
  15054. * @tparam Args Types of arguments to use to construct the object.
  15055. * @param entt A valid identifier.
  15056. * @param args Parameters to use to construct an object for the entity.
  15057. * @return A reference to the newly created object.
  15058. */
  15059. template<typename... Args>
  15060. value_type &emplace(const entity_type entt, Args &&...args) {
  15061. if constexpr(std::is_aggregate_v<value_type>) {
  15062. const auto it = emplace_element(entt, false, Type{std::forward<Args>(args)...});
  15063. return element_at(static_cast<size_type>(it.index()));
  15064. } else {
  15065. const auto it = emplace_element(entt, false, std::forward<Args>(args)...);
  15066. return element_at(static_cast<size_type>(it.index()));
  15067. }
  15068. }
  15069. /**
  15070. * @brief Updates the instance assigned to a given entity in-place.
  15071. * @tparam Func Types of the function objects to invoke.
  15072. * @param entt A valid identifier.
  15073. * @param func Valid function objects.
  15074. * @return A reference to the updated instance.
  15075. */
  15076. template<typename... Func>
  15077. value_type &patch(const entity_type entt, Func &&...func) {
  15078. const auto idx = base_type::index(entt);
  15079. auto &elem = element_at(idx);
  15080. (std::forward<Func>(func)(elem), ...);
  15081. return elem;
  15082. }
  15083. /**
  15084. * @brief Assigns one or more entities to a storage and constructs their
  15085. * objects from a given instance.
  15086. *
  15087. * @warning
  15088. * Attempting to assign an entity that already belongs to the storage
  15089. * results in undefined behavior.
  15090. *
  15091. * @tparam It Type of input iterator.
  15092. * @param first An iterator to the first element of the range of entities.
  15093. * @param last An iterator past the last element of the range of entities.
  15094. * @param value An instance of the object to construct.
  15095. */
  15096. template<typename It>
  15097. void insert(It first, It last, const value_type &value = {}) {
  15098. for(; first != last; ++first) {
  15099. emplace_element(*first, true, value);
  15100. }
  15101. }
  15102. /**
  15103. * @brief Assigns one or more entities to a storage and constructs their
  15104. * objects from a given range.
  15105. *
  15106. * @sa construct
  15107. *
  15108. * @tparam EIt Type of input iterator.
  15109. * @tparam CIt Type of input iterator.
  15110. * @param first An iterator to the first element of the range of entities.
  15111. * @param last An iterator past the last element of the range of entities.
  15112. * @param from An iterator to the first element of the range of objects.
  15113. */
  15114. template<typename EIt, typename CIt, typename = std::enable_if_t<std::is_same_v<typename std::iterator_traits<CIt>::value_type, value_type>>>
  15115. void insert(EIt first, EIt last, CIt from) {
  15116. for(; first != last; ++first, ++from) {
  15117. emplace_element(*first, true, *from);
  15118. }
  15119. }
  15120. /**
  15121. * @brief Returns an iterable object to use to _visit_ a storage.
  15122. *
  15123. * The iterable object returns a tuple that contains the current entity and
  15124. * a reference to its component.
  15125. *
  15126. * @return An iterable object to use to _visit_ the storage.
  15127. */
  15128. [[nodiscard]] iterable each() ENTT_NOEXCEPT {
  15129. return {internal::extended_storage_iterator{base_type::begin(), begin()}, internal::extended_storage_iterator{base_type::end(), end()}};
  15130. }
  15131. /*! @copydoc each */
  15132. [[nodiscard]] const_iterable each() const ENTT_NOEXCEPT {
  15133. return {internal::extended_storage_iterator{base_type::cbegin(), cbegin()}, internal::extended_storage_iterator{base_type::cend(), cend()}};
  15134. }
  15135. private:
  15136. compressed_pair<container_type, allocator_type> packed;
  15137. };
  15138. /*! @copydoc basic_storage */
  15139. template<typename Entity, typename Type, typename Allocator>
  15140. class basic_storage<Entity, Type, Allocator, std::enable_if_t<ignore_as_empty_v<Type>>>
  15141. : public basic_sparse_set<Entity, typename std::allocator_traits<Allocator>::template rebind_alloc<Entity>> {
  15142. using alloc_traits = std::allocator_traits<Allocator>;
  15143. static_assert(std::is_same_v<typename alloc_traits::value_type, Type>, "Invalid value type");
  15144. using underlying_type = basic_sparse_set<Entity, typename alloc_traits::template rebind_alloc<Entity>>;
  15145. using comp_traits = component_traits<Type>;
  15146. public:
  15147. /*! @brief Base type. */
  15148. using base_type = underlying_type;
  15149. /*! @brief Allocator type. */
  15150. using allocator_type = Allocator;
  15151. /*! @brief Type of the objects assigned to entities. */
  15152. using value_type = Type;
  15153. /*! @brief Underlying entity identifier. */
  15154. using entity_type = Entity;
  15155. /*! @brief Unsigned integer type. */
  15156. using size_type = std::size_t;
  15157. /*! @brief Extended iterable storage proxy. */
  15158. using iterable = iterable_adaptor<internal::extended_storage_iterator<typename base_type::iterator>>;
  15159. /*! @brief Constant extended iterable storage proxy. */
  15160. using const_iterable = iterable_adaptor<internal::extended_storage_iterator<typename base_type::const_iterator>>;
  15161. /*! @brief Default constructor. */
  15162. basic_storage()
  15163. : basic_storage{allocator_type{}} {}
  15164. /**
  15165. * @brief Constructs an empty container with a given allocator.
  15166. * @param allocator The allocator to use.
  15167. */
  15168. explicit basic_storage(const allocator_type &allocator)
  15169. : base_type{type_id<value_type>(), deletion_policy{comp_traits::in_place_delete}, allocator} {}
  15170. /**
  15171. * @brief Move constructor.
  15172. * @param other The instance to move from.
  15173. */
  15174. basic_storage(basic_storage &&other) ENTT_NOEXCEPT = default;
  15175. /**
  15176. * @brief Allocator-extended move constructor.
  15177. * @param other The instance to move from.
  15178. * @param allocator The allocator to use.
  15179. */
  15180. basic_storage(basic_storage &&other, const allocator_type &allocator) ENTT_NOEXCEPT
  15181. : base_type{std::move(other), allocator} {}
  15182. /**
  15183. * @brief Move assignment operator.
  15184. * @param other The instance to move from.
  15185. * @return This storage.
  15186. */
  15187. basic_storage &operator=(basic_storage &&other) ENTT_NOEXCEPT = default;
  15188. /**
  15189. * @brief Returns the associated allocator.
  15190. * @return The associated allocator.
  15191. */
  15192. [[nodiscard]] constexpr allocator_type get_allocator() const ENTT_NOEXCEPT {
  15193. return allocator_type{base_type::get_allocator()};
  15194. }
  15195. /**
  15196. * @brief Returns the object assigned to an entity, that is `void`.
  15197. *
  15198. * @warning
  15199. * Attempting to use an entity that doesn't belong to the storage results in
  15200. * undefined behavior.
  15201. *
  15202. * @param entt A valid identifier.
  15203. */
  15204. void get([[maybe_unused]] const entity_type entt) const ENTT_NOEXCEPT {
  15205. ENTT_ASSERT(base_type::contains(entt), "Storage does not contain entity");
  15206. }
  15207. /**
  15208. * @brief Returns an empty tuple.
  15209. *
  15210. * @warning
  15211. * Attempting to use an entity that doesn't belong to the storage results in
  15212. * undefined behavior.
  15213. *
  15214. * @param entt A valid identifier.
  15215. * @return Returns an empty tuple.
  15216. */
  15217. [[nodiscard]] std::tuple<> get_as_tuple([[maybe_unused]] const entity_type entt) const ENTT_NOEXCEPT {
  15218. ENTT_ASSERT(base_type::contains(entt), "Storage does not contain entity");
  15219. return std::tuple{};
  15220. }
  15221. /**
  15222. * @brief Assigns an entity to a storage and constructs its object.
  15223. *
  15224. * @warning
  15225. * Attempting to use an entity that already belongs to the storage results
  15226. * in undefined behavior.
  15227. *
  15228. * @tparam Args Types of arguments to use to construct the object.
  15229. * @param entt A valid identifier.
  15230. */
  15231. template<typename... Args>
  15232. void emplace(const entity_type entt, Args &&...) {
  15233. base_type::try_emplace(entt, false);
  15234. }
  15235. /**
  15236. * @brief Updates the instance assigned to a given entity in-place.
  15237. * @tparam Func Types of the function objects to invoke.
  15238. * @param entt A valid identifier.
  15239. * @param func Valid function objects.
  15240. */
  15241. template<typename... Func>
  15242. void patch([[maybe_unused]] const entity_type entt, Func &&...func) {
  15243. ENTT_ASSERT(base_type::contains(entt), "Storage does not contain entity");
  15244. (std::forward<Func>(func)(), ...);
  15245. }
  15246. /**
  15247. * @brief Assigns entities to a storage.
  15248. * @tparam It Type of input iterator.
  15249. * @tparam Args Types of optional arguments.
  15250. * @param first An iterator to the first element of the range of entities.
  15251. * @param last An iterator past the last element of the range of entities.
  15252. */
  15253. template<typename It, typename... Args>
  15254. void insert(It first, It last, Args &&...) {
  15255. for(; first != last; ++first) {
  15256. base_type::try_emplace(*first, true);
  15257. }
  15258. }
  15259. /**
  15260. * @brief Returns an iterable object to use to _visit_ a storage.
  15261. *
  15262. * The iterable object returns a tuple that contains the current entity.
  15263. *
  15264. * @return An iterable object to use to _visit_ the storage.
  15265. */
  15266. [[nodiscard]] iterable each() ENTT_NOEXCEPT {
  15267. return {internal::extended_storage_iterator{base_type::begin()}, internal::extended_storage_iterator{base_type::end()}};
  15268. }
  15269. /*! @copydoc each */
  15270. [[nodiscard]] const_iterable each() const ENTT_NOEXCEPT {
  15271. return {internal::extended_storage_iterator{base_type::cbegin()}, internal::extended_storage_iterator{base_type::cend()}};
  15272. }
  15273. };
  15274. /**
  15275. * @brief Provides a common way to access certain properties of storage types.
  15276. * @tparam Entity A valid entity type (see entt_traits for more details).
  15277. * @tparam Type Type of objects managed by the storage class.
  15278. */
  15279. template<typename Entity, typename Type, typename = void>
  15280. struct storage_traits {
  15281. /*! @brief Resulting type after component-to-storage conversion. */
  15282. using storage_type = sigh_storage_mixin<basic_storage<Entity, Type>>;
  15283. };
  15284. } // namespace entt
  15285. #endif
  15286. // #include "utility.hpp"
  15287. namespace entt {
  15288. /**
  15289. * @brief Group.
  15290. *
  15291. * Primary template isn't defined on purpose. All the specializations give a
  15292. * compile-time error, but for a few reasonable cases.
  15293. */
  15294. template<typename, typename, typename, typename>
  15295. class basic_group;
  15296. /**
  15297. * @brief Non-owning group.
  15298. *
  15299. * A non-owning group returns all entities and only the entities that have at
  15300. * least the given components. Moreover, it's guaranteed that the entity list
  15301. * is tightly packed in memory for fast iterations.
  15302. *
  15303. * @b Important
  15304. *
  15305. * Iterators aren't invalidated if:
  15306. *
  15307. * * New instances of the given components are created and assigned to entities.
  15308. * * The entity currently pointed is modified (as an example, if one of the
  15309. * given components is removed from the entity to which the iterator points).
  15310. * * The entity currently pointed is destroyed.
  15311. *
  15312. * In all other cases, modifying the pools iterated by the group in any way
  15313. * invalidates all the iterators and using them results in undefined behavior.
  15314. *
  15315. * @note
  15316. * Groups share references to the underlying data structures of the registry
  15317. * that generated them. Therefore any change to the entities and to the
  15318. * components made by means of the registry are immediately reflected by all the
  15319. * groups.<br/>
  15320. * Moreover, sorting a non-owning group affects all the instances of the same
  15321. * group (it means that users don't have to call `sort` on each instance to sort
  15322. * all of them because they _share_ entities and components).
  15323. *
  15324. * @warning
  15325. * Lifetime of a group must not overcome that of the registry that generated it.
  15326. * In any other case, attempting to use a group results in undefined behavior.
  15327. *
  15328. * @tparam Entity A valid entity type (see entt_traits for more details).
  15329. * @tparam Get Type of components observed by the group.
  15330. * @tparam Exclude Types of components used to filter the group.
  15331. */
  15332. template<typename Entity, typename... Get, typename... Exclude>
  15333. class basic_group<Entity, owned_t<>, get_t<Get...>, exclude_t<Exclude...>> {
  15334. /*! @brief A registry is allowed to create groups. */
  15335. friend class basic_registry<Entity>;
  15336. template<typename Comp>
  15337. using storage_type = constness_as_t<typename storage_traits<Entity, std::remove_const_t<Comp>>::storage_type, Comp>;
  15338. using basic_common_type = std::common_type_t<typename storage_type<Get>::base_type...>;
  15339. struct extended_group_iterator final {
  15340. using difference_type = std::ptrdiff_t;
  15341. using value_type = decltype(std::tuple_cat(std::tuple<Entity>{}, std::declval<basic_group>().get({})));
  15342. using pointer = input_iterator_pointer<value_type>;
  15343. using reference = value_type;
  15344. using iterator_category = std::input_iterator_tag;
  15345. extended_group_iterator() = default;
  15346. extended_group_iterator(typename basic_common_type::iterator from, const std::tuple<storage_type<Get> *...> &args)
  15347. : it{from},
  15348. pools{args} {}
  15349. extended_group_iterator &operator++() ENTT_NOEXCEPT {
  15350. return ++it, *this;
  15351. }
  15352. extended_group_iterator operator++(int) ENTT_NOEXCEPT {
  15353. extended_group_iterator orig = *this;
  15354. return ++(*this), orig;
  15355. }
  15356. [[nodiscard]] reference operator*() const ENTT_NOEXCEPT {
  15357. const auto entt = *it;
  15358. return std::tuple_cat(std::make_tuple(entt), std::get<storage_type<Get> *>(pools)->get_as_tuple(entt)...);
  15359. }
  15360. [[nodiscard]] pointer operator->() const ENTT_NOEXCEPT {
  15361. return operator*();
  15362. }
  15363. [[nodiscard]] bool operator==(const extended_group_iterator &other) const ENTT_NOEXCEPT {
  15364. return other.it == it;
  15365. }
  15366. [[nodiscard]] bool operator!=(const extended_group_iterator &other) const ENTT_NOEXCEPT {
  15367. return !(*this == other);
  15368. }
  15369. private:
  15370. typename basic_common_type::iterator it;
  15371. std::tuple<storage_type<Get> *...> pools;
  15372. };
  15373. basic_group(basic_common_type &ref, storage_type<Get> &...gpool) ENTT_NOEXCEPT
  15374. : handler{&ref},
  15375. pools{&gpool...} {}
  15376. public:
  15377. /*! @brief Underlying entity identifier. */
  15378. using entity_type = Entity;
  15379. /*! @brief Unsigned integer type. */
  15380. using size_type = std::size_t;
  15381. /*! @brief Common type among all storage types. */
  15382. using base_type = basic_common_type;
  15383. /*! @brief Random access iterator type. */
  15384. using iterator = typename base_type::iterator;
  15385. /*! @brief Reversed iterator type. */
  15386. using reverse_iterator = typename base_type::reverse_iterator;
  15387. /*! @brief Iterable group type. */
  15388. using iterable = iterable_adaptor<extended_group_iterator>;
  15389. /*! @brief Default constructor to use to create empty, invalid groups. */
  15390. basic_group() ENTT_NOEXCEPT
  15391. : handler{} {}
  15392. /**
  15393. * @brief Returns a const reference to the underlying handler.
  15394. * @return A const reference to the underlying handler.
  15395. */
  15396. const base_type &handle() const ENTT_NOEXCEPT {
  15397. return *handler;
  15398. }
  15399. /**
  15400. * @brief Returns the storage for a given component type.
  15401. * @tparam Comp Type of component of which to return the storage.
  15402. * @return The storage for the given component type.
  15403. */
  15404. template<typename Comp>
  15405. [[nodiscard]] decltype(auto) storage() const ENTT_NOEXCEPT {
  15406. return *std::get<storage_type<Comp> *>(pools);
  15407. }
  15408. /**
  15409. * @brief Returns the storage for a given component type.
  15410. * @tparam Comp Index of component of which to return the storage.
  15411. * @return The storage for the given component type.
  15412. */
  15413. template<std::size_t Comp>
  15414. [[nodiscard]] decltype(auto) storage() const ENTT_NOEXCEPT {
  15415. return *std::get<Comp>(pools);
  15416. }
  15417. /**
  15418. * @brief Returns the number of entities that have the given components.
  15419. * @return Number of entities that have the given components.
  15420. */
  15421. [[nodiscard]] size_type size() const ENTT_NOEXCEPT {
  15422. return *this ? handler->size() : size_type{};
  15423. }
  15424. /**
  15425. * @brief Returns the number of elements that a group has currently
  15426. * allocated space for.
  15427. * @return Capacity of the group.
  15428. */
  15429. [[nodiscard]] size_type capacity() const ENTT_NOEXCEPT {
  15430. return *this ? handler->capacity() : size_type{};
  15431. }
  15432. /*! @brief Requests the removal of unused capacity. */
  15433. void shrink_to_fit() {
  15434. if(*this) {
  15435. handler->shrink_to_fit();
  15436. }
  15437. }
  15438. /**
  15439. * @brief Checks whether a group is empty.
  15440. * @return True if the group is empty, false otherwise.
  15441. */
  15442. [[nodiscard]] bool empty() const ENTT_NOEXCEPT {
  15443. return !*this || handler->empty();
  15444. }
  15445. /**
  15446. * @brief Returns an iterator to the first entity of the group.
  15447. *
  15448. * The returned iterator points to the first entity of the group. If the
  15449. * group is empty, the returned iterator will be equal to `end()`.
  15450. *
  15451. * @return An iterator to the first entity of the group.
  15452. */
  15453. [[nodiscard]] iterator begin() const ENTT_NOEXCEPT {
  15454. return *this ? handler->begin() : iterator{};
  15455. }
  15456. /**
  15457. * @brief Returns an iterator that is past the last entity of the group.
  15458. *
  15459. * The returned iterator points to the entity following the last entity of
  15460. * the group. Attempting to dereference the returned iterator results in
  15461. * undefined behavior.
  15462. *
  15463. * @return An iterator to the entity following the last entity of the
  15464. * group.
  15465. */
  15466. [[nodiscard]] iterator end() const ENTT_NOEXCEPT {
  15467. return *this ? handler->end() : iterator{};
  15468. }
  15469. /**
  15470. * @brief Returns an iterator to the first entity of the reversed group.
  15471. *
  15472. * The returned iterator points to the first entity of the reversed group.
  15473. * If the group is empty, the returned iterator will be equal to `rend()`.
  15474. *
  15475. * @return An iterator to the first entity of the reversed group.
  15476. */
  15477. [[nodiscard]] reverse_iterator rbegin() const ENTT_NOEXCEPT {
  15478. return *this ? handler->rbegin() : reverse_iterator{};
  15479. }
  15480. /**
  15481. * @brief Returns an iterator that is past the last entity of the reversed
  15482. * group.
  15483. *
  15484. * The returned iterator points to the entity following the last entity of
  15485. * the reversed group. Attempting to dereference the returned iterator
  15486. * results in undefined behavior.
  15487. *
  15488. * @return An iterator to the entity following the last entity of the
  15489. * reversed group.
  15490. */
  15491. [[nodiscard]] reverse_iterator rend() const ENTT_NOEXCEPT {
  15492. return *this ? handler->rend() : reverse_iterator{};
  15493. }
  15494. /**
  15495. * @brief Returns the first entity of the group, if any.
  15496. * @return The first entity of the group if one exists, the null entity
  15497. * otherwise.
  15498. */
  15499. [[nodiscard]] entity_type front() const ENTT_NOEXCEPT {
  15500. const auto it = begin();
  15501. return it != end() ? *it : null;
  15502. }
  15503. /**
  15504. * @brief Returns the last entity of the group, if any.
  15505. * @return The last entity of the group if one exists, the null entity
  15506. * otherwise.
  15507. */
  15508. [[nodiscard]] entity_type back() const ENTT_NOEXCEPT {
  15509. const auto it = rbegin();
  15510. return it != rend() ? *it : null;
  15511. }
  15512. /**
  15513. * @brief Finds an entity.
  15514. * @param entt A valid identifier.
  15515. * @return An iterator to the given entity if it's found, past the end
  15516. * iterator otherwise.
  15517. */
  15518. [[nodiscard]] iterator find(const entity_type entt) const ENTT_NOEXCEPT {
  15519. const auto it = *this ? handler->find(entt) : iterator{};
  15520. return it != end() && *it == entt ? it : end();
  15521. }
  15522. /**
  15523. * @brief Returns the identifier that occupies the given position.
  15524. * @param pos Position of the element to return.
  15525. * @return The identifier that occupies the given position.
  15526. */
  15527. [[nodiscard]] entity_type operator[](const size_type pos) const {
  15528. return begin()[pos];
  15529. }
  15530. /**
  15531. * @brief Checks if a group is properly initialized.
  15532. * @return True if the group is properly initialized, false otherwise.
  15533. */
  15534. [[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
  15535. return handler != nullptr;
  15536. }
  15537. /**
  15538. * @brief Checks if a group contains an entity.
  15539. * @param entt A valid identifier.
  15540. * @return True if the group contains the given entity, false otherwise.
  15541. */
  15542. [[nodiscard]] bool contains(const entity_type entt) const ENTT_NOEXCEPT {
  15543. return *this && handler->contains(entt);
  15544. }
  15545. /**
  15546. * @brief Returns the components assigned to the given entity.
  15547. *
  15548. * Prefer this function instead of `registry::get` during iterations. It has
  15549. * far better performance than its counterpart.
  15550. *
  15551. * @warning
  15552. * Attempting to use an invalid component type results in a compilation
  15553. * error. Attempting to use an entity that doesn't belong to the group
  15554. * results in undefined behavior.
  15555. *
  15556. * @tparam Comp Types of components to get.
  15557. * @param entt A valid identifier.
  15558. * @return The components assigned to the entity.
  15559. */
  15560. template<typename... Comp>
  15561. [[nodiscard]] decltype(auto) get(const entity_type entt) const {
  15562. ENTT_ASSERT(contains(entt), "Group does not contain entity");
  15563. if constexpr(sizeof...(Comp) == 0) {
  15564. return std::tuple_cat(std::get<storage_type<Get> *>(pools)->get_as_tuple(entt)...);
  15565. } else if constexpr(sizeof...(Comp) == 1) {
  15566. return (std::get<storage_type<Comp> *>(pools)->get(entt), ...);
  15567. } else {
  15568. return std::tuple_cat(std::get<storage_type<Comp> *>(pools)->get_as_tuple(entt)...);
  15569. }
  15570. }
  15571. /**
  15572. * @brief Iterates entities and components and applies the given function
  15573. * object to them.
  15574. *
  15575. * The function object is invoked for each entity. It is provided with the
  15576. * entity itself and a set of references to non-empty components. The
  15577. * _constness_ of the components is as requested.<br/>
  15578. * The signature of the function must be equivalent to one of the following
  15579. * forms:
  15580. *
  15581. * @code{.cpp}
  15582. * void(const entity_type, Type &...);
  15583. * void(Type &...);
  15584. * @endcode
  15585. *
  15586. * @note
  15587. * Empty types aren't explicitly instantiated and therefore they are never
  15588. * returned during iterations.
  15589. *
  15590. * @tparam Func Type of the function object to invoke.
  15591. * @param func A valid function object.
  15592. */
  15593. template<typename Func>
  15594. void each(Func func) const {
  15595. for(const auto entt: *this) {
  15596. if constexpr(is_applicable_v<Func, decltype(std::tuple_cat(std::tuple<entity_type>{}, std::declval<basic_group>().get({})))>) {
  15597. std::apply(func, std::tuple_cat(std::make_tuple(entt), get(entt)));
  15598. } else {
  15599. std::apply(func, get(entt));
  15600. }
  15601. }
  15602. }
  15603. /**
  15604. * @brief Returns an iterable object to use to _visit_ a group.
  15605. *
  15606. * The iterable object returns tuples that contain the current entity and a
  15607. * set of references to its non-empty components. The _constness_ of the
  15608. * components is as requested.
  15609. *
  15610. * @note
  15611. * Empty types aren't explicitly instantiated and therefore they are never
  15612. * returned during iterations.
  15613. *
  15614. * @return An iterable object to use to _visit_ the group.
  15615. */
  15616. [[nodiscard]] iterable each() const ENTT_NOEXCEPT {
  15617. return handler ? iterable{extended_group_iterator{handler->begin(), pools}, extended_group_iterator{handler->end(), pools}}
  15618. : iterable{extended_group_iterator{{}, pools}, extended_group_iterator{{}, pools}};
  15619. }
  15620. /**
  15621. * @brief Sort a group according to the given comparison function.
  15622. *
  15623. * Sort the group so that iterating it with a couple of iterators returns
  15624. * entities and components in the expected order. See `begin` and `end` for
  15625. * more details.
  15626. *
  15627. * The comparison function object must return `true` if the first element
  15628. * is _less_ than the second one, `false` otherwise. The signature of the
  15629. * comparison function should be equivalent to one of the following:
  15630. *
  15631. * @code{.cpp}
  15632. * bool(std::tuple<Component &...>, std::tuple<Component &...>);
  15633. * bool(const Component &..., const Component &...);
  15634. * bool(const Entity, const Entity);
  15635. * @endcode
  15636. *
  15637. * Where `Component` are such that they are iterated by the group.<br/>
  15638. * Moreover, the comparison function object shall induce a
  15639. * _strict weak ordering_ on the values.
  15640. *
  15641. * The sort function object must offer a member function template
  15642. * `operator()` that accepts three arguments:
  15643. *
  15644. * * An iterator to the first element of the range to sort.
  15645. * * An iterator past the last element of the range to sort.
  15646. * * A comparison function to use to compare the elements.
  15647. *
  15648. * @tparam Comp Optional types of components to compare.
  15649. * @tparam Compare Type of comparison function object.
  15650. * @tparam Sort Type of sort function object.
  15651. * @tparam Args Types of arguments to forward to the sort function object.
  15652. * @param compare A valid comparison function object.
  15653. * @param algo A valid sort function object.
  15654. * @param args Arguments to forward to the sort function object, if any.
  15655. */
  15656. template<typename... Comp, typename Compare, typename Sort = std_sort, typename... Args>
  15657. void sort(Compare compare, Sort algo = Sort{}, Args &&...args) {
  15658. if(*this) {
  15659. if constexpr(sizeof...(Comp) == 0) {
  15660. static_assert(std::is_invocable_v<Compare, const entity_type, const entity_type>, "Invalid comparison function");
  15661. handler->sort(std::move(compare), std::move(algo), std::forward<Args>(args)...);
  15662. } else {
  15663. auto comp = [this, &compare](const entity_type lhs, const entity_type rhs) {
  15664. if constexpr(sizeof...(Comp) == 1) {
  15665. return compare((std::get<storage_type<Comp> *>(pools)->get(lhs), ...), (std::get<storage_type<Comp> *>(pools)->get(rhs), ...));
  15666. } else {
  15667. return compare(std::forward_as_tuple(std::get<storage_type<Comp> *>(pools)->get(lhs)...), std::forward_as_tuple(std::get<storage_type<Comp> *>(pools)->get(rhs)...));
  15668. }
  15669. };
  15670. handler->sort(std::move(comp), std::move(algo), std::forward<Args>(args)...);
  15671. }
  15672. }
  15673. }
  15674. /**
  15675. * @brief Sort the shared pool of entities according to the given component.
  15676. *
  15677. * Non-owning groups of the same type share with the registry a pool of
  15678. * entities with its own order that doesn't depend on the order of any pool
  15679. * of components. Users can order the underlying data structure so that it
  15680. * respects the order of the pool of the given component.
  15681. *
  15682. * @note
  15683. * The shared pool of entities and thus its order is affected by the changes
  15684. * to each and every pool that it tracks. Therefore changes to those pools
  15685. * can quickly ruin the order imposed to the pool of entities shared between
  15686. * the non-owning groups.
  15687. *
  15688. * @tparam Comp Type of component to use to impose the order.
  15689. */
  15690. template<typename Comp>
  15691. void sort() const {
  15692. if(*this) {
  15693. handler->respect(*std::get<storage_type<Comp> *>(pools));
  15694. }
  15695. }
  15696. private:
  15697. base_type *const handler;
  15698. const std::tuple<storage_type<Get> *...> pools;
  15699. };
  15700. /**
  15701. * @brief Owning group.
  15702. *
  15703. * Owning groups return all entities and only the entities that have at least
  15704. * the given components. Moreover:
  15705. *
  15706. * * It's guaranteed that the entity list is tightly packed in memory for fast
  15707. * iterations.
  15708. * * It's guaranteed that the lists of owned components are tightly packed in
  15709. * memory for even faster iterations and to allow direct access.
  15710. * * They stay true to the order of the owned components and all instances have
  15711. * the same order in memory.
  15712. *
  15713. * The more types of components are owned by a group, the faster it is to
  15714. * iterate them.
  15715. *
  15716. * @b Important
  15717. *
  15718. * Iterators aren't invalidated if:
  15719. *
  15720. * * New instances of the given components are created and assigned to entities.
  15721. * * The entity currently pointed is modified (as an example, if one of the
  15722. * given components is removed from the entity to which the iterator points).
  15723. * * The entity currently pointed is destroyed.
  15724. *
  15725. * In all other cases, modifying the pools iterated by the group in any way
  15726. * invalidates all the iterators and using them results in undefined behavior.
  15727. *
  15728. * @note
  15729. * Groups share references to the underlying data structures of the registry
  15730. * that generated them. Therefore any change to the entities and to the
  15731. * components made by means of the registry are immediately reflected by all the
  15732. * groups.
  15733. * Moreover, sorting an owning group affects all the instance of the same group
  15734. * (it means that users don't have to call `sort` on each instance to sort all
  15735. * of them because they share the underlying data structure).
  15736. *
  15737. * @warning
  15738. * Lifetime of a group must not overcome that of the registry that generated it.
  15739. * In any other case, attempting to use a group results in undefined behavior.
  15740. *
  15741. * @tparam Entity A valid entity type (see entt_traits for more details).
  15742. * @tparam Owned Types of components owned by the group.
  15743. * @tparam Get Types of components observed by the group.
  15744. * @tparam Exclude Types of components used to filter the group.
  15745. */
  15746. template<typename Entity, typename... Owned, typename... Get, typename... Exclude>
  15747. class basic_group<Entity, owned_t<Owned...>, get_t<Get...>, exclude_t<Exclude...>> {
  15748. /*! @brief A registry is allowed to create groups. */
  15749. friend class basic_registry<Entity>;
  15750. template<typename Comp>
  15751. using storage_type = constness_as_t<typename storage_traits<Entity, std::remove_const_t<Comp>>::storage_type, Comp>;
  15752. using basic_common_type = std::common_type_t<typename storage_type<Owned>::base_type..., typename storage_type<Get>::base_type...>;
  15753. class extended_group_iterator final {
  15754. template<typename Type>
  15755. auto index_to_element(storage_type<Type> &cpool) const {
  15756. if constexpr(ignore_as_empty_v<std::remove_const_t<Type>>) {
  15757. return std::make_tuple();
  15758. } else {
  15759. return std::forward_as_tuple(cpool.rbegin()[it.index()]);
  15760. }
  15761. }
  15762. public:
  15763. using difference_type = std::ptrdiff_t;
  15764. using value_type = decltype(std::tuple_cat(std::tuple<Entity>{}, std::declval<basic_group>().get({})));
  15765. using pointer = input_iterator_pointer<value_type>;
  15766. using reference = value_type;
  15767. using iterator_category = std::input_iterator_tag;
  15768. extended_group_iterator() = default;
  15769. template<typename... Other>
  15770. extended_group_iterator(typename basic_common_type::iterator from, const std::tuple<storage_type<Owned> *..., storage_type<Get> *...> &cpools)
  15771. : it{from},
  15772. pools{cpools} {}
  15773. extended_group_iterator &operator++() ENTT_NOEXCEPT {
  15774. return ++it, *this;
  15775. }
  15776. extended_group_iterator operator++(int) ENTT_NOEXCEPT {
  15777. extended_group_iterator orig = *this;
  15778. return ++(*this), orig;
  15779. }
  15780. [[nodiscard]] reference operator*() const ENTT_NOEXCEPT {
  15781. return std::tuple_cat(
  15782. std::make_tuple(*it),
  15783. index_to_element<Owned>(*std::get<storage_type<Owned> *>(pools))...,
  15784. std::get<storage_type<Get> *>(pools)->get_as_tuple(*it)...);
  15785. }
  15786. [[nodiscard]] pointer operator->() const ENTT_NOEXCEPT {
  15787. return operator*();
  15788. }
  15789. [[nodiscard]] bool operator==(const extended_group_iterator &other) const ENTT_NOEXCEPT {
  15790. return other.it == it;
  15791. }
  15792. [[nodiscard]] bool operator!=(const extended_group_iterator &other) const ENTT_NOEXCEPT {
  15793. return !(*this == other);
  15794. }
  15795. private:
  15796. typename basic_common_type::iterator it;
  15797. std::tuple<storage_type<Owned> *..., storage_type<Get> *...> pools;
  15798. };
  15799. basic_group(const std::size_t &extent, storage_type<Owned> &...opool, storage_type<Get> &...gpool) ENTT_NOEXCEPT
  15800. : pools{&opool..., &gpool...},
  15801. length{&extent} {}
  15802. public:
  15803. /*! @brief Underlying entity identifier. */
  15804. using entity_type = Entity;
  15805. /*! @brief Unsigned integer type. */
  15806. using size_type = std::size_t;
  15807. /*! @brief Common type among all storage types. */
  15808. using base_type = basic_common_type;
  15809. /*! @brief Random access iterator type. */
  15810. using iterator = typename base_type::iterator;
  15811. /*! @brief Reversed iterator type. */
  15812. using reverse_iterator = typename base_type::reverse_iterator;
  15813. /*! @brief Iterable group type. */
  15814. using iterable = iterable_adaptor<extended_group_iterator>;
  15815. /*! @brief Default constructor to use to create empty, invalid groups. */
  15816. basic_group() ENTT_NOEXCEPT
  15817. : length{} {}
  15818. /**
  15819. * @brief Returns the storage for a given component type.
  15820. * @tparam Comp Type of component of which to return the storage.
  15821. * @return The storage for the given component type.
  15822. */
  15823. template<typename Comp>
  15824. [[nodiscard]] decltype(auto) storage() const ENTT_NOEXCEPT {
  15825. return *std::get<storage_type<Comp> *>(pools);
  15826. }
  15827. /**
  15828. * @brief Returns the storage for a given component type.
  15829. * @tparam Comp Index of component of which to return the storage.
  15830. * @return The storage for the given component type.
  15831. */
  15832. template<std::size_t Comp>
  15833. [[nodiscard]] decltype(auto) storage() const ENTT_NOEXCEPT {
  15834. return *std::get<Comp>(pools);
  15835. }
  15836. /**
  15837. * @brief Returns the number of entities that have the given components.
  15838. * @return Number of entities that have the given components.
  15839. */
  15840. [[nodiscard]] size_type size() const ENTT_NOEXCEPT {
  15841. return *this ? *length : size_type{};
  15842. }
  15843. /**
  15844. * @brief Checks whether a group is empty.
  15845. * @return True if the group is empty, false otherwise.
  15846. */
  15847. [[nodiscard]] bool empty() const ENTT_NOEXCEPT {
  15848. return !*this || !*length;
  15849. }
  15850. /**
  15851. * @brief Returns an iterator to the first entity of the group.
  15852. *
  15853. * The returned iterator points to the first entity of the group. If the
  15854. * group is empty, the returned iterator will be equal to `end()`.
  15855. *
  15856. * @return An iterator to the first entity of the group.
  15857. */
  15858. [[nodiscard]] iterator begin() const ENTT_NOEXCEPT {
  15859. return *this ? (std::get<0>(pools)->base_type::end() - *length) : iterator{};
  15860. }
  15861. /**
  15862. * @brief Returns an iterator that is past the last entity of the group.
  15863. *
  15864. * The returned iterator points to the entity following the last entity of
  15865. * the group. Attempting to dereference the returned iterator results in
  15866. * undefined behavior.
  15867. *
  15868. * @return An iterator to the entity following the last entity of the
  15869. * group.
  15870. */
  15871. [[nodiscard]] iterator end() const ENTT_NOEXCEPT {
  15872. return *this ? std::get<0>(pools)->base_type::end() : iterator{};
  15873. }
  15874. /**
  15875. * @brief Returns an iterator to the first entity of the reversed group.
  15876. *
  15877. * The returned iterator points to the first entity of the reversed group.
  15878. * If the group is empty, the returned iterator will be equal to `rend()`.
  15879. *
  15880. * @return An iterator to the first entity of the reversed group.
  15881. */
  15882. [[nodiscard]] reverse_iterator rbegin() const ENTT_NOEXCEPT {
  15883. return *this ? std::get<0>(pools)->base_type::rbegin() : reverse_iterator{};
  15884. }
  15885. /**
  15886. * @brief Returns an iterator that is past the last entity of the reversed
  15887. * group.
  15888. *
  15889. * The returned iterator points to the entity following the last entity of
  15890. * the reversed group. Attempting to dereference the returned iterator
  15891. * results in undefined behavior.
  15892. *
  15893. * @return An iterator to the entity following the last entity of the
  15894. * reversed group.
  15895. */
  15896. [[nodiscard]] reverse_iterator rend() const ENTT_NOEXCEPT {
  15897. return *this ? (std::get<0>(pools)->base_type::rbegin() + *length) : reverse_iterator{};
  15898. }
  15899. /**
  15900. * @brief Returns the first entity of the group, if any.
  15901. * @return The first entity of the group if one exists, the null entity
  15902. * otherwise.
  15903. */
  15904. [[nodiscard]] entity_type front() const ENTT_NOEXCEPT {
  15905. const auto it = begin();
  15906. return it != end() ? *it : null;
  15907. }
  15908. /**
  15909. * @brief Returns the last entity of the group, if any.
  15910. * @return The last entity of the group if one exists, the null entity
  15911. * otherwise.
  15912. */
  15913. [[nodiscard]] entity_type back() const ENTT_NOEXCEPT {
  15914. const auto it = rbegin();
  15915. return it != rend() ? *it : null;
  15916. }
  15917. /**
  15918. * @brief Finds an entity.
  15919. * @param entt A valid identifier.
  15920. * @return An iterator to the given entity if it's found, past the end
  15921. * iterator otherwise.
  15922. */
  15923. [[nodiscard]] iterator find(const entity_type entt) const ENTT_NOEXCEPT {
  15924. const auto it = *this ? std::get<0>(pools)->find(entt) : iterator{};
  15925. return it != end() && it >= begin() && *it == entt ? it : end();
  15926. }
  15927. /**
  15928. * @brief Returns the identifier that occupies the given position.
  15929. * @param pos Position of the element to return.
  15930. * @return The identifier that occupies the given position.
  15931. */
  15932. [[nodiscard]] entity_type operator[](const size_type pos) const {
  15933. return begin()[pos];
  15934. }
  15935. /**
  15936. * @brief Checks if a group is properly initialized.
  15937. * @return True if the group is properly initialized, false otherwise.
  15938. */
  15939. [[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
  15940. return length != nullptr;
  15941. }
  15942. /**
  15943. * @brief Checks if a group contains an entity.
  15944. * @param entt A valid identifier.
  15945. * @return True if the group contains the given entity, false otherwise.
  15946. */
  15947. [[nodiscard]] bool contains(const entity_type entt) const ENTT_NOEXCEPT {
  15948. return *this && std::get<0>(pools)->contains(entt) && (std::get<0>(pools)->index(entt) < (*length));
  15949. }
  15950. /**
  15951. * @brief Returns the components assigned to the given entity.
  15952. *
  15953. * Prefer this function instead of `registry::get` during iterations. It has
  15954. * far better performance than its counterpart.
  15955. *
  15956. * @warning
  15957. * Attempting to use an invalid component type results in a compilation
  15958. * error. Attempting to use an entity that doesn't belong to the group
  15959. * results in undefined behavior.
  15960. *
  15961. * @tparam Comp Types of components to get.
  15962. * @param entt A valid identifier.
  15963. * @return The components assigned to the entity.
  15964. */
  15965. template<typename... Comp>
  15966. [[nodiscard]] decltype(auto) get(const entity_type entt) const {
  15967. ENTT_ASSERT(contains(entt), "Group does not contain entity");
  15968. if constexpr(sizeof...(Comp) == 0) {
  15969. return std::tuple_cat(std::get<storage_type<Owned> *>(pools)->get_as_tuple(entt)..., std::get<storage_type<Get> *>(pools)->get_as_tuple(entt)...);
  15970. } else if constexpr(sizeof...(Comp) == 1) {
  15971. return (std::get<storage_type<Comp> *>(pools)->get(entt), ...);
  15972. } else {
  15973. return std::tuple_cat(std::get<storage_type<Comp> *>(pools)->get_as_tuple(entt)...);
  15974. }
  15975. }
  15976. /**
  15977. * @brief Iterates entities and components and applies the given function
  15978. * object to them.
  15979. *
  15980. * The function object is invoked for each entity. It is provided with the
  15981. * entity itself and a set of references to non-empty components. The
  15982. * _constness_ of the components is as requested.<br/>
  15983. * The signature of the function must be equivalent to one of the following
  15984. * forms:
  15985. *
  15986. * @code{.cpp}
  15987. * void(const entity_type, Type &...);
  15988. * void(Type &...);
  15989. * @endcode
  15990. *
  15991. * @note
  15992. * Empty types aren't explicitly instantiated and therefore they are never
  15993. * returned during iterations.
  15994. *
  15995. * @tparam Func Type of the function object to invoke.
  15996. * @param func A valid function object.
  15997. */
  15998. template<typename Func>
  15999. void each(Func func) const {
  16000. for(auto args: each()) {
  16001. if constexpr(is_applicable_v<Func, decltype(std::tuple_cat(std::tuple<entity_type>{}, std::declval<basic_group>().get({})))>) {
  16002. std::apply(func, args);
  16003. } else {
  16004. std::apply([&func](auto, auto &&...less) { func(std::forward<decltype(less)>(less)...); }, args);
  16005. }
  16006. }
  16007. }
  16008. /**
  16009. * @brief Returns an iterable object to use to _visit_ a group.
  16010. *
  16011. * The iterable object returns tuples that contain the current entity and a
  16012. * set of references to its non-empty components. The _constness_ of the
  16013. * components is as requested.
  16014. *
  16015. * @note
  16016. * Empty types aren't explicitly instantiated and therefore they are never
  16017. * returned during iterations.
  16018. *
  16019. * @return An iterable object to use to _visit_ the group.
  16020. */
  16021. [[nodiscard]] iterable each() const ENTT_NOEXCEPT {
  16022. iterator last = length ? std::get<0>(pools)->basic_common_type::end() : iterator{};
  16023. return {extended_group_iterator{last - *length, pools}, extended_group_iterator{last, pools}};
  16024. }
  16025. /**
  16026. * @brief Sort a group according to the given comparison function.
  16027. *
  16028. * Sort the group so that iterating it with a couple of iterators returns
  16029. * entities and components in the expected order. See `begin` and `end` for
  16030. * more details.
  16031. *
  16032. * The comparison function object must return `true` if the first element
  16033. * is _less_ than the second one, `false` otherwise. The signature of the
  16034. * comparison function should be equivalent to one of the following:
  16035. *
  16036. * @code{.cpp}
  16037. * bool(std::tuple<Component &...>, std::tuple<Component &...>);
  16038. * bool(const Component &, const Component &);
  16039. * bool(const Entity, const Entity);
  16040. * @endcode
  16041. *
  16042. * Where `Component` are either owned types or not but still such that they
  16043. * are iterated by the group.<br/>
  16044. * Moreover, the comparison function object shall induce a
  16045. * _strict weak ordering_ on the values.
  16046. *
  16047. * The sort function object must offer a member function template
  16048. * `operator()` that accepts three arguments:
  16049. *
  16050. * * An iterator to the first element of the range to sort.
  16051. * * An iterator past the last element of the range to sort.
  16052. * * A comparison function to use to compare the elements.
  16053. *
  16054. * @tparam Comp Optional types of components to compare.
  16055. * @tparam Compare Type of comparison function object.
  16056. * @tparam Sort Type of sort function object.
  16057. * @tparam Args Types of arguments to forward to the sort function object.
  16058. * @param compare A valid comparison function object.
  16059. * @param algo A valid sort function object.
  16060. * @param args Arguments to forward to the sort function object, if any.
  16061. */
  16062. template<typename... Comp, typename Compare, typename Sort = std_sort, typename... Args>
  16063. void sort(Compare compare, Sort algo = Sort{}, Args &&...args) const {
  16064. auto *cpool = std::get<0>(pools);
  16065. if constexpr(sizeof...(Comp) == 0) {
  16066. static_assert(std::is_invocable_v<Compare, const entity_type, const entity_type>, "Invalid comparison function");
  16067. cpool->sort_n(*length, std::move(compare), std::move(algo), std::forward<Args>(args)...);
  16068. } else {
  16069. auto comp = [this, &compare](const entity_type lhs, const entity_type rhs) {
  16070. if constexpr(sizeof...(Comp) == 1) {
  16071. return compare((std::get<storage_type<Comp> *>(pools)->get(lhs), ...), (std::get<storage_type<Comp> *>(pools)->get(rhs), ...));
  16072. } else {
  16073. return compare(std::forward_as_tuple(std::get<storage_type<Comp> *>(pools)->get(lhs)...), std::forward_as_tuple(std::get<storage_type<Comp> *>(pools)->get(rhs)...));
  16074. }
  16075. };
  16076. cpool->sort_n(*length, std::move(comp), std::move(algo), std::forward<Args>(args)...);
  16077. }
  16078. [this](auto *head, auto *...other) {
  16079. for(auto next = *length; next; --next) {
  16080. const auto pos = next - 1;
  16081. [[maybe_unused]] const auto entt = head->data()[pos];
  16082. (other->swap_elements(other->data()[pos], entt), ...);
  16083. }
  16084. }(std::get<storage_type<Owned> *>(pools)...);
  16085. }
  16086. private:
  16087. const std::tuple<storage_type<Owned> *..., storage_type<Get> *...> pools;
  16088. const size_type *const length;
  16089. };
  16090. } // namespace entt
  16091. #endif
  16092. // #include "entity/handle.hpp"
  16093. #ifndef ENTT_ENTITY_HANDLE_HPP
  16094. #define ENTT_ENTITY_HANDLE_HPP
  16095. #include <tuple>
  16096. #include <type_traits>
  16097. #include <utility>
  16098. // #include "../config/config.h"
  16099. // #include "../core/type_traits.hpp"
  16100. // #include "fwd.hpp"
  16101. // #include "registry.hpp"
  16102. #ifndef ENTT_ENTITY_REGISTRY_HPP
  16103. #define ENTT_ENTITY_REGISTRY_HPP
  16104. #include <algorithm>
  16105. #include <cstddef>
  16106. #include <iterator>
  16107. #include <memory>
  16108. #include <tuple>
  16109. #include <type_traits>
  16110. #include <utility>
  16111. #include <vector>
  16112. // #include "../config/config.h"
  16113. // #include "../container/dense_map.hpp"
  16114. #ifndef ENTT_CONTAINER_DENSE_MAP_HPP
  16115. #define ENTT_CONTAINER_DENSE_MAP_HPP
  16116. #include <algorithm>
  16117. #include <cmath>
  16118. #include <cstddef>
  16119. #include <functional>
  16120. #include <iterator>
  16121. #include <limits>
  16122. #include <memory>
  16123. #include <tuple>
  16124. #include <type_traits>
  16125. #include <utility>
  16126. #include <vector>
  16127. // #include "../config/config.h"
  16128. #ifndef ENTT_CONFIG_CONFIG_H
  16129. #define ENTT_CONFIG_CONFIG_H
  16130. // #include "version.h"
  16131. #ifndef ENTT_CONFIG_VERSION_H
  16132. #define ENTT_CONFIG_VERSION_H
  16133. // #include "macro.h"
  16134. #ifndef ENTT_CONFIG_MACRO_H
  16135. #define ENTT_CONFIG_MACRO_H
  16136. #define ENTT_STR(arg) #arg
  16137. #define ENTT_XSTR(arg) ENTT_STR(arg)
  16138. #endif
  16139. #define ENTT_VERSION_MAJOR 3
  16140. #define ENTT_VERSION_MINOR 10
  16141. #define ENTT_VERSION_PATCH 3
  16142. #define ENTT_VERSION \
  16143. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  16144. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  16145. #endif
  16146. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  16147. # define ENTT_THROW throw
  16148. # define ENTT_TRY try
  16149. # define ENTT_CATCH catch(...)
  16150. #else
  16151. # define ENTT_THROW
  16152. # define ENTT_TRY if(true)
  16153. # define ENTT_CATCH if(false)
  16154. #endif
  16155. #ifndef ENTT_NOEXCEPT
  16156. # define ENTT_NOEXCEPT noexcept
  16157. # define ENTT_NOEXCEPT_IF(expr) noexcept(expr)
  16158. # else
  16159. # define ENTT_NOEXCEPT_IF(...)
  16160. #endif
  16161. #ifdef ENTT_USE_ATOMIC
  16162. # include <atomic>
  16163. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  16164. #else
  16165. # define ENTT_MAYBE_ATOMIC(Type) Type
  16166. #endif
  16167. #ifndef ENTT_ID_TYPE
  16168. # include <cstdint>
  16169. # define ENTT_ID_TYPE std::uint32_t
  16170. #endif
  16171. #ifndef ENTT_SPARSE_PAGE
  16172. # define ENTT_SPARSE_PAGE 4096
  16173. #endif
  16174. #ifndef ENTT_PACKED_PAGE
  16175. # define ENTT_PACKED_PAGE 1024
  16176. #endif
  16177. #ifdef ENTT_DISABLE_ASSERT
  16178. # undef ENTT_ASSERT
  16179. # define ENTT_ASSERT(...) (void(0))
  16180. #elif !defined ENTT_ASSERT
  16181. # include <cassert>
  16182. # define ENTT_ASSERT(condition, ...) assert(condition)
  16183. #endif
  16184. #ifdef ENTT_NO_ETO
  16185. # define ENTT_IGNORE_IF_EMPTY false
  16186. #else
  16187. # define ENTT_IGNORE_IF_EMPTY true
  16188. #endif
  16189. #ifdef ENTT_STANDARD_CPP
  16190. # define ENTT_NONSTD false
  16191. #else
  16192. # define ENTT_NONSTD true
  16193. # if defined __clang__ || defined __GNUC__
  16194. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  16195. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  16196. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  16197. # elif defined _MSC_VER
  16198. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  16199. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  16200. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  16201. # endif
  16202. #endif
  16203. #if defined _MSC_VER
  16204. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  16205. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  16206. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  16207. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  16208. #endif
  16209. #endif
  16210. // #include "../core/compressed_pair.hpp"
  16211. #ifndef ENTT_CORE_COMPRESSED_PAIR_HPP
  16212. #define ENTT_CORE_COMPRESSED_PAIR_HPP
  16213. #include <cstddef>
  16214. #include <tuple>
  16215. #include <type_traits>
  16216. #include <utility>
  16217. // #include "../config/config.h"
  16218. #ifndef ENTT_CONFIG_CONFIG_H
  16219. #define ENTT_CONFIG_CONFIG_H
  16220. // #include "version.h"
  16221. #ifndef ENTT_CONFIG_VERSION_H
  16222. #define ENTT_CONFIG_VERSION_H
  16223. // #include "macro.h"
  16224. #ifndef ENTT_CONFIG_MACRO_H
  16225. #define ENTT_CONFIG_MACRO_H
  16226. #define ENTT_STR(arg) #arg
  16227. #define ENTT_XSTR(arg) ENTT_STR(arg)
  16228. #endif
  16229. #define ENTT_VERSION_MAJOR 3
  16230. #define ENTT_VERSION_MINOR 10
  16231. #define ENTT_VERSION_PATCH 3
  16232. #define ENTT_VERSION \
  16233. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  16234. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  16235. #endif
  16236. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  16237. # define ENTT_THROW throw
  16238. # define ENTT_TRY try
  16239. # define ENTT_CATCH catch(...)
  16240. #else
  16241. # define ENTT_THROW
  16242. # define ENTT_TRY if(true)
  16243. # define ENTT_CATCH if(false)
  16244. #endif
  16245. #ifndef ENTT_NOEXCEPT
  16246. # define ENTT_NOEXCEPT noexcept
  16247. # define ENTT_NOEXCEPT_IF(expr) noexcept(expr)
  16248. # else
  16249. # define ENTT_NOEXCEPT_IF(...)
  16250. #endif
  16251. #ifdef ENTT_USE_ATOMIC
  16252. # include <atomic>
  16253. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  16254. #else
  16255. # define ENTT_MAYBE_ATOMIC(Type) Type
  16256. #endif
  16257. #ifndef ENTT_ID_TYPE
  16258. # include <cstdint>
  16259. # define ENTT_ID_TYPE std::uint32_t
  16260. #endif
  16261. #ifndef ENTT_SPARSE_PAGE
  16262. # define ENTT_SPARSE_PAGE 4096
  16263. #endif
  16264. #ifndef ENTT_PACKED_PAGE
  16265. # define ENTT_PACKED_PAGE 1024
  16266. #endif
  16267. #ifdef ENTT_DISABLE_ASSERT
  16268. # undef ENTT_ASSERT
  16269. # define ENTT_ASSERT(...) (void(0))
  16270. #elif !defined ENTT_ASSERT
  16271. # include <cassert>
  16272. # define ENTT_ASSERT(condition, ...) assert(condition)
  16273. #endif
  16274. #ifdef ENTT_NO_ETO
  16275. # define ENTT_IGNORE_IF_EMPTY false
  16276. #else
  16277. # define ENTT_IGNORE_IF_EMPTY true
  16278. #endif
  16279. #ifdef ENTT_STANDARD_CPP
  16280. # define ENTT_NONSTD false
  16281. #else
  16282. # define ENTT_NONSTD true
  16283. # if defined __clang__ || defined __GNUC__
  16284. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  16285. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  16286. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  16287. # elif defined _MSC_VER
  16288. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  16289. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  16290. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  16291. # endif
  16292. #endif
  16293. #if defined _MSC_VER
  16294. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  16295. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  16296. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  16297. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  16298. #endif
  16299. #endif
  16300. // #include "type_traits.hpp"
  16301. #ifndef ENTT_CORE_TYPE_TRAITS_HPP
  16302. #define ENTT_CORE_TYPE_TRAITS_HPP
  16303. #include <cstddef>
  16304. #include <iterator>
  16305. #include <type_traits>
  16306. #include <utility>
  16307. // #include "../config/config.h"
  16308. // #include "fwd.hpp"
  16309. #ifndef ENTT_CORE_FWD_HPP
  16310. #define ENTT_CORE_FWD_HPP
  16311. #include <cstdint>
  16312. #include <type_traits>
  16313. // #include "../config/config.h"
  16314. namespace entt {
  16315. template<std::size_t Len = sizeof(double[2]), std::size_t = alignof(typename std::aligned_storage_t<Len + !Len>)>
  16316. class basic_any;
  16317. /*! @brief Alias declaration for type identifiers. */
  16318. using id_type = ENTT_ID_TYPE;
  16319. /*! @brief Alias declaration for the most common use case. */
  16320. using any = basic_any<>;
  16321. } // namespace entt
  16322. #endif
  16323. namespace entt {
  16324. /**
  16325. * @brief Utility class to disambiguate overloaded functions.
  16326. * @tparam N Number of choices available.
  16327. */
  16328. template<std::size_t N>
  16329. struct choice_t
  16330. // Unfortunately, doxygen cannot parse such a construct.
  16331. : /*! @cond TURN_OFF_DOXYGEN */ choice_t<N - 1> /*! @endcond */
  16332. {};
  16333. /*! @copybrief choice_t */
  16334. template<>
  16335. struct choice_t<0> {};
  16336. /**
  16337. * @brief Variable template for the choice trick.
  16338. * @tparam N Number of choices available.
  16339. */
  16340. template<std::size_t N>
  16341. inline constexpr choice_t<N> choice{};
  16342. /**
  16343. * @brief Identity type trait.
  16344. *
  16345. * Useful to establish non-deduced contexts in template argument deduction
  16346. * (waiting for C++20) or to provide types through function arguments.
  16347. *
  16348. * @tparam Type A type.
  16349. */
  16350. template<typename Type>
  16351. struct type_identity {
  16352. /*! @brief Identity type. */
  16353. using type = Type;
  16354. };
  16355. /**
  16356. * @brief Helper type.
  16357. * @tparam Type A type.
  16358. */
  16359. template<typename Type>
  16360. using type_identity_t = typename type_identity<Type>::type;
  16361. /**
  16362. * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains.
  16363. * @tparam Type The type of which to return the size.
  16364. * @tparam The size of the type if `sizeof` accepts it, 0 otherwise.
  16365. */
  16366. template<typename Type, typename = void>
  16367. struct size_of: std::integral_constant<std::size_t, 0u> {};
  16368. /*! @copydoc size_of */
  16369. template<typename Type>
  16370. struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
  16371. : std::integral_constant<std::size_t, sizeof(Type)> {};
  16372. /**
  16373. * @brief Helper variable template.
  16374. * @tparam Type The type of which to return the size.
  16375. */
  16376. template<typename Type>
  16377. inline constexpr std::size_t size_of_v = size_of<Type>::value;
  16378. /**
  16379. * @brief Using declaration to be used to _repeat_ the same type a number of
  16380. * times equal to the size of a given parameter pack.
  16381. * @tparam Type A type to repeat.
  16382. */
  16383. template<typename Type, typename>
  16384. using unpack_as_type = Type;
  16385. /**
  16386. * @brief Helper variable template to be used to _repeat_ the same value a
  16387. * number of times equal to the size of a given parameter pack.
  16388. * @tparam Value A value to repeat.
  16389. */
  16390. template<auto Value, typename>
  16391. inline constexpr auto unpack_as_value = Value;
  16392. /**
  16393. * @brief Wraps a static constant.
  16394. * @tparam Value A static constant.
  16395. */
  16396. template<auto Value>
  16397. using integral_constant = std::integral_constant<decltype(Value), Value>;
  16398. /**
  16399. * @brief Alias template to facilitate the creation of named values.
  16400. * @tparam Value A constant value at least convertible to `id_type`.
  16401. */
  16402. template<id_type Value>
  16403. using tag = integral_constant<Value>;
  16404. /**
  16405. * @brief A class to use to push around lists of types, nothing more.
  16406. * @tparam Type Types provided by the type list.
  16407. */
  16408. template<typename... Type>
  16409. struct type_list {
  16410. /*! @brief Type list type. */
  16411. using type = type_list;
  16412. /*! @brief Compile-time number of elements in the type list. */
  16413. static constexpr auto size = sizeof...(Type);
  16414. };
  16415. /*! @brief Primary template isn't defined on purpose. */
  16416. template<std::size_t, typename>
  16417. struct type_list_element;
  16418. /**
  16419. * @brief Provides compile-time indexed access to the types of a type list.
  16420. * @tparam Index Index of the type to return.
  16421. * @tparam Type First type provided by the type list.
  16422. * @tparam Other Other types provided by the type list.
  16423. */
  16424. template<std::size_t Index, typename Type, typename... Other>
  16425. struct type_list_element<Index, type_list<Type, Other...>>
  16426. : type_list_element<Index - 1u, type_list<Other...>> {};
  16427. /**
  16428. * @brief Provides compile-time indexed access to the types of a type list.
  16429. * @tparam Type First type provided by the type list.
  16430. * @tparam Other Other types provided by the type list.
  16431. */
  16432. template<typename Type, typename... Other>
  16433. struct type_list_element<0u, type_list<Type, Other...>> {
  16434. /*! @brief Searched type. */
  16435. using type = Type;
  16436. };
  16437. /**
  16438. * @brief Helper type.
  16439. * @tparam Index Index of the type to return.
  16440. * @tparam List Type list to search into.
  16441. */
  16442. template<std::size_t Index, typename List>
  16443. using type_list_element_t = typename type_list_element<Index, List>::type;
  16444. /**
  16445. * @brief Concatenates multiple type lists.
  16446. * @tparam Type Types provided by the first type list.
  16447. * @tparam Other Types provided by the second type list.
  16448. * @return A type list composed by the types of both the type lists.
  16449. */
  16450. template<typename... Type, typename... Other>
  16451. constexpr type_list<Type..., Other...> operator+(type_list<Type...>, type_list<Other...>) {
  16452. return {};
  16453. }
  16454. /*! @brief Primary template isn't defined on purpose. */
  16455. template<typename...>
  16456. struct type_list_cat;
  16457. /*! @brief Concatenates multiple type lists. */
  16458. template<>
  16459. struct type_list_cat<> {
  16460. /*! @brief A type list composed by the types of all the type lists. */
  16461. using type = type_list<>;
  16462. };
  16463. /**
  16464. * @brief Concatenates multiple type lists.
  16465. * @tparam Type Types provided by the first type list.
  16466. * @tparam Other Types provided by the second type list.
  16467. * @tparam List Other type lists, if any.
  16468. */
  16469. template<typename... Type, typename... Other, typename... List>
  16470. struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
  16471. /*! @brief A type list composed by the types of all the type lists. */
  16472. using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
  16473. };
  16474. /**
  16475. * @brief Concatenates multiple type lists.
  16476. * @tparam Type Types provided by the type list.
  16477. */
  16478. template<typename... Type>
  16479. struct type_list_cat<type_list<Type...>> {
  16480. /*! @brief A type list composed by the types of all the type lists. */
  16481. using type = type_list<Type...>;
  16482. };
  16483. /**
  16484. * @brief Helper type.
  16485. * @tparam List Type lists to concatenate.
  16486. */
  16487. template<typename... List>
  16488. using type_list_cat_t = typename type_list_cat<List...>::type;
  16489. /*! @brief Primary template isn't defined on purpose. */
  16490. template<typename>
  16491. struct type_list_unique;
  16492. /**
  16493. * @brief Removes duplicates types from a type list.
  16494. * @tparam Type One of the types provided by the given type list.
  16495. * @tparam Other The other types provided by the given type list.
  16496. */
  16497. template<typename Type, typename... Other>
  16498. struct type_list_unique<type_list<Type, Other...>> {
  16499. /*! @brief A type list without duplicate types. */
  16500. using type = std::conditional_t<
  16501. (std::is_same_v<Type, Other> || ...),
  16502. typename type_list_unique<type_list<Other...>>::type,
  16503. type_list_cat_t<type_list<Type>, typename type_list_unique<type_list<Other...>>::type>>;
  16504. };
  16505. /*! @brief Removes duplicates types from a type list. */
  16506. template<>
  16507. struct type_list_unique<type_list<>> {
  16508. /*! @brief A type list without duplicate types. */
  16509. using type = type_list<>;
  16510. };
  16511. /**
  16512. * @brief Helper type.
  16513. * @tparam Type A type list.
  16514. */
  16515. template<typename Type>
  16516. using type_list_unique_t = typename type_list_unique<Type>::type;
  16517. /**
  16518. * @brief Provides the member constant `value` to true if a type list contains a
  16519. * given type, false otherwise.
  16520. * @tparam List Type list.
  16521. * @tparam Type Type to look for.
  16522. */
  16523. template<typename List, typename Type>
  16524. struct type_list_contains;
  16525. /**
  16526. * @copybrief type_list_contains
  16527. * @tparam Type Types provided by the type list.
  16528. * @tparam Other Type to look for.
  16529. */
  16530. template<typename... Type, typename Other>
  16531. struct type_list_contains<type_list<Type...>, Other>: std::disjunction<std::is_same<Type, Other>...> {};
  16532. /**
  16533. * @brief Helper variable template.
  16534. * @tparam List Type list.
  16535. * @tparam Type Type to look for.
  16536. */
  16537. template<typename List, typename Type>
  16538. inline constexpr bool type_list_contains_v = type_list_contains<List, Type>::value;
  16539. /*! @brief Primary template isn't defined on purpose. */
  16540. template<typename...>
  16541. struct type_list_diff;
  16542. /**
  16543. * @brief Computes the difference between two type lists.
  16544. * @tparam Type Types provided by the first type list.
  16545. * @tparam Other Types provided by the second type list.
  16546. */
  16547. template<typename... Type, typename... Other>
  16548. struct type_list_diff<type_list<Type...>, type_list<Other...>> {
  16549. /*! @brief A type list that is the difference between the two type lists. */
  16550. using type = type_list_cat_t<std::conditional_t<type_list_contains_v<type_list<Other...>, Type>, type_list<>, type_list<Type>>...>;
  16551. };
  16552. /**
  16553. * @brief Helper type.
  16554. * @tparam List Type lists between which to compute the difference.
  16555. */
  16556. template<typename... List>
  16557. using type_list_diff_t = typename type_list_diff<List...>::type;
  16558. /**
  16559. * @brief A class to use to push around lists of constant values, nothing more.
  16560. * @tparam Value Values provided by the value list.
  16561. */
  16562. template<auto... Value>
  16563. struct value_list {
  16564. /*! @brief Value list type. */
  16565. using type = value_list;
  16566. /*! @brief Compile-time number of elements in the value list. */
  16567. static constexpr auto size = sizeof...(Value);
  16568. };
  16569. /*! @brief Primary template isn't defined on purpose. */
  16570. template<std::size_t, typename>
  16571. struct value_list_element;
  16572. /**
  16573. * @brief Provides compile-time indexed access to the values of a value list.
  16574. * @tparam Index Index of the value to return.
  16575. * @tparam Value First value provided by the value list.
  16576. * @tparam Other Other values provided by the value list.
  16577. */
  16578. template<std::size_t Index, auto Value, auto... Other>
  16579. struct value_list_element<Index, value_list<Value, Other...>>
  16580. : value_list_element<Index - 1u, value_list<Other...>> {};
  16581. /**
  16582. * @brief Provides compile-time indexed access to the types of a type list.
  16583. * @tparam Value First value provided by the value list.
  16584. * @tparam Other Other values provided by the value list.
  16585. */
  16586. template<auto Value, auto... Other>
  16587. struct value_list_element<0u, value_list<Value, Other...>> {
  16588. /*! @brief Searched value. */
  16589. static constexpr auto value = Value;
  16590. };
  16591. /**
  16592. * @brief Helper type.
  16593. * @tparam Index Index of the value to return.
  16594. * @tparam List Value list to search into.
  16595. */
  16596. template<std::size_t Index, typename List>
  16597. inline constexpr auto value_list_element_v = value_list_element<Index, List>::value;
  16598. /**
  16599. * @brief Concatenates multiple value lists.
  16600. * @tparam Value Values provided by the first value list.
  16601. * @tparam Other Values provided by the second value list.
  16602. * @return A value list composed by the values of both the value lists.
  16603. */
  16604. template<auto... Value, auto... Other>
  16605. constexpr value_list<Value..., Other...> operator+(value_list<Value...>, value_list<Other...>) {
  16606. return {};
  16607. }
  16608. /*! @brief Primary template isn't defined on purpose. */
  16609. template<typename...>
  16610. struct value_list_cat;
  16611. /*! @brief Concatenates multiple value lists. */
  16612. template<>
  16613. struct value_list_cat<> {
  16614. /*! @brief A value list composed by the values of all the value lists. */
  16615. using type = value_list<>;
  16616. };
  16617. /**
  16618. * @brief Concatenates multiple value lists.
  16619. * @tparam Value Values provided by the first value list.
  16620. * @tparam Other Values provided by the second value list.
  16621. * @tparam List Other value lists, if any.
  16622. */
  16623. template<auto... Value, auto... Other, typename... List>
  16624. struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
  16625. /*! @brief A value list composed by the values of all the value lists. */
  16626. using type = typename value_list_cat<value_list<Value..., Other...>, List...>::type;
  16627. };
  16628. /**
  16629. * @brief Concatenates multiple value lists.
  16630. * @tparam Value Values provided by the value list.
  16631. */
  16632. template<auto... Value>
  16633. struct value_list_cat<value_list<Value...>> {
  16634. /*! @brief A value list composed by the values of all the value lists. */
  16635. using type = value_list<Value...>;
  16636. };
  16637. /**
  16638. * @brief Helper type.
  16639. * @tparam List Value lists to concatenate.
  16640. */
  16641. template<typename... List>
  16642. using value_list_cat_t = typename value_list_cat<List...>::type;
  16643. /*! @brief Same as std::is_invocable, but with tuples. */
  16644. template<typename, typename>
  16645. struct is_applicable: std::false_type {};
  16646. /**
  16647. * @copybrief is_applicable
  16648. * @tparam Func A valid function type.
  16649. * @tparam Tuple Tuple-like type.
  16650. * @tparam Args The list of arguments to use to probe the function type.
  16651. */
  16652. template<typename Func, template<typename...> class Tuple, typename... Args>
  16653. struct is_applicable<Func, Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  16654. /**
  16655. * @copybrief is_applicable
  16656. * @tparam Func A valid function type.
  16657. * @tparam Tuple Tuple-like type.
  16658. * @tparam Args The list of arguments to use to probe the function type.
  16659. */
  16660. template<typename Func, template<typename...> class Tuple, typename... Args>
  16661. struct is_applicable<Func, const Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  16662. /**
  16663. * @brief Helper variable template.
  16664. * @tparam Func A valid function type.
  16665. * @tparam Args The list of arguments to use to probe the function type.
  16666. */
  16667. template<typename Func, typename Args>
  16668. inline constexpr bool is_applicable_v = is_applicable<Func, Args>::value;
  16669. /*! @brief Same as std::is_invocable_r, but with tuples for arguments. */
  16670. template<typename, typename, typename>
  16671. struct is_applicable_r: std::false_type {};
  16672. /**
  16673. * @copybrief is_applicable_r
  16674. * @tparam Ret The type to which the return type of the function should be
  16675. * convertible.
  16676. * @tparam Func A valid function type.
  16677. * @tparam Args The list of arguments to use to probe the function type.
  16678. */
  16679. template<typename Ret, typename Func, typename... Args>
  16680. struct is_applicable_r<Ret, Func, std::tuple<Args...>>: std::is_invocable_r<Ret, Func, Args...> {};
  16681. /**
  16682. * @brief Helper variable template.
  16683. * @tparam Ret The type to which the return type of the function should be
  16684. * convertible.
  16685. * @tparam Func A valid function type.
  16686. * @tparam Args The list of arguments to use to probe the function type.
  16687. */
  16688. template<typename Ret, typename Func, typename Args>
  16689. inline constexpr bool is_applicable_r_v = is_applicable_r<Ret, Func, Args>::value;
  16690. /**
  16691. * @brief Provides the member constant `value` to true if a given type is
  16692. * complete, false otherwise.
  16693. * @tparam Type The type to test.
  16694. */
  16695. template<typename Type, typename = void>
  16696. struct is_complete: std::false_type {};
  16697. /*! @copydoc is_complete */
  16698. template<typename Type>
  16699. struct is_complete<Type, std::void_t<decltype(sizeof(Type))>>: std::true_type {};
  16700. /**
  16701. * @brief Helper variable template.
  16702. * @tparam Type The type to test.
  16703. */
  16704. template<typename Type>
  16705. inline constexpr bool is_complete_v = is_complete<Type>::value;
  16706. /**
  16707. * @brief Provides the member constant `value` to true if a given type is an
  16708. * iterator, false otherwise.
  16709. * @tparam Type The type to test.
  16710. */
  16711. template<typename Type, typename = void>
  16712. struct is_iterator: std::false_type {};
  16713. /**
  16714. * @cond TURN_OFF_DOXYGEN
  16715. * Internal details not to be documented.
  16716. */
  16717. namespace internal {
  16718. template<typename, typename = void>
  16719. struct has_iterator_category: std::false_type {};
  16720. template<typename Type>
  16721. struct has_iterator_category<Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>: std::true_type {};
  16722. } // namespace internal
  16723. /**
  16724. * Internal details not to be documented.
  16725. * @endcond
  16726. */
  16727. /*! @copydoc is_iterator */
  16728. template<typename Type>
  16729. struct is_iterator<Type, std::enable_if_t<!std::is_same_v<std::remove_const_t<std::remove_pointer_t<Type>>, void>>>
  16730. : internal::has_iterator_category<Type> {};
  16731. /**
  16732. * @brief Helper variable template.
  16733. * @tparam Type The type to test.
  16734. */
  16735. template<typename Type>
  16736. inline constexpr bool is_iterator_v = is_iterator<Type>::value;
  16737. /**
  16738. * @brief Provides the member constant `value` to true if a given type is both
  16739. * an empty and non-final class, false otherwise.
  16740. * @tparam Type The type to test
  16741. */
  16742. template<typename Type>
  16743. struct is_ebco_eligible
  16744. : std::conjunction<std::is_empty<Type>, std::negation<std::is_final<Type>>> {};
  16745. /**
  16746. * @brief Helper variable template.
  16747. * @tparam Type The type to test.
  16748. */
  16749. template<typename Type>
  16750. inline constexpr bool is_ebco_eligible_v = is_ebco_eligible<Type>::value;
  16751. /**
  16752. * @brief Provides the member constant `value` to true if `Type::is_transparent`
  16753. * is valid and denotes a type, false otherwise.
  16754. * @tparam Type The type to test.
  16755. */
  16756. template<typename Type, typename = void>
  16757. struct is_transparent: std::false_type {};
  16758. /*! @copydoc is_transparent */
  16759. template<typename Type>
  16760. struct is_transparent<Type, std::void_t<typename Type::is_transparent>>: std::true_type {};
  16761. /**
  16762. * @brief Helper variable template.
  16763. * @tparam Type The type to test.
  16764. */
  16765. template<typename Type>
  16766. inline constexpr bool is_transparent_v = is_transparent<Type>::value;
  16767. /**
  16768. * @brief Provides the member constant `value` to true if a given type is
  16769. * equality comparable, false otherwise.
  16770. * @tparam Type The type to test.
  16771. */
  16772. template<typename Type, typename = void>
  16773. struct is_equality_comparable: std::false_type {};
  16774. /**
  16775. * @cond TURN_OFF_DOXYGEN
  16776. * Internal details not to be documented.
  16777. */
  16778. namespace internal {
  16779. template<typename, typename = void>
  16780. struct has_tuple_size_value: std::false_type {};
  16781. template<typename Type>
  16782. struct has_tuple_size_value<Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>: std::true_type {};
  16783. template<typename Type, std::size_t... Index>
  16784. [[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
  16785. return (is_equality_comparable<std::tuple_element_t<Index, Type>>::value && ...);
  16786. }
  16787. template<typename>
  16788. [[nodiscard]] constexpr bool maybe_equality_comparable(choice_t<0>) {
  16789. return true;
  16790. }
  16791. template<typename Type>
  16792. [[nodiscard]] constexpr auto maybe_equality_comparable(choice_t<1>) -> decltype(std::declval<typename Type::value_type>(), bool{}) {
  16793. if constexpr(is_iterator_v<Type>) {
  16794. return true;
  16795. } else if constexpr(std::is_same_v<typename Type::value_type, Type>) {
  16796. return maybe_equality_comparable<Type>(choice<0>);
  16797. } else {
  16798. return is_equality_comparable<typename Type::value_type>::value;
  16799. }
  16800. }
  16801. template<typename Type>
  16802. [[nodiscard]] constexpr std::enable_if_t<is_complete_v<std::tuple_size<std::remove_const_t<Type>>>, bool> maybe_equality_comparable(choice_t<2>) {
  16803. if constexpr(has_tuple_size_value<Type>::value) {
  16804. return unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
  16805. } else {
  16806. return maybe_equality_comparable<Type>(choice<1>);
  16807. }
  16808. }
  16809. } // namespace internal
  16810. /**
  16811. * Internal details not to be documented.
  16812. * @endcond
  16813. */
  16814. /*! @copydoc is_equality_comparable */
  16815. template<typename Type>
  16816. struct is_equality_comparable<Type, std::void_t<decltype(std::declval<Type>() == std::declval<Type>())>>
  16817. : std::bool_constant<internal::maybe_equality_comparable<Type>(choice<2>)> {};
  16818. /**
  16819. * @brief Helper variable template.
  16820. * @tparam Type The type to test.
  16821. */
  16822. template<typename Type>
  16823. inline constexpr bool is_equality_comparable_v = is_equality_comparable<Type>::value;
  16824. /**
  16825. * @brief Transcribes the constness of a type to another type.
  16826. * @tparam To The type to which to transcribe the constness.
  16827. * @tparam From The type from which to transcribe the constness.
  16828. */
  16829. template<typename To, typename From>
  16830. struct constness_as {
  16831. /*! @brief The type resulting from the transcription of the constness. */
  16832. using type = std::remove_const_t<To>;
  16833. };
  16834. /*! @copydoc constness_as */
  16835. template<typename To, typename From>
  16836. struct constness_as<To, const From> {
  16837. /*! @brief The type resulting from the transcription of the constness. */
  16838. using type = std::add_const_t<To>;
  16839. };
  16840. /**
  16841. * @brief Alias template to facilitate the transcription of the constness.
  16842. * @tparam To The type to which to transcribe the constness.
  16843. * @tparam From The type from which to transcribe the constness.
  16844. */
  16845. template<typename To, typename From>
  16846. using constness_as_t = typename constness_as<To, From>::type;
  16847. /**
  16848. * @brief Extracts the class of a non-static member object or function.
  16849. * @tparam Member A pointer to a non-static member object or function.
  16850. */
  16851. template<typename Member>
  16852. class member_class {
  16853. static_assert(std::is_member_pointer_v<Member>, "Invalid pointer type to non-static member object or function");
  16854. template<typename Class, typename Ret, typename... Args>
  16855. static Class *clazz(Ret (Class::*)(Args...));
  16856. template<typename Class, typename Ret, typename... Args>
  16857. static Class *clazz(Ret (Class::*)(Args...) const);
  16858. template<typename Class, typename Type>
  16859. static Class *clazz(Type Class::*);
  16860. public:
  16861. /*! @brief The class of the given non-static member object or function. */
  16862. using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
  16863. };
  16864. /**
  16865. * @brief Helper type.
  16866. * @tparam Member A pointer to a non-static member object or function.
  16867. */
  16868. template<typename Member>
  16869. using member_class_t = typename member_class<Member>::type;
  16870. } // namespace entt
  16871. #endif
  16872. namespace entt {
  16873. /**
  16874. * @cond TURN_OFF_DOXYGEN
  16875. * Internal details not to be documented.
  16876. */
  16877. namespace internal {
  16878. template<typename Type, std::size_t, typename = void>
  16879. struct compressed_pair_element {
  16880. using reference = Type &;
  16881. using const_reference = const Type &;
  16882. template<bool Dummy = true, typename = std::enable_if_t<Dummy && std::is_default_constructible_v<Type>>>
  16883. compressed_pair_element()
  16884. : value{} {}
  16885. template<typename Args, typename = std::enable_if_t<!std::is_same_v<std::remove_cv_t<std::remove_reference_t<Args>>, compressed_pair_element>>>
  16886. compressed_pair_element(Args &&args)
  16887. : value{std::forward<Args>(args)} {}
  16888. template<typename... Args, std::size_t... Index>
  16889. compressed_pair_element(std::tuple<Args...> args, std::index_sequence<Index...>)
  16890. : value{std::forward<Args>(std::get<Index>(args))...} {}
  16891. [[nodiscard]] reference get() ENTT_NOEXCEPT {
  16892. return value;
  16893. }
  16894. [[nodiscard]] const_reference get() const ENTT_NOEXCEPT {
  16895. return value;
  16896. }
  16897. private:
  16898. Type value;
  16899. };
  16900. template<typename Type, std::size_t Tag>
  16901. struct compressed_pair_element<Type, Tag, std::enable_if_t<is_ebco_eligible_v<Type>>>: Type {
  16902. using reference = Type &;
  16903. using const_reference = const Type &;
  16904. using base_type = Type;
  16905. template<bool Dummy = true, typename = std::enable_if_t<Dummy && std::is_default_constructible_v<base_type>>>
  16906. compressed_pair_element()
  16907. : base_type{} {}
  16908. template<typename Args, typename = std::enable_if_t<!std::is_same_v<std::remove_cv_t<std::remove_reference_t<Args>>, compressed_pair_element>>>
  16909. compressed_pair_element(Args &&args)
  16910. : base_type{std::forward<Args>(args)} {}
  16911. template<typename... Args, std::size_t... Index>
  16912. compressed_pair_element(std::tuple<Args...> args, std::index_sequence<Index...>)
  16913. : base_type{std::forward<Args>(std::get<Index>(args))...} {}
  16914. [[nodiscard]] reference get() ENTT_NOEXCEPT {
  16915. return *this;
  16916. }
  16917. [[nodiscard]] const_reference get() const ENTT_NOEXCEPT {
  16918. return *this;
  16919. }
  16920. };
  16921. } // namespace internal
  16922. /**
  16923. * Internal details not to be documented.
  16924. * @endcond
  16925. */
  16926. /**
  16927. * @brief A compressed pair.
  16928. *
  16929. * A pair that exploits the _Empty Base Class Optimization_ (or _EBCO_) to
  16930. * reduce its final size to a minimum.
  16931. *
  16932. * @tparam First The type of the first element that the pair stores.
  16933. * @tparam Second The type of the second element that the pair stores.
  16934. */
  16935. template<typename First, typename Second>
  16936. class compressed_pair final
  16937. : internal::compressed_pair_element<First, 0u>,
  16938. internal::compressed_pair_element<Second, 1u> {
  16939. using first_base = internal::compressed_pair_element<First, 0u>;
  16940. using second_base = internal::compressed_pair_element<Second, 1u>;
  16941. public:
  16942. /*! @brief The type of the first element that the pair stores. */
  16943. using first_type = First;
  16944. /*! @brief The type of the second element that the pair stores. */
  16945. using second_type = Second;
  16946. /**
  16947. * @brief Default constructor, conditionally enabled.
  16948. *
  16949. * This constructor is only available when the types that the pair stores
  16950. * are both at least default constructible.
  16951. *
  16952. * @tparam Dummy Dummy template parameter used for internal purposes.
  16953. */
  16954. template<bool Dummy = true, typename = std::enable_if_t<Dummy && std::is_default_constructible_v<first_type> && std::is_default_constructible_v<second_type>>>
  16955. constexpr compressed_pair()
  16956. : first_base{},
  16957. second_base{} {}
  16958. /**
  16959. * @brief Copy constructor.
  16960. * @param other The instance to copy from.
  16961. */
  16962. constexpr compressed_pair(const compressed_pair &other) = default;
  16963. /**
  16964. * @brief Move constructor.
  16965. * @param other The instance to move from.
  16966. */
  16967. constexpr compressed_pair(compressed_pair &&other) = default;
  16968. /**
  16969. * @brief Constructs a pair from its values.
  16970. * @tparam Arg Type of value to use to initialize the first element.
  16971. * @tparam Other Type of value to use to initialize the second element.
  16972. * @param arg Value to use to initialize the first element.
  16973. * @param other Value to use to initialize the second element.
  16974. */
  16975. template<typename Arg, typename Other>
  16976. constexpr compressed_pair(Arg &&arg, Other &&other)
  16977. : first_base{std::forward<Arg>(arg)},
  16978. second_base{std::forward<Other>(other)} {}
  16979. /**
  16980. * @brief Constructs a pair by forwarding the arguments to its parts.
  16981. * @tparam Args Types of arguments to use to initialize the first element.
  16982. * @tparam Other Types of arguments to use to initialize the second element.
  16983. * @param args Arguments to use to initialize the first element.
  16984. * @param other Arguments to use to initialize the second element.
  16985. */
  16986. template<typename... Args, typename... Other>
  16987. constexpr compressed_pair(std::piecewise_construct_t, std::tuple<Args...> args, std::tuple<Other...> other)
  16988. : first_base{std::move(args), std::index_sequence_for<Args...>{}},
  16989. second_base{std::move(other), std::index_sequence_for<Other...>{}} {}
  16990. /**
  16991. * @brief Copy assignment operator.
  16992. * @param other The instance to copy from.
  16993. * @return This compressed pair object.
  16994. */
  16995. constexpr compressed_pair &operator=(const compressed_pair &other) = default;
  16996. /**
  16997. * @brief Move assignment operator.
  16998. * @param other The instance to move from.
  16999. * @return This compressed pair object.
  17000. */
  17001. constexpr compressed_pair &operator=(compressed_pair &&other) = default;
  17002. /**
  17003. * @brief Returns the first element that a pair stores.
  17004. * @return The first element that a pair stores.
  17005. */
  17006. [[nodiscard]] first_type &first() ENTT_NOEXCEPT {
  17007. return static_cast<first_base &>(*this).get();
  17008. }
  17009. /*! @copydoc first */
  17010. [[nodiscard]] const first_type &first() const ENTT_NOEXCEPT {
  17011. return static_cast<const first_base &>(*this).get();
  17012. }
  17013. /**
  17014. * @brief Returns the second element that a pair stores.
  17015. * @return The second element that a pair stores.
  17016. */
  17017. [[nodiscard]] second_type &second() ENTT_NOEXCEPT {
  17018. return static_cast<second_base &>(*this).get();
  17019. }
  17020. /*! @copydoc second */
  17021. [[nodiscard]] const second_type &second() const ENTT_NOEXCEPT {
  17022. return static_cast<const second_base &>(*this).get();
  17023. }
  17024. /**
  17025. * @brief Swaps two compressed pair objects.
  17026. * @param other The compressed pair to swap with.
  17027. */
  17028. void swap(compressed_pair &other) {
  17029. using std::swap;
  17030. swap(first(), other.first());
  17031. swap(second(), other.second());
  17032. }
  17033. /**
  17034. * @brief Extracts an element from the compressed pair.
  17035. * @tparam Index An integer value that is either 0 or 1.
  17036. * @return Returns a reference to the first element if `Index` is 0 and a
  17037. * reference to the second element if `Index` is 1.
  17038. */
  17039. template<std::size_t Index>
  17040. decltype(auto) get() ENTT_NOEXCEPT {
  17041. if constexpr(Index == 0u) {
  17042. return first();
  17043. } else {
  17044. static_assert(Index == 1u, "Index out of bounds");
  17045. return second();
  17046. }
  17047. }
  17048. /*! @copydoc get */
  17049. template<std::size_t Index>
  17050. decltype(auto) get() const ENTT_NOEXCEPT {
  17051. if constexpr(Index == 0u) {
  17052. return first();
  17053. } else {
  17054. static_assert(Index == 1u, "Index out of bounds");
  17055. return second();
  17056. }
  17057. }
  17058. };
  17059. /**
  17060. * @brief Deduction guide.
  17061. * @tparam Type Type of value to use to initialize the first element.
  17062. * @tparam Other Type of value to use to initialize the second element.
  17063. */
  17064. template<typename Type, typename Other>
  17065. compressed_pair(Type &&, Other &&) -> compressed_pair<std::decay_t<Type>, std::decay_t<Other>>;
  17066. /**
  17067. * @brief Swaps two compressed pair objects.
  17068. * @tparam First The type of the first element that the pairs store.
  17069. * @tparam Second The type of the second element that the pairs store.
  17070. * @param lhs A valid compressed pair object.
  17071. * @param rhs A valid compressed pair object.
  17072. */
  17073. template<typename First, typename Second>
  17074. inline void swap(compressed_pair<First, Second> &lhs, compressed_pair<First, Second> &rhs) {
  17075. lhs.swap(rhs);
  17076. }
  17077. } // namespace entt
  17078. // disable structured binding support for clang 6, it messes when specializing tuple_size
  17079. #if !defined __clang_major__ || __clang_major__ > 6
  17080. namespace std {
  17081. /**
  17082. * @brief `std::tuple_size` specialization for `compressed_pair`s.
  17083. * @tparam First The type of the first element that the pair stores.
  17084. * @tparam Second The type of the second element that the pair stores.
  17085. */
  17086. template<typename First, typename Second>
  17087. struct tuple_size<entt::compressed_pair<First, Second>>: integral_constant<size_t, 2u> {};
  17088. /**
  17089. * @brief `std::tuple_element` specialization for `compressed_pair`s.
  17090. * @tparam Index The index of the type to return.
  17091. * @tparam First The type of the first element that the pair stores.
  17092. * @tparam Second The type of the second element that the pair stores.
  17093. */
  17094. template<size_t Index, typename First, typename Second>
  17095. struct tuple_element<Index, entt::compressed_pair<First, Second>>: conditional<Index == 0u, First, Second> {
  17096. static_assert(Index < 2u, "Index out of bounds");
  17097. };
  17098. } // namespace std
  17099. #endif
  17100. #endif
  17101. // #include "../core/iterator.hpp"
  17102. #ifndef ENTT_CORE_ITERATOR_HPP
  17103. #define ENTT_CORE_ITERATOR_HPP
  17104. #include <iterator>
  17105. #include <memory>
  17106. #include <utility>
  17107. // #include "../config/config.h"
  17108. namespace entt {
  17109. /**
  17110. * @brief Helper type to use as pointer with input iterators.
  17111. * @tparam Type of wrapped value.
  17112. */
  17113. template<typename Type>
  17114. struct input_iterator_pointer final {
  17115. /*! @brief Pointer type. */
  17116. using pointer = Type *;
  17117. /*! @brief Default copy constructor, deleted on purpose. */
  17118. input_iterator_pointer(const input_iterator_pointer &) = delete;
  17119. /*! @brief Default move constructor. */
  17120. input_iterator_pointer(input_iterator_pointer &&) = default;
  17121. /**
  17122. * @brief Constructs a proxy object by move.
  17123. * @param val Value to use to initialize the proxy object.
  17124. */
  17125. input_iterator_pointer(Type &&val)
  17126. : value{std::move(val)} {}
  17127. /**
  17128. * @brief Default copy assignment operator, deleted on purpose.
  17129. * @return This proxy object.
  17130. */
  17131. input_iterator_pointer &operator=(const input_iterator_pointer &) = delete;
  17132. /**
  17133. * @brief Default move assignment operator.
  17134. * @return This proxy object.
  17135. */
  17136. input_iterator_pointer &operator=(input_iterator_pointer &&) = default;
  17137. /**
  17138. * @brief Access operator for accessing wrapped values.
  17139. * @return A pointer to the wrapped value.
  17140. */
  17141. [[nodiscard]] pointer operator->() ENTT_NOEXCEPT {
  17142. return std::addressof(value);
  17143. }
  17144. private:
  17145. Type value;
  17146. };
  17147. /**
  17148. * @brief Utility class to create an iterable object from a pair of iterators.
  17149. * @tparam It Type of iterator.
  17150. * @tparam Sentinel Type of sentinel.
  17151. */
  17152. template<typename It, typename Sentinel = It>
  17153. struct iterable_adaptor final {
  17154. /*! @brief Value type. */
  17155. using value_type = typename std::iterator_traits<It>::value_type;
  17156. /*! @brief Iterator type. */
  17157. using iterator = It;
  17158. /*! @brief Sentinel type. */
  17159. using sentinel = Sentinel;
  17160. /*! @brief Default constructor. */
  17161. iterable_adaptor() = default;
  17162. /**
  17163. * @brief Creates an iterable object from a pair of iterators.
  17164. * @param from Begin iterator.
  17165. * @param to End iterator.
  17166. */
  17167. iterable_adaptor(iterator from, sentinel to)
  17168. : first{from},
  17169. last{to} {}
  17170. /**
  17171. * @brief Returns an iterator to the beginning.
  17172. * @return An iterator to the first element of the range.
  17173. */
  17174. [[nodiscard]] iterator begin() const ENTT_NOEXCEPT {
  17175. return first;
  17176. }
  17177. /**
  17178. * @brief Returns an iterator to the end.
  17179. * @return An iterator to the element following the last element of the
  17180. * range.
  17181. */
  17182. [[nodiscard]] sentinel end() const ENTT_NOEXCEPT {
  17183. return last;
  17184. }
  17185. /*! @copydoc begin */
  17186. [[nodiscard]] iterator cbegin() const ENTT_NOEXCEPT {
  17187. return begin();
  17188. }
  17189. /*! @copydoc end */
  17190. [[nodiscard]] sentinel cend() const ENTT_NOEXCEPT {
  17191. return end();
  17192. }
  17193. private:
  17194. It first;
  17195. Sentinel last;
  17196. };
  17197. } // namespace entt
  17198. #endif
  17199. // #include "../core/memory.hpp"
  17200. #ifndef ENTT_CORE_MEMORY_HPP
  17201. #define ENTT_CORE_MEMORY_HPP
  17202. #include <cstddef>
  17203. #include <limits>
  17204. #include <memory>
  17205. #include <tuple>
  17206. #include <type_traits>
  17207. #include <utility>
  17208. // #include "../config/config.h"
  17209. namespace entt {
  17210. /**
  17211. * @brief Unwraps fancy pointers, does nothing otherwise (waiting for C++20).
  17212. * @tparam Type Pointer type.
  17213. * @param ptr Fancy or raw pointer.
  17214. * @return A raw pointer that represents the address of the original pointer.
  17215. */
  17216. template<typename Type>
  17217. [[nodiscard]] constexpr auto to_address(Type &&ptr) ENTT_NOEXCEPT {
  17218. if constexpr(std::is_pointer_v<std::remove_cv_t<std::remove_reference_t<Type>>>) {
  17219. return ptr;
  17220. } else {
  17221. return to_address(std::forward<Type>(ptr).operator->());
  17222. }
  17223. }
  17224. /**
  17225. * @brief Utility function to design allocation-aware containers.
  17226. * @tparam Allocator Type of allocator.
  17227. * @param lhs A valid allocator.
  17228. * @param rhs Another valid allocator.
  17229. */
  17230. template<typename Allocator>
  17231. constexpr void propagate_on_container_copy_assignment([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) ENTT_NOEXCEPT {
  17232. if constexpr(std::allocator_traits<Allocator>::propagate_on_container_copy_assignment::value) {
  17233. lhs = rhs;
  17234. }
  17235. }
  17236. /**
  17237. * @brief Utility function to design allocation-aware containers.
  17238. * @tparam Allocator Type of allocator.
  17239. * @param lhs A valid allocator.
  17240. * @param rhs Another valid allocator.
  17241. */
  17242. template<typename Allocator>
  17243. constexpr void propagate_on_container_move_assignment([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) ENTT_NOEXCEPT {
  17244. if constexpr(std::allocator_traits<Allocator>::propagate_on_container_move_assignment::value) {
  17245. lhs = std::move(rhs);
  17246. }
  17247. }
  17248. /**
  17249. * @brief Utility function to design allocation-aware containers.
  17250. * @tparam Allocator Type of allocator.
  17251. * @param lhs A valid allocator.
  17252. * @param rhs Another valid allocator.
  17253. */
  17254. template<typename Allocator>
  17255. constexpr void propagate_on_container_swap([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) ENTT_NOEXCEPT {
  17256. ENTT_ASSERT(std::allocator_traits<Allocator>::propagate_on_container_swap::value || lhs == rhs, "Cannot swap the containers");
  17257. if constexpr(std::allocator_traits<Allocator>::propagate_on_container_swap::value) {
  17258. using std::swap;
  17259. swap(lhs, rhs);
  17260. }
  17261. }
  17262. /**
  17263. * @brief Checks whether a value is a power of two or not.
  17264. * @param value A value that may or may not be a power of two.
  17265. * @return True if the value is a power of two, false otherwise.
  17266. */
  17267. [[nodiscard]] inline constexpr bool is_power_of_two(const std::size_t value) ENTT_NOEXCEPT {
  17268. return value && ((value & (value - 1)) == 0);
  17269. }
  17270. /**
  17271. * @brief Computes the smallest power of two greater than or equal to a value.
  17272. * @param value The value to use.
  17273. * @return The smallest power of two greater than or equal to the given value.
  17274. */
  17275. [[nodiscard]] inline constexpr std::size_t next_power_of_two(const std::size_t value) ENTT_NOEXCEPT {
  17276. ENTT_ASSERT(value < (std::size_t{1u} << (std::numeric_limits<std::size_t>::digits - 1)), "Numeric limits exceeded");
  17277. std::size_t curr = value - (value != 0u);
  17278. for(int next = 1; next < std::numeric_limits<std::size_t>::digits; next = next * 2) {
  17279. curr |= curr >> next;
  17280. }
  17281. return ++curr;
  17282. }
  17283. /**
  17284. * @brief Fast module utility function (powers of two only).
  17285. * @param value A value for which to calculate the modulus.
  17286. * @param mod _Modulus_, it must be a power of two.
  17287. * @return The common remainder.
  17288. */
  17289. [[nodiscard]] inline constexpr std::size_t fast_mod(const std::size_t value, const std::size_t mod) ENTT_NOEXCEPT {
  17290. ENTT_ASSERT(is_power_of_two(mod), "Value must be a power of two");
  17291. return value & (mod - 1u);
  17292. }
  17293. /**
  17294. * @brief Deleter for allocator-aware unique pointers (waiting for C++20).
  17295. * @tparam Args Types of arguments to use to construct the object.
  17296. */
  17297. template<typename Allocator>
  17298. struct allocation_deleter: private Allocator {
  17299. /*! @brief Allocator type. */
  17300. using allocator_type = Allocator;
  17301. /*! @brief Pointer type. */
  17302. using pointer = typename std::allocator_traits<Allocator>::pointer;
  17303. /**
  17304. * @brief Inherited constructors.
  17305. * @param alloc The allocator to use.
  17306. */
  17307. allocation_deleter(const allocator_type &alloc)
  17308. : Allocator{alloc} {}
  17309. /**
  17310. * @brief Destroys the pointed object and deallocates its memory.
  17311. * @param ptr A valid pointer to an object of the given type.
  17312. */
  17313. void operator()(pointer ptr) {
  17314. using alloc_traits = typename std::allocator_traits<Allocator>;
  17315. alloc_traits::destroy(*this, to_address(ptr));
  17316. alloc_traits::deallocate(*this, ptr, 1u);
  17317. }
  17318. };
  17319. /**
  17320. * @brief Allows `std::unique_ptr` to use allocators (waiting for C++20).
  17321. * @tparam Type Type of object to allocate for and to construct.
  17322. * @tparam Allocator Type of allocator used to manage memory and elements.
  17323. * @tparam Args Types of arguments to use to construct the object.
  17324. * @param allocator The allocator to use.
  17325. * @param args Parameters to use to construct the object.
  17326. * @return A properly initialized unique pointer with a custom deleter.
  17327. */
  17328. template<typename Type, typename Allocator, typename... Args>
  17329. auto allocate_unique(Allocator &allocator, Args &&...args) {
  17330. static_assert(!std::is_array_v<Type>, "Array types are not supported");
  17331. using alloc_traits = typename std::allocator_traits<Allocator>::template rebind_traits<Type>;
  17332. using allocator_type = typename alloc_traits::allocator_type;
  17333. allocator_type alloc{allocator};
  17334. auto ptr = alloc_traits::allocate(alloc, 1u);
  17335. ENTT_TRY {
  17336. alloc_traits::construct(alloc, to_address(ptr), std::forward<Args>(args)...);
  17337. }
  17338. ENTT_CATCH {
  17339. alloc_traits::deallocate(alloc, ptr, 1u);
  17340. ENTT_THROW;
  17341. }
  17342. return std::unique_ptr<Type, allocation_deleter<allocator_type>>{ptr, alloc};
  17343. }
  17344. /**
  17345. * @cond TURN_OFF_DOXYGEN
  17346. * Internal details not to be documented.
  17347. */
  17348. namespace internal {
  17349. template<typename Type>
  17350. struct uses_allocator_construction {
  17351. template<typename Allocator, typename... Params>
  17352. static constexpr auto args([[maybe_unused]] const Allocator &allocator, Params &&...params) ENTT_NOEXCEPT {
  17353. if constexpr(!std::uses_allocator_v<Type, Allocator> && std::is_constructible_v<Type, Params...>) {
  17354. return std::forward_as_tuple(std::forward<Params>(params)...);
  17355. } else {
  17356. static_assert(std::uses_allocator_v<Type, Allocator>, "Ill-formed request");
  17357. if constexpr(std::is_constructible_v<Type, std::allocator_arg_t, const Allocator &, Params...>) {
  17358. return std::tuple<std::allocator_arg_t, const Allocator &, Params &&...>(std::allocator_arg, allocator, std::forward<Params>(params)...);
  17359. } else {
  17360. static_assert(std::is_constructible_v<Type, Params..., const Allocator &>, "Ill-formed request");
  17361. return std::forward_as_tuple(std::forward<Params>(params)..., allocator);
  17362. }
  17363. }
  17364. }
  17365. };
  17366. template<typename Type, typename Other>
  17367. struct uses_allocator_construction<std::pair<Type, Other>> {
  17368. using type = std::pair<Type, Other>;
  17369. template<typename Allocator, typename First, typename Second>
  17370. static constexpr auto args(const Allocator &allocator, std::piecewise_construct_t, First &&first, Second &&second) ENTT_NOEXCEPT {
  17371. return std::make_tuple(
  17372. std::piecewise_construct,
  17373. std::apply([&allocator](auto &&...curr) { return uses_allocator_construction<Type>::args(allocator, std::forward<decltype(curr)>(curr)...); }, std::forward<First>(first)),
  17374. std::apply([&allocator](auto &&...curr) { return uses_allocator_construction<Other>::args(allocator, std::forward<decltype(curr)>(curr)...); }, std::forward<Second>(second)));
  17375. }
  17376. template<typename Allocator>
  17377. static constexpr auto args(const Allocator &allocator) ENTT_NOEXCEPT {
  17378. return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::tuple<>{}, std::tuple<>{});
  17379. }
  17380. template<typename Allocator, typename First, typename Second>
  17381. static constexpr auto args(const Allocator &allocator, First &&first, Second &&second) ENTT_NOEXCEPT {
  17382. 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)));
  17383. }
  17384. template<typename Allocator, typename First, typename Second>
  17385. static constexpr auto args(const Allocator &allocator, const std::pair<First, Second> &value) ENTT_NOEXCEPT {
  17386. return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::forward_as_tuple(value.first), std::forward_as_tuple(value.second));
  17387. }
  17388. template<typename Allocator, typename First, typename Second>
  17389. static constexpr auto args(const Allocator &allocator, std::pair<First, Second> &&value) ENTT_NOEXCEPT {
  17390. 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)));
  17391. }
  17392. };
  17393. } // namespace internal
  17394. /**
  17395. * Internal details not to be documented.
  17396. * @endcond
  17397. */
  17398. /**
  17399. * @brief Uses-allocator construction utility (waiting for C++20).
  17400. *
  17401. * Primarily intended for internal use. Prepares the argument list needed to
  17402. * create an object of a given type by means of uses-allocator construction.
  17403. *
  17404. * @tparam Type Type to return arguments for.
  17405. * @tparam Allocator Type of allocator used to manage memory and elements.
  17406. * @tparam Args Types of arguments to use to construct the object.
  17407. * @param allocator The allocator to use.
  17408. * @param args Parameters to use to construct the object.
  17409. * @return The arguments needed to create an object of the given type.
  17410. */
  17411. template<typename Type, typename Allocator, typename... Args>
  17412. constexpr auto uses_allocator_construction_args(const Allocator &allocator, Args &&...args) ENTT_NOEXCEPT {
  17413. return internal::uses_allocator_construction<Type>::args(allocator, std::forward<Args>(args)...);
  17414. }
  17415. /**
  17416. * @brief Uses-allocator construction utility (waiting for C++20).
  17417. *
  17418. * Primarily intended for internal use. Creates an object of a given type by
  17419. * means of uses-allocator construction.
  17420. *
  17421. * @tparam Type Type of object to create.
  17422. * @tparam Allocator Type of allocator used to manage memory and elements.
  17423. * @tparam Args Types of arguments to use to construct the object.
  17424. * @param allocator The allocator to use.
  17425. * @param args Parameters to use to construct the object.
  17426. * @return A newly created object of the given type.
  17427. */
  17428. template<typename Type, typename Allocator, typename... Args>
  17429. constexpr Type make_obj_using_allocator(const Allocator &allocator, Args &&...args) {
  17430. return std::make_from_tuple<Type>(internal::uses_allocator_construction<Type>::args(allocator, std::forward<Args>(args)...));
  17431. }
  17432. /**
  17433. * @brief Uses-allocator construction utility (waiting for C++20).
  17434. *
  17435. * Primarily intended for internal use. Creates an object of a given type by
  17436. * means of uses-allocator construction at an uninitialized memory location.
  17437. *
  17438. * @tparam Type Type of object to create.
  17439. * @tparam Allocator Type of allocator used to manage memory and elements.
  17440. * @tparam Args Types of arguments to use to construct the object.
  17441. * @param value Memory location in which to place the object.
  17442. * @param allocator The allocator to use.
  17443. * @param args Parameters to use to construct the object.
  17444. * @return A pointer to the newly created object of the given type.
  17445. */
  17446. template<typename Type, typename Allocator, typename... Args>
  17447. constexpr Type *uninitialized_construct_using_allocator(Type *value, const Allocator &allocator, Args &&...args) {
  17448. return std::apply([&](auto &&...curr) { return new(value) Type(std::forward<decltype(curr)>(curr)...); }, internal::uses_allocator_construction<Type>::args(allocator, std::forward<Args>(args)...));
  17449. }
  17450. } // namespace entt
  17451. #endif
  17452. // #include "../core/type_traits.hpp"
  17453. #ifndef ENTT_CORE_TYPE_TRAITS_HPP
  17454. #define ENTT_CORE_TYPE_TRAITS_HPP
  17455. #include <cstddef>
  17456. #include <iterator>
  17457. #include <type_traits>
  17458. #include <utility>
  17459. // #include "../config/config.h"
  17460. // #include "fwd.hpp"
  17461. namespace entt {
  17462. /**
  17463. * @brief Utility class to disambiguate overloaded functions.
  17464. * @tparam N Number of choices available.
  17465. */
  17466. template<std::size_t N>
  17467. struct choice_t
  17468. // Unfortunately, doxygen cannot parse such a construct.
  17469. : /*! @cond TURN_OFF_DOXYGEN */ choice_t<N - 1> /*! @endcond */
  17470. {};
  17471. /*! @copybrief choice_t */
  17472. template<>
  17473. struct choice_t<0> {};
  17474. /**
  17475. * @brief Variable template for the choice trick.
  17476. * @tparam N Number of choices available.
  17477. */
  17478. template<std::size_t N>
  17479. inline constexpr choice_t<N> choice{};
  17480. /**
  17481. * @brief Identity type trait.
  17482. *
  17483. * Useful to establish non-deduced contexts in template argument deduction
  17484. * (waiting for C++20) or to provide types through function arguments.
  17485. *
  17486. * @tparam Type A type.
  17487. */
  17488. template<typename Type>
  17489. struct type_identity {
  17490. /*! @brief Identity type. */
  17491. using type = Type;
  17492. };
  17493. /**
  17494. * @brief Helper type.
  17495. * @tparam Type A type.
  17496. */
  17497. template<typename Type>
  17498. using type_identity_t = typename type_identity<Type>::type;
  17499. /**
  17500. * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains.
  17501. * @tparam Type The type of which to return the size.
  17502. * @tparam The size of the type if `sizeof` accepts it, 0 otherwise.
  17503. */
  17504. template<typename Type, typename = void>
  17505. struct size_of: std::integral_constant<std::size_t, 0u> {};
  17506. /*! @copydoc size_of */
  17507. template<typename Type>
  17508. struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
  17509. : std::integral_constant<std::size_t, sizeof(Type)> {};
  17510. /**
  17511. * @brief Helper variable template.
  17512. * @tparam Type The type of which to return the size.
  17513. */
  17514. template<typename Type>
  17515. inline constexpr std::size_t size_of_v = size_of<Type>::value;
  17516. /**
  17517. * @brief Using declaration to be used to _repeat_ the same type a number of
  17518. * times equal to the size of a given parameter pack.
  17519. * @tparam Type A type to repeat.
  17520. */
  17521. template<typename Type, typename>
  17522. using unpack_as_type = Type;
  17523. /**
  17524. * @brief Helper variable template to be used to _repeat_ the same value a
  17525. * number of times equal to the size of a given parameter pack.
  17526. * @tparam Value A value to repeat.
  17527. */
  17528. template<auto Value, typename>
  17529. inline constexpr auto unpack_as_value = Value;
  17530. /**
  17531. * @brief Wraps a static constant.
  17532. * @tparam Value A static constant.
  17533. */
  17534. template<auto Value>
  17535. using integral_constant = std::integral_constant<decltype(Value), Value>;
  17536. /**
  17537. * @brief Alias template to facilitate the creation of named values.
  17538. * @tparam Value A constant value at least convertible to `id_type`.
  17539. */
  17540. template<id_type Value>
  17541. using tag = integral_constant<Value>;
  17542. /**
  17543. * @brief A class to use to push around lists of types, nothing more.
  17544. * @tparam Type Types provided by the type list.
  17545. */
  17546. template<typename... Type>
  17547. struct type_list {
  17548. /*! @brief Type list type. */
  17549. using type = type_list;
  17550. /*! @brief Compile-time number of elements in the type list. */
  17551. static constexpr auto size = sizeof...(Type);
  17552. };
  17553. /*! @brief Primary template isn't defined on purpose. */
  17554. template<std::size_t, typename>
  17555. struct type_list_element;
  17556. /**
  17557. * @brief Provides compile-time indexed access to the types of a type list.
  17558. * @tparam Index Index of the type to return.
  17559. * @tparam Type First type provided by the type list.
  17560. * @tparam Other Other types provided by the type list.
  17561. */
  17562. template<std::size_t Index, typename Type, typename... Other>
  17563. struct type_list_element<Index, type_list<Type, Other...>>
  17564. : type_list_element<Index - 1u, type_list<Other...>> {};
  17565. /**
  17566. * @brief Provides compile-time indexed access to the types of a type list.
  17567. * @tparam Type First type provided by the type list.
  17568. * @tparam Other Other types provided by the type list.
  17569. */
  17570. template<typename Type, typename... Other>
  17571. struct type_list_element<0u, type_list<Type, Other...>> {
  17572. /*! @brief Searched type. */
  17573. using type = Type;
  17574. };
  17575. /**
  17576. * @brief Helper type.
  17577. * @tparam Index Index of the type to return.
  17578. * @tparam List Type list to search into.
  17579. */
  17580. template<std::size_t Index, typename List>
  17581. using type_list_element_t = typename type_list_element<Index, List>::type;
  17582. /**
  17583. * @brief Concatenates multiple type lists.
  17584. * @tparam Type Types provided by the first type list.
  17585. * @tparam Other Types provided by the second type list.
  17586. * @return A type list composed by the types of both the type lists.
  17587. */
  17588. template<typename... Type, typename... Other>
  17589. constexpr type_list<Type..., Other...> operator+(type_list<Type...>, type_list<Other...>) {
  17590. return {};
  17591. }
  17592. /*! @brief Primary template isn't defined on purpose. */
  17593. template<typename...>
  17594. struct type_list_cat;
  17595. /*! @brief Concatenates multiple type lists. */
  17596. template<>
  17597. struct type_list_cat<> {
  17598. /*! @brief A type list composed by the types of all the type lists. */
  17599. using type = type_list<>;
  17600. };
  17601. /**
  17602. * @brief Concatenates multiple type lists.
  17603. * @tparam Type Types provided by the first type list.
  17604. * @tparam Other Types provided by the second type list.
  17605. * @tparam List Other type lists, if any.
  17606. */
  17607. template<typename... Type, typename... Other, typename... List>
  17608. struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
  17609. /*! @brief A type list composed by the types of all the type lists. */
  17610. using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
  17611. };
  17612. /**
  17613. * @brief Concatenates multiple type lists.
  17614. * @tparam Type Types provided by the type list.
  17615. */
  17616. template<typename... Type>
  17617. struct type_list_cat<type_list<Type...>> {
  17618. /*! @brief A type list composed by the types of all the type lists. */
  17619. using type = type_list<Type...>;
  17620. };
  17621. /**
  17622. * @brief Helper type.
  17623. * @tparam List Type lists to concatenate.
  17624. */
  17625. template<typename... List>
  17626. using type_list_cat_t = typename type_list_cat<List...>::type;
  17627. /*! @brief Primary template isn't defined on purpose. */
  17628. template<typename>
  17629. struct type_list_unique;
  17630. /**
  17631. * @brief Removes duplicates types from a type list.
  17632. * @tparam Type One of the types provided by the given type list.
  17633. * @tparam Other The other types provided by the given type list.
  17634. */
  17635. template<typename Type, typename... Other>
  17636. struct type_list_unique<type_list<Type, Other...>> {
  17637. /*! @brief A type list without duplicate types. */
  17638. using type = std::conditional_t<
  17639. (std::is_same_v<Type, Other> || ...),
  17640. typename type_list_unique<type_list<Other...>>::type,
  17641. type_list_cat_t<type_list<Type>, typename type_list_unique<type_list<Other...>>::type>>;
  17642. };
  17643. /*! @brief Removes duplicates types from a type list. */
  17644. template<>
  17645. struct type_list_unique<type_list<>> {
  17646. /*! @brief A type list without duplicate types. */
  17647. using type = type_list<>;
  17648. };
  17649. /**
  17650. * @brief Helper type.
  17651. * @tparam Type A type list.
  17652. */
  17653. template<typename Type>
  17654. using type_list_unique_t = typename type_list_unique<Type>::type;
  17655. /**
  17656. * @brief Provides the member constant `value` to true if a type list contains a
  17657. * given type, false otherwise.
  17658. * @tparam List Type list.
  17659. * @tparam Type Type to look for.
  17660. */
  17661. template<typename List, typename Type>
  17662. struct type_list_contains;
  17663. /**
  17664. * @copybrief type_list_contains
  17665. * @tparam Type Types provided by the type list.
  17666. * @tparam Other Type to look for.
  17667. */
  17668. template<typename... Type, typename Other>
  17669. struct type_list_contains<type_list<Type...>, Other>: std::disjunction<std::is_same<Type, Other>...> {};
  17670. /**
  17671. * @brief Helper variable template.
  17672. * @tparam List Type list.
  17673. * @tparam Type Type to look for.
  17674. */
  17675. template<typename List, typename Type>
  17676. inline constexpr bool type_list_contains_v = type_list_contains<List, Type>::value;
  17677. /*! @brief Primary template isn't defined on purpose. */
  17678. template<typename...>
  17679. struct type_list_diff;
  17680. /**
  17681. * @brief Computes the difference between two type lists.
  17682. * @tparam Type Types provided by the first type list.
  17683. * @tparam Other Types provided by the second type list.
  17684. */
  17685. template<typename... Type, typename... Other>
  17686. struct type_list_diff<type_list<Type...>, type_list<Other...>> {
  17687. /*! @brief A type list that is the difference between the two type lists. */
  17688. using type = type_list_cat_t<std::conditional_t<type_list_contains_v<type_list<Other...>, Type>, type_list<>, type_list<Type>>...>;
  17689. };
  17690. /**
  17691. * @brief Helper type.
  17692. * @tparam List Type lists between which to compute the difference.
  17693. */
  17694. template<typename... List>
  17695. using type_list_diff_t = typename type_list_diff<List...>::type;
  17696. /**
  17697. * @brief A class to use to push around lists of constant values, nothing more.
  17698. * @tparam Value Values provided by the value list.
  17699. */
  17700. template<auto... Value>
  17701. struct value_list {
  17702. /*! @brief Value list type. */
  17703. using type = value_list;
  17704. /*! @brief Compile-time number of elements in the value list. */
  17705. static constexpr auto size = sizeof...(Value);
  17706. };
  17707. /*! @brief Primary template isn't defined on purpose. */
  17708. template<std::size_t, typename>
  17709. struct value_list_element;
  17710. /**
  17711. * @brief Provides compile-time indexed access to the values of a value list.
  17712. * @tparam Index Index of the value to return.
  17713. * @tparam Value First value provided by the value list.
  17714. * @tparam Other Other values provided by the value list.
  17715. */
  17716. template<std::size_t Index, auto Value, auto... Other>
  17717. struct value_list_element<Index, value_list<Value, Other...>>
  17718. : value_list_element<Index - 1u, value_list<Other...>> {};
  17719. /**
  17720. * @brief Provides compile-time indexed access to the types of a type list.
  17721. * @tparam Value First value provided by the value list.
  17722. * @tparam Other Other values provided by the value list.
  17723. */
  17724. template<auto Value, auto... Other>
  17725. struct value_list_element<0u, value_list<Value, Other...>> {
  17726. /*! @brief Searched value. */
  17727. static constexpr auto value = Value;
  17728. };
  17729. /**
  17730. * @brief Helper type.
  17731. * @tparam Index Index of the value to return.
  17732. * @tparam List Value list to search into.
  17733. */
  17734. template<std::size_t Index, typename List>
  17735. inline constexpr auto value_list_element_v = value_list_element<Index, List>::value;
  17736. /**
  17737. * @brief Concatenates multiple value lists.
  17738. * @tparam Value Values provided by the first value list.
  17739. * @tparam Other Values provided by the second value list.
  17740. * @return A value list composed by the values of both the value lists.
  17741. */
  17742. template<auto... Value, auto... Other>
  17743. constexpr value_list<Value..., Other...> operator+(value_list<Value...>, value_list<Other...>) {
  17744. return {};
  17745. }
  17746. /*! @brief Primary template isn't defined on purpose. */
  17747. template<typename...>
  17748. struct value_list_cat;
  17749. /*! @brief Concatenates multiple value lists. */
  17750. template<>
  17751. struct value_list_cat<> {
  17752. /*! @brief A value list composed by the values of all the value lists. */
  17753. using type = value_list<>;
  17754. };
  17755. /**
  17756. * @brief Concatenates multiple value lists.
  17757. * @tparam Value Values provided by the first value list.
  17758. * @tparam Other Values provided by the second value list.
  17759. * @tparam List Other value lists, if any.
  17760. */
  17761. template<auto... Value, auto... Other, typename... List>
  17762. struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
  17763. /*! @brief A value list composed by the values of all the value lists. */
  17764. using type = typename value_list_cat<value_list<Value..., Other...>, List...>::type;
  17765. };
  17766. /**
  17767. * @brief Concatenates multiple value lists.
  17768. * @tparam Value Values provided by the value list.
  17769. */
  17770. template<auto... Value>
  17771. struct value_list_cat<value_list<Value...>> {
  17772. /*! @brief A value list composed by the values of all the value lists. */
  17773. using type = value_list<Value...>;
  17774. };
  17775. /**
  17776. * @brief Helper type.
  17777. * @tparam List Value lists to concatenate.
  17778. */
  17779. template<typename... List>
  17780. using value_list_cat_t = typename value_list_cat<List...>::type;
  17781. /*! @brief Same as std::is_invocable, but with tuples. */
  17782. template<typename, typename>
  17783. struct is_applicable: std::false_type {};
  17784. /**
  17785. * @copybrief is_applicable
  17786. * @tparam Func A valid function type.
  17787. * @tparam Tuple Tuple-like type.
  17788. * @tparam Args The list of arguments to use to probe the function type.
  17789. */
  17790. template<typename Func, template<typename...> class Tuple, typename... Args>
  17791. struct is_applicable<Func, Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  17792. /**
  17793. * @copybrief is_applicable
  17794. * @tparam Func A valid function type.
  17795. * @tparam Tuple Tuple-like type.
  17796. * @tparam Args The list of arguments to use to probe the function type.
  17797. */
  17798. template<typename Func, template<typename...> class Tuple, typename... Args>
  17799. struct is_applicable<Func, const Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  17800. /**
  17801. * @brief Helper variable template.
  17802. * @tparam Func A valid function type.
  17803. * @tparam Args The list of arguments to use to probe the function type.
  17804. */
  17805. template<typename Func, typename Args>
  17806. inline constexpr bool is_applicable_v = is_applicable<Func, Args>::value;
  17807. /*! @brief Same as std::is_invocable_r, but with tuples for arguments. */
  17808. template<typename, typename, typename>
  17809. struct is_applicable_r: std::false_type {};
  17810. /**
  17811. * @copybrief is_applicable_r
  17812. * @tparam Ret The type to which the return type of the function should be
  17813. * convertible.
  17814. * @tparam Func A valid function type.
  17815. * @tparam Args The list of arguments to use to probe the function type.
  17816. */
  17817. template<typename Ret, typename Func, typename... Args>
  17818. struct is_applicable_r<Ret, Func, std::tuple<Args...>>: std::is_invocable_r<Ret, Func, Args...> {};
  17819. /**
  17820. * @brief Helper variable template.
  17821. * @tparam Ret The type to which the return type of the function should be
  17822. * convertible.
  17823. * @tparam Func A valid function type.
  17824. * @tparam Args The list of arguments to use to probe the function type.
  17825. */
  17826. template<typename Ret, typename Func, typename Args>
  17827. inline constexpr bool is_applicable_r_v = is_applicable_r<Ret, Func, Args>::value;
  17828. /**
  17829. * @brief Provides the member constant `value` to true if a given type is
  17830. * complete, false otherwise.
  17831. * @tparam Type The type to test.
  17832. */
  17833. template<typename Type, typename = void>
  17834. struct is_complete: std::false_type {};
  17835. /*! @copydoc is_complete */
  17836. template<typename Type>
  17837. struct is_complete<Type, std::void_t<decltype(sizeof(Type))>>: std::true_type {};
  17838. /**
  17839. * @brief Helper variable template.
  17840. * @tparam Type The type to test.
  17841. */
  17842. template<typename Type>
  17843. inline constexpr bool is_complete_v = is_complete<Type>::value;
  17844. /**
  17845. * @brief Provides the member constant `value` to true if a given type is an
  17846. * iterator, false otherwise.
  17847. * @tparam Type The type to test.
  17848. */
  17849. template<typename Type, typename = void>
  17850. struct is_iterator: std::false_type {};
  17851. /**
  17852. * @cond TURN_OFF_DOXYGEN
  17853. * Internal details not to be documented.
  17854. */
  17855. namespace internal {
  17856. template<typename, typename = void>
  17857. struct has_iterator_category: std::false_type {};
  17858. template<typename Type>
  17859. struct has_iterator_category<Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>: std::true_type {};
  17860. } // namespace internal
  17861. /**
  17862. * Internal details not to be documented.
  17863. * @endcond
  17864. */
  17865. /*! @copydoc is_iterator */
  17866. template<typename Type>
  17867. struct is_iterator<Type, std::enable_if_t<!std::is_same_v<std::remove_const_t<std::remove_pointer_t<Type>>, void>>>
  17868. : internal::has_iterator_category<Type> {};
  17869. /**
  17870. * @brief Helper variable template.
  17871. * @tparam Type The type to test.
  17872. */
  17873. template<typename Type>
  17874. inline constexpr bool is_iterator_v = is_iterator<Type>::value;
  17875. /**
  17876. * @brief Provides the member constant `value` to true if a given type is both
  17877. * an empty and non-final class, false otherwise.
  17878. * @tparam Type The type to test
  17879. */
  17880. template<typename Type>
  17881. struct is_ebco_eligible
  17882. : std::conjunction<std::is_empty<Type>, std::negation<std::is_final<Type>>> {};
  17883. /**
  17884. * @brief Helper variable template.
  17885. * @tparam Type The type to test.
  17886. */
  17887. template<typename Type>
  17888. inline constexpr bool is_ebco_eligible_v = is_ebco_eligible<Type>::value;
  17889. /**
  17890. * @brief Provides the member constant `value` to true if `Type::is_transparent`
  17891. * is valid and denotes a type, false otherwise.
  17892. * @tparam Type The type to test.
  17893. */
  17894. template<typename Type, typename = void>
  17895. struct is_transparent: std::false_type {};
  17896. /*! @copydoc is_transparent */
  17897. template<typename Type>
  17898. struct is_transparent<Type, std::void_t<typename Type::is_transparent>>: std::true_type {};
  17899. /**
  17900. * @brief Helper variable template.
  17901. * @tparam Type The type to test.
  17902. */
  17903. template<typename Type>
  17904. inline constexpr bool is_transparent_v = is_transparent<Type>::value;
  17905. /**
  17906. * @brief Provides the member constant `value` to true if a given type is
  17907. * equality comparable, false otherwise.
  17908. * @tparam Type The type to test.
  17909. */
  17910. template<typename Type, typename = void>
  17911. struct is_equality_comparable: std::false_type {};
  17912. /**
  17913. * @cond TURN_OFF_DOXYGEN
  17914. * Internal details not to be documented.
  17915. */
  17916. namespace internal {
  17917. template<typename, typename = void>
  17918. struct has_tuple_size_value: std::false_type {};
  17919. template<typename Type>
  17920. struct has_tuple_size_value<Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>: std::true_type {};
  17921. template<typename Type, std::size_t... Index>
  17922. [[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
  17923. return (is_equality_comparable<std::tuple_element_t<Index, Type>>::value && ...);
  17924. }
  17925. template<typename>
  17926. [[nodiscard]] constexpr bool maybe_equality_comparable(choice_t<0>) {
  17927. return true;
  17928. }
  17929. template<typename Type>
  17930. [[nodiscard]] constexpr auto maybe_equality_comparable(choice_t<1>) -> decltype(std::declval<typename Type::value_type>(), bool{}) {
  17931. if constexpr(is_iterator_v<Type>) {
  17932. return true;
  17933. } else if constexpr(std::is_same_v<typename Type::value_type, Type>) {
  17934. return maybe_equality_comparable<Type>(choice<0>);
  17935. } else {
  17936. return is_equality_comparable<typename Type::value_type>::value;
  17937. }
  17938. }
  17939. template<typename Type>
  17940. [[nodiscard]] constexpr std::enable_if_t<is_complete_v<std::tuple_size<std::remove_const_t<Type>>>, bool> maybe_equality_comparable(choice_t<2>) {
  17941. if constexpr(has_tuple_size_value<Type>::value) {
  17942. return unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
  17943. } else {
  17944. return maybe_equality_comparable<Type>(choice<1>);
  17945. }
  17946. }
  17947. } // namespace internal
  17948. /**
  17949. * Internal details not to be documented.
  17950. * @endcond
  17951. */
  17952. /*! @copydoc is_equality_comparable */
  17953. template<typename Type>
  17954. struct is_equality_comparable<Type, std::void_t<decltype(std::declval<Type>() == std::declval<Type>())>>
  17955. : std::bool_constant<internal::maybe_equality_comparable<Type>(choice<2>)> {};
  17956. /**
  17957. * @brief Helper variable template.
  17958. * @tparam Type The type to test.
  17959. */
  17960. template<typename Type>
  17961. inline constexpr bool is_equality_comparable_v = is_equality_comparable<Type>::value;
  17962. /**
  17963. * @brief Transcribes the constness of a type to another type.
  17964. * @tparam To The type to which to transcribe the constness.
  17965. * @tparam From The type from which to transcribe the constness.
  17966. */
  17967. template<typename To, typename From>
  17968. struct constness_as {
  17969. /*! @brief The type resulting from the transcription of the constness. */
  17970. using type = std::remove_const_t<To>;
  17971. };
  17972. /*! @copydoc constness_as */
  17973. template<typename To, typename From>
  17974. struct constness_as<To, const From> {
  17975. /*! @brief The type resulting from the transcription of the constness. */
  17976. using type = std::add_const_t<To>;
  17977. };
  17978. /**
  17979. * @brief Alias template to facilitate the transcription of the constness.
  17980. * @tparam To The type to which to transcribe the constness.
  17981. * @tparam From The type from which to transcribe the constness.
  17982. */
  17983. template<typename To, typename From>
  17984. using constness_as_t = typename constness_as<To, From>::type;
  17985. /**
  17986. * @brief Extracts the class of a non-static member object or function.
  17987. * @tparam Member A pointer to a non-static member object or function.
  17988. */
  17989. template<typename Member>
  17990. class member_class {
  17991. static_assert(std::is_member_pointer_v<Member>, "Invalid pointer type to non-static member object or function");
  17992. template<typename Class, typename Ret, typename... Args>
  17993. static Class *clazz(Ret (Class::*)(Args...));
  17994. template<typename Class, typename Ret, typename... Args>
  17995. static Class *clazz(Ret (Class::*)(Args...) const);
  17996. template<typename Class, typename Type>
  17997. static Class *clazz(Type Class::*);
  17998. public:
  17999. /*! @brief The class of the given non-static member object or function. */
  18000. using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
  18001. };
  18002. /**
  18003. * @brief Helper type.
  18004. * @tparam Member A pointer to a non-static member object or function.
  18005. */
  18006. template<typename Member>
  18007. using member_class_t = typename member_class<Member>::type;
  18008. } // namespace entt
  18009. #endif
  18010. // #include "fwd.hpp"
  18011. #ifndef ENTT_CONTAINER_FWD_HPP
  18012. #define ENTT_CONTAINER_FWD_HPP
  18013. #include <functional>
  18014. #include <memory>
  18015. namespace entt {
  18016. template<
  18017. typename Key,
  18018. typename Type,
  18019. typename = std::hash<Key>,
  18020. typename = std::equal_to<Key>,
  18021. typename = std::allocator<std::pair<const Key, Type>>>
  18022. class dense_map;
  18023. template<
  18024. typename Type,
  18025. typename = std::hash<Type>,
  18026. typename = std::equal_to<Type>,
  18027. typename = std::allocator<Type>>
  18028. class dense_set;
  18029. } // namespace entt
  18030. #endif
  18031. namespace entt {
  18032. /**
  18033. * @cond TURN_OFF_DOXYGEN
  18034. * Internal details not to be documented.
  18035. */
  18036. namespace internal {
  18037. template<typename Key, typename Type>
  18038. struct dense_map_node final {
  18039. using value_type = std::pair<Key, Type>;
  18040. template<typename... Args>
  18041. dense_map_node(const std::size_t pos, Args &&...args)
  18042. : next{pos},
  18043. element{std::forward<Args>(args)...} {}
  18044. template<typename Allocator, typename... Args>
  18045. dense_map_node(std::allocator_arg_t, const Allocator &allocator, const std::size_t pos, Args &&...args)
  18046. : next{pos},
  18047. element{entt::make_obj_using_allocator<value_type>(allocator, std::forward<Args>(args)...)} {}
  18048. template<typename Allocator>
  18049. dense_map_node(std::allocator_arg_t, const Allocator &allocator, const dense_map_node &other)
  18050. : next{other.next},
  18051. element{entt::make_obj_using_allocator<value_type>(allocator, other.element)} {}
  18052. template<typename Allocator>
  18053. dense_map_node(std::allocator_arg_t, const Allocator &allocator, dense_map_node &&other)
  18054. : next{other.next},
  18055. element{entt::make_obj_using_allocator<value_type>(allocator, std::move(other.element))} {}
  18056. std::size_t next;
  18057. value_type element;
  18058. };
  18059. template<typename It>
  18060. class dense_map_iterator final {
  18061. template<typename>
  18062. friend class dense_map_iterator;
  18063. using first_type = decltype(std::as_const(std::declval<It>()->element.first));
  18064. using second_type = decltype((std::declval<It>()->element.second));
  18065. public:
  18066. using value_type = std::pair<first_type, second_type>;
  18067. using pointer = input_iterator_pointer<value_type>;
  18068. using reference = value_type;
  18069. using difference_type = std::ptrdiff_t;
  18070. using iterator_category = std::input_iterator_tag;
  18071. dense_map_iterator() ENTT_NOEXCEPT
  18072. : it{} {}
  18073. dense_map_iterator(const It iter) ENTT_NOEXCEPT
  18074. : it{iter} {}
  18075. template<typename Other, typename = std::enable_if_t<!std::is_same_v<It, Other> && std::is_constructible_v<It, Other>>>
  18076. dense_map_iterator(const dense_map_iterator<Other> &other) ENTT_NOEXCEPT
  18077. : it{other.it} {}
  18078. dense_map_iterator &operator++() ENTT_NOEXCEPT {
  18079. return ++it, *this;
  18080. }
  18081. dense_map_iterator operator++(int) ENTT_NOEXCEPT {
  18082. dense_map_iterator orig = *this;
  18083. return ++(*this), orig;
  18084. }
  18085. dense_map_iterator &operator--() ENTT_NOEXCEPT {
  18086. return --it, *this;
  18087. }
  18088. dense_map_iterator operator--(int) ENTT_NOEXCEPT {
  18089. dense_map_iterator orig = *this;
  18090. return operator--(), orig;
  18091. }
  18092. dense_map_iterator &operator+=(const difference_type value) ENTT_NOEXCEPT {
  18093. it += value;
  18094. return *this;
  18095. }
  18096. dense_map_iterator operator+(const difference_type value) const ENTT_NOEXCEPT {
  18097. dense_map_iterator copy = *this;
  18098. return (copy += value);
  18099. }
  18100. dense_map_iterator &operator-=(const difference_type value) ENTT_NOEXCEPT {
  18101. return (*this += -value);
  18102. }
  18103. dense_map_iterator operator-(const difference_type value) const ENTT_NOEXCEPT {
  18104. return (*this + -value);
  18105. }
  18106. [[nodiscard]] reference operator[](const difference_type value) const ENTT_NOEXCEPT {
  18107. return {it[value].element.first, it[value].element.second};
  18108. }
  18109. [[nodiscard]] pointer operator->() const ENTT_NOEXCEPT {
  18110. return operator*();
  18111. }
  18112. [[nodiscard]] reference operator*() const ENTT_NOEXCEPT {
  18113. return {it->element.first, it->element.second};
  18114. }
  18115. template<typename ILhs, typename IRhs>
  18116. friend std::ptrdiff_t operator-(const dense_map_iterator<ILhs> &, const dense_map_iterator<IRhs> &) ENTT_NOEXCEPT;
  18117. template<typename ILhs, typename IRhs>
  18118. friend bool operator==(const dense_map_iterator<ILhs> &, const dense_map_iterator<IRhs> &) ENTT_NOEXCEPT;
  18119. template<typename ILhs, typename IRhs>
  18120. friend bool operator<(const dense_map_iterator<ILhs> &, const dense_map_iterator<IRhs> &) ENTT_NOEXCEPT;
  18121. private:
  18122. It it;
  18123. };
  18124. template<typename ILhs, typename IRhs>
  18125. [[nodiscard]] std::ptrdiff_t operator-(const dense_map_iterator<ILhs> &lhs, const dense_map_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  18126. return lhs.it - rhs.it;
  18127. }
  18128. template<typename ILhs, typename IRhs>
  18129. [[nodiscard]] bool operator==(const dense_map_iterator<ILhs> &lhs, const dense_map_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  18130. return lhs.it == rhs.it;
  18131. }
  18132. template<typename ILhs, typename IRhs>
  18133. [[nodiscard]] bool operator!=(const dense_map_iterator<ILhs> &lhs, const dense_map_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  18134. return !(lhs == rhs);
  18135. }
  18136. template<typename ILhs, typename IRhs>
  18137. [[nodiscard]] bool operator<(const dense_map_iterator<ILhs> &lhs, const dense_map_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  18138. return lhs.it < rhs.it;
  18139. }
  18140. template<typename ILhs, typename IRhs>
  18141. [[nodiscard]] bool operator>(const dense_map_iterator<ILhs> &lhs, const dense_map_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  18142. return rhs < lhs;
  18143. }
  18144. template<typename ILhs, typename IRhs>
  18145. [[nodiscard]] bool operator<=(const dense_map_iterator<ILhs> &lhs, const dense_map_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  18146. return !(lhs > rhs);
  18147. }
  18148. template<typename ILhs, typename IRhs>
  18149. [[nodiscard]] bool operator>=(const dense_map_iterator<ILhs> &lhs, const dense_map_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  18150. return !(lhs < rhs);
  18151. }
  18152. template<typename It>
  18153. class dense_map_local_iterator final {
  18154. template<typename>
  18155. friend class dense_map_local_iterator;
  18156. using first_type = decltype(std::as_const(std::declval<It>()->element.first));
  18157. using second_type = decltype((std::declval<It>()->element.second));
  18158. public:
  18159. using value_type = std::pair<first_type, second_type>;
  18160. using pointer = input_iterator_pointer<value_type>;
  18161. using reference = value_type;
  18162. using difference_type = std::ptrdiff_t;
  18163. using iterator_category = std::input_iterator_tag;
  18164. dense_map_local_iterator() ENTT_NOEXCEPT
  18165. : it{},
  18166. offset{} {}
  18167. dense_map_local_iterator(It iter, const std::size_t pos) ENTT_NOEXCEPT
  18168. : it{iter},
  18169. offset{pos} {}
  18170. template<typename Other, typename = std::enable_if_t<!std::is_same_v<It, Other> && std::is_constructible_v<It, Other>>>
  18171. dense_map_local_iterator(const dense_map_local_iterator<Other> &other) ENTT_NOEXCEPT
  18172. : it{other.it},
  18173. offset{other.offset} {}
  18174. dense_map_local_iterator &operator++() ENTT_NOEXCEPT {
  18175. return offset = it[offset].next, *this;
  18176. }
  18177. dense_map_local_iterator operator++(int) ENTT_NOEXCEPT {
  18178. dense_map_local_iterator orig = *this;
  18179. return ++(*this), orig;
  18180. }
  18181. [[nodiscard]] pointer operator->() const ENTT_NOEXCEPT {
  18182. return operator*();
  18183. }
  18184. [[nodiscard]] reference operator*() const ENTT_NOEXCEPT {
  18185. return {it[offset].element.first, it[offset].element.second};
  18186. }
  18187. [[nodiscard]] std::size_t index() const ENTT_NOEXCEPT {
  18188. return offset;
  18189. }
  18190. private:
  18191. It it;
  18192. std::size_t offset;
  18193. };
  18194. template<typename ILhs, typename IRhs>
  18195. [[nodiscard]] bool operator==(const dense_map_local_iterator<ILhs> &lhs, const dense_map_local_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  18196. return lhs.index() == rhs.index();
  18197. }
  18198. template<typename ILhs, typename IRhs>
  18199. [[nodiscard]] bool operator!=(const dense_map_local_iterator<ILhs> &lhs, const dense_map_local_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  18200. return !(lhs == rhs);
  18201. }
  18202. } // namespace internal
  18203. /**
  18204. * Internal details not to be documented.
  18205. * @endcond
  18206. */
  18207. /**
  18208. * @brief Associative container for key-value pairs with unique keys.
  18209. *
  18210. * Internally, elements are organized into buckets. Which bucket an element is
  18211. * placed into depends entirely on the hash of its key. Keys with the same hash
  18212. * code appear in the same bucket.
  18213. *
  18214. * @tparam Key Key type of the associative container.
  18215. * @tparam Type Mapped type of the associative container.
  18216. * @tparam Hash Type of function to use to hash the keys.
  18217. * @tparam KeyEqual Type of function to use to compare the keys for equality.
  18218. * @tparam Allocator Type of allocator used to manage memory and elements.
  18219. */
  18220. template<typename Key, typename Type, typename Hash, typename KeyEqual, typename Allocator>
  18221. class dense_map {
  18222. static constexpr float default_threshold = 0.875f;
  18223. static constexpr std::size_t minimum_capacity = 8u;
  18224. using node_type = internal::dense_map_node<Key, Type>;
  18225. using alloc_traits = typename std::allocator_traits<Allocator>;
  18226. static_assert(std::is_same_v<typename alloc_traits::value_type, std::pair<const Key, Type>>, "Invalid value type");
  18227. using sparse_container_type = std::vector<std::size_t, typename alloc_traits::template rebind_alloc<std::size_t>>;
  18228. using packed_container_type = std::vector<node_type, typename alloc_traits::template rebind_alloc<node_type>>;
  18229. template<typename Other>
  18230. [[nodiscard]] std::size_t key_to_bucket(const Other &key) const ENTT_NOEXCEPT {
  18231. return fast_mod(sparse.second()(key), bucket_count());
  18232. }
  18233. template<typename Other>
  18234. [[nodiscard]] auto constrained_find(const Other &key, std::size_t bucket) {
  18235. for(auto it = begin(bucket), last = end(bucket); it != last; ++it) {
  18236. if(packed.second()(it->first, key)) {
  18237. return begin() + static_cast<typename iterator::difference_type>(it.index());
  18238. }
  18239. }
  18240. return end();
  18241. }
  18242. template<typename Other>
  18243. [[nodiscard]] auto constrained_find(const Other &key, std::size_t bucket) const {
  18244. for(auto it = cbegin(bucket), last = cend(bucket); it != last; ++it) {
  18245. if(packed.second()(it->first, key)) {
  18246. return cbegin() + static_cast<typename iterator::difference_type>(it.index());
  18247. }
  18248. }
  18249. return cend();
  18250. }
  18251. template<typename Other, typename... Args>
  18252. [[nodiscard]] auto insert_or_do_nothing(Other &&key, Args &&...args) {
  18253. const auto index = key_to_bucket(key);
  18254. if(auto it = constrained_find(key, index); it != end()) {
  18255. return std::make_pair(it, false);
  18256. }
  18257. 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)...));
  18258. sparse.first()[index] = packed.first().size() - 1u;
  18259. rehash_if_required();
  18260. return std::make_pair(--end(), true);
  18261. }
  18262. template<typename Other, typename Arg>
  18263. [[nodiscard]] auto insert_or_overwrite(Other &&key, Arg &&value) {
  18264. const auto index = key_to_bucket(key);
  18265. if(auto it = constrained_find(key, index); it != end()) {
  18266. it->second = std::forward<Arg>(value);
  18267. return std::make_pair(it, false);
  18268. }
  18269. packed.first().emplace_back(sparse.first()[index], std::forward<Other>(key), std::forward<Arg>(value));
  18270. sparse.first()[index] = packed.first().size() - 1u;
  18271. rehash_if_required();
  18272. return std::make_pair(--end(), true);
  18273. }
  18274. void move_and_pop(const std::size_t pos) {
  18275. if(const auto last = size() - 1u; pos != last) {
  18276. packed.first()[pos] = std::move(packed.first().back());
  18277. size_type *curr = sparse.first().data() + key_to_bucket(packed.first().back().element.first);
  18278. for(; *curr != last; curr = &packed.first()[*curr].next) {}
  18279. *curr = pos;
  18280. }
  18281. packed.first().pop_back();
  18282. }
  18283. void rehash_if_required() {
  18284. if(size() > (bucket_count() * max_load_factor())) {
  18285. rehash(bucket_count() * 2u);
  18286. }
  18287. }
  18288. public:
  18289. /*! @brief Key type of the container. */
  18290. using key_type = Key;
  18291. /*! @brief Mapped type of the container. */
  18292. using mapped_type = Type;
  18293. /*! @brief Key-value type of the container. */
  18294. using value_type = std::pair<const Key, Type>;
  18295. /*! @brief Unsigned integer type. */
  18296. using size_type = std::size_t;
  18297. /*! @brief Type of function to use to hash the keys. */
  18298. using hasher = Hash;
  18299. /*! @brief Type of function to use to compare the keys for equality. */
  18300. using key_equal = KeyEqual;
  18301. /*! @brief Allocator type. */
  18302. using allocator_type = Allocator;
  18303. /*! @brief Input iterator type. */
  18304. using iterator = internal::dense_map_iterator<typename packed_container_type::iterator>;
  18305. /*! @brief Constant input iterator type. */
  18306. using const_iterator = internal::dense_map_iterator<typename packed_container_type::const_iterator>;
  18307. /*! @brief Input iterator type. */
  18308. using local_iterator = internal::dense_map_local_iterator<typename packed_container_type::iterator>;
  18309. /*! @brief Constant input iterator type. */
  18310. using const_local_iterator = internal::dense_map_local_iterator<typename packed_container_type::const_iterator>;
  18311. /*! @brief Default constructor. */
  18312. dense_map()
  18313. : dense_map(minimum_capacity) {}
  18314. /**
  18315. * @brief Constructs an empty container with a given allocator.
  18316. * @param allocator The allocator to use.
  18317. */
  18318. explicit dense_map(const allocator_type &allocator)
  18319. : dense_map{minimum_capacity, hasher{}, key_equal{}, allocator} {}
  18320. /**
  18321. * @brief Constructs an empty container with a given allocator and user
  18322. * supplied minimal number of buckets.
  18323. * @param bucket_count Minimal number of buckets.
  18324. * @param allocator The allocator to use.
  18325. */
  18326. dense_map(const size_type bucket_count, const allocator_type &allocator)
  18327. : dense_map{bucket_count, hasher{}, key_equal{}, allocator} {}
  18328. /**
  18329. * @brief Constructs an empty container with a given allocator, hash
  18330. * function and user supplied minimal number of buckets.
  18331. * @param bucket_count Minimal number of buckets.
  18332. * @param hash Hash function to use.
  18333. * @param allocator The allocator to use.
  18334. */
  18335. dense_map(const size_type bucket_count, const hasher &hash, const allocator_type &allocator)
  18336. : dense_map{bucket_count, hash, key_equal{}, allocator} {}
  18337. /**
  18338. * @brief Constructs an empty container with a given allocator, hash
  18339. * function, compare function and user supplied minimal number of buckets.
  18340. * @param bucket_count Minimal number of buckets.
  18341. * @param hash Hash function to use.
  18342. * @param equal Compare function to use.
  18343. * @param allocator The allocator to use.
  18344. */
  18345. explicit dense_map(const size_type bucket_count, const hasher &hash = hasher{}, const key_equal &equal = key_equal{}, const allocator_type &allocator = allocator_type{})
  18346. : sparse{allocator, hash},
  18347. packed{allocator, equal},
  18348. threshold{default_threshold} {
  18349. rehash(bucket_count);
  18350. }
  18351. /*! @brief Default copy constructor. */
  18352. dense_map(const dense_map &) = default;
  18353. /**
  18354. * @brief Allocator-extended copy constructor.
  18355. * @param other The instance to copy from.
  18356. * @param allocator The allocator to use.
  18357. */
  18358. dense_map(const dense_map &other, const allocator_type &allocator)
  18359. : sparse{std::piecewise_construct, std::forward_as_tuple(other.sparse.first(), allocator), std::forward_as_tuple(other.sparse.second())},
  18360. packed{std::piecewise_construct, std::forward_as_tuple(other.packed.first(), allocator), std::forward_as_tuple(other.packed.second())},
  18361. threshold{other.threshold} {}
  18362. /*! @brief Default move constructor. */
  18363. dense_map(dense_map &&) = default;
  18364. /**
  18365. * @brief Allocator-extended move constructor.
  18366. * @param other The instance to move from.
  18367. * @param allocator The allocator to use.
  18368. */
  18369. dense_map(dense_map &&other, const allocator_type &allocator)
  18370. : sparse{std::piecewise_construct, std::forward_as_tuple(std::move(other.sparse.first()), allocator), std::forward_as_tuple(std::move(other.sparse.second()))},
  18371. packed{std::piecewise_construct, std::forward_as_tuple(std::move(other.packed.first()), allocator), std::forward_as_tuple(std::move(other.packed.second()))},
  18372. threshold{other.threshold} {}
  18373. /**
  18374. * @brief Default copy assignment operator.
  18375. * @return This container.
  18376. */
  18377. dense_map &operator=(const dense_map &) = default;
  18378. /**
  18379. * @brief Default move assignment operator.
  18380. * @return This container.
  18381. */
  18382. dense_map &operator=(dense_map &&) = default;
  18383. /**
  18384. * @brief Returns the associated allocator.
  18385. * @return The associated allocator.
  18386. */
  18387. [[nodiscard]] constexpr allocator_type get_allocator() const ENTT_NOEXCEPT {
  18388. return sparse.first().get_allocator();
  18389. }
  18390. /**
  18391. * @brief Returns an iterator to the beginning.
  18392. *
  18393. * The returned iterator points to the first instance of the internal array.
  18394. * If the array is empty, the returned iterator will be equal to `end()`.
  18395. *
  18396. * @return An iterator to the first instance of the internal array.
  18397. */
  18398. [[nodiscard]] const_iterator cbegin() const ENTT_NOEXCEPT {
  18399. return packed.first().begin();
  18400. }
  18401. /*! @copydoc cbegin */
  18402. [[nodiscard]] const_iterator begin() const ENTT_NOEXCEPT {
  18403. return cbegin();
  18404. }
  18405. /*! @copydoc begin */
  18406. [[nodiscard]] iterator begin() ENTT_NOEXCEPT {
  18407. return packed.first().begin();
  18408. }
  18409. /**
  18410. * @brief Returns an iterator to the end.
  18411. *
  18412. * The returned iterator points to the element following the last instance
  18413. * of the internal array. Attempting to dereference the returned iterator
  18414. * results in undefined behavior.
  18415. *
  18416. * @return An iterator to the element following the last instance of the
  18417. * internal array.
  18418. */
  18419. [[nodiscard]] const_iterator cend() const ENTT_NOEXCEPT {
  18420. return packed.first().end();
  18421. }
  18422. /*! @copydoc cend */
  18423. [[nodiscard]] const_iterator end() const ENTT_NOEXCEPT {
  18424. return cend();
  18425. }
  18426. /*! @copydoc end */
  18427. [[nodiscard]] iterator end() ENTT_NOEXCEPT {
  18428. return packed.first().end();
  18429. }
  18430. /**
  18431. * @brief Checks whether a container is empty.
  18432. * @return True if the container is empty, false otherwise.
  18433. */
  18434. [[nodiscard]] bool empty() const ENTT_NOEXCEPT {
  18435. return packed.first().empty();
  18436. }
  18437. /**
  18438. * @brief Returns the number of elements in a container.
  18439. * @return Number of elements in a container.
  18440. */
  18441. [[nodiscard]] size_type size() const ENTT_NOEXCEPT {
  18442. return packed.first().size();
  18443. }
  18444. /*! @brief Clears the container. */
  18445. void clear() ENTT_NOEXCEPT {
  18446. sparse.first().clear();
  18447. packed.first().clear();
  18448. rehash(0u);
  18449. }
  18450. /**
  18451. * @brief Inserts an element into the container, if the key does not exist.
  18452. * @param value A key-value pair eventually convertible to the value type.
  18453. * @return A pair consisting of an iterator to the inserted element (or to
  18454. * the element that prevented the insertion) and a bool denoting whether the
  18455. * insertion took place.
  18456. */
  18457. std::pair<iterator, bool> insert(const value_type &value) {
  18458. return insert_or_do_nothing(value.first, value.second);
  18459. }
  18460. /*! @copydoc insert */
  18461. std::pair<iterator, bool> insert(value_type &&value) {
  18462. return insert_or_do_nothing(std::move(value.first), std::move(value.second));
  18463. }
  18464. /**
  18465. * @copydoc insert
  18466. * @tparam Arg Type of the key-value pair to insert into the container.
  18467. */
  18468. template<typename Arg>
  18469. std::enable_if_t<std::is_constructible_v<value_type, Arg &&>, std::pair<iterator, bool>>
  18470. insert(Arg &&value) {
  18471. return insert_or_do_nothing(std::forward<Arg>(value).first, std::forward<Arg>(value).second);
  18472. }
  18473. /**
  18474. * @brief Inserts elements into the container, if their keys do not exist.
  18475. * @tparam It Type of input iterator.
  18476. * @param first An iterator to the first element of the range of elements.
  18477. * @param last An iterator past the last element of the range of elements.
  18478. */
  18479. template<typename It>
  18480. void insert(It first, It last) {
  18481. for(; first != last; ++first) {
  18482. insert(*first);
  18483. }
  18484. }
  18485. /**
  18486. * @brief Inserts an element into the container or assigns to the current
  18487. * element if the key already exists.
  18488. * @tparam Arg Type of the value to insert or assign.
  18489. * @param key A key used both to look up and to insert if not found.
  18490. * @param value A value to insert or assign.
  18491. * @return A pair consisting of an iterator to the element and a bool
  18492. * denoting whether the insertion took place.
  18493. */
  18494. template<typename Arg>
  18495. std::pair<iterator, bool> insert_or_assign(const key_type &key, Arg &&value) {
  18496. return insert_or_overwrite(key, std::forward<Arg>(value));
  18497. }
  18498. /*! @copydoc insert_or_assign */
  18499. template<typename Arg>
  18500. std::pair<iterator, bool> insert_or_assign(key_type &&key, Arg &&value) {
  18501. return insert_or_overwrite(std::move(key), std::forward<Arg>(value));
  18502. }
  18503. /**
  18504. * @brief Constructs an element in-place, if the key does not exist.
  18505. *
  18506. * The element is also constructed when the container already has the key,
  18507. * in which case the newly constructed object is destroyed immediately.
  18508. *
  18509. * @tparam Args Types of arguments to forward to the constructor of the
  18510. * element.
  18511. * @param args Arguments to forward to the constructor of the element.
  18512. * @return A pair consisting of an iterator to the inserted element (or to
  18513. * the element that prevented the insertion) and a bool denoting whether the
  18514. * insertion took place.
  18515. */
  18516. template<typename... Args>
  18517. std::pair<iterator, bool> emplace([[maybe_unused]] Args &&...args) {
  18518. if constexpr(sizeof...(Args) == 0u) {
  18519. return insert_or_do_nothing(key_type{});
  18520. } else if constexpr(sizeof...(Args) == 1u) {
  18521. return insert_or_do_nothing(std::forward<Args>(args).first..., std::forward<Args>(args).second...);
  18522. } else if constexpr(sizeof...(Args) == 2u) {
  18523. return insert_or_do_nothing(std::forward<Args>(args)...);
  18524. } else {
  18525. auto &node = packed.first().emplace_back(packed.first().size(), std::forward<Args>(args)...);
  18526. const auto index = key_to_bucket(node.element.first);
  18527. if(auto it = constrained_find(node.element.first, index); it != end()) {
  18528. packed.first().pop_back();
  18529. return std::make_pair(it, false);
  18530. }
  18531. std::swap(node.next, sparse.first()[index]);
  18532. rehash_if_required();
  18533. return std::make_pair(--end(), true);
  18534. }
  18535. }
  18536. /**
  18537. * @brief Inserts in-place if the key does not exist, does nothing if the
  18538. * key exists.
  18539. * @tparam Args Types of arguments to forward to the constructor of the
  18540. * element.
  18541. * @param key A key used both to look up and to insert if not found.
  18542. * @param args Arguments to forward to the constructor of the element.
  18543. * @return A pair consisting of an iterator to the inserted element (or to
  18544. * the element that prevented the insertion) and a bool denoting whether the
  18545. * insertion took place.
  18546. */
  18547. template<typename... Args>
  18548. std::pair<iterator, bool> try_emplace(const key_type &key, Args &&...args) {
  18549. return insert_or_do_nothing(key, std::forward<Args>(args)...);
  18550. }
  18551. /*! @copydoc try_emplace */
  18552. template<typename... Args>
  18553. std::pair<iterator, bool> try_emplace(key_type &&key, Args &&...args) {
  18554. return insert_or_do_nothing(std::move(key), std::forward<Args>(args)...);
  18555. }
  18556. /**
  18557. * @brief Removes an element from a given position.
  18558. * @param pos An iterator to the element to remove.
  18559. * @return An iterator following the removed element.
  18560. */
  18561. iterator erase(const_iterator pos) {
  18562. const auto diff = pos - cbegin();
  18563. erase(pos->first);
  18564. return begin() + diff;
  18565. }
  18566. /**
  18567. * @brief Removes the given elements from a container.
  18568. * @param first An iterator to the first element of the range of elements.
  18569. * @param last An iterator past the last element of the range of elements.
  18570. * @return An iterator following the last removed element.
  18571. */
  18572. iterator erase(const_iterator first, const_iterator last) {
  18573. const auto dist = first - cbegin();
  18574. for(auto from = last - cbegin(); from != dist; --from) {
  18575. erase(packed.first()[from - 1u].element.first);
  18576. }
  18577. return (begin() + dist);
  18578. }
  18579. /**
  18580. * @brief Removes the element associated with a given key.
  18581. * @param key A key value of an element to remove.
  18582. * @return Number of elements removed (either 0 or 1).
  18583. */
  18584. size_type erase(const key_type &key) {
  18585. for(size_type *curr = sparse.first().data() + key_to_bucket(key); *curr != (std::numeric_limits<size_type>::max)(); curr = &packed.first()[*curr].next) {
  18586. if(packed.second()(packed.first()[*curr].element.first, key)) {
  18587. const auto index = *curr;
  18588. *curr = packed.first()[*curr].next;
  18589. move_and_pop(index);
  18590. return 1u;
  18591. }
  18592. }
  18593. return 0u;
  18594. }
  18595. /**
  18596. * @brief Exchanges the contents with those of a given container.
  18597. * @param other Container to exchange the content with.
  18598. */
  18599. void swap(dense_map &other) {
  18600. using std::swap;
  18601. swap(sparse, other.sparse);
  18602. swap(packed, other.packed);
  18603. swap(threshold, other.threshold);
  18604. }
  18605. /**
  18606. * @brief Accesses a given element with bounds checking.
  18607. * @param key A key of an element to find.
  18608. * @return A reference to the mapped value of the requested element.
  18609. */
  18610. [[nodiscard]] mapped_type &at(const key_type &key) {
  18611. auto it = find(key);
  18612. ENTT_ASSERT(it != end(), "Invalid key");
  18613. return it->second;
  18614. }
  18615. /*! @copydoc at */
  18616. [[nodiscard]] const mapped_type &at(const key_type &key) const {
  18617. auto it = find(key);
  18618. ENTT_ASSERT(it != cend(), "Invalid key");
  18619. return it->second;
  18620. }
  18621. /**
  18622. * @brief Accesses or inserts a given element.
  18623. * @param key A key of an element to find or insert.
  18624. * @return A reference to the mapped value of the requested element.
  18625. */
  18626. [[nodiscard]] mapped_type &operator[](const key_type &key) {
  18627. return insert_or_do_nothing(key).first->second;
  18628. }
  18629. /**
  18630. * @brief Accesses or inserts a given element.
  18631. * @param key A key of an element to find or insert.
  18632. * @return A reference to the mapped value of the requested element.
  18633. */
  18634. [[nodiscard]] mapped_type &operator[](key_type &&key) {
  18635. return insert_or_do_nothing(std::move(key)).first->second;
  18636. }
  18637. /**
  18638. * @brief Finds an element with a given key.
  18639. * @param key Key value of an element to search for.
  18640. * @return An iterator to an element with the given key. If no such element
  18641. * is found, a past-the-end iterator is returned.
  18642. */
  18643. [[nodiscard]] iterator find(const key_type &key) {
  18644. return constrained_find(key, key_to_bucket(key));
  18645. }
  18646. /*! @copydoc find */
  18647. [[nodiscard]] const_iterator find(const key_type &key) const {
  18648. return constrained_find(key, key_to_bucket(key));
  18649. }
  18650. /**
  18651. * @brief Finds an element with a key that compares _equivalent_ to a given
  18652. * value.
  18653. * @tparam Other Type of the key value of an element to search for.
  18654. * @param key Key value of an element to search for.
  18655. * @return An iterator to an element with the given key. If no such element
  18656. * is found, a past-the-end iterator is returned.
  18657. */
  18658. template<typename Other>
  18659. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, iterator>>
  18660. find(const Other &key) {
  18661. return constrained_find(key, key_to_bucket(key));
  18662. }
  18663. /*! @copydoc find */
  18664. template<typename Other>
  18665. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, const_iterator>>
  18666. find(const Other &key) const {
  18667. return constrained_find(key, key_to_bucket(key));
  18668. }
  18669. /**
  18670. * @brief Checks if the container contains an element with a given key.
  18671. * @param key Key value of an element to search for.
  18672. * @return True if there is such an element, false otherwise.
  18673. */
  18674. [[nodiscard]] bool contains(const key_type &key) const {
  18675. return (find(key) != cend());
  18676. }
  18677. /**
  18678. * @brief Checks if the container contains an element with a key that
  18679. * compares _equivalent_ to a given value.
  18680. * @tparam Other Type of the key value of an element to search for.
  18681. * @param key Key value of an element to search for.
  18682. * @return True if there is such an element, false otherwise.
  18683. */
  18684. template<typename Other>
  18685. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, bool>>
  18686. contains(const Other &key) const {
  18687. return (find(key) != cend());
  18688. }
  18689. /**
  18690. * @brief Returns an iterator to the beginning of a given bucket.
  18691. * @param index An index of a bucket to access.
  18692. * @return An iterator to the beginning of the given bucket.
  18693. */
  18694. [[nodiscard]] const_local_iterator cbegin(const size_type index) const {
  18695. return {packed.first().begin(), sparse.first()[index]};
  18696. }
  18697. /**
  18698. * @brief Returns an iterator to the beginning of a given bucket.
  18699. * @param index An index of a bucket to access.
  18700. * @return An iterator to the beginning of the given bucket.
  18701. */
  18702. [[nodiscard]] const_local_iterator begin(const size_type index) const {
  18703. return cbegin(index);
  18704. }
  18705. /**
  18706. * @brief Returns an iterator to the beginning of a given bucket.
  18707. * @param index An index of a bucket to access.
  18708. * @return An iterator to the beginning of the given bucket.
  18709. */
  18710. [[nodiscard]] local_iterator begin(const size_type index) {
  18711. return {packed.first().begin(), sparse.first()[index]};
  18712. }
  18713. /**
  18714. * @brief Returns an iterator to the end of a given bucket.
  18715. * @param index An index of a bucket to access.
  18716. * @return An iterator to the end of the given bucket.
  18717. */
  18718. [[nodiscard]] const_local_iterator cend([[maybe_unused]] const size_type index) const {
  18719. return {packed.first().begin(), (std::numeric_limits<size_type>::max)()};
  18720. }
  18721. /**
  18722. * @brief Returns an iterator to the end of a given bucket.
  18723. * @param index An index of a bucket to access.
  18724. * @return An iterator to the end of the given bucket.
  18725. */
  18726. [[nodiscard]] const_local_iterator end([[maybe_unused]] const size_type index) const {
  18727. return cend(index);
  18728. }
  18729. /**
  18730. * @brief Returns an iterator to the end of a given bucket.
  18731. * @param index An index of a bucket to access.
  18732. * @return An iterator to the end of the given bucket.
  18733. */
  18734. [[nodiscard]] local_iterator end([[maybe_unused]] const size_type index) {
  18735. return {packed.first().begin(), (std::numeric_limits<size_type>::max)()};
  18736. }
  18737. /**
  18738. * @brief Returns the number of buckets.
  18739. * @return The number of buckets.
  18740. */
  18741. [[nodiscard]] size_type bucket_count() const {
  18742. return sparse.first().size();
  18743. }
  18744. /**
  18745. * @brief Returns the maximum number of buckets.
  18746. * @return The maximum number of buckets.
  18747. */
  18748. [[nodiscard]] size_type max_bucket_count() const {
  18749. return sparse.first().max_size();
  18750. }
  18751. /**
  18752. * @brief Returns the number of elements in a given bucket.
  18753. * @param index The index of the bucket to examine.
  18754. * @return The number of elements in the given bucket.
  18755. */
  18756. [[nodiscard]] size_type bucket_size(const size_type index) const {
  18757. return static_cast<size_type>(std::distance(begin(index), end(index)));
  18758. }
  18759. /**
  18760. * @brief Returns the bucket for a given key.
  18761. * @param key The value of the key to examine.
  18762. * @return The bucket for the given key.
  18763. */
  18764. [[nodiscard]] size_type bucket(const key_type &key) const {
  18765. return key_to_bucket(key);
  18766. }
  18767. /**
  18768. * @brief Returns the average number of elements per bucket.
  18769. * @return The average number of elements per bucket.
  18770. */
  18771. [[nodiscard]] float load_factor() const {
  18772. return size() / static_cast<float>(bucket_count());
  18773. }
  18774. /**
  18775. * @brief Returns the maximum average number of elements per bucket.
  18776. * @return The maximum average number of elements per bucket.
  18777. */
  18778. [[nodiscard]] float max_load_factor() const {
  18779. return threshold;
  18780. }
  18781. /**
  18782. * @brief Sets the desired maximum average number of elements per bucket.
  18783. * @param value A desired maximum average number of elements per bucket.
  18784. */
  18785. void max_load_factor(const float value) {
  18786. ENTT_ASSERT(value > 0.f, "Invalid load factor");
  18787. threshold = value;
  18788. rehash(0u);
  18789. }
  18790. /**
  18791. * @brief Reserves at least the specified number of buckets and regenerates
  18792. * the hash table.
  18793. * @param count New number of buckets.
  18794. */
  18795. void rehash(const size_type count) {
  18796. auto value = (std::max)(count, minimum_capacity);
  18797. value = (std::max)(value, static_cast<size_type>(size() / max_load_factor()));
  18798. if(const auto sz = next_power_of_two(value); sz != bucket_count()) {
  18799. sparse.first().resize(sz);
  18800. std::fill(sparse.first().begin(), sparse.first().end(), (std::numeric_limits<size_type>::max)());
  18801. for(size_type pos{}, last = size(); pos < last; ++pos) {
  18802. const auto index = key_to_bucket(packed.first()[pos].element.first);
  18803. packed.first()[pos].next = std::exchange(sparse.first()[index], pos);
  18804. }
  18805. }
  18806. }
  18807. /**
  18808. * @brief Reserves space for at least the specified number of elements and
  18809. * regenerates the hash table.
  18810. * @param count New number of elements.
  18811. */
  18812. void reserve(const size_type count) {
  18813. packed.first().reserve(count);
  18814. rehash(static_cast<size_type>(std::ceil(count / max_load_factor())));
  18815. }
  18816. /**
  18817. * @brief Returns the function used to hash the keys.
  18818. * @return The function used to hash the keys.
  18819. */
  18820. [[nodiscard]] hasher hash_function() const {
  18821. return sparse.second();
  18822. }
  18823. /**
  18824. * @brief Returns the function used to compare keys for equality.
  18825. * @return The function used to compare keys for equality.
  18826. */
  18827. [[nodiscard]] key_equal key_eq() const {
  18828. return packed.second();
  18829. }
  18830. private:
  18831. compressed_pair<sparse_container_type, hasher> sparse;
  18832. compressed_pair<packed_container_type, key_equal> packed;
  18833. float threshold;
  18834. };
  18835. } // namespace entt
  18836. /**
  18837. * @cond TURN_OFF_DOXYGEN
  18838. * Internal details not to be documented.
  18839. */
  18840. namespace std {
  18841. template<typename Key, typename Value, typename Allocator>
  18842. struct uses_allocator<entt::internal::dense_map_node<Key, Value>, Allocator>
  18843. : std::true_type {};
  18844. } // namespace std
  18845. /**
  18846. * Internal details not to be documented.
  18847. * @endcond
  18848. */
  18849. #endif
  18850. // #include "../core/algorithm.hpp"
  18851. // #include "../core/any.hpp"
  18852. // #include "../core/fwd.hpp"
  18853. // #include "../core/iterator.hpp"
  18854. // #include "../core/type_info.hpp"
  18855. // #include "../core/type_traits.hpp"
  18856. // #include "../core/utility.hpp"
  18857. #ifndef ENTT_CORE_UTILITY_HPP
  18858. #define ENTT_CORE_UTILITY_HPP
  18859. #include <utility>
  18860. // #include "../config/config.h"
  18861. namespace entt {
  18862. /*! @brief Identity function object (waiting for C++20). */
  18863. struct identity {
  18864. /*! @brief Indicates that this is a transparent function object. */
  18865. using is_transparent = void;
  18866. /**
  18867. * @brief Returns its argument unchanged.
  18868. * @tparam Type Type of the argument.
  18869. * @param value The actual argument.
  18870. * @return The submitted value as-is.
  18871. */
  18872. template<class Type>
  18873. [[nodiscard]] constexpr Type &&operator()(Type &&value) const ENTT_NOEXCEPT {
  18874. return std::forward<Type>(value);
  18875. }
  18876. };
  18877. /**
  18878. * @brief Constant utility to disambiguate overloaded members of a class.
  18879. * @tparam Type Type of the desired overload.
  18880. * @tparam Class Type of class to which the member belongs.
  18881. * @param member A valid pointer to a member.
  18882. * @return Pointer to the member.
  18883. */
  18884. template<typename Type, typename Class>
  18885. [[nodiscard]] constexpr auto overload(Type Class::*member) ENTT_NOEXCEPT {
  18886. return member;
  18887. }
  18888. /**
  18889. * @brief Constant utility to disambiguate overloaded functions.
  18890. * @tparam Func Function type of the desired overload.
  18891. * @param func A valid pointer to a function.
  18892. * @return Pointer to the function.
  18893. */
  18894. template<typename Func>
  18895. [[nodiscard]] constexpr auto overload(Func *func) ENTT_NOEXCEPT {
  18896. return func;
  18897. }
  18898. /**
  18899. * @brief Helper type for visitors.
  18900. * @tparam Func Types of function objects.
  18901. */
  18902. template<class... Func>
  18903. struct overloaded: Func... {
  18904. using Func::operator()...;
  18905. };
  18906. /**
  18907. * @brief Deduction guide.
  18908. * @tparam Func Types of function objects.
  18909. */
  18910. template<class... Func>
  18911. overloaded(Func...) -> overloaded<Func...>;
  18912. /**
  18913. * @brief Basic implementation of a y-combinator.
  18914. * @tparam Func Type of a potentially recursive function.
  18915. */
  18916. template<class Func>
  18917. struct y_combinator {
  18918. /**
  18919. * @brief Constructs a y-combinator from a given function.
  18920. * @param recursive A potentially recursive function.
  18921. */
  18922. y_combinator(Func recursive)
  18923. : func{std::move(recursive)} {}
  18924. /**
  18925. * @brief Invokes a y-combinator and therefore its underlying function.
  18926. * @tparam Args Types of arguments to use to invoke the underlying function.
  18927. * @param args Parameters to use to invoke the underlying function.
  18928. * @return Return value of the underlying function, if any.
  18929. */
  18930. template<class... Args>
  18931. decltype(auto) operator()(Args &&...args) const {
  18932. return func(*this, std::forward<Args>(args)...);
  18933. }
  18934. /*! @copydoc operator()() */
  18935. template<class... Args>
  18936. decltype(auto) operator()(Args &&...args) {
  18937. return func(*this, std::forward<Args>(args)...);
  18938. }
  18939. private:
  18940. Func func;
  18941. };
  18942. } // namespace entt
  18943. #endif
  18944. // #include "component.hpp"
  18945. // #include "entity.hpp"
  18946. // #include "fwd.hpp"
  18947. // #include "group.hpp"
  18948. #ifndef ENTT_ENTITY_GROUP_HPP
  18949. #define ENTT_ENTITY_GROUP_HPP
  18950. #include <tuple>
  18951. #include <type_traits>
  18952. #include <utility>
  18953. // #include "../config/config.h"
  18954. // #include "../core/iterator.hpp"
  18955. // #include "../core/type_traits.hpp"
  18956. // #include "component.hpp"
  18957. // #include "entity.hpp"
  18958. // #include "fwd.hpp"
  18959. // #include "sparse_set.hpp"
  18960. // #include "storage.hpp"
  18961. // #include "utility.hpp"
  18962. namespace entt {
  18963. /**
  18964. * @brief Group.
  18965. *
  18966. * Primary template isn't defined on purpose. All the specializations give a
  18967. * compile-time error, but for a few reasonable cases.
  18968. */
  18969. template<typename, typename, typename, typename>
  18970. class basic_group;
  18971. /**
  18972. * @brief Non-owning group.
  18973. *
  18974. * A non-owning group returns all entities and only the entities that have at
  18975. * least the given components. Moreover, it's guaranteed that the entity list
  18976. * is tightly packed in memory for fast iterations.
  18977. *
  18978. * @b Important
  18979. *
  18980. * Iterators aren't invalidated if:
  18981. *
  18982. * * New instances of the given components are created and assigned to entities.
  18983. * * The entity currently pointed is modified (as an example, if one of the
  18984. * given components is removed from the entity to which the iterator points).
  18985. * * The entity currently pointed is destroyed.
  18986. *
  18987. * In all other cases, modifying the pools iterated by the group in any way
  18988. * invalidates all the iterators and using them results in undefined behavior.
  18989. *
  18990. * @note
  18991. * Groups share references to the underlying data structures of the registry
  18992. * that generated them. Therefore any change to the entities and to the
  18993. * components made by means of the registry are immediately reflected by all the
  18994. * groups.<br/>
  18995. * Moreover, sorting a non-owning group affects all the instances of the same
  18996. * group (it means that users don't have to call `sort` on each instance to sort
  18997. * all of them because they _share_ entities and components).
  18998. *
  18999. * @warning
  19000. * Lifetime of a group must not overcome that of the registry that generated it.
  19001. * In any other case, attempting to use a group results in undefined behavior.
  19002. *
  19003. * @tparam Entity A valid entity type (see entt_traits for more details).
  19004. * @tparam Get Type of components observed by the group.
  19005. * @tparam Exclude Types of components used to filter the group.
  19006. */
  19007. template<typename Entity, typename... Get, typename... Exclude>
  19008. class basic_group<Entity, owned_t<>, get_t<Get...>, exclude_t<Exclude...>> {
  19009. /*! @brief A registry is allowed to create groups. */
  19010. friend class basic_registry<Entity>;
  19011. template<typename Comp>
  19012. using storage_type = constness_as_t<typename storage_traits<Entity, std::remove_const_t<Comp>>::storage_type, Comp>;
  19013. using basic_common_type = std::common_type_t<typename storage_type<Get>::base_type...>;
  19014. struct extended_group_iterator final {
  19015. using difference_type = std::ptrdiff_t;
  19016. using value_type = decltype(std::tuple_cat(std::tuple<Entity>{}, std::declval<basic_group>().get({})));
  19017. using pointer = input_iterator_pointer<value_type>;
  19018. using reference = value_type;
  19019. using iterator_category = std::input_iterator_tag;
  19020. extended_group_iterator() = default;
  19021. extended_group_iterator(typename basic_common_type::iterator from, const std::tuple<storage_type<Get> *...> &args)
  19022. : it{from},
  19023. pools{args} {}
  19024. extended_group_iterator &operator++() ENTT_NOEXCEPT {
  19025. return ++it, *this;
  19026. }
  19027. extended_group_iterator operator++(int) ENTT_NOEXCEPT {
  19028. extended_group_iterator orig = *this;
  19029. return ++(*this), orig;
  19030. }
  19031. [[nodiscard]] reference operator*() const ENTT_NOEXCEPT {
  19032. const auto entt = *it;
  19033. return std::tuple_cat(std::make_tuple(entt), std::get<storage_type<Get> *>(pools)->get_as_tuple(entt)...);
  19034. }
  19035. [[nodiscard]] pointer operator->() const ENTT_NOEXCEPT {
  19036. return operator*();
  19037. }
  19038. [[nodiscard]] bool operator==(const extended_group_iterator &other) const ENTT_NOEXCEPT {
  19039. return other.it == it;
  19040. }
  19041. [[nodiscard]] bool operator!=(const extended_group_iterator &other) const ENTT_NOEXCEPT {
  19042. return !(*this == other);
  19043. }
  19044. private:
  19045. typename basic_common_type::iterator it;
  19046. std::tuple<storage_type<Get> *...> pools;
  19047. };
  19048. basic_group(basic_common_type &ref, storage_type<Get> &...gpool) ENTT_NOEXCEPT
  19049. : handler{&ref},
  19050. pools{&gpool...} {}
  19051. public:
  19052. /*! @brief Underlying entity identifier. */
  19053. using entity_type = Entity;
  19054. /*! @brief Unsigned integer type. */
  19055. using size_type = std::size_t;
  19056. /*! @brief Common type among all storage types. */
  19057. using base_type = basic_common_type;
  19058. /*! @brief Random access iterator type. */
  19059. using iterator = typename base_type::iterator;
  19060. /*! @brief Reversed iterator type. */
  19061. using reverse_iterator = typename base_type::reverse_iterator;
  19062. /*! @brief Iterable group type. */
  19063. using iterable = iterable_adaptor<extended_group_iterator>;
  19064. /*! @brief Default constructor to use to create empty, invalid groups. */
  19065. basic_group() ENTT_NOEXCEPT
  19066. : handler{} {}
  19067. /**
  19068. * @brief Returns a const reference to the underlying handler.
  19069. * @return A const reference to the underlying handler.
  19070. */
  19071. const base_type &handle() const ENTT_NOEXCEPT {
  19072. return *handler;
  19073. }
  19074. /**
  19075. * @brief Returns the storage for a given component type.
  19076. * @tparam Comp Type of component of which to return the storage.
  19077. * @return The storage for the given component type.
  19078. */
  19079. template<typename Comp>
  19080. [[nodiscard]] decltype(auto) storage() const ENTT_NOEXCEPT {
  19081. return *std::get<storage_type<Comp> *>(pools);
  19082. }
  19083. /**
  19084. * @brief Returns the storage for a given component type.
  19085. * @tparam Comp Index of component of which to return the storage.
  19086. * @return The storage for the given component type.
  19087. */
  19088. template<std::size_t Comp>
  19089. [[nodiscard]] decltype(auto) storage() const ENTT_NOEXCEPT {
  19090. return *std::get<Comp>(pools);
  19091. }
  19092. /**
  19093. * @brief Returns the number of entities that have the given components.
  19094. * @return Number of entities that have the given components.
  19095. */
  19096. [[nodiscard]] size_type size() const ENTT_NOEXCEPT {
  19097. return *this ? handler->size() : size_type{};
  19098. }
  19099. /**
  19100. * @brief Returns the number of elements that a group has currently
  19101. * allocated space for.
  19102. * @return Capacity of the group.
  19103. */
  19104. [[nodiscard]] size_type capacity() const ENTT_NOEXCEPT {
  19105. return *this ? handler->capacity() : size_type{};
  19106. }
  19107. /*! @brief Requests the removal of unused capacity. */
  19108. void shrink_to_fit() {
  19109. if(*this) {
  19110. handler->shrink_to_fit();
  19111. }
  19112. }
  19113. /**
  19114. * @brief Checks whether a group is empty.
  19115. * @return True if the group is empty, false otherwise.
  19116. */
  19117. [[nodiscard]] bool empty() const ENTT_NOEXCEPT {
  19118. return !*this || handler->empty();
  19119. }
  19120. /**
  19121. * @brief Returns an iterator to the first entity of the group.
  19122. *
  19123. * The returned iterator points to the first entity of the group. If the
  19124. * group is empty, the returned iterator will be equal to `end()`.
  19125. *
  19126. * @return An iterator to the first entity of the group.
  19127. */
  19128. [[nodiscard]] iterator begin() const ENTT_NOEXCEPT {
  19129. return *this ? handler->begin() : iterator{};
  19130. }
  19131. /**
  19132. * @brief Returns an iterator that is past the last entity of the group.
  19133. *
  19134. * The returned iterator points to the entity following the last entity of
  19135. * the group. Attempting to dereference the returned iterator results in
  19136. * undefined behavior.
  19137. *
  19138. * @return An iterator to the entity following the last entity of the
  19139. * group.
  19140. */
  19141. [[nodiscard]] iterator end() const ENTT_NOEXCEPT {
  19142. return *this ? handler->end() : iterator{};
  19143. }
  19144. /**
  19145. * @brief Returns an iterator to the first entity of the reversed group.
  19146. *
  19147. * The returned iterator points to the first entity of the reversed group.
  19148. * If the group is empty, the returned iterator will be equal to `rend()`.
  19149. *
  19150. * @return An iterator to the first entity of the reversed group.
  19151. */
  19152. [[nodiscard]] reverse_iterator rbegin() const ENTT_NOEXCEPT {
  19153. return *this ? handler->rbegin() : reverse_iterator{};
  19154. }
  19155. /**
  19156. * @brief Returns an iterator that is past the last entity of the reversed
  19157. * group.
  19158. *
  19159. * The returned iterator points to the entity following the last entity of
  19160. * the reversed group. Attempting to dereference the returned iterator
  19161. * results in undefined behavior.
  19162. *
  19163. * @return An iterator to the entity following the last entity of the
  19164. * reversed group.
  19165. */
  19166. [[nodiscard]] reverse_iterator rend() const ENTT_NOEXCEPT {
  19167. return *this ? handler->rend() : reverse_iterator{};
  19168. }
  19169. /**
  19170. * @brief Returns the first entity of the group, if any.
  19171. * @return The first entity of the group if one exists, the null entity
  19172. * otherwise.
  19173. */
  19174. [[nodiscard]] entity_type front() const ENTT_NOEXCEPT {
  19175. const auto it = begin();
  19176. return it != end() ? *it : null;
  19177. }
  19178. /**
  19179. * @brief Returns the last entity of the group, if any.
  19180. * @return The last entity of the group if one exists, the null entity
  19181. * otherwise.
  19182. */
  19183. [[nodiscard]] entity_type back() const ENTT_NOEXCEPT {
  19184. const auto it = rbegin();
  19185. return it != rend() ? *it : 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 ENTT_NOEXCEPT {
  19194. const auto it = *this ? handler->find(entt) : iterator{};
  19195. return it != end() && *it == entt ? it : end();
  19196. }
  19197. /**
  19198. * @brief Returns the identifier that occupies the given position.
  19199. * @param pos Position of the element to return.
  19200. * @return The identifier that occupies the given position.
  19201. */
  19202. [[nodiscard]] entity_type operator[](const size_type pos) const {
  19203. return begin()[pos];
  19204. }
  19205. /**
  19206. * @brief Checks if a group is properly initialized.
  19207. * @return True if the group is properly initialized, false otherwise.
  19208. */
  19209. [[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
  19210. return handler != nullptr;
  19211. }
  19212. /**
  19213. * @brief Checks if a group contains an entity.
  19214. * @param entt A valid identifier.
  19215. * @return True if the group contains the given entity, false otherwise.
  19216. */
  19217. [[nodiscard]] bool contains(const entity_type entt) const ENTT_NOEXCEPT {
  19218. return *this && handler->contains(entt);
  19219. }
  19220. /**
  19221. * @brief Returns the components assigned to the given entity.
  19222. *
  19223. * Prefer this function instead of `registry::get` during iterations. It has
  19224. * far better performance than its counterpart.
  19225. *
  19226. * @warning
  19227. * Attempting to use an invalid component type results in a compilation
  19228. * error. Attempting to use an entity that doesn't belong to the group
  19229. * results in undefined behavior.
  19230. *
  19231. * @tparam Comp Types of components to get.
  19232. * @param entt A valid identifier.
  19233. * @return The components assigned to the entity.
  19234. */
  19235. template<typename... Comp>
  19236. [[nodiscard]] decltype(auto) get(const entity_type entt) const {
  19237. ENTT_ASSERT(contains(entt), "Group does not contain entity");
  19238. if constexpr(sizeof...(Comp) == 0) {
  19239. return std::tuple_cat(std::get<storage_type<Get> *>(pools)->get_as_tuple(entt)...);
  19240. } else if constexpr(sizeof...(Comp) == 1) {
  19241. return (std::get<storage_type<Comp> *>(pools)->get(entt), ...);
  19242. } else {
  19243. return std::tuple_cat(std::get<storage_type<Comp> *>(pools)->get_as_tuple(entt)...);
  19244. }
  19245. }
  19246. /**
  19247. * @brief Iterates entities and components and applies the given function
  19248. * object to them.
  19249. *
  19250. * The function object is invoked for each entity. It is provided with the
  19251. * entity itself and a set of references to non-empty components. The
  19252. * _constness_ of the components is as requested.<br/>
  19253. * The signature of the function must be equivalent to one of the following
  19254. * forms:
  19255. *
  19256. * @code{.cpp}
  19257. * void(const entity_type, Type &...);
  19258. * void(Type &...);
  19259. * @endcode
  19260. *
  19261. * @note
  19262. * Empty types aren't explicitly instantiated and therefore they are never
  19263. * returned during iterations.
  19264. *
  19265. * @tparam Func Type of the function object to invoke.
  19266. * @param func A valid function object.
  19267. */
  19268. template<typename Func>
  19269. void each(Func func) const {
  19270. for(const auto entt: *this) {
  19271. if constexpr(is_applicable_v<Func, decltype(std::tuple_cat(std::tuple<entity_type>{}, std::declval<basic_group>().get({})))>) {
  19272. std::apply(func, std::tuple_cat(std::make_tuple(entt), get(entt)));
  19273. } else {
  19274. std::apply(func, get(entt));
  19275. }
  19276. }
  19277. }
  19278. /**
  19279. * @brief Returns an iterable object to use to _visit_ a group.
  19280. *
  19281. * The iterable object returns tuples that contain the current entity and a
  19282. * set of references to its non-empty components. The _constness_ of the
  19283. * components is as requested.
  19284. *
  19285. * @note
  19286. * Empty types aren't explicitly instantiated and therefore they are never
  19287. * returned during iterations.
  19288. *
  19289. * @return An iterable object to use to _visit_ the group.
  19290. */
  19291. [[nodiscard]] iterable each() const ENTT_NOEXCEPT {
  19292. return handler ? iterable{extended_group_iterator{handler->begin(), pools}, extended_group_iterator{handler->end(), pools}}
  19293. : iterable{extended_group_iterator{{}, pools}, extended_group_iterator{{}, pools}};
  19294. }
  19295. /**
  19296. * @brief Sort a group according to the given comparison function.
  19297. *
  19298. * Sort the group so that iterating it with a couple of iterators returns
  19299. * entities and components in the expected order. See `begin` and `end` for
  19300. * more details.
  19301. *
  19302. * The comparison function object must return `true` if the first element
  19303. * is _less_ than the second one, `false` otherwise. The signature of the
  19304. * comparison function should be equivalent to one of the following:
  19305. *
  19306. * @code{.cpp}
  19307. * bool(std::tuple<Component &...>, std::tuple<Component &...>);
  19308. * bool(const Component &..., const Component &...);
  19309. * bool(const Entity, const Entity);
  19310. * @endcode
  19311. *
  19312. * Where `Component` are such that they are iterated by the group.<br/>
  19313. * Moreover, the comparison function object shall induce a
  19314. * _strict weak ordering_ on the values.
  19315. *
  19316. * The sort function object must offer a member function template
  19317. * `operator()` that accepts three arguments:
  19318. *
  19319. * * An iterator to the first element of the range to sort.
  19320. * * An iterator past the last element of the range to sort.
  19321. * * A comparison function to use to compare the elements.
  19322. *
  19323. * @tparam Comp Optional types of components to compare.
  19324. * @tparam Compare Type of comparison function object.
  19325. * @tparam Sort Type of sort function object.
  19326. * @tparam Args Types of arguments to forward to the sort function object.
  19327. * @param compare A valid comparison function object.
  19328. * @param algo A valid sort function object.
  19329. * @param args Arguments to forward to the sort function object, if any.
  19330. */
  19331. template<typename... Comp, typename Compare, typename Sort = std_sort, typename... Args>
  19332. void sort(Compare compare, Sort algo = Sort{}, Args &&...args) {
  19333. if(*this) {
  19334. if constexpr(sizeof...(Comp) == 0) {
  19335. static_assert(std::is_invocable_v<Compare, const entity_type, const entity_type>, "Invalid comparison function");
  19336. handler->sort(std::move(compare), std::move(algo), std::forward<Args>(args)...);
  19337. } else {
  19338. auto comp = [this, &compare](const entity_type lhs, const entity_type rhs) {
  19339. if constexpr(sizeof...(Comp) == 1) {
  19340. return compare((std::get<storage_type<Comp> *>(pools)->get(lhs), ...), (std::get<storage_type<Comp> *>(pools)->get(rhs), ...));
  19341. } else {
  19342. return compare(std::forward_as_tuple(std::get<storage_type<Comp> *>(pools)->get(lhs)...), std::forward_as_tuple(std::get<storage_type<Comp> *>(pools)->get(rhs)...));
  19343. }
  19344. };
  19345. handler->sort(std::move(comp), std::move(algo), std::forward<Args>(args)...);
  19346. }
  19347. }
  19348. }
  19349. /**
  19350. * @brief Sort the shared pool of entities according to the given component.
  19351. *
  19352. * Non-owning groups of the same type share with the registry a pool of
  19353. * entities with its own order that doesn't depend on the order of any pool
  19354. * of components. Users can order the underlying data structure so that it
  19355. * respects the order of the pool of the given component.
  19356. *
  19357. * @note
  19358. * The shared pool of entities and thus its order is affected by the changes
  19359. * to each and every pool that it tracks. Therefore changes to those pools
  19360. * can quickly ruin the order imposed to the pool of entities shared between
  19361. * the non-owning groups.
  19362. *
  19363. * @tparam Comp Type of component to use to impose the order.
  19364. */
  19365. template<typename Comp>
  19366. void sort() const {
  19367. if(*this) {
  19368. handler->respect(*std::get<storage_type<Comp> *>(pools));
  19369. }
  19370. }
  19371. private:
  19372. base_type *const handler;
  19373. const std::tuple<storage_type<Get> *...> pools;
  19374. };
  19375. /**
  19376. * @brief Owning group.
  19377. *
  19378. * Owning groups return all entities and only the entities that have at least
  19379. * the given components. Moreover:
  19380. *
  19381. * * It's guaranteed that the entity list is tightly packed in memory for fast
  19382. * iterations.
  19383. * * It's guaranteed that the lists of owned components are tightly packed in
  19384. * memory for even faster iterations and to allow direct access.
  19385. * * They stay true to the order of the owned components and all instances have
  19386. * the same order in memory.
  19387. *
  19388. * The more types of components are owned by a group, the faster it is to
  19389. * iterate them.
  19390. *
  19391. * @b Important
  19392. *
  19393. * Iterators aren't invalidated if:
  19394. *
  19395. * * New instances of the given components are created and assigned to entities.
  19396. * * The entity currently pointed is modified (as an example, if one of the
  19397. * given components is removed from the entity to which the iterator points).
  19398. * * The entity currently pointed is destroyed.
  19399. *
  19400. * In all other cases, modifying the pools iterated by the group in any way
  19401. * invalidates all the iterators and using them results in undefined behavior.
  19402. *
  19403. * @note
  19404. * Groups share references to the underlying data structures of the registry
  19405. * that generated them. Therefore any change to the entities and to the
  19406. * components made by means of the registry are immediately reflected by all the
  19407. * groups.
  19408. * Moreover, sorting an owning group affects all the instance of the same group
  19409. * (it means that users don't have to call `sort` on each instance to sort all
  19410. * of them because they share the underlying data structure).
  19411. *
  19412. * @warning
  19413. * Lifetime of a group must not overcome that of the registry that generated it.
  19414. * In any other case, attempting to use a group results in undefined behavior.
  19415. *
  19416. * @tparam Entity A valid entity type (see entt_traits for more details).
  19417. * @tparam Owned Types of components owned by the group.
  19418. * @tparam Get Types of components observed by the group.
  19419. * @tparam Exclude Types of components used to filter the group.
  19420. */
  19421. template<typename Entity, typename... Owned, typename... Get, typename... Exclude>
  19422. class basic_group<Entity, owned_t<Owned...>, get_t<Get...>, exclude_t<Exclude...>> {
  19423. /*! @brief A registry is allowed to create groups. */
  19424. friend class basic_registry<Entity>;
  19425. template<typename Comp>
  19426. using storage_type = constness_as_t<typename storage_traits<Entity, std::remove_const_t<Comp>>::storage_type, Comp>;
  19427. using basic_common_type = std::common_type_t<typename storage_type<Owned>::base_type..., typename storage_type<Get>::base_type...>;
  19428. class extended_group_iterator final {
  19429. template<typename Type>
  19430. auto index_to_element(storage_type<Type> &cpool) const {
  19431. if constexpr(ignore_as_empty_v<std::remove_const_t<Type>>) {
  19432. return std::make_tuple();
  19433. } else {
  19434. return std::forward_as_tuple(cpool.rbegin()[it.index()]);
  19435. }
  19436. }
  19437. public:
  19438. using difference_type = std::ptrdiff_t;
  19439. using value_type = decltype(std::tuple_cat(std::tuple<Entity>{}, std::declval<basic_group>().get({})));
  19440. using pointer = input_iterator_pointer<value_type>;
  19441. using reference = value_type;
  19442. using iterator_category = std::input_iterator_tag;
  19443. extended_group_iterator() = default;
  19444. template<typename... Other>
  19445. extended_group_iterator(typename basic_common_type::iterator from, const std::tuple<storage_type<Owned> *..., storage_type<Get> *...> &cpools)
  19446. : it{from},
  19447. pools{cpools} {}
  19448. extended_group_iterator &operator++() ENTT_NOEXCEPT {
  19449. return ++it, *this;
  19450. }
  19451. extended_group_iterator operator++(int) ENTT_NOEXCEPT {
  19452. extended_group_iterator orig = *this;
  19453. return ++(*this), orig;
  19454. }
  19455. [[nodiscard]] reference operator*() const ENTT_NOEXCEPT {
  19456. return std::tuple_cat(
  19457. std::make_tuple(*it),
  19458. index_to_element<Owned>(*std::get<storage_type<Owned> *>(pools))...,
  19459. std::get<storage_type<Get> *>(pools)->get_as_tuple(*it)...);
  19460. }
  19461. [[nodiscard]] pointer operator->() const ENTT_NOEXCEPT {
  19462. return operator*();
  19463. }
  19464. [[nodiscard]] bool operator==(const extended_group_iterator &other) const ENTT_NOEXCEPT {
  19465. return other.it == it;
  19466. }
  19467. [[nodiscard]] bool operator!=(const extended_group_iterator &other) const ENTT_NOEXCEPT {
  19468. return !(*this == other);
  19469. }
  19470. private:
  19471. typename basic_common_type::iterator it;
  19472. std::tuple<storage_type<Owned> *..., storage_type<Get> *...> pools;
  19473. };
  19474. basic_group(const std::size_t &extent, storage_type<Owned> &...opool, storage_type<Get> &...gpool) ENTT_NOEXCEPT
  19475. : pools{&opool..., &gpool...},
  19476. length{&extent} {}
  19477. public:
  19478. /*! @brief Underlying entity identifier. */
  19479. using entity_type = Entity;
  19480. /*! @brief Unsigned integer type. */
  19481. using size_type = std::size_t;
  19482. /*! @brief Common type among all storage types. */
  19483. using base_type = basic_common_type;
  19484. /*! @brief Random access iterator type. */
  19485. using iterator = typename base_type::iterator;
  19486. /*! @brief Reversed iterator type. */
  19487. using reverse_iterator = typename base_type::reverse_iterator;
  19488. /*! @brief Iterable group type. */
  19489. using iterable = iterable_adaptor<extended_group_iterator>;
  19490. /*! @brief Default constructor to use to create empty, invalid groups. */
  19491. basic_group() ENTT_NOEXCEPT
  19492. : length{} {}
  19493. /**
  19494. * @brief Returns the storage for a given component type.
  19495. * @tparam Comp Type of component of which to return the storage.
  19496. * @return The storage for the given component type.
  19497. */
  19498. template<typename Comp>
  19499. [[nodiscard]] decltype(auto) storage() const ENTT_NOEXCEPT {
  19500. return *std::get<storage_type<Comp> *>(pools);
  19501. }
  19502. /**
  19503. * @brief Returns the storage for a given component type.
  19504. * @tparam Comp Index of component of which to return the storage.
  19505. * @return The storage for the given component type.
  19506. */
  19507. template<std::size_t Comp>
  19508. [[nodiscard]] decltype(auto) storage() const ENTT_NOEXCEPT {
  19509. return *std::get<Comp>(pools);
  19510. }
  19511. /**
  19512. * @brief Returns the number of entities that have the given components.
  19513. * @return Number of entities that have the given components.
  19514. */
  19515. [[nodiscard]] size_type size() const ENTT_NOEXCEPT {
  19516. return *this ? *length : size_type{};
  19517. }
  19518. /**
  19519. * @brief Checks whether a group is empty.
  19520. * @return True if the group is empty, false otherwise.
  19521. */
  19522. [[nodiscard]] bool empty() const ENTT_NOEXCEPT {
  19523. return !*this || !*length;
  19524. }
  19525. /**
  19526. * @brief Returns an iterator to the first entity of the group.
  19527. *
  19528. * The returned iterator points to the first entity of the group. If the
  19529. * group is empty, the returned iterator will be equal to `end()`.
  19530. *
  19531. * @return An iterator to the first entity of the group.
  19532. */
  19533. [[nodiscard]] iterator begin() const ENTT_NOEXCEPT {
  19534. return *this ? (std::get<0>(pools)->base_type::end() - *length) : iterator{};
  19535. }
  19536. /**
  19537. * @brief Returns an iterator that is past the last entity of the group.
  19538. *
  19539. * The returned iterator points to the entity following the last entity of
  19540. * the group. Attempting to dereference the returned iterator results in
  19541. * undefined behavior.
  19542. *
  19543. * @return An iterator to the entity following the last entity of the
  19544. * group.
  19545. */
  19546. [[nodiscard]] iterator end() const ENTT_NOEXCEPT {
  19547. return *this ? std::get<0>(pools)->base_type::end() : iterator{};
  19548. }
  19549. /**
  19550. * @brief Returns an iterator to the first entity of the reversed group.
  19551. *
  19552. * The returned iterator points to the first entity of the reversed group.
  19553. * If the group is empty, the returned iterator will be equal to `rend()`.
  19554. *
  19555. * @return An iterator to the first entity of the reversed group.
  19556. */
  19557. [[nodiscard]] reverse_iterator rbegin() const ENTT_NOEXCEPT {
  19558. return *this ? std::get<0>(pools)->base_type::rbegin() : reverse_iterator{};
  19559. }
  19560. /**
  19561. * @brief Returns an iterator that is past the last entity of the reversed
  19562. * group.
  19563. *
  19564. * The returned iterator points to the entity following the last entity of
  19565. * the reversed group. Attempting to dereference the returned iterator
  19566. * results in undefined behavior.
  19567. *
  19568. * @return An iterator to the entity following the last entity of the
  19569. * reversed group.
  19570. */
  19571. [[nodiscard]] reverse_iterator rend() const ENTT_NOEXCEPT {
  19572. return *this ? (std::get<0>(pools)->base_type::rbegin() + *length) : reverse_iterator{};
  19573. }
  19574. /**
  19575. * @brief Returns the first entity of the group, if any.
  19576. * @return The first entity of the group if one exists, the null entity
  19577. * otherwise.
  19578. */
  19579. [[nodiscard]] entity_type front() const ENTT_NOEXCEPT {
  19580. const auto it = begin();
  19581. return it != end() ? *it : null;
  19582. }
  19583. /**
  19584. * @brief Returns the last entity of the group, if any.
  19585. * @return The last entity of the group if one exists, the null entity
  19586. * otherwise.
  19587. */
  19588. [[nodiscard]] entity_type back() const ENTT_NOEXCEPT {
  19589. const auto it = rbegin();
  19590. return it != rend() ? *it : null;
  19591. }
  19592. /**
  19593. * @brief Finds an entity.
  19594. * @param entt A valid identifier.
  19595. * @return An iterator to the given entity if it's found, past the end
  19596. * iterator otherwise.
  19597. */
  19598. [[nodiscard]] iterator find(const entity_type entt) const ENTT_NOEXCEPT {
  19599. const auto it = *this ? std::get<0>(pools)->find(entt) : iterator{};
  19600. return it != end() && it >= begin() && *it == entt ? it : end();
  19601. }
  19602. /**
  19603. * @brief Returns the identifier that occupies the given position.
  19604. * @param pos Position of the element to return.
  19605. * @return The identifier that occupies the given position.
  19606. */
  19607. [[nodiscard]] entity_type operator[](const size_type pos) const {
  19608. return begin()[pos];
  19609. }
  19610. /**
  19611. * @brief Checks if a group is properly initialized.
  19612. * @return True if the group is properly initialized, false otherwise.
  19613. */
  19614. [[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
  19615. return length != nullptr;
  19616. }
  19617. /**
  19618. * @brief Checks if a group contains an entity.
  19619. * @param entt A valid identifier.
  19620. * @return True if the group contains the given entity, false otherwise.
  19621. */
  19622. [[nodiscard]] bool contains(const entity_type entt) const ENTT_NOEXCEPT {
  19623. return *this && std::get<0>(pools)->contains(entt) && (std::get<0>(pools)->index(entt) < (*length));
  19624. }
  19625. /**
  19626. * @brief Returns the components assigned to the given entity.
  19627. *
  19628. * Prefer this function instead of `registry::get` during iterations. It has
  19629. * far better performance than its counterpart.
  19630. *
  19631. * @warning
  19632. * Attempting to use an invalid component type results in a compilation
  19633. * error. Attempting to use an entity that doesn't belong to the group
  19634. * results in undefined behavior.
  19635. *
  19636. * @tparam Comp Types of components to get.
  19637. * @param entt A valid identifier.
  19638. * @return The components assigned to the entity.
  19639. */
  19640. template<typename... Comp>
  19641. [[nodiscard]] decltype(auto) get(const entity_type entt) const {
  19642. ENTT_ASSERT(contains(entt), "Group does not contain entity");
  19643. if constexpr(sizeof...(Comp) == 0) {
  19644. return std::tuple_cat(std::get<storage_type<Owned> *>(pools)->get_as_tuple(entt)..., std::get<storage_type<Get> *>(pools)->get_as_tuple(entt)...);
  19645. } else if constexpr(sizeof...(Comp) == 1) {
  19646. return (std::get<storage_type<Comp> *>(pools)->get(entt), ...);
  19647. } else {
  19648. return std::tuple_cat(std::get<storage_type<Comp> *>(pools)->get_as_tuple(entt)...);
  19649. }
  19650. }
  19651. /**
  19652. * @brief Iterates entities and components and applies the given function
  19653. * object to them.
  19654. *
  19655. * The function object is invoked for each entity. It is provided with the
  19656. * entity itself and a set of references to non-empty components. The
  19657. * _constness_ of the components is as requested.<br/>
  19658. * The signature of the function must be equivalent to one of the following
  19659. * forms:
  19660. *
  19661. * @code{.cpp}
  19662. * void(const entity_type, Type &...);
  19663. * void(Type &...);
  19664. * @endcode
  19665. *
  19666. * @note
  19667. * Empty types aren't explicitly instantiated and therefore they are never
  19668. * returned during iterations.
  19669. *
  19670. * @tparam Func Type of the function object to invoke.
  19671. * @param func A valid function object.
  19672. */
  19673. template<typename Func>
  19674. void each(Func func) const {
  19675. for(auto args: each()) {
  19676. if constexpr(is_applicable_v<Func, decltype(std::tuple_cat(std::tuple<entity_type>{}, std::declval<basic_group>().get({})))>) {
  19677. std::apply(func, args);
  19678. } else {
  19679. std::apply([&func](auto, auto &&...less) { func(std::forward<decltype(less)>(less)...); }, args);
  19680. }
  19681. }
  19682. }
  19683. /**
  19684. * @brief Returns an iterable object to use to _visit_ a group.
  19685. *
  19686. * The iterable object returns tuples that contain the current entity and a
  19687. * set of references to its non-empty components. The _constness_ of the
  19688. * components is as requested.
  19689. *
  19690. * @note
  19691. * Empty types aren't explicitly instantiated and therefore they are never
  19692. * returned during iterations.
  19693. *
  19694. * @return An iterable object to use to _visit_ the group.
  19695. */
  19696. [[nodiscard]] iterable each() const ENTT_NOEXCEPT {
  19697. iterator last = length ? std::get<0>(pools)->basic_common_type::end() : iterator{};
  19698. return {extended_group_iterator{last - *length, pools}, extended_group_iterator{last, pools}};
  19699. }
  19700. /**
  19701. * @brief Sort a group according to the given comparison function.
  19702. *
  19703. * Sort the group so that iterating it with a couple of iterators returns
  19704. * entities and components in the expected order. See `begin` and `end` for
  19705. * more details.
  19706. *
  19707. * The comparison function object must return `true` if the first element
  19708. * is _less_ than the second one, `false` otherwise. The signature of the
  19709. * comparison function should be equivalent to one of the following:
  19710. *
  19711. * @code{.cpp}
  19712. * bool(std::tuple<Component &...>, std::tuple<Component &...>);
  19713. * bool(const Component &, const Component &);
  19714. * bool(const Entity, const Entity);
  19715. * @endcode
  19716. *
  19717. * Where `Component` are either owned types or not but still such that they
  19718. * are iterated by the group.<br/>
  19719. * Moreover, the comparison function object shall induce a
  19720. * _strict weak ordering_ on the values.
  19721. *
  19722. * The sort function object must offer a member function template
  19723. * `operator()` that accepts three arguments:
  19724. *
  19725. * * An iterator to the first element of the range to sort.
  19726. * * An iterator past the last element of the range to sort.
  19727. * * A comparison function to use to compare the elements.
  19728. *
  19729. * @tparam Comp Optional types of components to compare.
  19730. * @tparam Compare Type of comparison function object.
  19731. * @tparam Sort Type of sort function object.
  19732. * @tparam Args Types of arguments to forward to the sort function object.
  19733. * @param compare A valid comparison function object.
  19734. * @param algo A valid sort function object.
  19735. * @param args Arguments to forward to the sort function object, if any.
  19736. */
  19737. template<typename... Comp, typename Compare, typename Sort = std_sort, typename... Args>
  19738. void sort(Compare compare, Sort algo = Sort{}, Args &&...args) const {
  19739. auto *cpool = std::get<0>(pools);
  19740. if constexpr(sizeof...(Comp) == 0) {
  19741. static_assert(std::is_invocable_v<Compare, const entity_type, const entity_type>, "Invalid comparison function");
  19742. cpool->sort_n(*length, std::move(compare), std::move(algo), std::forward<Args>(args)...);
  19743. } else {
  19744. auto comp = [this, &compare](const entity_type lhs, const entity_type rhs) {
  19745. if constexpr(sizeof...(Comp) == 1) {
  19746. return compare((std::get<storage_type<Comp> *>(pools)->get(lhs), ...), (std::get<storage_type<Comp> *>(pools)->get(rhs), ...));
  19747. } else {
  19748. return compare(std::forward_as_tuple(std::get<storage_type<Comp> *>(pools)->get(lhs)...), std::forward_as_tuple(std::get<storage_type<Comp> *>(pools)->get(rhs)...));
  19749. }
  19750. };
  19751. cpool->sort_n(*length, std::move(comp), std::move(algo), std::forward<Args>(args)...);
  19752. }
  19753. [this](auto *head, auto *...other) {
  19754. for(auto next = *length; next; --next) {
  19755. const auto pos = next - 1;
  19756. [[maybe_unused]] const auto entt = head->data()[pos];
  19757. (other->swap_elements(other->data()[pos], entt), ...);
  19758. }
  19759. }(std::get<storage_type<Owned> *>(pools)...);
  19760. }
  19761. private:
  19762. const std::tuple<storage_type<Owned> *..., storage_type<Get> *...> pools;
  19763. const size_type *const length;
  19764. };
  19765. } // namespace entt
  19766. #endif
  19767. // #include "runtime_view.hpp"
  19768. #ifndef ENTT_ENTITY_RUNTIME_VIEW_HPP
  19769. #define ENTT_ENTITY_RUNTIME_VIEW_HPP
  19770. #include <algorithm>
  19771. #include <iterator>
  19772. #include <type_traits>
  19773. #include <utility>
  19774. #include <vector>
  19775. // #include "../config/config.h"
  19776. // #include "entity.hpp"
  19777. // #include "fwd.hpp"
  19778. // #include "sparse_set.hpp"
  19779. namespace entt {
  19780. /**
  19781. * @cond TURN_OFF_DOXYGEN
  19782. * Internal details not to be documented.
  19783. */
  19784. namespace internal {
  19785. template<typename Set>
  19786. class runtime_view_iterator final {
  19787. using iterator_type = typename Set::iterator;
  19788. [[nodiscard]] bool valid() const {
  19789. return (!tombstone_check || *it != tombstone)
  19790. && std::all_of(++pools->begin(), pools->end(), [entt = *it](const auto *curr) { return curr->contains(entt); })
  19791. && std::none_of(filter->cbegin(), filter->cend(), [entt = *it](const auto *curr) { return curr && curr->contains(entt); });
  19792. }
  19793. public:
  19794. using difference_type = typename iterator_type::difference_type;
  19795. using value_type = typename iterator_type::value_type;
  19796. using pointer = typename iterator_type::pointer;
  19797. using reference = typename iterator_type::reference;
  19798. using iterator_category = std::bidirectional_iterator_tag;
  19799. runtime_view_iterator() ENTT_NOEXCEPT
  19800. : pools{},
  19801. filter{},
  19802. it{},
  19803. tombstone_check{} {}
  19804. runtime_view_iterator(const std::vector<const Set *> &cpools, const std::vector<const Set *> &ignore, iterator_type curr) ENTT_NOEXCEPT
  19805. : pools{&cpools},
  19806. filter{&ignore},
  19807. it{curr},
  19808. tombstone_check{pools->size() == 1u && (*pools)[0u]->policy() == deletion_policy::in_place} {
  19809. if(it != (*pools)[0]->end() && !valid()) {
  19810. ++(*this);
  19811. }
  19812. }
  19813. runtime_view_iterator &operator++() {
  19814. while(++it != (*pools)[0]->end() && !valid()) {}
  19815. return *this;
  19816. }
  19817. runtime_view_iterator operator++(int) {
  19818. runtime_view_iterator orig = *this;
  19819. return ++(*this), orig;
  19820. }
  19821. runtime_view_iterator &operator--() {
  19822. while(--it != (*pools)[0]->begin() && !valid()) {}
  19823. return *this;
  19824. }
  19825. runtime_view_iterator operator--(int) {
  19826. runtime_view_iterator orig = *this;
  19827. return operator--(), orig;
  19828. }
  19829. [[nodiscard]] pointer operator->() const ENTT_NOEXCEPT {
  19830. return it.operator->();
  19831. }
  19832. [[nodiscard]] reference operator*() const ENTT_NOEXCEPT {
  19833. return *operator->();
  19834. }
  19835. [[nodiscard]] bool operator==(const runtime_view_iterator &other) const ENTT_NOEXCEPT {
  19836. return it == other.it;
  19837. }
  19838. [[nodiscard]] bool operator!=(const runtime_view_iterator &other) const ENTT_NOEXCEPT {
  19839. return !(*this == other);
  19840. }
  19841. private:
  19842. const std::vector<const Set *> *pools;
  19843. const std::vector<const Set *> *filter;
  19844. iterator_type it;
  19845. bool tombstone_check;
  19846. };
  19847. } // namespace internal
  19848. /**
  19849. * Internal details not to be documented.
  19850. * @endcond
  19851. */
  19852. /**
  19853. * @brief Runtime view implementation.
  19854. *
  19855. * Primary template isn't defined on purpose. All the specializations give a
  19856. * compile-time error, but for a few reasonable cases.
  19857. */
  19858. template<typename>
  19859. struct basic_runtime_view;
  19860. /**
  19861. * @brief Generic runtime view.
  19862. *
  19863. * Runtime views iterate over those entities that have at least all the given
  19864. * components in their bags. During initialization, a runtime view looks at the
  19865. * number of entities available for each component and picks up a reference to
  19866. * the smallest set of candidate entities in order to get a performance boost
  19867. * when iterate.<br/>
  19868. * Order of elements during iterations are highly dependent on the order of the
  19869. * underlying data structures. See sparse_set and its specializations for more
  19870. * details.
  19871. *
  19872. * @b Important
  19873. *
  19874. * Iterators aren't invalidated if:
  19875. *
  19876. * * New instances of the given components are created and assigned to entities.
  19877. * * The entity currently pointed is modified (as an example, if one of the
  19878. * given components is removed from the entity to which the iterator points).
  19879. * * The entity currently pointed is destroyed.
  19880. *
  19881. * In all the other cases, modifying the pools of the given components in any
  19882. * way invalidates all the iterators and using them results in undefined
  19883. * behavior.
  19884. *
  19885. * @note
  19886. * Views share references to the underlying data structures of the registry that
  19887. * generated them. Therefore any change to the entities and to the components
  19888. * made by means of the registry are immediately reflected by the views, unless
  19889. * a pool was missing when the view was built (in this case, the view won't
  19890. * have a valid reference and won't be updated accordingly).
  19891. *
  19892. * @warning
  19893. * Lifetime of a view must not overcome that of the registry that generated it.
  19894. * In any other case, attempting to use a view results in undefined behavior.
  19895. *
  19896. * @tparam Entity A valid entity type (see entt_traits for more details).
  19897. * @tparam Allocator Type of allocator used to manage memory and elements.
  19898. */
  19899. template<typename Entity, typename Allocator>
  19900. struct basic_runtime_view<basic_sparse_set<Entity, Allocator>> {
  19901. /*! @brief Underlying entity identifier. */
  19902. using entity_type = Entity;
  19903. /*! @brief Unsigned integer type. */
  19904. using size_type = std::size_t;
  19905. /*! @brief Common type among all storage types. */
  19906. using base_type = basic_sparse_set<Entity, Allocator>;
  19907. /*! @brief Bidirectional iterator type. */
  19908. using iterator = internal::runtime_view_iterator<base_type>;
  19909. /*! @brief Default constructor to use to create empty, invalid views. */
  19910. basic_runtime_view() ENTT_NOEXCEPT
  19911. : pools{},
  19912. filter{} {}
  19913. /**
  19914. * @brief Appends an opaque storage object to a runtime view.
  19915. * @param base An opaque reference to a storage object.
  19916. * @return This runtime view.
  19917. */
  19918. basic_runtime_view &iterate(const base_type &base) {
  19919. if(pools.empty() || !(base.size() < pools[0u]->size())) {
  19920. pools.push_back(&base);
  19921. } else {
  19922. pools.push_back(std::exchange(pools[0u], &base));
  19923. }
  19924. return *this;
  19925. }
  19926. /**
  19927. * @brief Adds an opaque storage object as a filter of a runtime view.
  19928. * @param base An opaque reference to a storage object.
  19929. * @return This runtime view.
  19930. */
  19931. basic_runtime_view &exclude(const base_type &base) {
  19932. filter.push_back(&base);
  19933. return *this;
  19934. }
  19935. /**
  19936. * @brief Estimates the number of entities iterated by the view.
  19937. * @return Estimated number of entities iterated by the view.
  19938. */
  19939. [[nodiscard]] size_type size_hint() const {
  19940. return pools.empty() ? size_type{} : pools.front()->size();
  19941. }
  19942. /**
  19943. * @brief Returns an iterator to the first entity that has the given
  19944. * components.
  19945. *
  19946. * The returned iterator points to the first entity that has the given
  19947. * components. If the view is empty, the returned iterator will be equal to
  19948. * `end()`.
  19949. *
  19950. * @return An iterator to the first entity that has the given components.
  19951. */
  19952. [[nodiscard]] iterator begin() const {
  19953. return pools.empty() ? iterator{} : iterator{pools, filter, pools[0]->begin()};
  19954. }
  19955. /**
  19956. * @brief Returns an iterator that is past the last entity that has the
  19957. * given components.
  19958. *
  19959. * The returned iterator points to the entity following the last entity that
  19960. * has the given components. Attempting to dereference the returned iterator
  19961. * results in undefined behavior.
  19962. *
  19963. * @return An iterator to the entity following the last entity that has the
  19964. * given components.
  19965. */
  19966. [[nodiscard]] iterator end() const {
  19967. return pools.empty() ? iterator{} : iterator{pools, filter, pools[0]->end()};
  19968. }
  19969. /**
  19970. * @brief Checks if a view contains an entity.
  19971. * @param entt A valid identifier.
  19972. * @return True if the view contains the given entity, false otherwise.
  19973. */
  19974. [[nodiscard]] bool contains(const entity_type entt) const {
  19975. return !pools.empty()
  19976. && std::all_of(pools.cbegin(), pools.cend(), [entt](const auto *curr) { return curr->contains(entt); })
  19977. && std::none_of(filter.cbegin(), filter.cend(), [entt](const auto *curr) { return curr && curr->contains(entt); });
  19978. }
  19979. /**
  19980. * @brief Iterates entities and applies the given function object to them.
  19981. *
  19982. * The function object is invoked for each entity. It is provided only with
  19983. * the entity itself. To get the components, users can use the registry with
  19984. * which the view was built.<br/>
  19985. * The signature of the function should be equivalent to the following:
  19986. *
  19987. * @code{.cpp}
  19988. * void(const entity_type);
  19989. * @endcode
  19990. *
  19991. * @tparam Func Type of the function object to invoke.
  19992. * @param func A valid function object.
  19993. */
  19994. template<typename Func>
  19995. void each(Func func) const {
  19996. for(const auto entity: *this) {
  19997. func(entity);
  19998. }
  19999. }
  20000. private:
  20001. std::vector<const base_type *> pools;
  20002. std::vector<const base_type *> filter;
  20003. };
  20004. } // namespace entt
  20005. #endif
  20006. // #include "sparse_set.hpp"
  20007. // #include "storage.hpp"
  20008. // #include "utility.hpp"
  20009. // #include "view.hpp"
  20010. #ifndef ENTT_ENTITY_VIEW_HPP
  20011. #define ENTT_ENTITY_VIEW_HPP
  20012. #include <algorithm>
  20013. #include <array>
  20014. #include <iterator>
  20015. #include <tuple>
  20016. #include <type_traits>
  20017. #include <utility>
  20018. // #include "../config/config.h"
  20019. // #include "../core/iterator.hpp"
  20020. // #include "../core/type_traits.hpp"
  20021. // #include "component.hpp"
  20022. // #include "entity.hpp"
  20023. // #include "fwd.hpp"
  20024. // #include "sparse_set.hpp"
  20025. // #include "storage.hpp"
  20026. // #include "utility.hpp"
  20027. namespace entt {
  20028. /**
  20029. * @cond TURN_OFF_DOXYGEN
  20030. * Internal details not to be documented.
  20031. */
  20032. namespace internal {
  20033. template<typename Type, std::size_t Component, std::size_t Exclude>
  20034. class view_iterator final {
  20035. using iterator_type = typename Type::const_iterator;
  20036. [[nodiscard]] bool valid() const ENTT_NOEXCEPT {
  20037. return ((Component != 0u) || (*it != tombstone))
  20038. && std::apply([entt = *it](const auto *...curr) { return (curr->contains(entt) && ...); }, pools)
  20039. && std::apply([entt = *it](const auto *...curr) { return (!curr->contains(entt) && ...); }, filter);
  20040. }
  20041. public:
  20042. using value_type = typename iterator_type::value_type;
  20043. using pointer = typename iterator_type::pointer;
  20044. using reference = typename iterator_type::reference;
  20045. using difference_type = typename iterator_type::difference_type;
  20046. using iterator_category = std::forward_iterator_tag;
  20047. view_iterator() ENTT_NOEXCEPT = default;
  20048. view_iterator(iterator_type curr, iterator_type to, std::array<const Type *, Component> all_of, std::array<const Type *, Exclude> none_of) ENTT_NOEXCEPT
  20049. : it{curr},
  20050. last{to},
  20051. pools{all_of},
  20052. filter{none_of} {
  20053. if(it != last && !valid()) {
  20054. ++(*this);
  20055. }
  20056. }
  20057. view_iterator &operator++() ENTT_NOEXCEPT {
  20058. while(++it != last && !valid()) {}
  20059. return *this;
  20060. }
  20061. view_iterator operator++(int) ENTT_NOEXCEPT {
  20062. view_iterator orig = *this;
  20063. return ++(*this), orig;
  20064. }
  20065. [[nodiscard]] pointer operator->() const ENTT_NOEXCEPT {
  20066. return &*it;
  20067. }
  20068. [[nodiscard]] reference operator*() const ENTT_NOEXCEPT {
  20069. return *operator->();
  20070. }
  20071. template<typename LhsType, auto... LhsArgs, typename RhsType, auto... RhsArgs>
  20072. friend bool operator==(const view_iterator<LhsType, LhsArgs...> &, const view_iterator<RhsType, RhsArgs...> &) ENTT_NOEXCEPT;
  20073. private:
  20074. iterator_type it;
  20075. iterator_type last;
  20076. std::array<const Type *, Component> pools;
  20077. std::array<const Type *, Exclude> filter;
  20078. };
  20079. template<typename LhsType, auto... LhsArgs, typename RhsType, auto... RhsArgs>
  20080. [[nodiscard]] bool operator==(const view_iterator<LhsType, LhsArgs...> &lhs, const view_iterator<RhsType, RhsArgs...> &rhs) ENTT_NOEXCEPT {
  20081. return lhs.it == rhs.it;
  20082. }
  20083. template<typename LhsType, auto... LhsArgs, typename RhsType, auto... RhsArgs>
  20084. [[nodiscard]] bool operator!=(const view_iterator<LhsType, LhsArgs...> &lhs, const view_iterator<RhsType, RhsArgs...> &rhs) ENTT_NOEXCEPT {
  20085. return !(lhs == rhs);
  20086. }
  20087. template<typename It, typename... Storage>
  20088. struct extended_view_iterator final {
  20089. using difference_type = std::ptrdiff_t;
  20090. using value_type = decltype(std::tuple_cat(std::make_tuple(*std::declval<It>()), std::declval<Storage>().get_as_tuple({})...));
  20091. using pointer = input_iterator_pointer<value_type>;
  20092. using reference = value_type;
  20093. using iterator_category = std::input_iterator_tag;
  20094. extended_view_iterator() = default;
  20095. extended_view_iterator(It from, std::tuple<Storage *...> storage)
  20096. : it{from},
  20097. pools{storage} {}
  20098. extended_view_iterator &operator++() ENTT_NOEXCEPT {
  20099. return ++it, *this;
  20100. }
  20101. extended_view_iterator operator++(int) ENTT_NOEXCEPT {
  20102. extended_view_iterator orig = *this;
  20103. return ++(*this), orig;
  20104. }
  20105. [[nodiscard]] reference operator*() const ENTT_NOEXCEPT {
  20106. return std::apply([entt = *it](auto *...curr) { return std::tuple_cat(std::make_tuple(entt), curr->get_as_tuple(entt)...); }, pools);
  20107. }
  20108. [[nodiscard]] pointer operator->() const ENTT_NOEXCEPT {
  20109. return operator*();
  20110. }
  20111. template<typename... Lhs, typename... Rhs>
  20112. friend bool operator==(const extended_view_iterator<Lhs...> &, const extended_view_iterator<Rhs...> &) ENTT_NOEXCEPT;
  20113. private:
  20114. It it;
  20115. std::tuple<Storage *...> pools;
  20116. };
  20117. template<typename... Lhs, typename... Rhs>
  20118. [[nodiscard]] bool operator==(const extended_view_iterator<Lhs...> &lhs, const extended_view_iterator<Rhs...> &rhs) ENTT_NOEXCEPT {
  20119. return lhs.it == rhs.it;
  20120. }
  20121. template<typename... Lhs, typename... Rhs>
  20122. [[nodiscard]] bool operator!=(const extended_view_iterator<Lhs...> &lhs, const extended_view_iterator<Rhs...> &rhs) ENTT_NOEXCEPT {
  20123. return !(lhs == rhs);
  20124. }
  20125. } // namespace internal
  20126. /**
  20127. * Internal details not to be documented.
  20128. * @endcond
  20129. */
  20130. /**
  20131. * @brief View implementation.
  20132. *
  20133. * Primary template isn't defined on purpose. All the specializations give a
  20134. * compile-time error, but for a few reasonable cases.
  20135. */
  20136. template<typename, typename, typename, typename>
  20137. class basic_view;
  20138. /**
  20139. * @brief Multi component view.
  20140. *
  20141. * Multi component views iterate over those entities that have at least all the
  20142. * given components in their bags. During initialization, a multi component view
  20143. * looks at the number of entities available for each component and uses the
  20144. * smallest set in order to get a performance boost when iterate.
  20145. *
  20146. * @b Important
  20147. *
  20148. * Iterators aren't invalidated if:
  20149. *
  20150. * * New instances of the given components are created and assigned to entities.
  20151. * * The entity currently pointed is modified (as an example, if one of the
  20152. * given components is removed from the entity to which the iterator points).
  20153. * * The entity currently pointed is destroyed.
  20154. *
  20155. * In all other cases, modifying the pools iterated by the view in any way
  20156. * invalidates all the iterators and using them results in undefined behavior.
  20157. *
  20158. * @tparam Entity A valid entity type (see entt_traits for more details).
  20159. * @tparam Component Types of components iterated by the view.
  20160. * @tparam Exclude Types of components used to filter the view.
  20161. */
  20162. template<typename Entity, typename... Component, typename... Exclude>
  20163. class basic_view<Entity, get_t<Component...>, exclude_t<Exclude...>> {
  20164. template<typename, typename, typename, typename>
  20165. friend class basic_view;
  20166. template<typename Comp>
  20167. using storage_type = constness_as_t<typename storage_traits<Entity, std::remove_const_t<Comp>>::storage_type, Comp>;
  20168. template<std::size_t... Index>
  20169. [[nodiscard]] auto pools_to_array(std::index_sequence<Index...>) const ENTT_NOEXCEPT {
  20170. std::size_t pos{};
  20171. std::array<const base_type *, sizeof...(Component) - 1u> other{};
  20172. (static_cast<void>(std::get<Index>(pools) == view ? void() : void(other[pos++] = std::get<Index>(pools))), ...);
  20173. return other;
  20174. }
  20175. template<std::size_t Comp, std::size_t Other, typename... Args>
  20176. [[nodiscard]] auto dispatch_get(const std::tuple<Entity, Args...> &curr) const {
  20177. if constexpr(Comp == Other) {
  20178. return std::forward_as_tuple(std::get<Args>(curr)...);
  20179. } else {
  20180. return std::get<Other>(pools)->get_as_tuple(std::get<0>(curr));
  20181. }
  20182. }
  20183. template<std::size_t Comp, typename Func, std::size_t... Index>
  20184. void each(Func func, std::index_sequence<Index...>) const {
  20185. for(const auto curr: std::get<Comp>(pools)->each()) {
  20186. const auto entt = std::get<0>(curr);
  20187. if(((sizeof...(Component) != 1u) || (entt != tombstone))
  20188. && ((Comp == Index || std::get<Index>(pools)->contains(entt)) && ...)
  20189. && std::apply([entt](const auto *...cpool) { return (!cpool->contains(entt) && ...); }, filter)) {
  20190. if constexpr(is_applicable_v<Func, decltype(std::tuple_cat(std::tuple<entity_type>{}, std::declval<basic_view>().get({})))>) {
  20191. std::apply(func, std::tuple_cat(std::make_tuple(entt), dispatch_get<Comp, Index>(curr)...));
  20192. } else {
  20193. std::apply(func, std::tuple_cat(dispatch_get<Comp, Index>(curr)...));
  20194. }
  20195. }
  20196. }
  20197. }
  20198. template<typename Func, std::size_t... Index>
  20199. void pick_and_each(Func func, std::index_sequence<Index...> seq) const {
  20200. ((std::get<Index>(pools) == view ? each<Index>(std::move(func), seq) : void()), ...);
  20201. }
  20202. public:
  20203. /*! @brief Underlying entity identifier. */
  20204. using entity_type = Entity;
  20205. /*! @brief Unsigned integer type. */
  20206. using size_type = std::size_t;
  20207. /*! @brief Common type among all storage types. */
  20208. using base_type = std::common_type_t<typename storage_type<Component>::base_type...>;
  20209. /*! @brief Bidirectional iterator type. */
  20210. using iterator = internal::view_iterator<base_type, sizeof...(Component) - 1u, sizeof...(Exclude)>;
  20211. /*! @brief Iterable view type. */
  20212. using iterable = iterable_adaptor<internal::extended_view_iterator<iterator, storage_type<Component>...>>;
  20213. /*! @brief Default constructor to use to create empty, invalid views. */
  20214. basic_view() ENTT_NOEXCEPT
  20215. : pools{},
  20216. filter{},
  20217. view{} {}
  20218. /**
  20219. * @brief Constructs a multi-type view from a set of storage classes.
  20220. * @param component The storage for the types to iterate.
  20221. * @param epool The storage for the types used to filter the view.
  20222. */
  20223. basic_view(storage_type<Component> &...component, const storage_type<Exclude> &...epool) ENTT_NOEXCEPT
  20224. : pools{&component...},
  20225. filter{&epool...},
  20226. view{(std::min)({&static_cast<const base_type &>(component)...}, [](auto *lhs, auto *rhs) { return lhs->size() < rhs->size(); })} {}
  20227. /**
  20228. * @brief Creates a new view driven by a given component in its iterations.
  20229. * @tparam Comp Type of component used to drive the iteration.
  20230. * @return A new view driven by the given component in its iterations.
  20231. */
  20232. template<typename Comp>
  20233. [[nodiscard]] basic_view use() const ENTT_NOEXCEPT {
  20234. basic_view other{*this};
  20235. other.view = std::get<storage_type<Comp> *>(pools);
  20236. return other;
  20237. }
  20238. /**
  20239. * @brief Creates a new view driven by a given component in its iterations.
  20240. * @tparam Comp Index of the component used to drive the iteration.
  20241. * @return A new view driven by the given component in its iterations.
  20242. */
  20243. template<std::size_t Comp>
  20244. [[nodiscard]] basic_view use() const ENTT_NOEXCEPT {
  20245. basic_view other{*this};
  20246. other.view = std::get<Comp>(pools);
  20247. return other;
  20248. }
  20249. /**
  20250. * @brief Returns the leading storage of a view.
  20251. * @return The leading storage of the view.
  20252. */
  20253. const base_type &handle() const ENTT_NOEXCEPT {
  20254. return *view;
  20255. }
  20256. /**
  20257. * @brief Returns the storage for a given component type.
  20258. * @tparam Comp Type of component of which to return the storage.
  20259. * @return The storage for the given component type.
  20260. */
  20261. template<typename Comp>
  20262. [[nodiscard]] decltype(auto) storage() const ENTT_NOEXCEPT {
  20263. return *std::get<storage_type<Comp> *>(pools);
  20264. }
  20265. /**
  20266. * @brief Returns the storage for a given component type.
  20267. * @tparam Comp Index of component of which to return the storage.
  20268. * @return The storage for the given component type.
  20269. */
  20270. template<std::size_t Comp>
  20271. [[nodiscard]] decltype(auto) storage() const ENTT_NOEXCEPT {
  20272. return *std::get<Comp>(pools);
  20273. }
  20274. /**
  20275. * @brief Estimates the number of entities iterated by the view.
  20276. * @return Estimated number of entities iterated by the view.
  20277. */
  20278. [[nodiscard]] size_type size_hint() const ENTT_NOEXCEPT {
  20279. return view->size();
  20280. }
  20281. /**
  20282. * @brief Returns an iterator to the first entity of the view.
  20283. *
  20284. * The returned iterator points to the first entity of the view. If the view
  20285. * is empty, the returned iterator will be equal to `end()`.
  20286. *
  20287. * @return An iterator to the first entity of the view.
  20288. */
  20289. [[nodiscard]] iterator begin() const ENTT_NOEXCEPT {
  20290. return iterator{view->begin(), view->end(), pools_to_array(std::index_sequence_for<Component...>{}), filter};
  20291. }
  20292. /**
  20293. * @brief Returns an iterator that is past the last entity of the view.
  20294. *
  20295. * The returned iterator points to the entity following the last entity of
  20296. * the view. Attempting to dereference the returned iterator results in
  20297. * undefined behavior.
  20298. *
  20299. * @return An iterator to the entity following the last entity of the view.
  20300. */
  20301. [[nodiscard]] iterator end() const ENTT_NOEXCEPT {
  20302. return iterator{view->end(), view->end(), pools_to_array(std::index_sequence_for<Component...>{}), filter};
  20303. }
  20304. /**
  20305. * @brief Returns the first entity of the view, if any.
  20306. * @return The first entity of the view if one exists, the null entity
  20307. * otherwise.
  20308. */
  20309. [[nodiscard]] entity_type front() const ENTT_NOEXCEPT {
  20310. const auto it = begin();
  20311. return it != end() ? *it : null;
  20312. }
  20313. /**
  20314. * @brief Returns the last entity of the view, if any.
  20315. * @return The last entity of the view if one exists, the null entity
  20316. * otherwise.
  20317. */
  20318. [[nodiscard]] entity_type back() const ENTT_NOEXCEPT {
  20319. auto it = view->rbegin();
  20320. for(const auto last = view->rend(); it != last && !contains(*it); ++it) {}
  20321. return it == view->rend() ? null : *it;
  20322. }
  20323. /**
  20324. * @brief Finds an entity.
  20325. * @param entt A valid identifier.
  20326. * @return An iterator to the given entity if it's found, past the end
  20327. * iterator otherwise.
  20328. */
  20329. [[nodiscard]] iterator find(const entity_type entt) const ENTT_NOEXCEPT {
  20330. return contains(entt) ? iterator{view->find(entt), view->end(), pools_to_array(std::index_sequence_for<Component...>{}), filter} : end();
  20331. }
  20332. /**
  20333. * @brief Returns the components assigned to the given entity.
  20334. * @param entt A valid identifier.
  20335. * @return The components assigned to the given entity.
  20336. */
  20337. [[nodiscard]] decltype(auto) operator[](const entity_type entt) const {
  20338. return get<Component...>(entt);
  20339. }
  20340. /**
  20341. * @brief Checks if a view is properly initialized.
  20342. * @return True if the view is properly initialized, false otherwise.
  20343. */
  20344. [[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
  20345. return view != nullptr;
  20346. }
  20347. /**
  20348. * @brief Checks if a view contains an entity.
  20349. * @param entt A valid identifier.
  20350. * @return True if the view contains the given entity, false otherwise.
  20351. */
  20352. [[nodiscard]] bool contains(const entity_type entt) const ENTT_NOEXCEPT {
  20353. return std::apply([entt](const auto *...curr) { return (curr->contains(entt) && ...); }, pools)
  20354. && std::apply([entt](const auto *...curr) { return (!curr->contains(entt) && ...); }, filter);
  20355. }
  20356. /**
  20357. * @brief Returns the components assigned to the given entity.
  20358. *
  20359. * @warning
  20360. * Attempting to use an entity that doesn't belong to the view results in
  20361. * undefined behavior.
  20362. *
  20363. * @tparam Comp Types of components to get.
  20364. * @param entt A valid identifier.
  20365. * @return The components assigned to the entity.
  20366. */
  20367. template<typename... Comp>
  20368. [[nodiscard]] decltype(auto) get(const entity_type entt) const {
  20369. ENTT_ASSERT(contains(entt), "View does not contain entity");
  20370. if constexpr(sizeof...(Comp) == 0) {
  20371. return std::apply([entt](auto *...curr) { return std::tuple_cat(curr->get_as_tuple(entt)...); }, pools);
  20372. } else if constexpr(sizeof...(Comp) == 1) {
  20373. return (std::get<storage_type<Comp> *>(pools)->get(entt), ...);
  20374. } else {
  20375. return std::tuple_cat(std::get<storage_type<Comp> *>(pools)->get_as_tuple(entt)...);
  20376. }
  20377. }
  20378. /**
  20379. * @brief Returns the components assigned to the given entity.
  20380. *
  20381. * @warning
  20382. * Attempting to use an entity that doesn't belong to the view results in
  20383. * undefined behavior.
  20384. *
  20385. * @tparam First Index of a component to get.
  20386. * @tparam Other Indexes of other components to get.
  20387. * @param entt A valid identifier.
  20388. * @return The components assigned to the entity.
  20389. */
  20390. template<std::size_t First, std::size_t... Other>
  20391. [[nodiscard]] decltype(auto) get(const entity_type entt) const {
  20392. ENTT_ASSERT(contains(entt), "View does not contain entity");
  20393. if constexpr(sizeof...(Other) == 0) {
  20394. return std::get<First>(pools)->get(entt);
  20395. } else {
  20396. return std::tuple_cat(std::get<First>(pools)->get_as_tuple(entt), std::get<Other>(pools)->get_as_tuple(entt)...);
  20397. }
  20398. }
  20399. /**
  20400. * @brief Iterates entities and components and applies the given function
  20401. * object to them.
  20402. *
  20403. * The function object is invoked for each entity. It is provided with the
  20404. * entity itself and a set of references to non-empty components. The
  20405. * _constness_ of the components is as requested.<br/>
  20406. * The signature of the function must be equivalent to one of the following
  20407. * forms:
  20408. *
  20409. * @code{.cpp}
  20410. * void(const entity_type, Type &...);
  20411. * void(Type &...);
  20412. * @endcode
  20413. *
  20414. * @tparam Func Type of the function object to invoke.
  20415. * @param func A valid function object.
  20416. */
  20417. template<typename Func>
  20418. void each(Func func) const {
  20419. pick_and_each(std::move(func), std::index_sequence_for<Component...>{});
  20420. }
  20421. /**
  20422. * @brief Returns an iterable object to use to _visit_ a view.
  20423. *
  20424. * The iterable object returns a tuple that contains the current entity and
  20425. * a set of references to its non-empty components. The _constness_ of the
  20426. * components is as requested.
  20427. *
  20428. * @return An iterable object to use to _visit_ the view.
  20429. */
  20430. [[nodiscard]] iterable each() const ENTT_NOEXCEPT {
  20431. return {internal::extended_view_iterator{begin(), pools}, internal::extended_view_iterator{end(), pools}};
  20432. }
  20433. /**
  20434. * @brief Combines two views in a _more specific_ one (friend function).
  20435. * @tparam Get Component list of the view to combine with.
  20436. * @tparam Excl Filter list of the view to combine with.
  20437. * @param other The view to combine with.
  20438. * @return A more specific view.
  20439. */
  20440. template<typename... Get, typename... Excl>
  20441. [[nodiscard]] auto operator|(const basic_view<Entity, get_t<Get...>, exclude_t<Excl...>> &other) const ENTT_NOEXCEPT {
  20442. using view_type = basic_view<Entity, get_t<Component..., Get...>, exclude_t<Exclude..., Excl...>>;
  20443. return std::make_from_tuple<view_type>(std::tuple_cat(
  20444. std::apply([](auto *...curr) { return std::forward_as_tuple(*curr...); }, pools),
  20445. std::apply([](auto *...curr) { return std::forward_as_tuple(*curr...); }, other.pools),
  20446. std::apply([](const auto *...curr) { return std::forward_as_tuple(static_cast<const storage_type<Exclude> &>(*curr)...); }, filter),
  20447. std::apply([](const auto *...curr) { return std::forward_as_tuple(static_cast<const storage_type<Excl> &>(*curr)...); }, other.filter)));
  20448. }
  20449. private:
  20450. std::tuple<storage_type<Component> *...> pools;
  20451. std::array<const base_type *, sizeof...(Exclude)> filter;
  20452. const base_type *view;
  20453. };
  20454. /**
  20455. * @brief Single component view specialization.
  20456. *
  20457. * Single component views are specialized in order to get a boost in terms of
  20458. * performance. This kind of views can access the underlying data structure
  20459. * directly and avoid superfluous checks.
  20460. *
  20461. * @b Important
  20462. *
  20463. * Iterators aren't invalidated if:
  20464. *
  20465. * * New instances of the given component are created and assigned to entities.
  20466. * * The entity currently pointed is modified (as an example, the given
  20467. * component is removed from the entity to which the iterator points).
  20468. * * The entity currently pointed is destroyed.
  20469. *
  20470. * In all other cases, modifying the pool iterated by the view in any way
  20471. * invalidates all the iterators and using them results in undefined behavior.
  20472. *
  20473. * @tparam Entity A valid entity type (see entt_traits for more details).
  20474. * @tparam Component Type of component iterated by the view.
  20475. */
  20476. template<typename Entity, typename Component>
  20477. class basic_view<Entity, get_t<Component>, exclude_t<>, std::void_t<std::enable_if_t<!component_traits<std::remove_const_t<Component>>::in_place_delete>>> {
  20478. template<typename, typename, typename, typename>
  20479. friend class basic_view;
  20480. using storage_type = constness_as_t<typename storage_traits<Entity, std::remove_const_t<Component>>::storage_type, Component>;
  20481. public:
  20482. /*! @brief Underlying entity identifier. */
  20483. using entity_type = Entity;
  20484. /*! @brief Unsigned integer type. */
  20485. using size_type = std::size_t;
  20486. /*! @brief Common type among all storage types. */
  20487. using base_type = typename storage_type::base_type;
  20488. /*! @brief Random access iterator type. */
  20489. using iterator = typename base_type::iterator;
  20490. /*! @brief Reversed iterator type. */
  20491. using reverse_iterator = typename base_type::reverse_iterator;
  20492. /*! @brief Iterable view type. */
  20493. using iterable = decltype(std::declval<storage_type>().each());
  20494. /*! @brief Default constructor to use to create empty, invalid views. */
  20495. basic_view() ENTT_NOEXCEPT
  20496. : pools{},
  20497. filter{},
  20498. view{} {}
  20499. /**
  20500. * @brief Constructs a single-type view from a storage class.
  20501. * @param ref The storage for the type to iterate.
  20502. */
  20503. basic_view(storage_type &ref) ENTT_NOEXCEPT
  20504. : pools{&ref},
  20505. filter{},
  20506. view{&ref} {}
  20507. /**
  20508. * @brief Returns the leading storage of a view.
  20509. * @return The leading storage of the view.
  20510. */
  20511. const base_type &handle() const ENTT_NOEXCEPT {
  20512. return *view;
  20513. }
  20514. /**
  20515. * @brief Returns the storage for a given component type.
  20516. * @tparam Comp Type of component of which to return the storage.
  20517. * @return The storage for the given component type.
  20518. */
  20519. template<typename Comp = Component>
  20520. [[nodiscard]] decltype(auto) storage() const ENTT_NOEXCEPT {
  20521. static_assert(std::is_same_v<Comp, Component>, "Invalid component type");
  20522. return *std::get<0>(pools);
  20523. }
  20524. /**
  20525. * @brief Returns the storage for a given component type.
  20526. * @tparam Comp Index of component of which to return the storage.
  20527. * @return The storage for the given component type.
  20528. */
  20529. template<std::size_t Comp>
  20530. [[nodiscard]] decltype(auto) storage() const ENTT_NOEXCEPT {
  20531. return *std::get<Comp>(pools);
  20532. }
  20533. /**
  20534. * @brief Returns the number of entities that have the given component.
  20535. * @return Number of entities that have the given component.
  20536. */
  20537. [[nodiscard]] size_type size() const ENTT_NOEXCEPT {
  20538. return view->size();
  20539. }
  20540. /**
  20541. * @brief Checks whether a view is empty.
  20542. * @return True if the view is empty, false otherwise.
  20543. */
  20544. [[nodiscard]] bool empty() const ENTT_NOEXCEPT {
  20545. return view->empty();
  20546. }
  20547. /**
  20548. * @brief Returns an iterator to the first entity of the view.
  20549. *
  20550. * The returned iterator points to the first entity of the view. If the view
  20551. * is empty, the returned iterator will be equal to `end()`.
  20552. *
  20553. * @return An iterator to the first entity of the view.
  20554. */
  20555. [[nodiscard]] iterator begin() const ENTT_NOEXCEPT {
  20556. return view->begin();
  20557. }
  20558. /**
  20559. * @brief Returns an iterator that is past the last entity of the view.
  20560. *
  20561. * The returned iterator points to the entity following the last entity of
  20562. * the view. Attempting to dereference the returned iterator results in
  20563. * undefined behavior.
  20564. *
  20565. * @return An iterator to the entity following the last entity of the view.
  20566. */
  20567. [[nodiscard]] iterator end() const ENTT_NOEXCEPT {
  20568. return view->end();
  20569. }
  20570. /**
  20571. * @brief Returns an iterator to the first entity of the reversed view.
  20572. *
  20573. * The returned iterator points to the first entity of the reversed view. If
  20574. * the view is empty, the returned iterator will be equal to `rend()`.
  20575. *
  20576. * @return An iterator to the first entity of the reversed view.
  20577. */
  20578. [[nodiscard]] reverse_iterator rbegin() const ENTT_NOEXCEPT {
  20579. return view->rbegin();
  20580. }
  20581. /**
  20582. * @brief Returns an iterator that is past the last entity of the reversed
  20583. * view.
  20584. *
  20585. * The returned iterator points to the entity following the last entity of
  20586. * the reversed view. Attempting to dereference the returned iterator
  20587. * results in undefined behavior.
  20588. *
  20589. * @return An iterator to the entity following the last entity of the
  20590. * reversed view.
  20591. */
  20592. [[nodiscard]] reverse_iterator rend() const ENTT_NOEXCEPT {
  20593. return view->rend();
  20594. }
  20595. /**
  20596. * @brief Returns the first entity of the view, if any.
  20597. * @return The first entity of the view if one exists, the null entity
  20598. * otherwise.
  20599. */
  20600. [[nodiscard]] entity_type front() const ENTT_NOEXCEPT {
  20601. return empty() ? null : *begin();
  20602. }
  20603. /**
  20604. * @brief Returns the last entity of the view, if any.
  20605. * @return The last entity of the view if one exists, the null entity
  20606. * otherwise.
  20607. */
  20608. [[nodiscard]] entity_type back() const ENTT_NOEXCEPT {
  20609. return empty() ? null : *rbegin();
  20610. }
  20611. /**
  20612. * @brief Finds an entity.
  20613. * @param entt A valid identifier.
  20614. * @return An iterator to the given entity if it's found, past the end
  20615. * iterator otherwise.
  20616. */
  20617. [[nodiscard]] iterator find(const entity_type entt) const ENTT_NOEXCEPT {
  20618. return contains(entt) ? view->find(entt) : end();
  20619. }
  20620. /**
  20621. * @brief Returns the identifier that occupies the given position.
  20622. * @param pos Position of the element to return.
  20623. * @return The identifier that occupies the given position.
  20624. */
  20625. [[nodiscard]] entity_type operator[](const size_type pos) const {
  20626. return begin()[pos];
  20627. }
  20628. /**
  20629. * @brief Returns the component assigned to the given entity.
  20630. * @param entt A valid identifier.
  20631. * @return The component assigned to the given entity.
  20632. */
  20633. [[nodiscard]] decltype(auto) operator[](const entity_type entt) const {
  20634. return get<Component>(entt);
  20635. }
  20636. /**
  20637. * @brief Checks if a view is properly initialized.
  20638. * @return True if the view is properly initialized, false otherwise.
  20639. */
  20640. [[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
  20641. return view != nullptr;
  20642. }
  20643. /**
  20644. * @brief Checks if a view contains an entity.
  20645. * @param entt A valid identifier.
  20646. * @return True if the view contains the given entity, false otherwise.
  20647. */
  20648. [[nodiscard]] bool contains(const entity_type entt) const ENTT_NOEXCEPT {
  20649. return view->contains(entt);
  20650. }
  20651. /**
  20652. * @brief Returns the component assigned to the given entity.
  20653. *
  20654. * @warning
  20655. * Attempting to use an entity that doesn't belong to the view results in
  20656. * undefined behavior.
  20657. *
  20658. * @tparam Comp Type or index of the component to get.
  20659. * @param entt A valid identifier.
  20660. * @return The component assigned to the entity.
  20661. */
  20662. template<typename... Comp>
  20663. [[nodiscard]] decltype(auto) get(const entity_type entt) const {
  20664. ENTT_ASSERT(contains(entt), "View does not contain entity");
  20665. if constexpr(sizeof...(Comp) == 0) {
  20666. return std::get<0>(pools)->get_as_tuple(entt);
  20667. } else {
  20668. static_assert(std::is_same_v<Comp..., Component>, "Invalid component type");
  20669. return std::get<0>(pools)->get(entt);
  20670. }
  20671. }
  20672. /*! @copydoc get */
  20673. template<std::size_t Comp>
  20674. [[nodiscard]] decltype(auto) get(const entity_type entt) const {
  20675. ENTT_ASSERT(contains(entt), "View does not contain entity");
  20676. return std::get<0>(pools)->get(entt);
  20677. }
  20678. /**
  20679. * @brief Iterates entities and components and applies the given function
  20680. * object to them.
  20681. *
  20682. * The function object is invoked for each entity. It is provided with the
  20683. * entity itself and a reference to the component if it's a non-empty one.
  20684. * The _constness_ of the component is as requested.<br/>
  20685. * The signature of the function must be equivalent to one of the following
  20686. * forms:
  20687. *
  20688. * @code{.cpp}
  20689. * void(const entity_type, Component &);
  20690. * void(Component &);
  20691. * @endcode
  20692. *
  20693. * @tparam Func Type of the function object to invoke.
  20694. * @param func A valid function object.
  20695. */
  20696. template<typename Func>
  20697. void each(Func func) const {
  20698. if constexpr(is_applicable_v<Func, decltype(*each().begin())>) {
  20699. for(const auto pack: each()) {
  20700. std::apply(func, pack);
  20701. }
  20702. } else if constexpr(std::is_invocable_v<Func, Component &>) {
  20703. for(auto &&component: *std::get<0>(pools)) {
  20704. func(component);
  20705. }
  20706. } else if constexpr(std::is_invocable_v<Func, Entity>) {
  20707. for(auto entity: *view) {
  20708. func(entity);
  20709. }
  20710. } else {
  20711. for(size_type pos{}, last = size(); pos < last; ++pos) {
  20712. func();
  20713. }
  20714. }
  20715. }
  20716. /**
  20717. * @brief Returns an iterable object to use to _visit_ a view.
  20718. *
  20719. * The iterable object returns a tuple that contains the current entity and
  20720. * a reference to its component if it's a non-empty one. The _constness_ of
  20721. * the component is as requested.
  20722. *
  20723. * @return An iterable object to use to _visit_ the view.
  20724. */
  20725. [[nodiscard]] iterable each() const ENTT_NOEXCEPT {
  20726. return std::get<0>(pools)->each();
  20727. }
  20728. /**
  20729. * @brief Combines two views in a _more specific_ one (friend function).
  20730. * @tparam Get Component list of the view to combine with.
  20731. * @tparam Excl Filter list of the view to combine with.
  20732. * @param other The view to combine with.
  20733. * @return A more specific view.
  20734. */
  20735. template<typename... Get, typename... Excl>
  20736. [[nodiscard]] auto operator|(const basic_view<Entity, get_t<Get...>, exclude_t<Excl...>> &other) const ENTT_NOEXCEPT {
  20737. using view_type = basic_view<Entity, get_t<Component, Get...>, exclude_t<Excl...>>;
  20738. return std::make_from_tuple<view_type>(std::tuple_cat(
  20739. std::forward_as_tuple(*std::get<0>(pools)),
  20740. std::apply([](auto *...curr) { return std::forward_as_tuple(*curr...); }, other.pools),
  20741. std::apply([](const auto *...curr) { return std::forward_as_tuple(static_cast<const typename view_type::template storage_type<Excl> &>(*curr)...); }, other.filter)));
  20742. }
  20743. private:
  20744. std::tuple<storage_type *> pools;
  20745. std::array<const base_type *, 0u> filter;
  20746. const base_type *view;
  20747. };
  20748. /**
  20749. * @brief Deduction guide.
  20750. * @tparam Storage Type of storage classes used to create the view.
  20751. * @param storage The storage for the types to iterate.
  20752. */
  20753. template<typename... Storage>
  20754. basic_view(Storage &...storage) -> basic_view<std::common_type_t<typename Storage::entity_type...>, get_t<constness_as_t<typename Storage::value_type, Storage>...>, exclude_t<>>;
  20755. } // namespace entt
  20756. #endif
  20757. namespace entt {
  20758. /**
  20759. * @cond TURN_OFF_DOXYGEN
  20760. * Internal details not to be documented.
  20761. */
  20762. namespace internal {
  20763. template<typename It>
  20764. class storage_proxy_iterator final {
  20765. template<typename Other>
  20766. friend class storage_proxy_iterator;
  20767. using mapped_type = std::remove_reference_t<decltype(std::declval<It>()->second)>;
  20768. public:
  20769. using value_type = std::pair<id_type, constness_as_t<typename mapped_type::element_type, mapped_type> &>;
  20770. using pointer = input_iterator_pointer<value_type>;
  20771. using reference = value_type;
  20772. using difference_type = std::ptrdiff_t;
  20773. using iterator_category = std::input_iterator_tag;
  20774. storage_proxy_iterator() ENTT_NOEXCEPT
  20775. : it{} {}
  20776. storage_proxy_iterator(const It iter) ENTT_NOEXCEPT
  20777. : it{iter} {}
  20778. template<typename Other, typename = std::enable_if_t<!std::is_same_v<It, Other> && std::is_constructible_v<It, Other>>>
  20779. storage_proxy_iterator(const storage_proxy_iterator<Other> &other) ENTT_NOEXCEPT
  20780. : it{other.it} {}
  20781. storage_proxy_iterator &operator++() ENTT_NOEXCEPT {
  20782. return ++it, *this;
  20783. }
  20784. storage_proxy_iterator operator++(int) ENTT_NOEXCEPT {
  20785. storage_proxy_iterator orig = *this;
  20786. return ++(*this), orig;
  20787. }
  20788. storage_proxy_iterator &operator--() ENTT_NOEXCEPT {
  20789. return --it, *this;
  20790. }
  20791. storage_proxy_iterator operator--(int) ENTT_NOEXCEPT {
  20792. storage_proxy_iterator orig = *this;
  20793. return operator--(), orig;
  20794. }
  20795. storage_proxy_iterator &operator+=(const difference_type value) ENTT_NOEXCEPT {
  20796. it += value;
  20797. return *this;
  20798. }
  20799. storage_proxy_iterator operator+(const difference_type value) const ENTT_NOEXCEPT {
  20800. storage_proxy_iterator copy = *this;
  20801. return (copy += value);
  20802. }
  20803. storage_proxy_iterator &operator-=(const difference_type value) ENTT_NOEXCEPT {
  20804. return (*this += -value);
  20805. }
  20806. storage_proxy_iterator operator-(const difference_type value) const ENTT_NOEXCEPT {
  20807. return (*this + -value);
  20808. }
  20809. [[nodiscard]] reference operator[](const difference_type value) const ENTT_NOEXCEPT {
  20810. return {it[value].first, *it[value].second};
  20811. }
  20812. [[nodiscard]] reference operator*() const ENTT_NOEXCEPT {
  20813. return {it->first, *it->second};
  20814. }
  20815. [[nodiscard]] pointer operator->() const ENTT_NOEXCEPT {
  20816. return operator*();
  20817. }
  20818. template<typename ILhs, typename IRhs>
  20819. friend std::ptrdiff_t operator-(const storage_proxy_iterator<ILhs> &, const storage_proxy_iterator<IRhs> &) ENTT_NOEXCEPT;
  20820. template<typename ILhs, typename IRhs>
  20821. friend bool operator==(const storage_proxy_iterator<ILhs> &, const storage_proxy_iterator<IRhs> &) ENTT_NOEXCEPT;
  20822. template<typename ILhs, typename IRhs>
  20823. friend bool operator<(const storage_proxy_iterator<ILhs> &, const storage_proxy_iterator<IRhs> &) ENTT_NOEXCEPT;
  20824. private:
  20825. It it;
  20826. };
  20827. template<typename ILhs, typename IRhs>
  20828. [[nodiscard]] std::ptrdiff_t operator-(const storage_proxy_iterator<ILhs> &lhs, const storage_proxy_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  20829. return lhs.it - rhs.it;
  20830. }
  20831. template<typename ILhs, typename IRhs>
  20832. [[nodiscard]] bool operator==(const storage_proxy_iterator<ILhs> &lhs, const storage_proxy_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  20833. return lhs.it == rhs.it;
  20834. }
  20835. template<typename ILhs, typename IRhs>
  20836. [[nodiscard]] bool operator!=(const storage_proxy_iterator<ILhs> &lhs, const storage_proxy_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  20837. return !(lhs == rhs);
  20838. }
  20839. template<typename ILhs, typename IRhs>
  20840. [[nodiscard]] bool operator<(const storage_proxy_iterator<ILhs> &lhs, const storage_proxy_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  20841. return lhs.it < rhs.it;
  20842. }
  20843. template<typename ILhs, typename IRhs>
  20844. [[nodiscard]] bool operator>(const storage_proxy_iterator<ILhs> &lhs, const storage_proxy_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  20845. return rhs < lhs;
  20846. }
  20847. template<typename ILhs, typename IRhs>
  20848. [[nodiscard]] bool operator<=(const storage_proxy_iterator<ILhs> &lhs, const storage_proxy_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  20849. return !(lhs > rhs);
  20850. }
  20851. template<typename ILhs, typename IRhs>
  20852. [[nodiscard]] bool operator>=(const storage_proxy_iterator<ILhs> &lhs, const storage_proxy_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  20853. return !(lhs < rhs);
  20854. }
  20855. struct registry_context {
  20856. template<typename Type, typename... Args>
  20857. Type &emplace_hint(const id_type id, Args &&...args) {
  20858. return any_cast<Type &>(data.try_emplace(id, std::in_place_type<Type>, std::forward<Args>(args)...).first->second);
  20859. }
  20860. template<typename Type, typename... Args>
  20861. Type &emplace(Args &&...args) {
  20862. return emplace_hint<Type>(type_id<Type>().hash(), std::forward<Args>(args)...);
  20863. }
  20864. template<typename Type>
  20865. bool erase(const id_type id = type_id<Type>().hash()) {
  20866. const auto it = data.find(id);
  20867. return it != data.end() && it->second.type() == type_id<Type>() ? (data.erase(it), true) : false;
  20868. }
  20869. template<typename Type>
  20870. [[nodiscard]] std::add_const_t<Type> &at(const id_type id = type_id<Type>().hash()) const {
  20871. return any_cast<std::add_const_t<Type> &>(data.at(id));
  20872. }
  20873. template<typename Type>
  20874. [[nodiscard]] Type &at(const id_type id = type_id<Type>().hash()) {
  20875. return any_cast<Type &>(data.at(id));
  20876. }
  20877. template<typename Type>
  20878. [[nodiscard]] std::add_const_t<Type> *find(const id_type id = type_id<Type>().hash()) const {
  20879. const auto it = data.find(id);
  20880. return it != data.cend() ? any_cast<std::add_const_t<Type>>(&it->second) : nullptr;
  20881. }
  20882. template<typename Type>
  20883. [[nodiscard]] Type *find(const id_type id = type_id<Type>().hash()) {
  20884. const auto it = data.find(id);
  20885. return it != data.end() ? any_cast<Type>(&it->second) : nullptr;
  20886. }
  20887. template<typename Type>
  20888. [[nodiscard]] bool contains(const id_type id = type_id<Type>().hash()) const {
  20889. const auto it = data.find(id);
  20890. return it != data.end() && it->second.type() == type_id<Type>();
  20891. }
  20892. private:
  20893. dense_map<id_type, basic_any<0u>, identity> data;
  20894. };
  20895. } // namespace internal
  20896. /**
  20897. * Internal details not to be documented.
  20898. * @endcond
  20899. */
  20900. /**
  20901. * @brief Fast and reliable entity-component system.
  20902. * @tparam Entity A valid entity type (see entt_traits for more details).
  20903. */
  20904. template<typename Entity>
  20905. class basic_registry {
  20906. using entity_traits = entt_traits<Entity>;
  20907. using basic_common_type = basic_sparse_set<Entity>;
  20908. template<typename Component>
  20909. using storage_type = typename storage_traits<Entity, Component>::storage_type;
  20910. template<typename...>
  20911. struct group_handler;
  20912. template<typename... Exclude, typename... Get, typename... Owned>
  20913. struct group_handler<exclude_t<Exclude...>, get_t<Get...>, Owned...> {
  20914. // nasty workaround for an issue with the toolset v141 that doesn't accept a fold expression here
  20915. static_assert(!std::disjunction_v<std::bool_constant<component_traits<Owned>::in_place_delete>...>, "Groups do not support in-place delete");
  20916. std::conditional_t<sizeof...(Owned) == 0, basic_common_type, std::size_t> current{};
  20917. template<typename Component>
  20918. void maybe_valid_if(basic_registry &owner, const Entity entt) {
  20919. [[maybe_unused]] const auto cpools = std::forward_as_tuple(owner.assure<Owned>()...);
  20920. const auto is_valid = ((std::is_same_v<Component, Owned> || std::get<storage_type<Owned> &>(cpools).contains(entt)) && ...)
  20921. && ((std::is_same_v<Component, Get> || owner.assure<Get>().contains(entt)) && ...)
  20922. && ((std::is_same_v<Component, Exclude> || !owner.assure<Exclude>().contains(entt)) && ...);
  20923. if constexpr(sizeof...(Owned) == 0) {
  20924. if(is_valid && !current.contains(entt)) {
  20925. current.emplace(entt);
  20926. }
  20927. } else {
  20928. if(is_valid && !(std::get<0>(cpools).index(entt) < current)) {
  20929. const auto pos = current++;
  20930. (std::get<storage_type<Owned> &>(cpools).swap_elements(std::get<storage_type<Owned> &>(cpools).data()[pos], entt), ...);
  20931. }
  20932. }
  20933. }
  20934. void discard_if([[maybe_unused]] basic_registry &owner, const Entity entt) {
  20935. if constexpr(sizeof...(Owned) == 0) {
  20936. current.remove(entt);
  20937. } else {
  20938. if(const auto cpools = std::forward_as_tuple(owner.assure<Owned>()...); std::get<0>(cpools).contains(entt) && (std::get<0>(cpools).index(entt) < current)) {
  20939. const auto pos = --current;
  20940. (std::get<storage_type<Owned> &>(cpools).swap_elements(std::get<storage_type<Owned> &>(cpools).data()[pos], entt), ...);
  20941. }
  20942. }
  20943. }
  20944. };
  20945. struct group_data {
  20946. std::size_t size;
  20947. std::unique_ptr<void, void (*)(void *)> group;
  20948. bool (*owned)(const id_type) ENTT_NOEXCEPT;
  20949. bool (*get)(const id_type) ENTT_NOEXCEPT;
  20950. bool (*exclude)(const id_type) ENTT_NOEXCEPT;
  20951. };
  20952. template<typename Component>
  20953. [[nodiscard]] auto &assure(const id_type id = type_hash<Component>::value()) {
  20954. static_assert(std::is_same_v<Component, std::decay_t<Component>>, "Non-decayed types not allowed");
  20955. auto &&cpool = pools[id];
  20956. if(!cpool) {
  20957. cpool.reset(new storage_type<Component>{});
  20958. cpool->bind(forward_as_any(*this));
  20959. }
  20960. ENTT_ASSERT(cpool->type() == type_id<Component>(), "Unexpected type");
  20961. return static_cast<storage_type<Component> &>(*cpool);
  20962. }
  20963. template<typename Component>
  20964. [[nodiscard]] const auto &assure(const id_type id = type_hash<Component>::value()) const {
  20965. static_assert(std::is_same_v<Component, std::decay_t<Component>>, "Non-decayed types not allowed");
  20966. if(const auto it = pools.find(id); it != pools.cend()) {
  20967. ENTT_ASSERT(it->second->type() == type_id<Component>(), "Unexpected type");
  20968. return static_cast<const storage_type<Component> &>(*it->second);
  20969. }
  20970. static storage_type<Component> placeholder{};
  20971. return placeholder;
  20972. }
  20973. auto generate_identifier(const std::size_t pos) ENTT_NOEXCEPT {
  20974. ENTT_ASSERT(pos < entity_traits::to_entity(null), "No entities available");
  20975. return entity_traits::combine(static_cast<typename entity_traits::entity_type>(pos), {});
  20976. }
  20977. auto recycle_identifier() ENTT_NOEXCEPT {
  20978. ENTT_ASSERT(free_list != null, "No entities available");
  20979. const auto curr = entity_traits::to_entity(free_list);
  20980. free_list = entity_traits::combine(entity_traits::to_integral(entities[curr]), tombstone);
  20981. return (entities[curr] = entity_traits::combine(curr, entity_traits::to_integral(entities[curr])));
  20982. }
  20983. auto release_entity(const Entity entity, const typename entity_traits::version_type version) {
  20984. const typename entity_traits::version_type vers = version + (version == entity_traits::to_version(tombstone));
  20985. entities[entity_traits::to_entity(entity)] = entity_traits::construct(entity_traits::to_integral(free_list), vers);
  20986. free_list = entity_traits::combine(entity_traits::to_integral(entity), tombstone);
  20987. return vers;
  20988. }
  20989. public:
  20990. /*! @brief Underlying entity identifier. */
  20991. using entity_type = Entity;
  20992. /*! @brief Underlying version type. */
  20993. using version_type = typename entity_traits::version_type;
  20994. /*! @brief Unsigned integer type. */
  20995. using size_type = std::size_t;
  20996. /*! @brief Common type among all storage types. */
  20997. using base_type = basic_common_type;
  20998. /*! @brief Context type. */
  20999. using context = internal::registry_context;
  21000. /*! @brief Default constructor. */
  21001. basic_registry()
  21002. : pools{},
  21003. groups{},
  21004. entities{},
  21005. free_list{tombstone},
  21006. vars{} {}
  21007. /**
  21008. * @brief Allocates enough memory upon construction to store `count` pools.
  21009. * @param count The number of pools to allocate memory for.
  21010. */
  21011. basic_registry(const size_type count)
  21012. : pools{},
  21013. groups{},
  21014. entities{},
  21015. free_list{tombstone},
  21016. vars{} {
  21017. pools.reserve(count);
  21018. }
  21019. /**
  21020. * @brief Move constructor.
  21021. * @param other The instance to move from.
  21022. */
  21023. basic_registry(basic_registry &&other)
  21024. : pools{std::move(other.pools)},
  21025. groups{std::move(other.groups)},
  21026. entities{std::move(other.entities)},
  21027. free_list{other.free_list},
  21028. vars{std::move(other.vars)} {
  21029. for(auto &&curr: pools) {
  21030. curr.second->bind(forward_as_any(*this));
  21031. }
  21032. }
  21033. /**
  21034. * @brief Move assignment operator.
  21035. * @param other The instance to move from.
  21036. * @return This registry.
  21037. */
  21038. basic_registry &operator=(basic_registry &&other) {
  21039. pools = std::move(other.pools);
  21040. groups = std::move(other.groups);
  21041. entities = std::move(other.entities);
  21042. free_list = other.free_list;
  21043. vars = std::move(other.vars);
  21044. for(auto &&curr: pools) {
  21045. curr.second->bind(forward_as_any(*this));
  21046. }
  21047. return *this;
  21048. }
  21049. /**
  21050. * @brief Returns an iterable object to use to _visit_ a registry.
  21051. *
  21052. * The iterable object returns a pair that contains the name and a reference
  21053. * to the current storage.
  21054. *
  21055. * @return An iterable object to use to _visit_ the registry.
  21056. */
  21057. [[nodiscard]] auto storage() ENTT_NOEXCEPT {
  21058. return iterable_adaptor{internal::storage_proxy_iterator{pools.begin()}, internal::storage_proxy_iterator{pools.end()}};
  21059. }
  21060. /*! @copydoc storage */
  21061. [[nodiscard]] auto storage() const ENTT_NOEXCEPT {
  21062. return iterable_adaptor{internal::storage_proxy_iterator{pools.cbegin()}, internal::storage_proxy_iterator{pools.cend()}};
  21063. }
  21064. /**
  21065. * @brief Finds the storage associated with a given name, if any.
  21066. * @param id Name used to map the storage within the registry.
  21067. * @return An iterator to the given storage if it's found, past the end
  21068. * iterator otherwise.
  21069. */
  21070. [[nodiscard]] auto storage(const id_type id) {
  21071. return internal::storage_proxy_iterator{pools.find(id)};
  21072. }
  21073. /**
  21074. * @brief Finds the storage associated with a given name, if any.
  21075. * @param id Name used to map the storage within the registry.
  21076. * @return An iterator to the given storage if it's found, past the end
  21077. * iterator otherwise.
  21078. */
  21079. [[nodiscard]] auto storage(const id_type id) const {
  21080. return internal::storage_proxy_iterator{pools.find(id)};
  21081. }
  21082. /**
  21083. * @brief Returns the storage for a given component type.
  21084. * @tparam Component Type of component of which to return the storage.
  21085. * @param id Optional name used to map the storage within the registry.
  21086. * @return The storage for the given component type.
  21087. */
  21088. template<typename Component>
  21089. decltype(auto) storage(const id_type id = type_hash<std::remove_const_t<Component>>::value()) {
  21090. if constexpr(std::is_const_v<Component>) {
  21091. return std::as_const(*this).template storage<std::remove_const_t<Component>>(id);
  21092. } else {
  21093. return assure<Component>(id);
  21094. }
  21095. }
  21096. /**
  21097. * @brief Returns the storage for a given component type.
  21098. *
  21099. * @warning
  21100. * If a storage for the given component doesn't exist yet, a temporary
  21101. * placeholder is returned instead.
  21102. *
  21103. * @tparam Component Type of component of which to return the storage.
  21104. * @param id Optional name used to map the storage within the registry.
  21105. * @return The storage for the given component type.
  21106. */
  21107. template<typename Component>
  21108. decltype(auto) storage(const id_type id = type_hash<std::remove_const_t<Component>>::value()) const {
  21109. return assure<std::remove_const_t<Component>>(id);
  21110. }
  21111. /**
  21112. * @brief Returns the number of entities created so far.
  21113. * @return Number of entities created so far.
  21114. */
  21115. [[nodiscard]] size_type size() const ENTT_NOEXCEPT {
  21116. return entities.size();
  21117. }
  21118. /**
  21119. * @brief Returns the number of entities still in use.
  21120. * @return Number of entities still in use.
  21121. */
  21122. [[nodiscard]] size_type alive() const {
  21123. auto sz = entities.size();
  21124. for(auto curr = free_list; curr != null; --sz) {
  21125. curr = entities[entity_traits::to_entity(curr)];
  21126. }
  21127. return sz;
  21128. }
  21129. /**
  21130. * @brief Increases the capacity (number of entities) of the registry.
  21131. * @param cap Desired capacity.
  21132. */
  21133. void reserve(const size_type cap) {
  21134. entities.reserve(cap);
  21135. }
  21136. /**
  21137. * @brief Returns the number of entities that a registry has currently
  21138. * allocated space for.
  21139. * @return Capacity of the registry.
  21140. */
  21141. [[nodiscard]] size_type capacity() const ENTT_NOEXCEPT {
  21142. return entities.capacity();
  21143. }
  21144. /**
  21145. * @brief Checks whether the registry is empty (no entities still in use).
  21146. * @return True if the registry is empty, false otherwise.
  21147. */
  21148. [[nodiscard]] bool empty() const {
  21149. return !alive();
  21150. }
  21151. /**
  21152. * @brief Direct access to the list of entities of a registry.
  21153. *
  21154. * The returned pointer is such that range `[data(), data() + size())` is
  21155. * always a valid range, even if the registry is empty.
  21156. *
  21157. * @warning
  21158. * This list contains both valid and destroyed entities and isn't suitable
  21159. * for direct use.
  21160. *
  21161. * @return A pointer to the array of entities.
  21162. */
  21163. [[nodiscard]] const entity_type *data() const ENTT_NOEXCEPT {
  21164. return entities.data();
  21165. }
  21166. /**
  21167. * @brief Returns the head of the list of released entities.
  21168. *
  21169. * This function is intended for use in conjunction with `assign`.<br/>
  21170. * The returned entity has an invalid identifier in all cases.
  21171. *
  21172. * @return The head of the list of released entities.
  21173. */
  21174. [[nodiscard]] entity_type released() const ENTT_NOEXCEPT {
  21175. return free_list;
  21176. }
  21177. /**
  21178. * @brief Checks if an identifier refers to a valid entity.
  21179. * @param entity An identifier, either valid or not.
  21180. * @return True if the identifier is valid, false otherwise.
  21181. */
  21182. [[nodiscard]] bool valid(const entity_type entity) const {
  21183. const auto pos = size_type(entity_traits::to_entity(entity));
  21184. return (pos < entities.size() && entities[pos] == entity);
  21185. }
  21186. /**
  21187. * @brief Returns the actual version for an identifier.
  21188. * @param entity A valid identifier.
  21189. * @return The version for the given identifier if valid, the tombstone
  21190. * version otherwise.
  21191. */
  21192. [[nodiscard]] version_type current(const entity_type entity) const {
  21193. const auto pos = size_type(entity_traits::to_entity(entity));
  21194. return entity_traits::to_version(pos < entities.size() ? entities[pos] : tombstone);
  21195. }
  21196. /**
  21197. * @brief Creates a new entity or recycles a destroyed one.
  21198. * @return A valid identifier.
  21199. */
  21200. [[nodiscard]] entity_type create() {
  21201. return (free_list == null) ? entities.emplace_back(generate_identifier(entities.size())) : recycle_identifier();
  21202. }
  21203. /**
  21204. * @copybrief create
  21205. *
  21206. * If the requested entity isn't in use, the suggested identifier is used.
  21207. * Otherwise, a new identifier is generated.
  21208. *
  21209. * @param hint Required identifier.
  21210. * @return A valid identifier.
  21211. */
  21212. [[nodiscard]] entity_type create(const entity_type hint) {
  21213. const auto length = entities.size();
  21214. if(hint == null || hint == tombstone) {
  21215. return create();
  21216. } else if(const auto req = entity_traits::to_entity(hint); !(req < length)) {
  21217. entities.resize(size_type(req) + 1u, null);
  21218. for(auto pos = length; pos < req; ++pos) {
  21219. release_entity(generate_identifier(pos), {});
  21220. }
  21221. return (entities[req] = hint);
  21222. } else if(const auto curr = entity_traits::to_entity(entities[req]); req == curr) {
  21223. return create();
  21224. } else {
  21225. auto *it = &free_list;
  21226. for(; entity_traits::to_entity(*it) != req; it = &entities[entity_traits::to_entity(*it)]) {}
  21227. *it = entity_traits::combine(curr, entity_traits::to_integral(*it));
  21228. return (entities[req] = hint);
  21229. }
  21230. }
  21231. /**
  21232. * @brief Assigns each element in a range an identifier.
  21233. *
  21234. * @sa create
  21235. *
  21236. * @tparam It Type of forward iterator.
  21237. * @param first An iterator to the first element of the range to generate.
  21238. * @param last An iterator past the last element of the range to generate.
  21239. */
  21240. template<typename It>
  21241. void create(It first, It last) {
  21242. for(; free_list != null && first != last; ++first) {
  21243. *first = recycle_identifier();
  21244. }
  21245. const auto length = entities.size();
  21246. entities.resize(length + std::distance(first, last), null);
  21247. for(auto pos = length; first != last; ++first, ++pos) {
  21248. *first = entities[pos] = generate_identifier(pos);
  21249. }
  21250. }
  21251. /**
  21252. * @brief Assigns identifiers to an empty registry.
  21253. *
  21254. * This function is intended for use in conjunction with `data`, `size` and
  21255. * `destroyed`.<br/>
  21256. * Don't try to inject ranges of randomly generated entities nor the _wrong_
  21257. * head for the list of destroyed entities. There is no guarantee that a
  21258. * registry will continue to work properly in this case.
  21259. *
  21260. * @warning
  21261. * There must be no entities still alive for this to work properly.
  21262. *
  21263. * @tparam It Type of input iterator.
  21264. * @param first An iterator to the first element of the range of entities.
  21265. * @param last An iterator past the last element of the range of entities.
  21266. * @param destroyed The head of the list of destroyed entities.
  21267. */
  21268. template<typename It>
  21269. void assign(It first, It last, const entity_type destroyed) {
  21270. ENTT_ASSERT(!alive(), "Entities still alive");
  21271. entities.assign(first, last);
  21272. free_list = destroyed;
  21273. }
  21274. /**
  21275. * @brief Releases an identifier.
  21276. *
  21277. * The version is updated and the identifier can be recycled at any time.
  21278. *
  21279. * @warning
  21280. * Attempting to use an invalid entity results in undefined behavior.
  21281. *
  21282. * @param entity A valid identifier.
  21283. * @return The version of the recycled entity.
  21284. */
  21285. version_type release(const entity_type entity) {
  21286. return release(entity, static_cast<version_type>(entity_traits::to_version(entity) + 1u));
  21287. }
  21288. /**
  21289. * @brief Releases an identifier.
  21290. *
  21291. * The suggested version or the valid version closest to the suggested one
  21292. * is used instead of the implicitly generated version.
  21293. *
  21294. * @sa release
  21295. *
  21296. * @param entity A valid identifier.
  21297. * @param version A desired version upon destruction.
  21298. * @return The version actually assigned to the entity.
  21299. */
  21300. version_type release(const entity_type entity, const version_type version) {
  21301. ENTT_ASSERT(orphan(entity), "Non-orphan entity");
  21302. return release_entity(entity, version);
  21303. }
  21304. /**
  21305. * @brief Releases all identifiers in a range.
  21306. *
  21307. * @sa release
  21308. *
  21309. * @tparam It Type of input iterator.
  21310. * @param first An iterator to the first element of the range of entities.
  21311. * @param last An iterator past the last element of the range of entities.
  21312. */
  21313. template<typename It>
  21314. void release(It first, It last) {
  21315. for(; first != last; ++first) {
  21316. release(*first);
  21317. }
  21318. }
  21319. /**
  21320. * @brief Destroys an entity and releases its identifier.
  21321. *
  21322. * @sa release
  21323. *
  21324. * @warning
  21325. * Adding or removing components to an entity that is being destroyed can
  21326. * result in undefined behavior. Attempting to use an invalid entity results
  21327. * in undefined behavior.
  21328. *
  21329. * @param entity A valid identifier.
  21330. * @return The version of the recycled entity.
  21331. */
  21332. version_type destroy(const entity_type entity) {
  21333. return destroy(entity, static_cast<version_type>(entity_traits::to_version(entity) + 1u));
  21334. }
  21335. /**
  21336. * @brief Destroys an entity and releases its identifier.
  21337. *
  21338. * The suggested version or the valid version closest to the suggested one
  21339. * is used instead of the implicitly generated version.
  21340. *
  21341. * @sa destroy
  21342. *
  21343. * @param entity A valid identifier.
  21344. * @param version A desired version upon destruction.
  21345. * @return The version actually assigned to the entity.
  21346. */
  21347. version_type destroy(const entity_type entity, const version_type version) {
  21348. ENTT_ASSERT(valid(entity), "Invalid entity");
  21349. for(size_type pos = pools.size(); pos; --pos) {
  21350. pools.begin()[pos - 1u].second->remove(entity);
  21351. }
  21352. return release_entity(entity, version);
  21353. }
  21354. /**
  21355. * @brief Destroys all entities in a range and releases their identifiers.
  21356. *
  21357. * @sa destroy
  21358. *
  21359. * @tparam It Type of input iterator.
  21360. * @param first An iterator to the first element of the range of entities.
  21361. * @param last An iterator past the last element of the range of entities.
  21362. */
  21363. template<typename It>
  21364. void destroy(It first, It last) {
  21365. for(; first != last; ++first) {
  21366. destroy(*first);
  21367. }
  21368. }
  21369. /**
  21370. * @brief Assigns the given component to an entity.
  21371. *
  21372. * The component must have a proper constructor or be of aggregate type.
  21373. *
  21374. * @warning
  21375. * Attempting to use an invalid entity or to assign a component to an entity
  21376. * that already owns it results in undefined behavior.
  21377. *
  21378. * @tparam Component Type of component to create.
  21379. * @tparam Args Types of arguments to use to construct the component.
  21380. * @param entity A valid identifier.
  21381. * @param args Parameters to use to initialize the component.
  21382. * @return A reference to the newly created component.
  21383. */
  21384. template<typename Component, typename... Args>
  21385. decltype(auto) emplace(const entity_type entity, Args &&...args) {
  21386. ENTT_ASSERT(valid(entity), "Invalid entity");
  21387. return assure<Component>().emplace(entity, std::forward<Args>(args)...);
  21388. }
  21389. /**
  21390. * @brief Assigns each entity in a range the given component.
  21391. *
  21392. * @sa emplace
  21393. *
  21394. * @tparam Component Type of component to create.
  21395. * @tparam It Type of input iterator.
  21396. * @param first An iterator to the first element of the range of entities.
  21397. * @param last An iterator past the last element of the range of entities.
  21398. * @param value An instance of the component to assign.
  21399. */
  21400. template<typename Component, typename It>
  21401. void insert(It first, It last, const Component &value = {}) {
  21402. ENTT_ASSERT(std::all_of(first, last, [this](const auto entity) { return valid(entity); }), "Invalid entity");
  21403. assure<Component>().insert(first, last, value);
  21404. }
  21405. /**
  21406. * @brief Assigns each entity in a range the given components.
  21407. *
  21408. * @sa emplace
  21409. *
  21410. * @tparam Component Type of component to create.
  21411. * @tparam EIt Type of input iterator.
  21412. * @tparam CIt Type of input iterator.
  21413. * @param first An iterator to the first element of the range of entities.
  21414. * @param last An iterator past the last element of the range of entities.
  21415. * @param from An iterator to the first element of the range of components.
  21416. */
  21417. template<typename Component, typename EIt, typename CIt, typename = std::enable_if_t<std::is_same_v<typename std::iterator_traits<CIt>::value_type, Component>>>
  21418. void insert(EIt first, EIt last, CIt from) {
  21419. ENTT_ASSERT(std::all_of(first, last, [this](const auto entity) { return valid(entity); }), "Invalid entity");
  21420. assure<Component>().insert(first, last, from);
  21421. }
  21422. /**
  21423. * @brief Assigns or replaces the given component for an entity.
  21424. *
  21425. * @warning
  21426. * Attempting to use an invalid entity results in undefined behavior.
  21427. *
  21428. * @tparam Component Type of component to assign or replace.
  21429. * @tparam Args Types of arguments to use to construct the component.
  21430. * @param entity A valid identifier.
  21431. * @param args Parameters to use to initialize the component.
  21432. * @return A reference to the newly created component.
  21433. */
  21434. template<typename Component, typename... Args>
  21435. decltype(auto) emplace_or_replace(const entity_type entity, Args &&...args) {
  21436. ENTT_ASSERT(valid(entity), "Invalid entity");
  21437. auto &cpool = assure<Component>();
  21438. return cpool.contains(entity)
  21439. ? cpool.patch(entity, [&args...](auto &...curr) { ((curr = Component{std::forward<Args>(args)...}), ...); })
  21440. : cpool.emplace(entity, std::forward<Args>(args)...);
  21441. }
  21442. /**
  21443. * @brief Patches the given component for an entity.
  21444. *
  21445. * The signature of the function should be equivalent to the following:
  21446. *
  21447. * @code{.cpp}
  21448. * void(Component &);
  21449. * @endcode
  21450. *
  21451. * @note
  21452. * Empty types aren't explicitly instantiated and therefore they are never
  21453. * returned. However, this function can be used to trigger an update signal
  21454. * for them.
  21455. *
  21456. * @warning
  21457. * Attempting to use an invalid entity or to patch a component of an entity
  21458. * that doesn't own it results in undefined behavior.
  21459. *
  21460. * @tparam Component Type of component to patch.
  21461. * @tparam Func Types of the function objects to invoke.
  21462. * @param entity A valid identifier.
  21463. * @param func Valid function objects.
  21464. * @return A reference to the patched component.
  21465. */
  21466. template<typename Component, typename... Func>
  21467. decltype(auto) patch(const entity_type entity, Func &&...func) {
  21468. ENTT_ASSERT(valid(entity), "Invalid entity");
  21469. return assure<Component>().patch(entity, std::forward<Func>(func)...);
  21470. }
  21471. /**
  21472. * @brief Replaces the given component for an entity.
  21473. *
  21474. * The component must have a proper constructor or be of aggregate type.
  21475. *
  21476. * @warning
  21477. * Attempting to use an invalid entity or to replace a component of an
  21478. * entity that doesn't own it results in undefined behavior.
  21479. *
  21480. * @tparam Component Type of component to replace.
  21481. * @tparam Args Types of arguments to use to construct the component.
  21482. * @param entity A valid identifier.
  21483. * @param args Parameters to use to initialize the component.
  21484. * @return A reference to the component being replaced.
  21485. */
  21486. template<typename Component, typename... Args>
  21487. decltype(auto) replace(const entity_type entity, Args &&...args) {
  21488. ENTT_ASSERT(valid(entity), "Invalid entity");
  21489. return assure<Component>().patch(entity, [&args...](auto &...curr) { ((curr = Component{std::forward<Args>(args)...}), ...); });
  21490. }
  21491. /**
  21492. * @brief Removes the given components from an entity.
  21493. *
  21494. * @warning
  21495. * Attempting to use an invalid entity results in undefined behavior.
  21496. *
  21497. * @tparam Component Type of component to remove.
  21498. * @tparam Other Other types of components to remove.
  21499. * @param entity A valid identifier.
  21500. * @return The number of components actually removed.
  21501. */
  21502. template<typename Component, typename... Other>
  21503. size_type remove(const entity_type entity) {
  21504. ENTT_ASSERT(valid(entity), "Invalid entity");
  21505. return (assure<Component>().remove(entity) + ... + assure<Other>().remove(entity));
  21506. }
  21507. /**
  21508. * @brief Removes the given components from all the entities in a range.
  21509. *
  21510. * @sa remove
  21511. *
  21512. * @tparam Component Type of component to remove.
  21513. * @tparam Other Other types of components to remove.
  21514. * @tparam It Type of input iterator.
  21515. * @param first An iterator to the first element of the range of entities.
  21516. * @param last An iterator past the last element of the range of entities.
  21517. * @return The number of components actually removed.
  21518. */
  21519. template<typename Component, typename... Other, typename It>
  21520. size_type remove(It first, It last) {
  21521. if constexpr(sizeof...(Other) == 0u) {
  21522. ENTT_ASSERT(std::all_of(first, last, [this](const auto entity) { return valid(entity); }), "Invalid entity");
  21523. return assure<Component>().remove(std::move(first), std::move(last));
  21524. } else {
  21525. size_type count{};
  21526. for(auto cpools = std::forward_as_tuple(assure<Component>(), assure<Other>()...); first != last; ++first) {
  21527. ENTT_ASSERT(valid(*first), "Invalid entity");
  21528. count += std::apply([entt = *first](auto &...curr) { return (curr.remove(entt) + ... + 0u); }, cpools);
  21529. }
  21530. return count;
  21531. }
  21532. }
  21533. /**
  21534. * @brief Erases the given components from an entity.
  21535. *
  21536. * @warning
  21537. * Attempting to use an invalid entity or to erase a component from an
  21538. * entity that doesn't own it results in undefined behavior.
  21539. *
  21540. * @tparam Component Types of components to erase.
  21541. * @tparam Other Other types of components to erase.
  21542. * @param entity A valid identifier.
  21543. */
  21544. template<typename Component, typename... Other>
  21545. void erase(const entity_type entity) {
  21546. ENTT_ASSERT(valid(entity), "Invalid entity");
  21547. (assure<Component>().erase(entity), (assure<Other>().erase(entity), ...));
  21548. }
  21549. /**
  21550. * @brief Erases the given components from all the entities in a range.
  21551. *
  21552. * @sa erase
  21553. *
  21554. * @tparam Component Types of components to erase.
  21555. * @tparam Other Other types of components to erase.
  21556. * @tparam It Type of input iterator.
  21557. * @param first An iterator to the first element of the range of entities.
  21558. * @param last An iterator past the last element of the range of entities.
  21559. */
  21560. template<typename Component, typename... Other, typename It>
  21561. void erase(It first, It last) {
  21562. if constexpr(sizeof...(Other) == 0u) {
  21563. ENTT_ASSERT(std::all_of(first, last, [this](const auto entity) { return valid(entity); }), "Invalid entity");
  21564. assure<Component>().erase(std::move(first), std::move(last));
  21565. } else {
  21566. for(auto cpools = std::forward_as_tuple(assure<Component>(), assure<Other>()...); first != last; ++first) {
  21567. ENTT_ASSERT(valid(*first), "Invalid entity");
  21568. std::apply([entt = *first](auto &...curr) { (curr.erase(entt), ...); }, cpools);
  21569. }
  21570. }
  21571. }
  21572. /**
  21573. * @brief Removes all tombstones from a registry or only the pools for the
  21574. * given components.
  21575. * @tparam Component Types of components for which to clear all tombstones.
  21576. */
  21577. template<typename... Component>
  21578. void compact() {
  21579. if constexpr(sizeof...(Component) == 0) {
  21580. for(auto &&curr: pools) {
  21581. curr.second->compact();
  21582. }
  21583. } else {
  21584. (assure<Component>().compact(), ...);
  21585. }
  21586. }
  21587. /**
  21588. * @brief Checks if an entity has all the given components.
  21589. *
  21590. * @warning
  21591. * Attempting to use an invalid entity results in undefined behavior.
  21592. *
  21593. * @tparam Component Components for which to perform the check.
  21594. * @param entity A valid identifier.
  21595. * @return True if the entity has all the components, false otherwise.
  21596. */
  21597. template<typename... Component>
  21598. [[nodiscard]] bool all_of(const entity_type entity) const {
  21599. ENTT_ASSERT(valid(entity), "Invalid entity");
  21600. return (assure<std::remove_const_t<Component>>().contains(entity) && ...);
  21601. }
  21602. /**
  21603. * @brief Checks if an entity has at least one of the given components.
  21604. *
  21605. * @warning
  21606. * Attempting to use an invalid entity results in undefined behavior.
  21607. *
  21608. * @tparam Component Components for which to perform the check.
  21609. * @param entity A valid identifier.
  21610. * @return True if the entity has at least one of the given components,
  21611. * false otherwise.
  21612. */
  21613. template<typename... Component>
  21614. [[nodiscard]] bool any_of(const entity_type entity) const {
  21615. ENTT_ASSERT(valid(entity), "Invalid entity");
  21616. return (assure<std::remove_const_t<Component>>().contains(entity) || ...);
  21617. }
  21618. /**
  21619. * @brief Returns references to the given components for an entity.
  21620. *
  21621. * @warning
  21622. * Attempting to use an invalid entity or to get a component from an entity
  21623. * that doesn't own it results in undefined behavior.
  21624. *
  21625. * @tparam Component Types of components to get.
  21626. * @param entity A valid identifier.
  21627. * @return References to the components owned by the entity.
  21628. */
  21629. template<typename... Component>
  21630. [[nodiscard]] decltype(auto) get([[maybe_unused]] const entity_type entity) const {
  21631. ENTT_ASSERT(valid(entity), "Invalid entity");
  21632. return view<Component...>().template get<const Component...>(entity);
  21633. }
  21634. /*! @copydoc get */
  21635. template<typename... Component>
  21636. [[nodiscard]] decltype(auto) get([[maybe_unused]] const entity_type entity) {
  21637. ENTT_ASSERT(valid(entity), "Invalid entity");
  21638. return view<Component...>().template get<Component...>(entity);
  21639. }
  21640. /**
  21641. * @brief Returns a reference to the given component for an entity.
  21642. *
  21643. * In case the entity doesn't own the component, the parameters provided are
  21644. * used to construct it.
  21645. *
  21646. * @warning
  21647. * Attempting to use an invalid entity results in undefined behavior.
  21648. *
  21649. * @tparam Component Type of component to get.
  21650. * @tparam Args Types of arguments to use to construct the component.
  21651. * @param entity A valid identifier.
  21652. * @param args Parameters to use to initialize the component.
  21653. * @return Reference to the component owned by the entity.
  21654. */
  21655. template<typename Component, typename... Args>
  21656. [[nodiscard]] decltype(auto) get_or_emplace(const entity_type entity, Args &&...args) {
  21657. ENTT_ASSERT(valid(entity), "Invalid entity");
  21658. auto &cpool = assure<Component>();
  21659. return cpool.contains(entity) ? cpool.get(entity) : cpool.emplace(entity, std::forward<Args>(args)...);
  21660. }
  21661. /**
  21662. * @brief Returns pointers to the given components for an entity.
  21663. *
  21664. * @warning
  21665. * Attempting to use an invalid entity results in undefined behavior.
  21666. *
  21667. * @note
  21668. * The registry retains ownership of the pointed-to components.
  21669. *
  21670. * @tparam Component Types of components to get.
  21671. * @param entity A valid identifier.
  21672. * @return Pointers to the components owned by the entity.
  21673. */
  21674. template<typename... Component>
  21675. [[nodiscard]] auto try_get([[maybe_unused]] const entity_type entity) const {
  21676. ENTT_ASSERT(valid(entity), "Invalid entity");
  21677. if constexpr(sizeof...(Component) == 1) {
  21678. const auto &cpool = assure<std::remove_const_t<Component>...>();
  21679. return cpool.contains(entity) ? std::addressof(cpool.get(entity)) : nullptr;
  21680. } else {
  21681. return std::make_tuple(try_get<Component>(entity)...);
  21682. }
  21683. }
  21684. /*! @copydoc try_get */
  21685. template<typename... Component>
  21686. [[nodiscard]] auto try_get([[maybe_unused]] const entity_type entity) {
  21687. if constexpr(sizeof...(Component) == 1) {
  21688. return (const_cast<Component *>(std::as_const(*this).template try_get<Component>(entity)), ...);
  21689. } else {
  21690. return std::make_tuple(try_get<Component>(entity)...);
  21691. }
  21692. }
  21693. /**
  21694. * @brief Clears a whole registry or the pools for the given components.
  21695. * @tparam Component Types of components to remove from their entities.
  21696. */
  21697. template<typename... Component>
  21698. void clear() {
  21699. if constexpr(sizeof...(Component) == 0) {
  21700. for(auto &&curr: pools) {
  21701. curr.second->clear();
  21702. }
  21703. each([this](const auto entity) { this->release(entity); });
  21704. } else {
  21705. (assure<Component>().clear(), ...);
  21706. }
  21707. }
  21708. /**
  21709. * @brief Iterates all the entities that are still in use.
  21710. *
  21711. * The signature of the function should be equivalent to the following:
  21712. *
  21713. * @code{.cpp}
  21714. * void(const Entity);
  21715. * @endcode
  21716. *
  21717. * It's not defined whether entities created during iteration are returned.
  21718. *
  21719. * @tparam Func Type of the function object to invoke.
  21720. * @param func A valid function object.
  21721. */
  21722. template<typename Func>
  21723. void each(Func func) const {
  21724. if(free_list == null) {
  21725. for(auto pos = entities.size(); pos; --pos) {
  21726. func(entities[pos - 1]);
  21727. }
  21728. } else {
  21729. for(auto pos = entities.size(); pos; --pos) {
  21730. if(const auto entity = entities[pos - 1]; entity_traits::to_entity(entity) == (pos - 1)) {
  21731. func(entity);
  21732. }
  21733. }
  21734. }
  21735. }
  21736. /**
  21737. * @brief Checks if an entity has components assigned.
  21738. * @param entity A valid identifier.
  21739. * @return True if the entity has no components assigned, false otherwise.
  21740. */
  21741. [[nodiscard]] bool orphan(const entity_type entity) const {
  21742. ENTT_ASSERT(valid(entity), "Invalid entity");
  21743. return std::none_of(pools.cbegin(), pools.cend(), [entity](auto &&curr) { return curr.second->contains(entity); });
  21744. }
  21745. /**
  21746. * @brief Returns a sink object for the given component.
  21747. *
  21748. * Use this function to receive notifications whenever a new instance of the
  21749. * given component is created and assigned to an entity.<br/>
  21750. * The function type for a listener is equivalent to:
  21751. *
  21752. * @code{.cpp}
  21753. * void(basic_registry<Entity> &, Entity);
  21754. * @endcode
  21755. *
  21756. * Listeners are invoked **after** assigning the component to the entity.
  21757. *
  21758. * @sa sink
  21759. *
  21760. * @tparam Component Type of component of which to get the sink.
  21761. * @return A temporary sink object.
  21762. */
  21763. template<typename Component>
  21764. [[nodiscard]] auto on_construct() {
  21765. return assure<Component>().on_construct();
  21766. }
  21767. /**
  21768. * @brief Returns a sink object for the given component.
  21769. *
  21770. * Use this function to receive notifications whenever an instance of the
  21771. * given component is explicitly updated.<br/>
  21772. * The function type for a listener is equivalent to:
  21773. *
  21774. * @code{.cpp}
  21775. * void(basic_registry<Entity> &, Entity);
  21776. * @endcode
  21777. *
  21778. * Listeners are invoked **after** updating the component.
  21779. *
  21780. * @sa sink
  21781. *
  21782. * @tparam Component Type of component of which to get the sink.
  21783. * @return A temporary sink object.
  21784. */
  21785. template<typename Component>
  21786. [[nodiscard]] auto on_update() {
  21787. return assure<Component>().on_update();
  21788. }
  21789. /**
  21790. * @brief Returns a sink object for the given component.
  21791. *
  21792. * Use this function to receive notifications whenever an instance of the
  21793. * given component is removed from an entity and thus destroyed.<br/>
  21794. * The function type for a listener is equivalent to:
  21795. *
  21796. * @code{.cpp}
  21797. * void(basic_registry<Entity> &, Entity);
  21798. * @endcode
  21799. *
  21800. * Listeners are invoked **before** removing the component from the entity.
  21801. *
  21802. * @sa sink
  21803. *
  21804. * @tparam Component Type of component of which to get the sink.
  21805. * @return A temporary sink object.
  21806. */
  21807. template<typename Component>
  21808. [[nodiscard]] auto on_destroy() {
  21809. return assure<Component>().on_destroy();
  21810. }
  21811. /**
  21812. * @brief Returns a view for the given components.
  21813. *
  21814. * Views are created on the fly and share with the registry its internal
  21815. * data structures. Feel free to discard them after the use.<br/>
  21816. * Creating and destroying a view is an incredibly cheap operation. As a
  21817. * rule of thumb, storing a view should never be an option.
  21818. *
  21819. * @tparam Component Type of component used to construct the view.
  21820. * @tparam Other Other types of components used to construct the view.
  21821. * @tparam Exclude Types of components used to filter the view.
  21822. * @return A newly created view.
  21823. */
  21824. template<typename Component, typename... Other, typename... Exclude>
  21825. [[nodiscard]] basic_view<entity_type, get_t<std::add_const_t<Component>, std::add_const_t<Other>...>, exclude_t<Exclude...>> view(exclude_t<Exclude...> = {}) const {
  21826. return {assure<std::remove_const_t<Component>>(), assure<std::remove_const_t<Other>>()..., assure<Exclude>()...};
  21827. }
  21828. /*! @copydoc view */
  21829. template<typename Component, typename... Other, typename... Exclude>
  21830. [[nodiscard]] basic_view<entity_type, get_t<Component, Other...>, exclude_t<Exclude...>> view(exclude_t<Exclude...> = {}) {
  21831. return {assure<std::remove_const_t<Component>>(), assure<std::remove_const_t<Other>>()..., assure<Exclude>()...};
  21832. }
  21833. /**
  21834. * @brief Returns a group for the given components.
  21835. *
  21836. * Groups are created on the fly and share with the registry its internal
  21837. * data structures. Feel free to discard them after the use.<br/>
  21838. * Creating and destroying a group is an incredibly cheap operation. As a
  21839. * rule of thumb, storing a group should never be an option.
  21840. *
  21841. * Groups support exclusion lists and can own types of components. The more
  21842. * types are owned by a group, the faster it is to iterate entities and
  21843. * components.<br/>
  21844. * However, groups also affect some features of the registry such as the
  21845. * creation and destruction of components.
  21846. *
  21847. * @note
  21848. * Pools of components that are owned by a group cannot be sorted anymore.
  21849. * The group takes the ownership of the pools and arrange components so as
  21850. * to iterate them as fast as possible.
  21851. *
  21852. * @tparam Owned Types of components owned by the group.
  21853. * @tparam Get Types of components observed by the group.
  21854. * @tparam Exclude Types of components used to filter the group.
  21855. * @return A newly created group.
  21856. */
  21857. template<typename... Owned, typename... Get, typename... Exclude>
  21858. [[nodiscard]] basic_group<entity_type, owned_t<Owned...>, get_t<Get...>, exclude_t<Exclude...>> group(get_t<Get...>, exclude_t<Exclude...> = {}) {
  21859. static_assert(sizeof...(Owned) + sizeof...(Get) > 0, "Exclusion-only groups are not supported");
  21860. static_assert(sizeof...(Owned) + sizeof...(Get) + sizeof...(Exclude) > 1, "Single component groups are not allowed");
  21861. using handler_type = group_handler<exclude_t<std::remove_const_t<Exclude>...>, get_t<std::remove_const_t<Get>...>, std::remove_const_t<Owned>...>;
  21862. const auto cpools = std::forward_as_tuple(assure<std::remove_const_t<Owned>>()..., assure<std::remove_const_t<Get>>()...);
  21863. constexpr auto size = sizeof...(Owned) + sizeof...(Get) + sizeof...(Exclude);
  21864. handler_type *handler = nullptr;
  21865. auto it = std::find_if(groups.cbegin(), groups.cend(), [size](const auto &gdata) {
  21866. return gdata.size == size
  21867. && (gdata.owned(type_hash<std::remove_const_t<Owned>>::value()) && ...)
  21868. && (gdata.get(type_hash<std::remove_const_t<Get>>::value()) && ...)
  21869. && (gdata.exclude(type_hash<Exclude>::value()) && ...);
  21870. });
  21871. if(it != groups.cend()) {
  21872. handler = static_cast<handler_type *>(it->group.get());
  21873. } else {
  21874. group_data candidate = {
  21875. size,
  21876. {new handler_type{}, [](void *instance) { delete static_cast<handler_type *>(instance); }},
  21877. []([[maybe_unused]] const id_type ctype) ENTT_NOEXCEPT { return ((ctype == type_hash<std::remove_const_t<Owned>>::value()) || ...); },
  21878. []([[maybe_unused]] const id_type ctype) ENTT_NOEXCEPT { return ((ctype == type_hash<std::remove_const_t<Get>>::value()) || ...); },
  21879. []([[maybe_unused]] const id_type ctype) ENTT_NOEXCEPT { return ((ctype == type_hash<Exclude>::value()) || ...); },
  21880. };
  21881. handler = static_cast<handler_type *>(candidate.group.get());
  21882. const void *maybe_valid_if = nullptr;
  21883. const void *discard_if = nullptr;
  21884. if constexpr(sizeof...(Owned) == 0) {
  21885. groups.push_back(std::move(candidate));
  21886. } else {
  21887. [[maybe_unused]] auto has_conflict = [size](const auto &gdata) {
  21888. const auto overlapping = (0u + ... + gdata.owned(type_hash<std::remove_const_t<Owned>>::value()));
  21889. const auto sz = overlapping + (0u + ... + gdata.get(type_hash<std::remove_const_t<Get>>::value())) + (0u + ... + gdata.exclude(type_hash<Exclude>::value()));
  21890. return !overlapping || ((sz == size) || (sz == gdata.size));
  21891. };
  21892. ENTT_ASSERT(std::all_of(groups.cbegin(), groups.cend(), std::move(has_conflict)), "Conflicting groups");
  21893. const auto next = std::find_if_not(groups.cbegin(), groups.cend(), [size](const auto &gdata) {
  21894. return !(0u + ... + gdata.owned(type_hash<std::remove_const_t<Owned>>::value())) || (size > gdata.size);
  21895. });
  21896. const auto prev = std::find_if(std::make_reverse_iterator(next), groups.crend(), [](const auto &gdata) {
  21897. return (0u + ... + gdata.owned(type_hash<std::remove_const_t<Owned>>::value()));
  21898. });
  21899. maybe_valid_if = (next == groups.cend() ? maybe_valid_if : next->group.get());
  21900. discard_if = (prev == groups.crend() ? discard_if : prev->group.get());
  21901. groups.insert(next, std::move(candidate));
  21902. }
  21903. (on_construct<std::remove_const_t<Owned>>().before(maybe_valid_if).template connect<&handler_type::template maybe_valid_if<std::remove_const_t<Owned>>>(*handler), ...);
  21904. (on_construct<std::remove_const_t<Get>>().before(maybe_valid_if).template connect<&handler_type::template maybe_valid_if<std::remove_const_t<Get>>>(*handler), ...);
  21905. (on_destroy<Exclude>().before(maybe_valid_if).template connect<&handler_type::template maybe_valid_if<Exclude>>(*handler), ...);
  21906. (on_destroy<std::remove_const_t<Owned>>().before(discard_if).template connect<&handler_type::discard_if>(*handler), ...);
  21907. (on_destroy<std::remove_const_t<Get>>().before(discard_if).template connect<&handler_type::discard_if>(*handler), ...);
  21908. (on_construct<Exclude>().before(discard_if).template connect<&handler_type::discard_if>(*handler), ...);
  21909. if constexpr(sizeof...(Owned) == 0) {
  21910. for(const auto entity: view<Owned..., Get...>(exclude<Exclude...>)) {
  21911. handler->current.emplace(entity);
  21912. }
  21913. } else {
  21914. // we cannot iterate backwards because we want to leave behind valid entities in case of owned types
  21915. for(auto *first = std::get<0>(cpools).data(), *last = first + std::get<0>(cpools).size(); first != last; ++first) {
  21916. handler->template maybe_valid_if<type_list_element_t<0, type_list<std::remove_const_t<Owned>...>>>(*this, *first);
  21917. }
  21918. }
  21919. }
  21920. return {handler->current, std::get<storage_type<std::remove_const_t<Owned>> &>(cpools)..., std::get<storage_type<std::remove_const_t<Get>> &>(cpools)...};
  21921. }
  21922. /*! @copydoc group */
  21923. template<typename... Owned, typename... Get, typename... Exclude>
  21924. [[nodiscard]] basic_group<entity_type, owned_t<std::add_const_t<Owned>...>, get_t<std::add_const_t<Get>...>, exclude_t<Exclude...>> group_if_exists(get_t<Get...>, exclude_t<Exclude...> = {}) const {
  21925. auto it = std::find_if(groups.cbegin(), groups.cend(), [](const auto &gdata) {
  21926. return gdata.size == (sizeof...(Owned) + sizeof...(Get) + sizeof...(Exclude))
  21927. && (gdata.owned(type_hash<std::remove_const_t<Owned>>::value()) && ...)
  21928. && (gdata.get(type_hash<std::remove_const_t<Get>>::value()) && ...)
  21929. && (gdata.exclude(type_hash<Exclude>::value()) && ...);
  21930. });
  21931. if(it == groups.cend()) {
  21932. return {};
  21933. } else {
  21934. using handler_type = group_handler<exclude_t<std::remove_const_t<Exclude>...>, get_t<std::remove_const_t<Get>...>, std::remove_const_t<Owned>...>;
  21935. return {static_cast<handler_type *>(it->group.get())->current, assure<std::remove_const_t<Owned>>()..., assure<std::remove_const_t<Get>>()...};
  21936. }
  21937. }
  21938. /*! @copydoc group */
  21939. template<typename... Owned, typename... Exclude>
  21940. [[nodiscard]] basic_group<entity_type, owned_t<Owned...>, get_t<>, exclude_t<Exclude...>> group(exclude_t<Exclude...> = {}) {
  21941. return group<Owned...>(get_t<>{}, exclude<Exclude...>);
  21942. }
  21943. /*! @copydoc group */
  21944. template<typename... Owned, typename... Exclude>
  21945. [[nodiscard]] basic_group<entity_type, owned_t<std::add_const_t<Owned>...>, get_t<>, exclude_t<Exclude...>> group_if_exists(exclude_t<Exclude...> = {}) const {
  21946. return group_if_exists<std::add_const_t<Owned>...>(get_t<>{}, exclude<Exclude...>);
  21947. }
  21948. /**
  21949. * @brief Checks whether the given components belong to any group.
  21950. * @tparam Component Types of components in which one is interested.
  21951. * @return True if the pools of the given components are _free_, false
  21952. * otherwise.
  21953. */
  21954. template<typename... Component>
  21955. [[nodiscard]] bool owned() const {
  21956. return std::any_of(groups.cbegin(), groups.cend(), [](auto &&gdata) { return (gdata.owned(type_hash<std::remove_const_t<Component>>::value()) || ...); });
  21957. }
  21958. /**
  21959. * @brief Checks whether a group can be sorted.
  21960. * @tparam Owned Types of components owned by the group.
  21961. * @tparam Get Types of components observed by the group.
  21962. * @tparam Exclude Types of components used to filter the group.
  21963. * @return True if the group can be sorted, false otherwise.
  21964. */
  21965. template<typename... Owned, typename... Get, typename... Exclude>
  21966. [[nodiscard]] bool sortable(const basic_group<entity_type, owned_t<Owned...>, get_t<Get...>, exclude_t<Exclude...>> &) ENTT_NOEXCEPT {
  21967. constexpr auto size = sizeof...(Owned) + sizeof...(Get) + sizeof...(Exclude);
  21968. auto pred = [size](const auto &gdata) { return (0u + ... + gdata.owned(type_hash<std::remove_const_t<Owned>>::value())) && (size < gdata.size); };
  21969. return std::find_if(groups.cbegin(), groups.cend(), std::move(pred)) == groups.cend();
  21970. }
  21971. /**
  21972. * @brief Sorts the elements of a given component.
  21973. *
  21974. * The order remains valid until a component of the given type is assigned
  21975. * to or removed from an entity.<br/>
  21976. * The comparison function object returns `true` if the first element is
  21977. * _less_ than the second one, `false` otherwise. Its signature is also
  21978. * equivalent to one of the following:
  21979. *
  21980. * @code{.cpp}
  21981. * bool(const Entity, const Entity);
  21982. * bool(const Component &, const Component &);
  21983. * @endcode
  21984. *
  21985. * Moreover, it shall induce a _strict weak ordering_ on the values.<br/>
  21986. * The sort function object offers an `operator()` that accepts:
  21987. *
  21988. * * An iterator to the first element of the range to sort.
  21989. * * An iterator past the last element of the range to sort.
  21990. * * A comparison function object to use to compare the elements.
  21991. *
  21992. * The comparison function object hasn't necessarily the type of the one
  21993. * passed along with the other parameters to this member function.
  21994. *
  21995. * @warning
  21996. * Pools of components owned by a group cannot be sorted.
  21997. *
  21998. * @tparam Component Type of components to sort.
  21999. * @tparam Compare Type of comparison function object.
  22000. * @tparam Sort Type of sort function object.
  22001. * @tparam Args Types of arguments to forward to the sort function object.
  22002. * @param compare A valid comparison function object.
  22003. * @param algo A valid sort function object.
  22004. * @param args Arguments to forward to the sort function object, if any.
  22005. */
  22006. template<typename Component, typename Compare, typename Sort = std_sort, typename... Args>
  22007. void sort(Compare compare, Sort algo = Sort{}, Args &&...args) {
  22008. ENTT_ASSERT(!owned<Component>(), "Cannot sort owned storage");
  22009. auto &cpool = assure<Component>();
  22010. if constexpr(std::is_invocable_v<Compare, decltype(cpool.get({})), decltype(cpool.get({}))>) {
  22011. 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))); };
  22012. cpool.sort(std::move(comp), std::move(algo), std::forward<Args>(args)...);
  22013. } else {
  22014. cpool.sort(std::move(compare), std::move(algo), std::forward<Args>(args)...);
  22015. }
  22016. }
  22017. /**
  22018. * @brief Sorts two pools of components in the same way.
  22019. *
  22020. * Being `To` and `From` the two sets, after invoking this function an
  22021. * iterator for `To` returns elements according to the following rules:
  22022. *
  22023. * * All entities in `To` that are also in `From` are returned first
  22024. * according to the order they have in `From`.
  22025. * * All entities in `To` that are not in `From` are returned in no
  22026. * particular order after all the other entities.
  22027. *
  22028. * Any subsequent change to `From` won't affect the order in `To`.
  22029. *
  22030. * @warning
  22031. * Pools of components owned by a group cannot be sorted.
  22032. *
  22033. * @tparam To Type of components to sort.
  22034. * @tparam From Type of components to use to sort.
  22035. */
  22036. template<typename To, typename From>
  22037. void sort() {
  22038. ENTT_ASSERT(!owned<To>(), "Cannot sort owned storage");
  22039. assure<To>().respect(assure<From>());
  22040. }
  22041. /**
  22042. * @brief Returns the context object, that is, a general purpose container.
  22043. * @return The context object, that is, a general purpose container.
  22044. */
  22045. context &ctx() ENTT_NOEXCEPT {
  22046. return vars;
  22047. }
  22048. /*! @copydoc ctx */
  22049. const context &ctx() const ENTT_NOEXCEPT {
  22050. return vars;
  22051. }
  22052. private:
  22053. dense_map<id_type, std::unique_ptr<base_type>, identity> pools;
  22054. std::vector<group_data> groups;
  22055. std::vector<entity_type> entities;
  22056. entity_type free_list;
  22057. context vars;
  22058. };
  22059. } // namespace entt
  22060. #endif
  22061. namespace entt {
  22062. /**
  22063. * @brief Non-owning handle to an entity.
  22064. *
  22065. * Tiny wrapper around a registry and an entity.
  22066. *
  22067. * @tparam Entity A valid entity type (see entt_traits for more details).
  22068. * @tparam Type Types to which to restrict the scope of a handle.
  22069. */
  22070. template<typename Entity, typename... Type>
  22071. struct basic_handle {
  22072. /*! @brief Type of registry accepted by the handle. */
  22073. using registry_type = constness_as_t<basic_registry<std::remove_const_t<Entity>>, Entity>;
  22074. /*! @brief Underlying entity identifier. */
  22075. using entity_type = typename registry_type::entity_type;
  22076. /*! @brief Underlying version type. */
  22077. using version_type = typename registry_type::version_type;
  22078. /*! @brief Unsigned integer type. */
  22079. using size_type = typename registry_type::size_type;
  22080. /*! @brief Constructs an invalid handle. */
  22081. basic_handle() ENTT_NOEXCEPT
  22082. : reg{},
  22083. entt{null} {}
  22084. /**
  22085. * @brief Constructs a handle from a given registry and entity.
  22086. * @param ref An instance of the registry class.
  22087. * @param value A valid identifier.
  22088. */
  22089. basic_handle(registry_type &ref, entity_type value) ENTT_NOEXCEPT
  22090. : reg{&ref},
  22091. entt{value} {}
  22092. /**
  22093. * @brief Constructs a const handle from a non-const one.
  22094. * @tparam Other A valid entity type (see entt_traits for more details).
  22095. * @tparam Args Scope of the handle to construct.
  22096. * @return A const handle referring to the same registry and the same
  22097. * entity.
  22098. */
  22099. template<typename Other, typename... Args>
  22100. operator basic_handle<Other, Args...>() const ENTT_NOEXCEPT {
  22101. static_assert(std::is_same_v<Other, Entity> || std::is_same_v<std::remove_const_t<Other>, Entity>, "Invalid conversion between different handles");
  22102. static_assert((sizeof...(Type) == 0 || ((sizeof...(Args) != 0 && sizeof...(Args) <= sizeof...(Type)) && ... && (type_list_contains_v<type_list<Type...>, Args>))), "Invalid conversion between different handles");
  22103. return reg ? basic_handle<Other, Args...>{*reg, entt} : basic_handle<Other, Args...>{};
  22104. }
  22105. /**
  22106. * @brief Converts a handle to its underlying entity.
  22107. * @return The contained identifier.
  22108. */
  22109. [[nodiscard]] operator entity_type() const ENTT_NOEXCEPT {
  22110. return entity();
  22111. }
  22112. /**
  22113. * @brief Checks if a handle refers to non-null registry pointer and entity.
  22114. * @return True if the handle refers to non-null registry and entity, false otherwise.
  22115. */
  22116. [[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
  22117. return reg && reg->valid(entt);
  22118. }
  22119. /**
  22120. * @brief Checks if a handle refers to a valid entity or not.
  22121. * @return True if the handle refers to a valid entity, false otherwise.
  22122. */
  22123. [[nodiscard]] bool valid() const {
  22124. return reg->valid(entt);
  22125. }
  22126. /**
  22127. * @brief Returns a pointer to the underlying registry, if any.
  22128. * @return A pointer to the underlying registry, if any.
  22129. */
  22130. [[nodiscard]] registry_type *registry() const ENTT_NOEXCEPT {
  22131. return reg;
  22132. }
  22133. /**
  22134. * @brief Returns the entity associated with a handle.
  22135. * @return The entity associated with the handle.
  22136. */
  22137. [[nodiscard]] entity_type entity() const ENTT_NOEXCEPT {
  22138. return entt;
  22139. }
  22140. /**
  22141. * @brief Destroys the entity associated with a handle.
  22142. * @sa basic_registry::destroy
  22143. */
  22144. void destroy() {
  22145. reg->destroy(entt);
  22146. }
  22147. /**
  22148. * @brief Destroys the entity associated with a handle.
  22149. * @sa basic_registry::destroy
  22150. * @param version A desired version upon destruction.
  22151. */
  22152. void destroy(const version_type version) {
  22153. reg->destroy(entt, version);
  22154. }
  22155. /**
  22156. * @brief Assigns the given component to a handle.
  22157. * @sa basic_registry::emplace
  22158. * @tparam Component Type of component to create.
  22159. * @tparam Args Types of arguments to use to construct the component.
  22160. * @param args Parameters to use to initialize the component.
  22161. * @return A reference to the newly created component.
  22162. */
  22163. template<typename Component, typename... Args>
  22164. decltype(auto) emplace(Args &&...args) const {
  22165. static_assert(((sizeof...(Type) == 0) || ... || std::is_same_v<Component, Type>), "Invalid type");
  22166. return reg->template emplace<Component>(entt, std::forward<Args>(args)...);
  22167. }
  22168. /**
  22169. * @brief Assigns or replaces the given component for a handle.
  22170. * @sa basic_registry::emplace_or_replace
  22171. * @tparam Component Type of component to assign or replace.
  22172. * @tparam Args Types of arguments to use to construct the component.
  22173. * @param args Parameters to use to initialize the component.
  22174. * @return A reference to the newly created component.
  22175. */
  22176. template<typename Component, typename... Args>
  22177. decltype(auto) emplace_or_replace(Args &&...args) const {
  22178. static_assert(((sizeof...(Type) == 0) || ... || std::is_same_v<Component, Type>), "Invalid type");
  22179. return reg->template emplace_or_replace<Component>(entt, std::forward<Args>(args)...);
  22180. }
  22181. /**
  22182. * @brief Patches the given component for a handle.
  22183. * @sa basic_registry::patch
  22184. * @tparam Component Type of component to patch.
  22185. * @tparam Func Types of the function objects to invoke.
  22186. * @param func Valid function objects.
  22187. * @return A reference to the patched component.
  22188. */
  22189. template<typename Component, typename... Func>
  22190. decltype(auto) patch(Func &&...func) const {
  22191. static_assert(((sizeof...(Type) == 0) || ... || std::is_same_v<Component, Type>), "Invalid type");
  22192. return reg->template patch<Component>(entt, std::forward<Func>(func)...);
  22193. }
  22194. /**
  22195. * @brief Replaces the given component for a handle.
  22196. * @sa basic_registry::replace
  22197. * @tparam Component Type of component to replace.
  22198. * @tparam Args Types of arguments to use to construct the component.
  22199. * @param args Parameters to use to initialize the component.
  22200. * @return A reference to the component being replaced.
  22201. */
  22202. template<typename Component, typename... Args>
  22203. decltype(auto) replace(Args &&...args) const {
  22204. static_assert(((sizeof...(Type) == 0) || ... || std::is_same_v<Component, Type>), "Invalid type");
  22205. return reg->template replace<Component>(entt, std::forward<Args>(args)...);
  22206. }
  22207. /**
  22208. * @brief Removes the given components from a handle.
  22209. * @sa basic_registry::remove
  22210. * @tparam Component Types of components to remove.
  22211. * @return The number of components actually removed.
  22212. */
  22213. template<typename... Component>
  22214. size_type remove() const {
  22215. static_assert(sizeof...(Type) == 0 || (type_list_contains_v<type_list<Type...>, Component> && ...), "Invalid type");
  22216. return reg->template remove<Component...>(entt);
  22217. }
  22218. /**
  22219. * @brief Erases the given components from a handle.
  22220. * @sa basic_registry::erase
  22221. * @tparam Component Types of components to erase.
  22222. */
  22223. template<typename... Component>
  22224. void erase() const {
  22225. static_assert(sizeof...(Type) == 0 || (type_list_contains_v<type_list<Type...>, Component> && ...), "Invalid type");
  22226. reg->template erase<Component...>(entt);
  22227. }
  22228. /**
  22229. * @brief Checks if a handle has all the given components.
  22230. * @sa basic_registry::all_of
  22231. * @tparam Component Components for which to perform the check.
  22232. * @return True if the handle has all the components, false otherwise.
  22233. */
  22234. template<typename... Component>
  22235. [[nodiscard]] decltype(auto) all_of() const {
  22236. return reg->template all_of<Component...>(entt);
  22237. }
  22238. /**
  22239. * @brief Checks if a handle has at least one of the given components.
  22240. * @sa basic_registry::any_of
  22241. * @tparam Component Components for which to perform the check.
  22242. * @return True if the handle has at least one of the given components,
  22243. * false otherwise.
  22244. */
  22245. template<typename... Component>
  22246. [[nodiscard]] decltype(auto) any_of() const {
  22247. return reg->template any_of<Component...>(entt);
  22248. }
  22249. /**
  22250. * @brief Returns references to the given components for a handle.
  22251. * @sa basic_registry::get
  22252. * @tparam Component Types of components to get.
  22253. * @return References to the components owned by the handle.
  22254. */
  22255. template<typename... Component>
  22256. [[nodiscard]] decltype(auto) get() const {
  22257. static_assert(sizeof...(Type) == 0 || (type_list_contains_v<type_list<Type...>, Component> && ...), "Invalid type");
  22258. return reg->template get<Component...>(entt);
  22259. }
  22260. /**
  22261. * @brief Returns a reference to the given component for a handle.
  22262. * @sa basic_registry::get_or_emplace
  22263. * @tparam Component Type of component to get.
  22264. * @tparam Args Types of arguments to use to construct the component.
  22265. * @param args Parameters to use to initialize the component.
  22266. * @return Reference to the component owned by the handle.
  22267. */
  22268. template<typename Component, typename... Args>
  22269. [[nodiscard]] decltype(auto) get_or_emplace(Args &&...args) const {
  22270. static_assert(((sizeof...(Type) == 0) || ... || std::is_same_v<Component, Type>), "Invalid type");
  22271. return reg->template get_or_emplace<Component>(entt, std::forward<Args>(args)...);
  22272. }
  22273. /**
  22274. * @brief Returns pointers to the given components for a handle.
  22275. * @sa basic_registry::try_get
  22276. * @tparam Component Types of components to get.
  22277. * @return Pointers to the components owned by the handle.
  22278. */
  22279. template<typename... Component>
  22280. [[nodiscard]] auto try_get() const {
  22281. static_assert(sizeof...(Type) == 0 || (type_list_contains_v<type_list<Type...>, Component> && ...), "Invalid type");
  22282. return reg->template try_get<Component...>(entt);
  22283. }
  22284. /**
  22285. * @brief Checks if a handle has components assigned.
  22286. * @return True if the handle has no components assigned, false otherwise.
  22287. */
  22288. [[nodiscard]] bool orphan() const {
  22289. return reg->orphan(entt);
  22290. }
  22291. /**
  22292. * @brief Visits a handle and returns the pools for its components.
  22293. *
  22294. * The signature of the function should be equivalent to the following:
  22295. *
  22296. * @code{.cpp}
  22297. * void(id_type, const basic_sparse_set<entity_type> &);
  22298. * @endcode
  22299. *
  22300. * Returned pools are those that contain the entity associated with the
  22301. * handle.
  22302. *
  22303. * @tparam Func Type of the function object to invoke.
  22304. * @param func A valid function object.
  22305. */
  22306. template<typename Func>
  22307. void visit(Func &&func) const {
  22308. for(auto [id, storage]: reg->storage()) {
  22309. if(storage.contains(entt)) {
  22310. func(id, storage);
  22311. }
  22312. }
  22313. }
  22314. private:
  22315. registry_type *reg;
  22316. entity_type entt;
  22317. };
  22318. /**
  22319. * @brief Compares two handles.
  22320. * @tparam Args Scope of the first handle.
  22321. * @tparam Other Scope of the second handle.
  22322. * @param lhs A valid handle.
  22323. * @param rhs A valid handle.
  22324. * @return True if both handles refer to the same registry and the same
  22325. * entity, false otherwise.
  22326. */
  22327. template<typename... Args, typename... Other>
  22328. [[nodiscard]] bool operator==(const basic_handle<Args...> &lhs, const basic_handle<Other...> &rhs) ENTT_NOEXCEPT {
  22329. return lhs.registry() == rhs.registry() && lhs.entity() == rhs.entity();
  22330. }
  22331. /**
  22332. * @brief Compares two handles.
  22333. * @tparam Args Scope of the first handle.
  22334. * @tparam Other Scope of the second handle.
  22335. * @param lhs A valid handle.
  22336. * @param rhs A valid handle.
  22337. * @return False if both handles refer to the same registry and the same
  22338. * entity, true otherwise.
  22339. */
  22340. template<typename... Args, typename... Other>
  22341. [[nodiscard]] bool operator!=(const basic_handle<Args...> &lhs, const basic_handle<Other...> &rhs) ENTT_NOEXCEPT {
  22342. return !(lhs == rhs);
  22343. }
  22344. /**
  22345. * @brief Deduction guide.
  22346. * @tparam Entity A valid entity type (see entt_traits for more details).
  22347. */
  22348. template<typename Entity>
  22349. basic_handle(basic_registry<Entity> &, Entity) -> basic_handle<Entity>;
  22350. /**
  22351. * @brief Deduction guide.
  22352. * @tparam Entity A valid entity type (see entt_traits for more details).
  22353. */
  22354. template<typename Entity>
  22355. basic_handle(const basic_registry<Entity> &, Entity) -> basic_handle<const Entity>;
  22356. } // namespace entt
  22357. #endif
  22358. // #include "entity/helper.hpp"
  22359. #ifndef ENTT_ENTITY_HELPER_HPP
  22360. #define ENTT_ENTITY_HELPER_HPP
  22361. #include <type_traits>
  22362. // #include "../config/config.h"
  22363. // #include "../core/fwd.hpp"
  22364. // #include "../core/type_traits.hpp"
  22365. // #include "../signal/delegate.hpp"
  22366. #ifndef ENTT_SIGNAL_DELEGATE_HPP
  22367. #define ENTT_SIGNAL_DELEGATE_HPP
  22368. #include <cstddef>
  22369. #include <functional>
  22370. #include <tuple>
  22371. #include <type_traits>
  22372. #include <utility>
  22373. // #include "../config/config.h"
  22374. // #include "../core/type_traits.hpp"
  22375. // #include "fwd.hpp"
  22376. namespace entt {
  22377. /**
  22378. * @cond TURN_OFF_DOXYGEN
  22379. * Internal details not to be documented.
  22380. */
  22381. namespace internal {
  22382. template<typename Ret, typename... Args>
  22383. auto function_pointer(Ret (*)(Args...)) -> Ret (*)(Args...);
  22384. template<typename Ret, typename Type, typename... Args, typename Other>
  22385. auto function_pointer(Ret (*)(Type, Args...), Other &&) -> Ret (*)(Args...);
  22386. template<typename Class, typename Ret, typename... Args, typename... Other>
  22387. auto function_pointer(Ret (Class::*)(Args...), Other &&...) -> Ret (*)(Args...);
  22388. template<typename Class, typename Ret, typename... Args, typename... Other>
  22389. auto function_pointer(Ret (Class::*)(Args...) const, Other &&...) -> Ret (*)(Args...);
  22390. template<typename Class, typename Type, typename... Other>
  22391. auto function_pointer(Type Class::*, Other &&...) -> Type (*)();
  22392. template<typename... Type>
  22393. using function_pointer_t = decltype(internal::function_pointer(std::declval<Type>()...));
  22394. template<typename... Class, typename Ret, typename... Args>
  22395. [[nodiscard]] constexpr auto index_sequence_for(Ret (*)(Args...)) {
  22396. return std::index_sequence_for<Class..., Args...>{};
  22397. }
  22398. } // namespace internal
  22399. /**
  22400. * Internal details not to be documented.
  22401. * @endcond
  22402. */
  22403. /*! @brief Used to wrap a function or a member of a specified type. */
  22404. template<auto>
  22405. struct connect_arg_t {};
  22406. /*! @brief Constant of type connect_arg_t used to disambiguate calls. */
  22407. template<auto Func>
  22408. inline constexpr connect_arg_t<Func> connect_arg{};
  22409. /**
  22410. * @brief Basic delegate implementation.
  22411. *
  22412. * Primary template isn't defined on purpose. All the specializations give a
  22413. * compile-time error unless the template parameter is a function type.
  22414. */
  22415. template<typename>
  22416. class delegate;
  22417. /**
  22418. * @brief Utility class to use to send around functions and members.
  22419. *
  22420. * Unmanaged delegate for function pointers and members. Users of this class are
  22421. * in charge of disconnecting instances before deleting them.
  22422. *
  22423. * A delegate can be used as a general purpose invoker without memory overhead
  22424. * for free functions possibly with payloads and bound or unbound members.
  22425. *
  22426. * @tparam Ret Return type of a function type.
  22427. * @tparam Args Types of arguments of a function type.
  22428. */
  22429. template<typename Ret, typename... Args>
  22430. class delegate<Ret(Args...)> {
  22431. template<auto Candidate, std::size_t... Index>
  22432. [[nodiscard]] auto wrap(std::index_sequence<Index...>) ENTT_NOEXCEPT {
  22433. return [](const void *, Args... args) -> Ret {
  22434. [[maybe_unused]] const auto arguments = std::forward_as_tuple(std::forward<Args>(args)...);
  22435. return static_cast<Ret>(std::invoke(Candidate, std::forward<type_list_element_t<Index, type_list<Args...>>>(std::get<Index>(arguments))...));
  22436. };
  22437. }
  22438. template<auto Candidate, typename Type, std::size_t... Index>
  22439. [[nodiscard]] auto wrap(Type &, std::index_sequence<Index...>) ENTT_NOEXCEPT {
  22440. return [](const void *payload, Args... args) -> Ret {
  22441. [[maybe_unused]] const auto arguments = std::forward_as_tuple(std::forward<Args>(args)...);
  22442. Type *curr = static_cast<Type *>(const_cast<constness_as_t<void, Type> *>(payload));
  22443. return static_cast<Ret>(std::invoke(Candidate, *curr, std::forward<type_list_element_t<Index, type_list<Args...>>>(std::get<Index>(arguments))...));
  22444. };
  22445. }
  22446. template<auto Candidate, typename Type, std::size_t... Index>
  22447. [[nodiscard]] auto wrap(Type *, std::index_sequence<Index...>) ENTT_NOEXCEPT {
  22448. return [](const void *payload, Args... args) -> Ret {
  22449. [[maybe_unused]] const auto arguments = std::forward_as_tuple(std::forward<Args>(args)...);
  22450. Type *curr = static_cast<Type *>(const_cast<constness_as_t<void, Type> *>(payload));
  22451. return static_cast<Ret>(std::invoke(Candidate, curr, std::forward<type_list_element_t<Index, type_list<Args...>>>(std::get<Index>(arguments))...));
  22452. };
  22453. }
  22454. public:
  22455. /*! @brief Function type of the contained target. */
  22456. using function_type = Ret(const void *, Args...);
  22457. /*! @brief Function type of the delegate. */
  22458. using type = Ret(Args...);
  22459. /*! @brief Return type of the delegate. */
  22460. using result_type = Ret;
  22461. /*! @brief Default constructor. */
  22462. delegate() ENTT_NOEXCEPT
  22463. : instance{nullptr},
  22464. fn{nullptr} {}
  22465. /**
  22466. * @brief Constructs a delegate and connects a free function or an unbound
  22467. * member.
  22468. * @tparam Candidate Function or member to connect to the delegate.
  22469. */
  22470. template<auto Candidate>
  22471. delegate(connect_arg_t<Candidate>) ENTT_NOEXCEPT {
  22472. connect<Candidate>();
  22473. }
  22474. /**
  22475. * @brief Constructs a delegate and connects a free function with payload or
  22476. * a bound member.
  22477. * @tparam Candidate Function or member to connect to the delegate.
  22478. * @tparam Type Type of class or type of payload.
  22479. * @param value_or_instance A valid object that fits the purpose.
  22480. */
  22481. template<auto Candidate, typename Type>
  22482. delegate(connect_arg_t<Candidate>, Type &&value_or_instance) ENTT_NOEXCEPT {
  22483. connect<Candidate>(std::forward<Type>(value_or_instance));
  22484. }
  22485. /**
  22486. * @brief Constructs a delegate and connects an user defined function with
  22487. * optional payload.
  22488. * @param function Function to connect to the delegate.
  22489. * @param payload User defined arbitrary data.
  22490. */
  22491. delegate(function_type *function, const void *payload = nullptr) ENTT_NOEXCEPT {
  22492. connect(function, payload);
  22493. }
  22494. /**
  22495. * @brief Connects a free function or an unbound member to a delegate.
  22496. * @tparam Candidate Function or member to connect to the delegate.
  22497. */
  22498. template<auto Candidate>
  22499. void connect() ENTT_NOEXCEPT {
  22500. instance = nullptr;
  22501. if constexpr(std::is_invocable_r_v<Ret, decltype(Candidate), Args...>) {
  22502. fn = [](const void *, Args... args) -> Ret {
  22503. return Ret(std::invoke(Candidate, std::forward<Args>(args)...));
  22504. };
  22505. } else if constexpr(std::is_member_pointer_v<decltype(Candidate)>) {
  22506. fn = wrap<Candidate>(internal::index_sequence_for<type_list_element_t<0, type_list<Args...>>>(internal::function_pointer_t<decltype(Candidate)>{}));
  22507. } else {
  22508. fn = wrap<Candidate>(internal::index_sequence_for(internal::function_pointer_t<decltype(Candidate)>{}));
  22509. }
  22510. }
  22511. /**
  22512. * @brief Connects a free function with payload or a bound member to a
  22513. * delegate.
  22514. *
  22515. * The delegate isn't responsible for the connected object or the payload.
  22516. * Users must always guarantee that the lifetime of the instance overcomes
  22517. * the one of the delegate.<br/>
  22518. * When used to connect a free function with payload, its signature must be
  22519. * such that the instance is the first argument before the ones used to
  22520. * define the delegate itself.
  22521. *
  22522. * @tparam Candidate Function or member to connect to the delegate.
  22523. * @tparam Type Type of class or type of payload.
  22524. * @param value_or_instance A valid reference that fits the purpose.
  22525. */
  22526. template<auto Candidate, typename Type>
  22527. void connect(Type &value_or_instance) ENTT_NOEXCEPT {
  22528. instance = &value_or_instance;
  22529. if constexpr(std::is_invocable_r_v<Ret, decltype(Candidate), Type &, Args...>) {
  22530. fn = [](const void *payload, Args... args) -> Ret {
  22531. Type *curr = static_cast<Type *>(const_cast<constness_as_t<void, Type> *>(payload));
  22532. return Ret(std::invoke(Candidate, *curr, std::forward<Args>(args)...));
  22533. };
  22534. } else {
  22535. fn = wrap<Candidate>(value_or_instance, internal::index_sequence_for(internal::function_pointer_t<decltype(Candidate), Type>{}));
  22536. }
  22537. }
  22538. /**
  22539. * @brief Connects a free function with payload or a bound member to a
  22540. * delegate.
  22541. *
  22542. * @sa connect(Type &)
  22543. *
  22544. * @tparam Candidate Function or member to connect to the delegate.
  22545. * @tparam Type Type of class or type of payload.
  22546. * @param value_or_instance A valid pointer that fits the purpose.
  22547. */
  22548. template<auto Candidate, typename Type>
  22549. void connect(Type *value_or_instance) ENTT_NOEXCEPT {
  22550. instance = value_or_instance;
  22551. if constexpr(std::is_invocable_r_v<Ret, decltype(Candidate), Type *, Args...>) {
  22552. fn = [](const void *payload, Args... args) -> Ret {
  22553. Type *curr = static_cast<Type *>(const_cast<constness_as_t<void, Type> *>(payload));
  22554. return Ret(std::invoke(Candidate, curr, std::forward<Args>(args)...));
  22555. };
  22556. } else {
  22557. fn = wrap<Candidate>(value_or_instance, internal::index_sequence_for(internal::function_pointer_t<decltype(Candidate), Type>{}));
  22558. }
  22559. }
  22560. /**
  22561. * @brief Connects an user defined function with optional payload to a
  22562. * delegate.
  22563. *
  22564. * The delegate isn't responsible for the connected object or the payload.
  22565. * Users must always guarantee that the lifetime of an instance overcomes
  22566. * the one of the delegate.<br/>
  22567. * The payload is returned as the first argument to the target function in
  22568. * all cases.
  22569. *
  22570. * @param function Function to connect to the delegate.
  22571. * @param payload User defined arbitrary data.
  22572. */
  22573. void connect(function_type *function, const void *payload = nullptr) ENTT_NOEXCEPT {
  22574. instance = payload;
  22575. fn = function;
  22576. }
  22577. /**
  22578. * @brief Resets a delegate.
  22579. *
  22580. * After a reset, a delegate cannot be invoked anymore.
  22581. */
  22582. void reset() ENTT_NOEXCEPT {
  22583. instance = nullptr;
  22584. fn = nullptr;
  22585. }
  22586. /**
  22587. * @brief Returns the instance or the payload linked to a delegate, if any.
  22588. * @return An opaque pointer to the underlying data.
  22589. */
  22590. [[nodiscard]] const void *data() const ENTT_NOEXCEPT {
  22591. return instance;
  22592. }
  22593. /**
  22594. * @brief Triggers a delegate.
  22595. *
  22596. * The delegate invokes the underlying function and returns the result.
  22597. *
  22598. * @warning
  22599. * Attempting to trigger an invalid delegate results in undefined
  22600. * behavior.
  22601. *
  22602. * @param args Arguments to use to invoke the underlying function.
  22603. * @return The value returned by the underlying function.
  22604. */
  22605. Ret operator()(Args... args) const {
  22606. ENTT_ASSERT(static_cast<bool>(*this), "Uninitialized delegate");
  22607. return fn(instance, std::forward<Args>(args)...);
  22608. }
  22609. /**
  22610. * @brief Checks whether a delegate actually stores a listener.
  22611. * @return False if the delegate is empty, true otherwise.
  22612. */
  22613. [[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
  22614. // no need to also test instance
  22615. return !(fn == nullptr);
  22616. }
  22617. /**
  22618. * @brief Compares the contents of two delegates.
  22619. * @param other Delegate with which to compare.
  22620. * @return False if the two contents differ, true otherwise.
  22621. */
  22622. [[nodiscard]] bool operator==(const delegate<Ret(Args...)> &other) const ENTT_NOEXCEPT {
  22623. return fn == other.fn && instance == other.instance;
  22624. }
  22625. private:
  22626. const void *instance;
  22627. function_type *fn;
  22628. };
  22629. /**
  22630. * @brief Compares the contents of two delegates.
  22631. * @tparam Ret Return type of a function type.
  22632. * @tparam Args Types of arguments of a function type.
  22633. * @param lhs A valid delegate object.
  22634. * @param rhs A valid delegate object.
  22635. * @return True if the two contents differ, false otherwise.
  22636. */
  22637. template<typename Ret, typename... Args>
  22638. [[nodiscard]] bool operator!=(const delegate<Ret(Args...)> &lhs, const delegate<Ret(Args...)> &rhs) ENTT_NOEXCEPT {
  22639. return !(lhs == rhs);
  22640. }
  22641. /**
  22642. * @brief Deduction guide.
  22643. * @tparam Candidate Function or member to connect to the delegate.
  22644. */
  22645. template<auto Candidate>
  22646. delegate(connect_arg_t<Candidate>) -> delegate<std::remove_pointer_t<internal::function_pointer_t<decltype(Candidate)>>>;
  22647. /**
  22648. * @brief Deduction guide.
  22649. * @tparam Candidate Function or member to connect to the delegate.
  22650. * @tparam Type Type of class or type of payload.
  22651. */
  22652. template<auto Candidate, typename Type>
  22653. delegate(connect_arg_t<Candidate>, Type &&) -> delegate<std::remove_pointer_t<internal::function_pointer_t<decltype(Candidate), Type>>>;
  22654. /**
  22655. * @brief Deduction guide.
  22656. * @tparam Ret Return type of a function type.
  22657. * @tparam Args Types of arguments of a function type.
  22658. */
  22659. template<typename Ret, typename... Args>
  22660. delegate(Ret (*)(const void *, Args...), const void * = nullptr) -> delegate<Ret(Args...)>;
  22661. } // namespace entt
  22662. #endif
  22663. // #include "fwd.hpp"
  22664. // #include "registry.hpp"
  22665. namespace entt {
  22666. /**
  22667. * @brief Converts a registry to a view.
  22668. * @tparam Entity A valid entity type (see entt_traits for more details).
  22669. */
  22670. template<typename Entity>
  22671. struct as_view {
  22672. /*! @brief Underlying entity identifier. */
  22673. using entity_type = std::remove_const_t<Entity>;
  22674. /*! @brief Type of registry to convert. */
  22675. using registry_type = constness_as_t<basic_registry<entity_type>, Entity>;
  22676. /**
  22677. * @brief Constructs a converter for a given registry.
  22678. * @param source A valid reference to a registry.
  22679. */
  22680. as_view(registry_type &source) ENTT_NOEXCEPT: reg{source} {}
  22681. /**
  22682. * @brief Conversion function from a registry to a view.
  22683. * @tparam Exclude Types of components used to filter the view.
  22684. * @tparam Component Type of components used to construct the view.
  22685. * @return A newly created view.
  22686. */
  22687. template<typename Exclude, typename... Component>
  22688. operator basic_view<entity_type, get_t<Component...>, Exclude>() const {
  22689. return reg.template view<Component...>(Exclude{});
  22690. }
  22691. private:
  22692. registry_type &reg;
  22693. };
  22694. /**
  22695. * @brief Deduction guide.
  22696. * @tparam Entity A valid entity type (see entt_traits for more details).
  22697. */
  22698. template<typename Entity>
  22699. as_view(basic_registry<Entity> &) -> as_view<Entity>;
  22700. /**
  22701. * @brief Deduction guide.
  22702. * @tparam Entity A valid entity type (see entt_traits for more details).
  22703. */
  22704. template<typename Entity>
  22705. as_view(const basic_registry<Entity> &) -> as_view<const Entity>;
  22706. /**
  22707. * @brief Converts a registry to a group.
  22708. * @tparam Entity A valid entity type (see entt_traits for more details).
  22709. */
  22710. template<typename Entity>
  22711. struct as_group {
  22712. /*! @brief Underlying entity identifier. */
  22713. using entity_type = std::remove_const_t<Entity>;
  22714. /*! @brief Type of registry to convert. */
  22715. using registry_type = constness_as_t<basic_registry<entity_type>, Entity>;
  22716. /**
  22717. * @brief Constructs a converter for a given registry.
  22718. * @param source A valid reference to a registry.
  22719. */
  22720. as_group(registry_type &source) ENTT_NOEXCEPT: reg{source} {}
  22721. /**
  22722. * @brief Conversion function from a registry to a group.
  22723. * @tparam Get Types of components observed by the group.
  22724. * @tparam Exclude Types of components used to filter the group.
  22725. * @tparam Owned Types of components owned by the group.
  22726. * @return A newly created group.
  22727. */
  22728. template<typename Get, typename Exclude, typename... Owned>
  22729. operator basic_group<entity_type, owned_t<Owned...>, Get, Exclude>() const {
  22730. if constexpr(std::is_const_v<registry_type>) {
  22731. return reg.template group_if_exists<Owned...>(Get{}, Exclude{});
  22732. } else {
  22733. return reg.template group<Owned...>(Get{}, Exclude{});
  22734. }
  22735. }
  22736. private:
  22737. registry_type &reg;
  22738. };
  22739. /**
  22740. * @brief Deduction guide.
  22741. * @tparam Entity A valid entity type (see entt_traits for more details).
  22742. */
  22743. template<typename Entity>
  22744. as_group(basic_registry<Entity> &) -> as_group<Entity>;
  22745. /**
  22746. * @brief Deduction guide.
  22747. * @tparam Entity A valid entity type (see entt_traits for more details).
  22748. */
  22749. template<typename Entity>
  22750. as_group(const basic_registry<Entity> &) -> as_group<const Entity>;
  22751. /**
  22752. * @brief Helper to create a listener that directly invokes a member function.
  22753. * @tparam Member Member function to invoke on a component of the given type.
  22754. * @tparam Entity A valid entity type (see entt_traits for more details).
  22755. * @param reg A registry that contains the given entity and its components.
  22756. * @param entt Entity from which to get the component.
  22757. */
  22758. template<auto Member, typename Entity = entity>
  22759. void invoke(basic_registry<Entity> &reg, const Entity entt) {
  22760. static_assert(std::is_member_function_pointer_v<decltype(Member)>, "Invalid pointer to non-static member function");
  22761. delegate<void(basic_registry<Entity> &, const Entity)> func;
  22762. func.template connect<Member>(reg.template get<member_class_t<decltype(Member)>>(entt));
  22763. func(reg, entt);
  22764. }
  22765. /**
  22766. * @brief Returns the entity associated with a given component.
  22767. *
  22768. * @warning
  22769. * Currently, this function only works correctly with the default pool as it
  22770. * makes assumptions about how the components are laid out.
  22771. *
  22772. * @tparam Entity A valid entity type (see entt_traits for more details).
  22773. * @tparam Component Type of component.
  22774. * @param reg A registry that contains the given entity and its components.
  22775. * @param instance A valid component instance.
  22776. * @return The entity associated with the given component.
  22777. */
  22778. template<typename Entity, typename Component>
  22779. Entity to_entity(const basic_registry<Entity> &reg, const Component &instance) {
  22780. const auto &storage = reg.template storage<Component>();
  22781. const typename basic_registry<Entity>::base_type &base = storage;
  22782. const auto *addr = std::addressof(instance);
  22783. for(auto it = base.rbegin(), last = base.rend(); it < last; it += ENTT_PACKED_PAGE) {
  22784. if(const auto dist = (addr - std::addressof(storage.get(*it))); dist >= 0 && dist < ENTT_PACKED_PAGE) {
  22785. return *(it + dist);
  22786. }
  22787. }
  22788. return null;
  22789. }
  22790. } // namespace entt
  22791. #endif
  22792. // #include "entity/observer.hpp"
  22793. #ifndef ENTT_ENTITY_OBSERVER_HPP
  22794. #define ENTT_ENTITY_OBSERVER_HPP
  22795. #include <cstddef>
  22796. #include <cstdint>
  22797. #include <limits>
  22798. #include <type_traits>
  22799. #include <utility>
  22800. // #include "../config/config.h"
  22801. // #include "../core/type_traits.hpp"
  22802. // #include "../signal/delegate.hpp"
  22803. // #include "entity.hpp"
  22804. // #include "fwd.hpp"
  22805. // #include "registry.hpp"
  22806. // #include "storage.hpp"
  22807. // #include "utility.hpp"
  22808. namespace entt {
  22809. /*! @brief Grouping matcher. */
  22810. template<typename...>
  22811. struct matcher {};
  22812. /**
  22813. * @brief Collector.
  22814. *
  22815. * Primary template isn't defined on purpose. All the specializations give a
  22816. * compile-time error, but for a few reasonable cases.
  22817. */
  22818. template<typename...>
  22819. struct basic_collector;
  22820. /**
  22821. * @brief Collector.
  22822. *
  22823. * A collector contains a set of rules (literally, matchers) to use to track
  22824. * entities.<br/>
  22825. * Its main purpose is to generate a descriptor that allows an observer to know
  22826. * how to connect to a registry.
  22827. */
  22828. template<>
  22829. struct basic_collector<> {
  22830. /**
  22831. * @brief Adds a grouping matcher to the collector.
  22832. * @tparam AllOf Types of components tracked by the matcher.
  22833. * @tparam NoneOf Types of components used to filter out entities.
  22834. * @return The updated collector.
  22835. */
  22836. template<typename... AllOf, typename... NoneOf>
  22837. static constexpr auto group(exclude_t<NoneOf...> = {}) ENTT_NOEXCEPT {
  22838. return basic_collector<matcher<type_list<>, type_list<>, type_list<NoneOf...>, AllOf...>>{};
  22839. }
  22840. /**
  22841. * @brief Adds an observing matcher to the collector.
  22842. * @tparam AnyOf Type of component for which changes should be detected.
  22843. * @return The updated collector.
  22844. */
  22845. template<typename AnyOf>
  22846. static constexpr auto update() ENTT_NOEXCEPT {
  22847. return basic_collector<matcher<type_list<>, type_list<>, AnyOf>>{};
  22848. }
  22849. };
  22850. /**
  22851. * @brief Collector.
  22852. * @copydetails basic_collector<>
  22853. * @tparam Reject Untracked types used to filter out entities.
  22854. * @tparam Require Untracked types required by the matcher.
  22855. * @tparam Rule Specific details of the current matcher.
  22856. * @tparam Other Other matchers.
  22857. */
  22858. template<typename... Reject, typename... Require, typename... Rule, typename... Other>
  22859. struct basic_collector<matcher<type_list<Reject...>, type_list<Require...>, Rule...>, Other...> {
  22860. /*! @brief Current matcher. */
  22861. using current_type = matcher<type_list<Reject...>, type_list<Require...>, Rule...>;
  22862. /**
  22863. * @brief Adds a grouping matcher to the collector.
  22864. * @tparam AllOf Types of components tracked by the matcher.
  22865. * @tparam NoneOf Types of components used to filter out entities.
  22866. * @return The updated collector.
  22867. */
  22868. template<typename... AllOf, typename... NoneOf>
  22869. static constexpr auto group(exclude_t<NoneOf...> = {}) ENTT_NOEXCEPT {
  22870. return basic_collector<matcher<type_list<>, type_list<>, type_list<NoneOf...>, AllOf...>, current_type, Other...>{};
  22871. }
  22872. /**
  22873. * @brief Adds an observing matcher to the collector.
  22874. * @tparam AnyOf Type of component for which changes should be detected.
  22875. * @return The updated collector.
  22876. */
  22877. template<typename AnyOf>
  22878. static constexpr auto update() ENTT_NOEXCEPT {
  22879. return basic_collector<matcher<type_list<>, type_list<>, AnyOf>, current_type, Other...>{};
  22880. }
  22881. /**
  22882. * @brief Updates the filter of the last added matcher.
  22883. * @tparam AllOf Types of components required by the matcher.
  22884. * @tparam NoneOf Types of components used to filter out entities.
  22885. * @return The updated collector.
  22886. */
  22887. template<typename... AllOf, typename... NoneOf>
  22888. static constexpr auto where(exclude_t<NoneOf...> = {}) ENTT_NOEXCEPT {
  22889. using extended_type = matcher<type_list<Reject..., NoneOf...>, type_list<Require..., AllOf...>, Rule...>;
  22890. return basic_collector<extended_type, Other...>{};
  22891. }
  22892. };
  22893. /*! @brief Variable template used to ease the definition of collectors. */
  22894. inline constexpr basic_collector<> collector{};
  22895. /**
  22896. * @brief Observer.
  22897. *
  22898. * An observer returns all the entities and only the entities that fit the
  22899. * requirements of at least one matcher. Moreover, it's guaranteed that the
  22900. * entity list is tightly packed in memory for fast iterations.<br/>
  22901. * In general, observers don't stay true to the order of any set of components.
  22902. *
  22903. * Observers work mainly with two types of matchers, provided through a
  22904. * collector:
  22905. *
  22906. * * Observing matcher: an observer will return at least all the living entities
  22907. * for which one or more of the given components have been updated and not yet
  22908. * destroyed.
  22909. * * Grouping matcher: an observer will return at least all the living entities
  22910. * that would have entered the given group if it existed and that would have
  22911. * not yet left it.
  22912. *
  22913. * If an entity respects the requirements of multiple matchers, it will be
  22914. * returned once and only once by the observer in any case.
  22915. *
  22916. * Matchers support also filtering by means of a _where_ clause that accepts
  22917. * both a list of types and an exclusion list.<br/>
  22918. * Whenever a matcher finds that an entity matches its requirements, the
  22919. * condition of the filter is verified before to register the entity itself.
  22920. * Moreover, a registered entity isn't returned by the observer if the condition
  22921. * set by the filter is broken in the meantime.
  22922. *
  22923. * @b Important
  22924. *
  22925. * Iterators aren't invalidated if:
  22926. *
  22927. * * New instances of the given components are created and assigned to entities.
  22928. * * The entity currently pointed is modified (as an example, if one of the
  22929. * given components is removed from the entity to which the iterator points).
  22930. * * The entity currently pointed is destroyed.
  22931. *
  22932. * In all the other cases, modifying the pools of the given components in any
  22933. * way invalidates all the iterators and using them results in undefined
  22934. * behavior.
  22935. *
  22936. * @warning
  22937. * Lifetime of an observer doesn't necessarily have to overcome that of the
  22938. * registry to which it is connected. However, the observer must be disconnected
  22939. * from the registry before being destroyed to avoid crashes due to dangling
  22940. * pointers.
  22941. *
  22942. * @tparam Entity A valid entity type (see entt_traits for more details).
  22943. */
  22944. template<typename Entity>
  22945. class basic_observer {
  22946. using payload_type = std::uint32_t;
  22947. template<typename>
  22948. struct matcher_handler;
  22949. template<typename... Reject, typename... Require, typename AnyOf>
  22950. struct matcher_handler<matcher<type_list<Reject...>, type_list<Require...>, AnyOf>> {
  22951. template<std::size_t Index>
  22952. static void maybe_valid_if(basic_observer &obs, basic_registry<Entity> &reg, const Entity entt) {
  22953. if(reg.template all_of<Require...>(entt) && !reg.template any_of<Reject...>(entt)) {
  22954. if(!obs.storage.contains(entt)) {
  22955. obs.storage.emplace(entt);
  22956. }
  22957. obs.storage.get(entt) |= (1 << Index);
  22958. }
  22959. }
  22960. template<std::size_t Index>
  22961. static void discard_if(basic_observer &obs, basic_registry<Entity> &, const Entity entt) {
  22962. if(obs.storage.contains(entt) && !(obs.storage.get(entt) &= (~(1 << Index)))) {
  22963. obs.storage.erase(entt);
  22964. }
  22965. }
  22966. template<std::size_t Index>
  22967. static void connect(basic_observer &obs, basic_registry<Entity> &reg) {
  22968. (reg.template on_destroy<Require>().template connect<&discard_if<Index>>(obs), ...);
  22969. (reg.template on_construct<Reject>().template connect<&discard_if<Index>>(obs), ...);
  22970. reg.template on_update<AnyOf>().template connect<&maybe_valid_if<Index>>(obs);
  22971. reg.template on_destroy<AnyOf>().template connect<&discard_if<Index>>(obs);
  22972. }
  22973. static void disconnect(basic_observer &obs, basic_registry<Entity> &reg) {
  22974. (reg.template on_destroy<Require>().disconnect(obs), ...);
  22975. (reg.template on_construct<Reject>().disconnect(obs), ...);
  22976. reg.template on_update<AnyOf>().disconnect(obs);
  22977. reg.template on_destroy<AnyOf>().disconnect(obs);
  22978. }
  22979. };
  22980. template<typename... Reject, typename... Require, typename... NoneOf, typename... AllOf>
  22981. struct matcher_handler<matcher<type_list<Reject...>, type_list<Require...>, type_list<NoneOf...>, AllOf...>> {
  22982. template<std::size_t Index, typename... Ignore>
  22983. static void maybe_valid_if(basic_observer &obs, basic_registry<Entity> &reg, const Entity entt) {
  22984. auto condition = [&reg, entt]() {
  22985. if constexpr(sizeof...(Ignore) == 0) {
  22986. return reg.template all_of<AllOf..., Require...>(entt) && !reg.template any_of<NoneOf..., Reject...>(entt);
  22987. } else {
  22988. return reg.template all_of<AllOf..., Require...>(entt) && ((std::is_same_v<Ignore..., NoneOf> || !reg.template any_of<NoneOf>(entt)) && ...) && !reg.template any_of<Reject...>(entt);
  22989. }
  22990. };
  22991. if(condition()) {
  22992. if(!obs.storage.contains(entt)) {
  22993. obs.storage.emplace(entt);
  22994. }
  22995. obs.storage.get(entt) |= (1 << Index);
  22996. }
  22997. }
  22998. template<std::size_t Index>
  22999. static void discard_if(basic_observer &obs, basic_registry<Entity> &, const Entity entt) {
  23000. if(obs.storage.contains(entt) && !(obs.storage.get(entt) &= (~(1 << Index)))) {
  23001. obs.storage.erase(entt);
  23002. }
  23003. }
  23004. template<std::size_t Index>
  23005. static void connect(basic_observer &obs, basic_registry<Entity> &reg) {
  23006. (reg.template on_destroy<Require>().template connect<&discard_if<Index>>(obs), ...);
  23007. (reg.template on_construct<Reject>().template connect<&discard_if<Index>>(obs), ...);
  23008. (reg.template on_construct<AllOf>().template connect<&maybe_valid_if<Index>>(obs), ...);
  23009. (reg.template on_destroy<NoneOf>().template connect<&maybe_valid_if<Index, NoneOf>>(obs), ...);
  23010. (reg.template on_destroy<AllOf>().template connect<&discard_if<Index>>(obs), ...);
  23011. (reg.template on_construct<NoneOf>().template connect<&discard_if<Index>>(obs), ...);
  23012. }
  23013. static void disconnect(basic_observer &obs, basic_registry<Entity> &reg) {
  23014. (reg.template on_destroy<Require>().disconnect(obs), ...);
  23015. (reg.template on_construct<Reject>().disconnect(obs), ...);
  23016. (reg.template on_construct<AllOf>().disconnect(obs), ...);
  23017. (reg.template on_destroy<NoneOf>().disconnect(obs), ...);
  23018. (reg.template on_destroy<AllOf>().disconnect(obs), ...);
  23019. (reg.template on_construct<NoneOf>().disconnect(obs), ...);
  23020. }
  23021. };
  23022. template<typename... Matcher>
  23023. static void disconnect(basic_registry<Entity> &reg, basic_observer &obs) {
  23024. (matcher_handler<Matcher>::disconnect(obs, reg), ...);
  23025. }
  23026. template<typename... Matcher, std::size_t... Index>
  23027. void connect(basic_registry<Entity> &reg, std::index_sequence<Index...>) {
  23028. static_assert(sizeof...(Matcher) < std::numeric_limits<payload_type>::digits, "Too many matchers");
  23029. (matcher_handler<Matcher>::template connect<Index>(*this, reg), ...);
  23030. release.template connect<&basic_observer::disconnect<Matcher...>>(reg);
  23031. }
  23032. public:
  23033. /*! @brief Underlying entity identifier. */
  23034. using entity_type = Entity;
  23035. /*! @brief Unsigned integer type. */
  23036. using size_type = std::size_t;
  23037. /*! @brief Random access iterator type. */
  23038. using iterator = typename basic_sparse_set<Entity>::iterator;
  23039. /*! @brief Default constructor. */
  23040. basic_observer()
  23041. : release{},
  23042. storage{} {}
  23043. /*! @brief Default copy constructor, deleted on purpose. */
  23044. basic_observer(const basic_observer &) = delete;
  23045. /*! @brief Default move constructor, deleted on purpose. */
  23046. basic_observer(basic_observer &&) = delete;
  23047. /**
  23048. * @brief Creates an observer and connects it to a given registry.
  23049. * @tparam Matcher Types of matchers to use to initialize the observer.
  23050. * @param reg A valid reference to a registry.
  23051. */
  23052. template<typename... Matcher>
  23053. basic_observer(basic_registry<entity_type> &reg, basic_collector<Matcher...>)
  23054. : basic_observer{} {
  23055. connect<Matcher...>(reg, std::index_sequence_for<Matcher...>{});
  23056. }
  23057. /*! @brief Default destructor. */
  23058. ~basic_observer() = default;
  23059. /**
  23060. * @brief Default copy assignment operator, deleted on purpose.
  23061. * @return This observer.
  23062. */
  23063. basic_observer &operator=(const basic_observer &) = delete;
  23064. /**
  23065. * @brief Default move assignment operator, deleted on purpose.
  23066. * @return This observer.
  23067. */
  23068. basic_observer &operator=(basic_observer &&) = delete;
  23069. /**
  23070. * @brief Connects an observer to a given registry.
  23071. * @tparam Matcher Types of matchers to use to initialize the observer.
  23072. * @param reg A valid reference to a registry.
  23073. */
  23074. template<typename... Matcher>
  23075. void connect(basic_registry<entity_type> &reg, basic_collector<Matcher...>) {
  23076. disconnect();
  23077. connect<Matcher...>(reg, std::index_sequence_for<Matcher...>{});
  23078. storage.clear();
  23079. }
  23080. /*! @brief Disconnects an observer from the registry it keeps track of. */
  23081. void disconnect() {
  23082. if(release) {
  23083. release(*this);
  23084. release.reset();
  23085. }
  23086. }
  23087. /**
  23088. * @brief Returns the number of elements in an observer.
  23089. * @return Number of elements.
  23090. */
  23091. [[nodiscard]] size_type size() const ENTT_NOEXCEPT {
  23092. return storage.size();
  23093. }
  23094. /**
  23095. * @brief Checks whether an observer is empty.
  23096. * @return True if the observer is empty, false otherwise.
  23097. */
  23098. [[nodiscard]] bool empty() const ENTT_NOEXCEPT {
  23099. return storage.empty();
  23100. }
  23101. /**
  23102. * @brief Direct access to the list of entities of the observer.
  23103. *
  23104. * The returned pointer is such that range `[data(), data() + size())` is
  23105. * always a valid range, even if the container is empty.
  23106. *
  23107. * @note
  23108. * Entities are in the reverse order as returned by the `begin`/`end`
  23109. * iterators.
  23110. *
  23111. * @return A pointer to the array of entities.
  23112. */
  23113. [[nodiscard]] const entity_type *data() const ENTT_NOEXCEPT {
  23114. return storage.data();
  23115. }
  23116. /**
  23117. * @brief Returns an iterator to the first entity of the observer.
  23118. *
  23119. * The returned iterator points to the first entity of the observer. If the
  23120. * container is empty, the returned iterator will be equal to `end()`.
  23121. *
  23122. * @return An iterator to the first entity of the observer.
  23123. */
  23124. [[nodiscard]] iterator begin() const ENTT_NOEXCEPT {
  23125. return storage.basic_sparse_set<entity_type>::begin();
  23126. }
  23127. /**
  23128. * @brief Returns an iterator that is past the last entity of the observer.
  23129. *
  23130. * The returned iterator points to the entity following the last entity of
  23131. * the observer. Attempting to dereference the returned iterator results in
  23132. * undefined behavior.
  23133. *
  23134. * @return An iterator to the entity following the last entity of the
  23135. * observer.
  23136. */
  23137. [[nodiscard]] iterator end() const ENTT_NOEXCEPT {
  23138. return storage.basic_sparse_set<entity_type>::end();
  23139. }
  23140. /*! @brief Clears the underlying container. */
  23141. void clear() ENTT_NOEXCEPT {
  23142. storage.clear();
  23143. }
  23144. /**
  23145. * @brief Iterates entities and applies the given function object to them.
  23146. *
  23147. * The function object is invoked for each entity.<br/>
  23148. * The signature of the function must be equivalent to the following form:
  23149. *
  23150. * @code{.cpp}
  23151. * void(const entity_type);
  23152. * @endcode
  23153. *
  23154. * @tparam Func Type of the function object to invoke.
  23155. * @param func A valid function object.
  23156. */
  23157. template<typename Func>
  23158. void each(Func func) const {
  23159. for(const auto entity: *this) {
  23160. func(entity);
  23161. }
  23162. }
  23163. /**
  23164. * @brief Iterates entities and applies the given function object to them,
  23165. * then clears the observer.
  23166. *
  23167. * @sa each
  23168. *
  23169. * @tparam Func Type of the function object to invoke.
  23170. * @param func A valid function object.
  23171. */
  23172. template<typename Func>
  23173. void each(Func func) {
  23174. std::as_const(*this).each(std::move(func));
  23175. clear();
  23176. }
  23177. private:
  23178. delegate<void(basic_observer &)> release;
  23179. basic_storage<entity_type, payload_type> storage;
  23180. };
  23181. } // namespace entt
  23182. #endif
  23183. // #include "entity/organizer.hpp"
  23184. #ifndef ENTT_ENTITY_ORGANIZER_HPP
  23185. #define ENTT_ENTITY_ORGANIZER_HPP
  23186. #include <algorithm>
  23187. #include <cstddef>
  23188. #include <type_traits>
  23189. #include <utility>
  23190. #include <vector>
  23191. // #include "../container/dense_map.hpp"
  23192. // #include "../core/type_info.hpp"
  23193. // #include "../core/type_traits.hpp"
  23194. // #include "../core/utility.hpp"
  23195. // #include "fwd.hpp"
  23196. // #include "helper.hpp"
  23197. #ifndef ENTT_ENTITY_HELPER_HPP
  23198. #define ENTT_ENTITY_HELPER_HPP
  23199. #include <type_traits>
  23200. // #include "../config/config.h"
  23201. // #include "../core/fwd.hpp"
  23202. // #include "../core/type_traits.hpp"
  23203. // #include "../signal/delegate.hpp"
  23204. // #include "fwd.hpp"
  23205. // #include "registry.hpp"
  23206. namespace entt {
  23207. /**
  23208. * @brief Converts a registry to a view.
  23209. * @tparam Entity A valid entity type (see entt_traits for more details).
  23210. */
  23211. template<typename Entity>
  23212. struct as_view {
  23213. /*! @brief Underlying entity identifier. */
  23214. using entity_type = std::remove_const_t<Entity>;
  23215. /*! @brief Type of registry to convert. */
  23216. using registry_type = constness_as_t<basic_registry<entity_type>, Entity>;
  23217. /**
  23218. * @brief Constructs a converter for a given registry.
  23219. * @param source A valid reference to a registry.
  23220. */
  23221. as_view(registry_type &source) ENTT_NOEXCEPT: reg{source} {}
  23222. /**
  23223. * @brief Conversion function from a registry to a view.
  23224. * @tparam Exclude Types of components used to filter the view.
  23225. * @tparam Component Type of components used to construct the view.
  23226. * @return A newly created view.
  23227. */
  23228. template<typename Exclude, typename... Component>
  23229. operator basic_view<entity_type, get_t<Component...>, Exclude>() const {
  23230. return reg.template view<Component...>(Exclude{});
  23231. }
  23232. private:
  23233. registry_type &reg;
  23234. };
  23235. /**
  23236. * @brief Deduction guide.
  23237. * @tparam Entity A valid entity type (see entt_traits for more details).
  23238. */
  23239. template<typename Entity>
  23240. as_view(basic_registry<Entity> &) -> as_view<Entity>;
  23241. /**
  23242. * @brief Deduction guide.
  23243. * @tparam Entity A valid entity type (see entt_traits for more details).
  23244. */
  23245. template<typename Entity>
  23246. as_view(const basic_registry<Entity> &) -> as_view<const Entity>;
  23247. /**
  23248. * @brief Converts a registry to a group.
  23249. * @tparam Entity A valid entity type (see entt_traits for more details).
  23250. */
  23251. template<typename Entity>
  23252. struct as_group {
  23253. /*! @brief Underlying entity identifier. */
  23254. using entity_type = std::remove_const_t<Entity>;
  23255. /*! @brief Type of registry to convert. */
  23256. using registry_type = constness_as_t<basic_registry<entity_type>, Entity>;
  23257. /**
  23258. * @brief Constructs a converter for a given registry.
  23259. * @param source A valid reference to a registry.
  23260. */
  23261. as_group(registry_type &source) ENTT_NOEXCEPT: reg{source} {}
  23262. /**
  23263. * @brief Conversion function from a registry to a group.
  23264. * @tparam Get Types of components observed by the group.
  23265. * @tparam Exclude Types of components used to filter the group.
  23266. * @tparam Owned Types of components owned by the group.
  23267. * @return A newly created group.
  23268. */
  23269. template<typename Get, typename Exclude, typename... Owned>
  23270. operator basic_group<entity_type, owned_t<Owned...>, Get, Exclude>() const {
  23271. if constexpr(std::is_const_v<registry_type>) {
  23272. return reg.template group_if_exists<Owned...>(Get{}, Exclude{});
  23273. } else {
  23274. return reg.template group<Owned...>(Get{}, Exclude{});
  23275. }
  23276. }
  23277. private:
  23278. registry_type &reg;
  23279. };
  23280. /**
  23281. * @brief Deduction guide.
  23282. * @tparam Entity A valid entity type (see entt_traits for more details).
  23283. */
  23284. template<typename Entity>
  23285. as_group(basic_registry<Entity> &) -> as_group<Entity>;
  23286. /**
  23287. * @brief Deduction guide.
  23288. * @tparam Entity A valid entity type (see entt_traits for more details).
  23289. */
  23290. template<typename Entity>
  23291. as_group(const basic_registry<Entity> &) -> as_group<const Entity>;
  23292. /**
  23293. * @brief Helper to create a listener that directly invokes a member function.
  23294. * @tparam Member Member function to invoke on a component of the given type.
  23295. * @tparam Entity A valid entity type (see entt_traits for more details).
  23296. * @param reg A registry that contains the given entity and its components.
  23297. * @param entt Entity from which to get the component.
  23298. */
  23299. template<auto Member, typename Entity = entity>
  23300. void invoke(basic_registry<Entity> &reg, const Entity entt) {
  23301. static_assert(std::is_member_function_pointer_v<decltype(Member)>, "Invalid pointer to non-static member function");
  23302. delegate<void(basic_registry<Entity> &, const Entity)> func;
  23303. func.template connect<Member>(reg.template get<member_class_t<decltype(Member)>>(entt));
  23304. func(reg, entt);
  23305. }
  23306. /**
  23307. * @brief Returns the entity associated with a given component.
  23308. *
  23309. * @warning
  23310. * Currently, this function only works correctly with the default pool as it
  23311. * makes assumptions about how the components are laid out.
  23312. *
  23313. * @tparam Entity A valid entity type (see entt_traits for more details).
  23314. * @tparam Component Type of component.
  23315. * @param reg A registry that contains the given entity and its components.
  23316. * @param instance A valid component instance.
  23317. * @return The entity associated with the given component.
  23318. */
  23319. template<typename Entity, typename Component>
  23320. Entity to_entity(const basic_registry<Entity> &reg, const Component &instance) {
  23321. const auto &storage = reg.template storage<Component>();
  23322. const typename basic_registry<Entity>::base_type &base = storage;
  23323. const auto *addr = std::addressof(instance);
  23324. for(auto it = base.rbegin(), last = base.rend(); it < last; it += ENTT_PACKED_PAGE) {
  23325. if(const auto dist = (addr - std::addressof(storage.get(*it))); dist >= 0 && dist < ENTT_PACKED_PAGE) {
  23326. return *(it + dist);
  23327. }
  23328. }
  23329. return null;
  23330. }
  23331. } // namespace entt
  23332. #endif
  23333. namespace entt {
  23334. /**
  23335. * @cond TURN_OFF_DOXYGEN
  23336. * Internal details not to be documented.
  23337. */
  23338. namespace internal {
  23339. template<typename>
  23340. struct is_view: std::false_type {};
  23341. template<typename Entity, typename... Component, typename... Exclude>
  23342. struct is_view<basic_view<Entity, get_t<Component...>, exclude_t<Exclude...>>>: std::true_type {};
  23343. template<typename Type>
  23344. inline constexpr bool is_view_v = is_view<Type>::value;
  23345. template<typename Type, typename Override>
  23346. struct unpack_type {
  23347. using ro = std::conditional_t<
  23348. type_list_contains_v<Override, std::add_const_t<Type>> || (std::is_const_v<Type> && !type_list_contains_v<Override, std::remove_const_t<Type>>),
  23349. type_list<std::remove_const_t<Type>>,
  23350. type_list<>>;
  23351. using rw = std::conditional_t<
  23352. type_list_contains_v<Override, std::remove_const_t<Type>> || (!std::is_const_v<Type> && !type_list_contains_v<Override, std::add_const_t<Type>>),
  23353. type_list<Type>,
  23354. type_list<>>;
  23355. };
  23356. template<typename Entity, typename... Override>
  23357. struct unpack_type<basic_registry<Entity>, type_list<Override...>> {
  23358. using ro = type_list<>;
  23359. using rw = type_list<>;
  23360. };
  23361. template<typename Entity, typename... Override>
  23362. struct unpack_type<const basic_registry<Entity>, type_list<Override...>>
  23363. : unpack_type<basic_registry<Entity>, type_list<Override...>> {};
  23364. template<typename Entity, typename... Component, typename... Exclude, typename... Override>
  23365. struct unpack_type<basic_view<Entity, get_t<Component...>, exclude_t<Exclude...>>, type_list<Override...>> {
  23366. using ro = type_list_cat_t<type_list<Exclude...>, typename unpack_type<Component, type_list<Override...>>::ro...>;
  23367. using rw = type_list_cat_t<typename unpack_type<Component, type_list<Override...>>::rw...>;
  23368. };
  23369. template<typename Entity, typename... Component, typename... Exclude, typename... Override>
  23370. struct unpack_type<const basic_view<Entity, get_t<Component...>, exclude_t<Exclude...>>, type_list<Override...>>
  23371. : unpack_type<basic_view<Entity, get_t<Component...>, exclude_t<Exclude...>>, type_list<Override...>> {};
  23372. template<typename, typename>
  23373. struct resource_traits;
  23374. template<typename... Args, typename... Req>
  23375. struct resource_traits<type_list<Args...>, type_list<Req...>> {
  23376. using args = type_list<std::remove_const_t<Args>...>;
  23377. using ro = type_list_cat_t<typename unpack_type<Args, type_list<Req...>>::ro..., typename unpack_type<Req, type_list<>>::ro...>;
  23378. using rw = type_list_cat_t<typename unpack_type<Args, type_list<Req...>>::rw..., typename unpack_type<Req, type_list<>>::rw...>;
  23379. };
  23380. template<typename... Req, typename Ret, typename... Args>
  23381. resource_traits<type_list<std::remove_reference_t<Args>...>, type_list<Req...>> free_function_to_resource_traits(Ret (*)(Args...));
  23382. template<typename... Req, typename Ret, typename Type, typename... Args>
  23383. resource_traits<type_list<std::remove_reference_t<Args>...>, type_list<Req...>> constrained_function_to_resource_traits(Ret (*)(Type &, Args...));
  23384. template<typename... Req, typename Ret, typename Class, typename... Args>
  23385. resource_traits<type_list<std::remove_reference_t<Args>...>, type_list<Req...>> constrained_function_to_resource_traits(Ret (Class::*)(Args...));
  23386. template<typename... Req, typename Ret, typename Class, typename... Args>
  23387. resource_traits<type_list<std::remove_reference_t<Args>...>, type_list<Req...>> constrained_function_to_resource_traits(Ret (Class::*)(Args...) const);
  23388. } // namespace internal
  23389. /**
  23390. * Internal details not to be documented.
  23391. * @endcond
  23392. */
  23393. /**
  23394. * @brief Utility class for creating a static task graph.
  23395. *
  23396. * This class offers minimal support (but sufficient in many cases) for creating
  23397. * an execution graph from functions and their requirements on resources.<br/>
  23398. * Note that the resulting tasks aren't executed in any case. This isn't the
  23399. * goal of the tool. Instead, they are returned to the user in the form of a
  23400. * graph that allows for safe execution.
  23401. *
  23402. * @tparam Entity A valid entity type (see entt_traits for more details).
  23403. */
  23404. template<typename Entity>
  23405. class basic_organizer final {
  23406. using callback_type = void(const void *, basic_registry<Entity> &);
  23407. using prepare_type = void(basic_registry<Entity> &);
  23408. using dependency_type = std::size_t(const bool, const type_info **, const std::size_t);
  23409. struct vertex_data final {
  23410. std::size_t ro_count{};
  23411. std::size_t rw_count{};
  23412. const char *name{};
  23413. const void *payload{};
  23414. callback_type *callback{};
  23415. dependency_type *dependency;
  23416. prepare_type *prepare{};
  23417. const type_info *info{};
  23418. };
  23419. template<typename Type>
  23420. [[nodiscard]] static decltype(auto) extract(basic_registry<Entity> &reg) {
  23421. if constexpr(std::is_same_v<Type, basic_registry<Entity>>) {
  23422. return reg;
  23423. } else if constexpr(internal::is_view_v<Type>) {
  23424. return as_view{reg};
  23425. } else {
  23426. return reg.ctx().template emplace<std::remove_reference_t<Type>>();
  23427. }
  23428. }
  23429. template<typename... Args>
  23430. [[nodiscard]] static auto to_args(basic_registry<Entity> &reg, type_list<Args...>) {
  23431. return std::tuple<decltype(extract<Args>(reg))...>(extract<Args>(reg)...);
  23432. }
  23433. template<typename... Type>
  23434. static std::size_t fill_dependencies(type_list<Type...>, [[maybe_unused]] const type_info **buffer, [[maybe_unused]] const std::size_t count) {
  23435. if constexpr(sizeof...(Type) == 0u) {
  23436. return {};
  23437. } else {
  23438. const type_info *info[sizeof...(Type)]{&type_id<Type>()...};
  23439. const auto length = (std::min)(count, sizeof...(Type));
  23440. std::copy_n(info, length, buffer);
  23441. return length;
  23442. }
  23443. }
  23444. template<typename... RO, typename... RW>
  23445. void track_dependencies(std::size_t index, const bool requires_registry, type_list<RO...>, type_list<RW...>) {
  23446. dependencies[type_hash<basic_registry<Entity>>::value()].emplace_back(index, requires_registry || (sizeof...(RO) + sizeof...(RW) == 0u));
  23447. (dependencies[type_hash<RO>::value()].emplace_back(index, false), ...);
  23448. (dependencies[type_hash<RW>::value()].emplace_back(index, true), ...);
  23449. }
  23450. [[nodiscard]] std::vector<bool> adjacency_matrix() {
  23451. const auto length = vertices.size();
  23452. std::vector<bool> edges(length * length, false);
  23453. // creates the adjacency matrix
  23454. for(const auto &deps: dependencies) {
  23455. const auto last = deps.second.cend();
  23456. auto it = deps.second.cbegin();
  23457. while(it != last) {
  23458. if(it->second) {
  23459. // rw item
  23460. if(auto curr = it++; it != last) {
  23461. if(it->second) {
  23462. edges[curr->first * length + it->first] = true;
  23463. } else {
  23464. if(const auto next = std::find_if(it, last, [](const auto &elem) { return elem.second; }); next != last) {
  23465. for(; it != next; ++it) {
  23466. edges[curr->first * length + it->first] = true;
  23467. edges[it->first * length + next->first] = true;
  23468. }
  23469. } else {
  23470. for(; it != next; ++it) {
  23471. edges[curr->first * length + it->first] = true;
  23472. }
  23473. }
  23474. }
  23475. }
  23476. } else {
  23477. // ro item, possibly only on first iteration
  23478. if(const auto next = std::find_if(it, last, [](const auto &elem) { return elem.second; }); next != last) {
  23479. for(; it != next; ++it) {
  23480. edges[it->first * length + next->first] = true;
  23481. }
  23482. } else {
  23483. it = last;
  23484. }
  23485. }
  23486. }
  23487. }
  23488. // computes the transitive closure
  23489. for(std::size_t vk{}; vk < length; ++vk) {
  23490. for(std::size_t vi{}; vi < length; ++vi) {
  23491. for(std::size_t vj{}; vj < length; ++vj) {
  23492. edges[vi * length + vj] = edges[vi * length + vj] || (edges[vi * length + vk] && edges[vk * length + vj]);
  23493. }
  23494. }
  23495. }
  23496. // applies the transitive reduction
  23497. for(std::size_t vert{}; vert < length; ++vert) {
  23498. edges[vert * length + vert] = false;
  23499. }
  23500. for(std::size_t vj{}; vj < length; ++vj) {
  23501. for(std::size_t vi{}; vi < length; ++vi) {
  23502. if(edges[vi * length + vj]) {
  23503. for(std::size_t vk{}; vk < length; ++vk) {
  23504. if(edges[vj * length + vk]) {
  23505. edges[vi * length + vk] = false;
  23506. }
  23507. }
  23508. }
  23509. }
  23510. }
  23511. return edges;
  23512. }
  23513. public:
  23514. /*! @brief Underlying entity identifier. */
  23515. using entity_type = Entity;
  23516. /*! @brief Unsigned integer type. */
  23517. using size_type = std::size_t;
  23518. /*! @brief Raw task function type. */
  23519. using function_type = callback_type;
  23520. /*! @brief Vertex type of a task graph defined as an adjacency list. */
  23521. struct vertex {
  23522. /**
  23523. * @brief Constructs a vertex of the task graph.
  23524. * @param vtype True if the vertex is a top-level one, false otherwise.
  23525. * @param data The data associated with the vertex.
  23526. * @param edges The indices of the children in the adjacency list.
  23527. */
  23528. vertex(const bool vtype, vertex_data data, std::vector<std::size_t> edges)
  23529. : is_top_level{vtype},
  23530. node{std::move(data)},
  23531. reachable{std::move(edges)} {}
  23532. /**
  23533. * @brief Fills a buffer with the type info objects for the writable
  23534. * resources of a vertex.
  23535. * @param buffer A buffer pre-allocated by the user.
  23536. * @param length The length of the user-supplied buffer.
  23537. * @return The number of type info objects written to the buffer.
  23538. */
  23539. size_type ro_dependency(const type_info **buffer, const std::size_t length) const ENTT_NOEXCEPT {
  23540. return node.dependency(false, buffer, length);
  23541. }
  23542. /**
  23543. * @brief Fills a buffer with the type info objects for the read-only
  23544. * resources of a vertex.
  23545. * @param buffer A buffer pre-allocated by the user.
  23546. * @param length The length of the user-supplied buffer.
  23547. * @return The number of type info objects written to the buffer.
  23548. */
  23549. size_type rw_dependency(const type_info **buffer, const std::size_t length) const ENTT_NOEXCEPT {
  23550. return node.dependency(true, buffer, length);
  23551. }
  23552. /**
  23553. * @brief Returns the number of read-only resources of a vertex.
  23554. * @return The number of read-only resources of the vertex.
  23555. */
  23556. size_type ro_count() const ENTT_NOEXCEPT {
  23557. return node.ro_count;
  23558. }
  23559. /**
  23560. * @brief Returns the number of writable resources of a vertex.
  23561. * @return The number of writable resources of the vertex.
  23562. */
  23563. size_type rw_count() const ENTT_NOEXCEPT {
  23564. return node.rw_count;
  23565. }
  23566. /**
  23567. * @brief Checks if a vertex is also a top-level one.
  23568. * @return True if the vertex is a top-level one, false otherwise.
  23569. */
  23570. bool top_level() const ENTT_NOEXCEPT {
  23571. return is_top_level;
  23572. }
  23573. /**
  23574. * @brief Returns a type info object associated with a vertex.
  23575. * @return A properly initialized type info object.
  23576. */
  23577. const type_info &info() const ENTT_NOEXCEPT {
  23578. return *node.info;
  23579. }
  23580. /**
  23581. * @brief Returns a user defined name associated with a vertex, if any.
  23582. * @return The user defined name associated with the vertex, if any.
  23583. */
  23584. const char *name() const ENTT_NOEXCEPT {
  23585. return node.name;
  23586. }
  23587. /**
  23588. * @brief Returns the function associated with a vertex.
  23589. * @return The function associated with the vertex.
  23590. */
  23591. function_type *callback() const ENTT_NOEXCEPT {
  23592. return node.callback;
  23593. }
  23594. /**
  23595. * @brief Returns the payload associated with a vertex, if any.
  23596. * @return The payload associated with the vertex, if any.
  23597. */
  23598. const void *data() const ENTT_NOEXCEPT {
  23599. return node.payload;
  23600. }
  23601. /**
  23602. * @brief Returns the list of nodes reachable from a given vertex.
  23603. * @return The list of nodes reachable from the vertex.
  23604. */
  23605. const std::vector<std::size_t> &children() const ENTT_NOEXCEPT {
  23606. return reachable;
  23607. }
  23608. /**
  23609. * @brief Prepares a registry and assures that all required resources
  23610. * are properly instantiated before using them.
  23611. * @param reg A valid registry.
  23612. */
  23613. void prepare(basic_registry<entity_type> &reg) const {
  23614. node.prepare ? node.prepare(reg) : void();
  23615. }
  23616. private:
  23617. bool is_top_level;
  23618. vertex_data node;
  23619. std::vector<std::size_t> reachable;
  23620. };
  23621. /**
  23622. * @brief Adds a free function to the task list.
  23623. * @tparam Candidate Function to add to the task list.
  23624. * @tparam Req Additional requirements and/or override resource access mode.
  23625. * @param name Optional name to associate with the task.
  23626. */
  23627. template<auto Candidate, typename... Req>
  23628. void emplace(const char *name = nullptr) {
  23629. using resource_type = decltype(internal::free_function_to_resource_traits<Req...>(Candidate));
  23630. constexpr auto requires_registry = type_list_contains_v<typename resource_type::args, basic_registry<entity_type>>;
  23631. callback_type *callback = +[](const void *, basic_registry<entity_type> &reg) {
  23632. std::apply(Candidate, to_args(reg, typename resource_type::args{}));
  23633. };
  23634. vertex_data vdata{
  23635. resource_type::ro::size,
  23636. resource_type::rw::size,
  23637. name,
  23638. nullptr,
  23639. callback,
  23640. +[](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); },
  23641. +[](basic_registry<entity_type> &reg) { void(to_args(reg, typename resource_type::args{})); },
  23642. &type_id<std::integral_constant<decltype(Candidate), Candidate>>()};
  23643. track_dependencies(vertices.size(), requires_registry, typename resource_type::ro{}, typename resource_type::rw{});
  23644. vertices.push_back(std::move(vdata));
  23645. }
  23646. /**
  23647. * @brief Adds a free function with payload or a member function with an
  23648. * instance to the task list.
  23649. * @tparam Candidate Function or member to add to the task list.
  23650. * @tparam Req Additional requirements and/or override resource access mode.
  23651. * @tparam Type Type of class or type of payload.
  23652. * @param value_or_instance A valid object that fits the purpose.
  23653. * @param name Optional name to associate with the task.
  23654. */
  23655. template<auto Candidate, typename... Req, typename Type>
  23656. void emplace(Type &value_or_instance, const char *name = nullptr) {
  23657. using resource_type = decltype(internal::constrained_function_to_resource_traits<Req...>(Candidate));
  23658. constexpr auto requires_registry = type_list_contains_v<typename resource_type::args, basic_registry<entity_type>>;
  23659. callback_type *callback = +[](const void *payload, basic_registry<entity_type> &reg) {
  23660. Type *curr = static_cast<Type *>(const_cast<constness_as_t<void, Type> *>(payload));
  23661. std::apply(Candidate, std::tuple_cat(std::forward_as_tuple(*curr), to_args(reg, typename resource_type::args{})));
  23662. };
  23663. vertex_data vdata{
  23664. resource_type::ro::size,
  23665. resource_type::rw::size,
  23666. name,
  23667. &value_or_instance,
  23668. callback,
  23669. +[](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); },
  23670. +[](basic_registry<entity_type> &reg) { void(to_args(reg, typename resource_type::args{})); },
  23671. &type_id<std::integral_constant<decltype(Candidate), Candidate>>()};
  23672. track_dependencies(vertices.size(), requires_registry, typename resource_type::ro{}, typename resource_type::rw{});
  23673. vertices.push_back(std::move(vdata));
  23674. }
  23675. /**
  23676. * @brief Adds an user defined function with optional payload to the task
  23677. * list.
  23678. * @tparam Req Additional requirements and/or override resource access mode.
  23679. * @param func Function to add to the task list.
  23680. * @param payload User defined arbitrary data.
  23681. * @param name Optional name to associate with the task.
  23682. */
  23683. template<typename... Req>
  23684. void emplace(function_type *func, const void *payload = nullptr, const char *name = nullptr) {
  23685. using resource_type = internal::resource_traits<type_list<>, type_list<Req...>>;
  23686. track_dependencies(vertices.size(), true, typename resource_type::ro{}, typename resource_type::rw{});
  23687. vertex_data vdata{
  23688. resource_type::ro::size,
  23689. resource_type::rw::size,
  23690. name,
  23691. payload,
  23692. func,
  23693. +[](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); },
  23694. nullptr,
  23695. &type_id<void>()};
  23696. vertices.push_back(std::move(vdata));
  23697. }
  23698. /**
  23699. * @brief Generates a task graph for the current content.
  23700. * @return The adjacency list of the task graph.
  23701. */
  23702. std::vector<vertex> graph() {
  23703. const auto edges = adjacency_matrix();
  23704. // creates the adjacency list
  23705. std::vector<vertex> adjacency_list{};
  23706. adjacency_list.reserve(vertices.size());
  23707. for(std::size_t col{}, length = vertices.size(); col < length; ++col) {
  23708. std::vector<std::size_t> reachable{};
  23709. const auto row = col * length;
  23710. bool is_top_level = true;
  23711. for(std::size_t next{}; next < length; ++next) {
  23712. if(edges[row + next]) {
  23713. reachable.push_back(next);
  23714. }
  23715. }
  23716. for(std::size_t next{}; next < length && is_top_level; ++next) {
  23717. is_top_level = !edges[next * length + col];
  23718. }
  23719. adjacency_list.emplace_back(is_top_level, vertices[col], std::move(reachable));
  23720. }
  23721. return adjacency_list;
  23722. }
  23723. /*! @brief Erases all elements from a container. */
  23724. void clear() {
  23725. dependencies.clear();
  23726. vertices.clear();
  23727. }
  23728. private:
  23729. dense_map<id_type, std::vector<std::pair<std::size_t, bool>>, identity> dependencies;
  23730. std::vector<vertex_data> vertices;
  23731. };
  23732. } // namespace entt
  23733. #endif
  23734. // #include "entity/registry.hpp"
  23735. #ifndef ENTT_ENTITY_REGISTRY_HPP
  23736. #define ENTT_ENTITY_REGISTRY_HPP
  23737. #include <algorithm>
  23738. #include <cstddef>
  23739. #include <iterator>
  23740. #include <memory>
  23741. #include <tuple>
  23742. #include <type_traits>
  23743. #include <utility>
  23744. #include <vector>
  23745. // #include "../config/config.h"
  23746. // #include "../container/dense_map.hpp"
  23747. // #include "../core/algorithm.hpp"
  23748. // #include "../core/any.hpp"
  23749. // #include "../core/fwd.hpp"
  23750. // #include "../core/iterator.hpp"
  23751. // #include "../core/type_info.hpp"
  23752. // #include "../core/type_traits.hpp"
  23753. // #include "../core/utility.hpp"
  23754. // #include "component.hpp"
  23755. // #include "entity.hpp"
  23756. // #include "fwd.hpp"
  23757. // #include "group.hpp"
  23758. // #include "runtime_view.hpp"
  23759. // #include "sparse_set.hpp"
  23760. // #include "storage.hpp"
  23761. // #include "utility.hpp"
  23762. // #include "view.hpp"
  23763. namespace entt {
  23764. /**
  23765. * @cond TURN_OFF_DOXYGEN
  23766. * Internal details not to be documented.
  23767. */
  23768. namespace internal {
  23769. template<typename It>
  23770. class storage_proxy_iterator final {
  23771. template<typename Other>
  23772. friend class storage_proxy_iterator;
  23773. using mapped_type = std::remove_reference_t<decltype(std::declval<It>()->second)>;
  23774. public:
  23775. using value_type = std::pair<id_type, constness_as_t<typename mapped_type::element_type, mapped_type> &>;
  23776. using pointer = input_iterator_pointer<value_type>;
  23777. using reference = value_type;
  23778. using difference_type = std::ptrdiff_t;
  23779. using iterator_category = std::input_iterator_tag;
  23780. storage_proxy_iterator() ENTT_NOEXCEPT
  23781. : it{} {}
  23782. storage_proxy_iterator(const It iter) ENTT_NOEXCEPT
  23783. : it{iter} {}
  23784. template<typename Other, typename = std::enable_if_t<!std::is_same_v<It, Other> && std::is_constructible_v<It, Other>>>
  23785. storage_proxy_iterator(const storage_proxy_iterator<Other> &other) ENTT_NOEXCEPT
  23786. : it{other.it} {}
  23787. storage_proxy_iterator &operator++() ENTT_NOEXCEPT {
  23788. return ++it, *this;
  23789. }
  23790. storage_proxy_iterator operator++(int) ENTT_NOEXCEPT {
  23791. storage_proxy_iterator orig = *this;
  23792. return ++(*this), orig;
  23793. }
  23794. storage_proxy_iterator &operator--() ENTT_NOEXCEPT {
  23795. return --it, *this;
  23796. }
  23797. storage_proxy_iterator operator--(int) ENTT_NOEXCEPT {
  23798. storage_proxy_iterator orig = *this;
  23799. return operator--(), orig;
  23800. }
  23801. storage_proxy_iterator &operator+=(const difference_type value) ENTT_NOEXCEPT {
  23802. it += value;
  23803. return *this;
  23804. }
  23805. storage_proxy_iterator operator+(const difference_type value) const ENTT_NOEXCEPT {
  23806. storage_proxy_iterator copy = *this;
  23807. return (copy += value);
  23808. }
  23809. storage_proxy_iterator &operator-=(const difference_type value) ENTT_NOEXCEPT {
  23810. return (*this += -value);
  23811. }
  23812. storage_proxy_iterator operator-(const difference_type value) const ENTT_NOEXCEPT {
  23813. return (*this + -value);
  23814. }
  23815. [[nodiscard]] reference operator[](const difference_type value) const ENTT_NOEXCEPT {
  23816. return {it[value].first, *it[value].second};
  23817. }
  23818. [[nodiscard]] reference operator*() const ENTT_NOEXCEPT {
  23819. return {it->first, *it->second};
  23820. }
  23821. [[nodiscard]] pointer operator->() const ENTT_NOEXCEPT {
  23822. return operator*();
  23823. }
  23824. template<typename ILhs, typename IRhs>
  23825. friend std::ptrdiff_t operator-(const storage_proxy_iterator<ILhs> &, const storage_proxy_iterator<IRhs> &) ENTT_NOEXCEPT;
  23826. template<typename ILhs, typename IRhs>
  23827. friend bool operator==(const storage_proxy_iterator<ILhs> &, const storage_proxy_iterator<IRhs> &) ENTT_NOEXCEPT;
  23828. template<typename ILhs, typename IRhs>
  23829. friend bool operator<(const storage_proxy_iterator<ILhs> &, const storage_proxy_iterator<IRhs> &) ENTT_NOEXCEPT;
  23830. private:
  23831. It it;
  23832. };
  23833. template<typename ILhs, typename IRhs>
  23834. [[nodiscard]] std::ptrdiff_t operator-(const storage_proxy_iterator<ILhs> &lhs, const storage_proxy_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  23835. return lhs.it - rhs.it;
  23836. }
  23837. template<typename ILhs, typename IRhs>
  23838. [[nodiscard]] bool operator==(const storage_proxy_iterator<ILhs> &lhs, const storage_proxy_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  23839. return lhs.it == rhs.it;
  23840. }
  23841. template<typename ILhs, typename IRhs>
  23842. [[nodiscard]] bool operator!=(const storage_proxy_iterator<ILhs> &lhs, const storage_proxy_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  23843. return !(lhs == rhs);
  23844. }
  23845. template<typename ILhs, typename IRhs>
  23846. [[nodiscard]] bool operator<(const storage_proxy_iterator<ILhs> &lhs, const storage_proxy_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  23847. return lhs.it < rhs.it;
  23848. }
  23849. template<typename ILhs, typename IRhs>
  23850. [[nodiscard]] bool operator>(const storage_proxy_iterator<ILhs> &lhs, const storage_proxy_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  23851. return rhs < lhs;
  23852. }
  23853. template<typename ILhs, typename IRhs>
  23854. [[nodiscard]] bool operator<=(const storage_proxy_iterator<ILhs> &lhs, const storage_proxy_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  23855. return !(lhs > rhs);
  23856. }
  23857. template<typename ILhs, typename IRhs>
  23858. [[nodiscard]] bool operator>=(const storage_proxy_iterator<ILhs> &lhs, const storage_proxy_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  23859. return !(lhs < rhs);
  23860. }
  23861. struct registry_context {
  23862. template<typename Type, typename... Args>
  23863. Type &emplace_hint(const id_type id, Args &&...args) {
  23864. return any_cast<Type &>(data.try_emplace(id, std::in_place_type<Type>, std::forward<Args>(args)...).first->second);
  23865. }
  23866. template<typename Type, typename... Args>
  23867. Type &emplace(Args &&...args) {
  23868. return emplace_hint<Type>(type_id<Type>().hash(), std::forward<Args>(args)...);
  23869. }
  23870. template<typename Type>
  23871. bool erase(const id_type id = type_id<Type>().hash()) {
  23872. const auto it = data.find(id);
  23873. return it != data.end() && it->second.type() == type_id<Type>() ? (data.erase(it), true) : false;
  23874. }
  23875. template<typename Type>
  23876. [[nodiscard]] std::add_const_t<Type> &at(const id_type id = type_id<Type>().hash()) const {
  23877. return any_cast<std::add_const_t<Type> &>(data.at(id));
  23878. }
  23879. template<typename Type>
  23880. [[nodiscard]] Type &at(const id_type id = type_id<Type>().hash()) {
  23881. return any_cast<Type &>(data.at(id));
  23882. }
  23883. template<typename Type>
  23884. [[nodiscard]] std::add_const_t<Type> *find(const id_type id = type_id<Type>().hash()) const {
  23885. const auto it = data.find(id);
  23886. return it != data.cend() ? any_cast<std::add_const_t<Type>>(&it->second) : nullptr;
  23887. }
  23888. template<typename Type>
  23889. [[nodiscard]] Type *find(const id_type id = type_id<Type>().hash()) {
  23890. const auto it = data.find(id);
  23891. return it != data.end() ? any_cast<Type>(&it->second) : nullptr;
  23892. }
  23893. template<typename Type>
  23894. [[nodiscard]] bool contains(const id_type id = type_id<Type>().hash()) const {
  23895. const auto it = data.find(id);
  23896. return it != data.end() && it->second.type() == type_id<Type>();
  23897. }
  23898. private:
  23899. dense_map<id_type, basic_any<0u>, identity> data;
  23900. };
  23901. } // namespace internal
  23902. /**
  23903. * Internal details not to be documented.
  23904. * @endcond
  23905. */
  23906. /**
  23907. * @brief Fast and reliable entity-component system.
  23908. * @tparam Entity A valid entity type (see entt_traits for more details).
  23909. */
  23910. template<typename Entity>
  23911. class basic_registry {
  23912. using entity_traits = entt_traits<Entity>;
  23913. using basic_common_type = basic_sparse_set<Entity>;
  23914. template<typename Component>
  23915. using storage_type = typename storage_traits<Entity, Component>::storage_type;
  23916. template<typename...>
  23917. struct group_handler;
  23918. template<typename... Exclude, typename... Get, typename... Owned>
  23919. struct group_handler<exclude_t<Exclude...>, get_t<Get...>, Owned...> {
  23920. // nasty workaround for an issue with the toolset v141 that doesn't accept a fold expression here
  23921. static_assert(!std::disjunction_v<std::bool_constant<component_traits<Owned>::in_place_delete>...>, "Groups do not support in-place delete");
  23922. std::conditional_t<sizeof...(Owned) == 0, basic_common_type, std::size_t> current{};
  23923. template<typename Component>
  23924. void maybe_valid_if(basic_registry &owner, const Entity entt) {
  23925. [[maybe_unused]] const auto cpools = std::forward_as_tuple(owner.assure<Owned>()...);
  23926. const auto is_valid = ((std::is_same_v<Component, Owned> || std::get<storage_type<Owned> &>(cpools).contains(entt)) && ...)
  23927. && ((std::is_same_v<Component, Get> || owner.assure<Get>().contains(entt)) && ...)
  23928. && ((std::is_same_v<Component, Exclude> || !owner.assure<Exclude>().contains(entt)) && ...);
  23929. if constexpr(sizeof...(Owned) == 0) {
  23930. if(is_valid && !current.contains(entt)) {
  23931. current.emplace(entt);
  23932. }
  23933. } else {
  23934. if(is_valid && !(std::get<0>(cpools).index(entt) < current)) {
  23935. const auto pos = current++;
  23936. (std::get<storage_type<Owned> &>(cpools).swap_elements(std::get<storage_type<Owned> &>(cpools).data()[pos], entt), ...);
  23937. }
  23938. }
  23939. }
  23940. void discard_if([[maybe_unused]] basic_registry &owner, const Entity entt) {
  23941. if constexpr(sizeof...(Owned) == 0) {
  23942. current.remove(entt);
  23943. } else {
  23944. if(const auto cpools = std::forward_as_tuple(owner.assure<Owned>()...); std::get<0>(cpools).contains(entt) && (std::get<0>(cpools).index(entt) < current)) {
  23945. const auto pos = --current;
  23946. (std::get<storage_type<Owned> &>(cpools).swap_elements(std::get<storage_type<Owned> &>(cpools).data()[pos], entt), ...);
  23947. }
  23948. }
  23949. }
  23950. };
  23951. struct group_data {
  23952. std::size_t size;
  23953. std::unique_ptr<void, void (*)(void *)> group;
  23954. bool (*owned)(const id_type) ENTT_NOEXCEPT;
  23955. bool (*get)(const id_type) ENTT_NOEXCEPT;
  23956. bool (*exclude)(const id_type) ENTT_NOEXCEPT;
  23957. };
  23958. template<typename Component>
  23959. [[nodiscard]] auto &assure(const id_type id = type_hash<Component>::value()) {
  23960. static_assert(std::is_same_v<Component, std::decay_t<Component>>, "Non-decayed types not allowed");
  23961. auto &&cpool = pools[id];
  23962. if(!cpool) {
  23963. cpool.reset(new storage_type<Component>{});
  23964. cpool->bind(forward_as_any(*this));
  23965. }
  23966. ENTT_ASSERT(cpool->type() == type_id<Component>(), "Unexpected type");
  23967. return static_cast<storage_type<Component> &>(*cpool);
  23968. }
  23969. template<typename Component>
  23970. [[nodiscard]] const auto &assure(const id_type id = type_hash<Component>::value()) const {
  23971. static_assert(std::is_same_v<Component, std::decay_t<Component>>, "Non-decayed types not allowed");
  23972. if(const auto it = pools.find(id); it != pools.cend()) {
  23973. ENTT_ASSERT(it->second->type() == type_id<Component>(), "Unexpected type");
  23974. return static_cast<const storage_type<Component> &>(*it->second);
  23975. }
  23976. static storage_type<Component> placeholder{};
  23977. return placeholder;
  23978. }
  23979. auto generate_identifier(const std::size_t pos) ENTT_NOEXCEPT {
  23980. ENTT_ASSERT(pos < entity_traits::to_entity(null), "No entities available");
  23981. return entity_traits::combine(static_cast<typename entity_traits::entity_type>(pos), {});
  23982. }
  23983. auto recycle_identifier() ENTT_NOEXCEPT {
  23984. ENTT_ASSERT(free_list != null, "No entities available");
  23985. const auto curr = entity_traits::to_entity(free_list);
  23986. free_list = entity_traits::combine(entity_traits::to_integral(entities[curr]), tombstone);
  23987. return (entities[curr] = entity_traits::combine(curr, entity_traits::to_integral(entities[curr])));
  23988. }
  23989. auto release_entity(const Entity entity, const typename entity_traits::version_type version) {
  23990. const typename entity_traits::version_type vers = version + (version == entity_traits::to_version(tombstone));
  23991. entities[entity_traits::to_entity(entity)] = entity_traits::construct(entity_traits::to_integral(free_list), vers);
  23992. free_list = entity_traits::combine(entity_traits::to_integral(entity), tombstone);
  23993. return vers;
  23994. }
  23995. public:
  23996. /*! @brief Underlying entity identifier. */
  23997. using entity_type = Entity;
  23998. /*! @brief Underlying version type. */
  23999. using version_type = typename entity_traits::version_type;
  24000. /*! @brief Unsigned integer type. */
  24001. using size_type = std::size_t;
  24002. /*! @brief Common type among all storage types. */
  24003. using base_type = basic_common_type;
  24004. /*! @brief Context type. */
  24005. using context = internal::registry_context;
  24006. /*! @brief Default constructor. */
  24007. basic_registry()
  24008. : pools{},
  24009. groups{},
  24010. entities{},
  24011. free_list{tombstone},
  24012. vars{} {}
  24013. /**
  24014. * @brief Allocates enough memory upon construction to store `count` pools.
  24015. * @param count The number of pools to allocate memory for.
  24016. */
  24017. basic_registry(const size_type count)
  24018. : pools{},
  24019. groups{},
  24020. entities{},
  24021. free_list{tombstone},
  24022. vars{} {
  24023. pools.reserve(count);
  24024. }
  24025. /**
  24026. * @brief Move constructor.
  24027. * @param other The instance to move from.
  24028. */
  24029. basic_registry(basic_registry &&other)
  24030. : pools{std::move(other.pools)},
  24031. groups{std::move(other.groups)},
  24032. entities{std::move(other.entities)},
  24033. free_list{other.free_list},
  24034. vars{std::move(other.vars)} {
  24035. for(auto &&curr: pools) {
  24036. curr.second->bind(forward_as_any(*this));
  24037. }
  24038. }
  24039. /**
  24040. * @brief Move assignment operator.
  24041. * @param other The instance to move from.
  24042. * @return This registry.
  24043. */
  24044. basic_registry &operator=(basic_registry &&other) {
  24045. pools = std::move(other.pools);
  24046. groups = std::move(other.groups);
  24047. entities = std::move(other.entities);
  24048. free_list = other.free_list;
  24049. vars = std::move(other.vars);
  24050. for(auto &&curr: pools) {
  24051. curr.second->bind(forward_as_any(*this));
  24052. }
  24053. return *this;
  24054. }
  24055. /**
  24056. * @brief Returns an iterable object to use to _visit_ a registry.
  24057. *
  24058. * The iterable object returns a pair that contains the name and a reference
  24059. * to the current storage.
  24060. *
  24061. * @return An iterable object to use to _visit_ the registry.
  24062. */
  24063. [[nodiscard]] auto storage() ENTT_NOEXCEPT {
  24064. return iterable_adaptor{internal::storage_proxy_iterator{pools.begin()}, internal::storage_proxy_iterator{pools.end()}};
  24065. }
  24066. /*! @copydoc storage */
  24067. [[nodiscard]] auto storage() const ENTT_NOEXCEPT {
  24068. return iterable_adaptor{internal::storage_proxy_iterator{pools.cbegin()}, internal::storage_proxy_iterator{pools.cend()}};
  24069. }
  24070. /**
  24071. * @brief Finds the storage associated with a given name, if any.
  24072. * @param id Name used to map the storage within the registry.
  24073. * @return An iterator to the given storage if it's found, past the end
  24074. * iterator otherwise.
  24075. */
  24076. [[nodiscard]] auto storage(const id_type id) {
  24077. return internal::storage_proxy_iterator{pools.find(id)};
  24078. }
  24079. /**
  24080. * @brief Finds the storage associated with a given name, if any.
  24081. * @param id Name used to map the storage within the registry.
  24082. * @return An iterator to the given storage if it's found, past the end
  24083. * iterator otherwise.
  24084. */
  24085. [[nodiscard]] auto storage(const id_type id) const {
  24086. return internal::storage_proxy_iterator{pools.find(id)};
  24087. }
  24088. /**
  24089. * @brief Returns the storage for a given component type.
  24090. * @tparam Component Type of component of which to return the storage.
  24091. * @param id Optional name used to map the storage within the registry.
  24092. * @return The storage for the given component type.
  24093. */
  24094. template<typename Component>
  24095. decltype(auto) storage(const id_type id = type_hash<std::remove_const_t<Component>>::value()) {
  24096. if constexpr(std::is_const_v<Component>) {
  24097. return std::as_const(*this).template storage<std::remove_const_t<Component>>(id);
  24098. } else {
  24099. return assure<Component>(id);
  24100. }
  24101. }
  24102. /**
  24103. * @brief Returns the storage for a given component type.
  24104. *
  24105. * @warning
  24106. * If a storage for the given component doesn't exist yet, a temporary
  24107. * placeholder is returned instead.
  24108. *
  24109. * @tparam Component Type of component of which to return the storage.
  24110. * @param id Optional name used to map the storage within the registry.
  24111. * @return The storage for the given component type.
  24112. */
  24113. template<typename Component>
  24114. decltype(auto) storage(const id_type id = type_hash<std::remove_const_t<Component>>::value()) const {
  24115. return assure<std::remove_const_t<Component>>(id);
  24116. }
  24117. /**
  24118. * @brief Returns the number of entities created so far.
  24119. * @return Number of entities created so far.
  24120. */
  24121. [[nodiscard]] size_type size() const ENTT_NOEXCEPT {
  24122. return entities.size();
  24123. }
  24124. /**
  24125. * @brief Returns the number of entities still in use.
  24126. * @return Number of entities still in use.
  24127. */
  24128. [[nodiscard]] size_type alive() const {
  24129. auto sz = entities.size();
  24130. for(auto curr = free_list; curr != null; --sz) {
  24131. curr = entities[entity_traits::to_entity(curr)];
  24132. }
  24133. return sz;
  24134. }
  24135. /**
  24136. * @brief Increases the capacity (number of entities) of the registry.
  24137. * @param cap Desired capacity.
  24138. */
  24139. void reserve(const size_type cap) {
  24140. entities.reserve(cap);
  24141. }
  24142. /**
  24143. * @brief Returns the number of entities that a registry has currently
  24144. * allocated space for.
  24145. * @return Capacity of the registry.
  24146. */
  24147. [[nodiscard]] size_type capacity() const ENTT_NOEXCEPT {
  24148. return entities.capacity();
  24149. }
  24150. /**
  24151. * @brief Checks whether the registry is empty (no entities still in use).
  24152. * @return True if the registry is empty, false otherwise.
  24153. */
  24154. [[nodiscard]] bool empty() const {
  24155. return !alive();
  24156. }
  24157. /**
  24158. * @brief Direct access to the list of entities of a registry.
  24159. *
  24160. * The returned pointer is such that range `[data(), data() + size())` is
  24161. * always a valid range, even if the registry is empty.
  24162. *
  24163. * @warning
  24164. * This list contains both valid and destroyed entities and isn't suitable
  24165. * for direct use.
  24166. *
  24167. * @return A pointer to the array of entities.
  24168. */
  24169. [[nodiscard]] const entity_type *data() const ENTT_NOEXCEPT {
  24170. return entities.data();
  24171. }
  24172. /**
  24173. * @brief Returns the head of the list of released entities.
  24174. *
  24175. * This function is intended for use in conjunction with `assign`.<br/>
  24176. * The returned entity has an invalid identifier in all cases.
  24177. *
  24178. * @return The head of the list of released entities.
  24179. */
  24180. [[nodiscard]] entity_type released() const ENTT_NOEXCEPT {
  24181. return free_list;
  24182. }
  24183. /**
  24184. * @brief Checks if an identifier refers to a valid entity.
  24185. * @param entity An identifier, either valid or not.
  24186. * @return True if the identifier is valid, false otherwise.
  24187. */
  24188. [[nodiscard]] bool valid(const entity_type entity) const {
  24189. const auto pos = size_type(entity_traits::to_entity(entity));
  24190. return (pos < entities.size() && entities[pos] == entity);
  24191. }
  24192. /**
  24193. * @brief Returns the actual version for an identifier.
  24194. * @param entity A valid identifier.
  24195. * @return The version for the given identifier if valid, the tombstone
  24196. * version otherwise.
  24197. */
  24198. [[nodiscard]] version_type current(const entity_type entity) const {
  24199. const auto pos = size_type(entity_traits::to_entity(entity));
  24200. return entity_traits::to_version(pos < entities.size() ? entities[pos] : tombstone);
  24201. }
  24202. /**
  24203. * @brief Creates a new entity or recycles a destroyed one.
  24204. * @return A valid identifier.
  24205. */
  24206. [[nodiscard]] entity_type create() {
  24207. return (free_list == null) ? entities.emplace_back(generate_identifier(entities.size())) : recycle_identifier();
  24208. }
  24209. /**
  24210. * @copybrief create
  24211. *
  24212. * If the requested entity isn't in use, the suggested identifier is used.
  24213. * Otherwise, a new identifier is generated.
  24214. *
  24215. * @param hint Required identifier.
  24216. * @return A valid identifier.
  24217. */
  24218. [[nodiscard]] entity_type create(const entity_type hint) {
  24219. const auto length = entities.size();
  24220. if(hint == null || hint == tombstone) {
  24221. return create();
  24222. } else if(const auto req = entity_traits::to_entity(hint); !(req < length)) {
  24223. entities.resize(size_type(req) + 1u, null);
  24224. for(auto pos = length; pos < req; ++pos) {
  24225. release_entity(generate_identifier(pos), {});
  24226. }
  24227. return (entities[req] = hint);
  24228. } else if(const auto curr = entity_traits::to_entity(entities[req]); req == curr) {
  24229. return create();
  24230. } else {
  24231. auto *it = &free_list;
  24232. for(; entity_traits::to_entity(*it) != req; it = &entities[entity_traits::to_entity(*it)]) {}
  24233. *it = entity_traits::combine(curr, entity_traits::to_integral(*it));
  24234. return (entities[req] = hint);
  24235. }
  24236. }
  24237. /**
  24238. * @brief Assigns each element in a range an identifier.
  24239. *
  24240. * @sa create
  24241. *
  24242. * @tparam It Type of forward iterator.
  24243. * @param first An iterator to the first element of the range to generate.
  24244. * @param last An iterator past the last element of the range to generate.
  24245. */
  24246. template<typename It>
  24247. void create(It first, It last) {
  24248. for(; free_list != null && first != last; ++first) {
  24249. *first = recycle_identifier();
  24250. }
  24251. const auto length = entities.size();
  24252. entities.resize(length + std::distance(first, last), null);
  24253. for(auto pos = length; first != last; ++first, ++pos) {
  24254. *first = entities[pos] = generate_identifier(pos);
  24255. }
  24256. }
  24257. /**
  24258. * @brief Assigns identifiers to an empty registry.
  24259. *
  24260. * This function is intended for use in conjunction with `data`, `size` and
  24261. * `destroyed`.<br/>
  24262. * Don't try to inject ranges of randomly generated entities nor the _wrong_
  24263. * head for the list of destroyed entities. There is no guarantee that a
  24264. * registry will continue to work properly in this case.
  24265. *
  24266. * @warning
  24267. * There must be no entities still alive for this to work properly.
  24268. *
  24269. * @tparam It Type of input iterator.
  24270. * @param first An iterator to the first element of the range of entities.
  24271. * @param last An iterator past the last element of the range of entities.
  24272. * @param destroyed The head of the list of destroyed entities.
  24273. */
  24274. template<typename It>
  24275. void assign(It first, It last, const entity_type destroyed) {
  24276. ENTT_ASSERT(!alive(), "Entities still alive");
  24277. entities.assign(first, last);
  24278. free_list = destroyed;
  24279. }
  24280. /**
  24281. * @brief Releases an identifier.
  24282. *
  24283. * The version is updated and the identifier can be recycled at any time.
  24284. *
  24285. * @warning
  24286. * Attempting to use an invalid entity results in undefined behavior.
  24287. *
  24288. * @param entity A valid identifier.
  24289. * @return The version of the recycled entity.
  24290. */
  24291. version_type release(const entity_type entity) {
  24292. return release(entity, static_cast<version_type>(entity_traits::to_version(entity) + 1u));
  24293. }
  24294. /**
  24295. * @brief Releases an identifier.
  24296. *
  24297. * The suggested version or the valid version closest to the suggested one
  24298. * is used instead of the implicitly generated version.
  24299. *
  24300. * @sa release
  24301. *
  24302. * @param entity A valid identifier.
  24303. * @param version A desired version upon destruction.
  24304. * @return The version actually assigned to the entity.
  24305. */
  24306. version_type release(const entity_type entity, const version_type version) {
  24307. ENTT_ASSERT(orphan(entity), "Non-orphan entity");
  24308. return release_entity(entity, version);
  24309. }
  24310. /**
  24311. * @brief Releases all identifiers in a range.
  24312. *
  24313. * @sa release
  24314. *
  24315. * @tparam It Type of input iterator.
  24316. * @param first An iterator to the first element of the range of entities.
  24317. * @param last An iterator past the last element of the range of entities.
  24318. */
  24319. template<typename It>
  24320. void release(It first, It last) {
  24321. for(; first != last; ++first) {
  24322. release(*first);
  24323. }
  24324. }
  24325. /**
  24326. * @brief Destroys an entity and releases its identifier.
  24327. *
  24328. * @sa release
  24329. *
  24330. * @warning
  24331. * Adding or removing components to an entity that is being destroyed can
  24332. * result in undefined behavior. Attempting to use an invalid entity results
  24333. * in undefined behavior.
  24334. *
  24335. * @param entity A valid identifier.
  24336. * @return The version of the recycled entity.
  24337. */
  24338. version_type destroy(const entity_type entity) {
  24339. return destroy(entity, static_cast<version_type>(entity_traits::to_version(entity) + 1u));
  24340. }
  24341. /**
  24342. * @brief Destroys an entity and releases its identifier.
  24343. *
  24344. * The suggested version or the valid version closest to the suggested one
  24345. * is used instead of the implicitly generated version.
  24346. *
  24347. * @sa destroy
  24348. *
  24349. * @param entity A valid identifier.
  24350. * @param version A desired version upon destruction.
  24351. * @return The version actually assigned to the entity.
  24352. */
  24353. version_type destroy(const entity_type entity, const version_type version) {
  24354. ENTT_ASSERT(valid(entity), "Invalid entity");
  24355. for(size_type pos = pools.size(); pos; --pos) {
  24356. pools.begin()[pos - 1u].second->remove(entity);
  24357. }
  24358. return release_entity(entity, version);
  24359. }
  24360. /**
  24361. * @brief Destroys all entities in a range and releases their identifiers.
  24362. *
  24363. * @sa destroy
  24364. *
  24365. * @tparam It Type of input iterator.
  24366. * @param first An iterator to the first element of the range of entities.
  24367. * @param last An iterator past the last element of the range of entities.
  24368. */
  24369. template<typename It>
  24370. void destroy(It first, It last) {
  24371. for(; first != last; ++first) {
  24372. destroy(*first);
  24373. }
  24374. }
  24375. /**
  24376. * @brief Assigns the given component to an entity.
  24377. *
  24378. * The component must have a proper constructor or be of aggregate type.
  24379. *
  24380. * @warning
  24381. * Attempting to use an invalid entity or to assign a component to an entity
  24382. * that already owns it results in undefined behavior.
  24383. *
  24384. * @tparam Component Type of component to create.
  24385. * @tparam Args Types of arguments to use to construct the component.
  24386. * @param entity A valid identifier.
  24387. * @param args Parameters to use to initialize the component.
  24388. * @return A reference to the newly created component.
  24389. */
  24390. template<typename Component, typename... Args>
  24391. decltype(auto) emplace(const entity_type entity, Args &&...args) {
  24392. ENTT_ASSERT(valid(entity), "Invalid entity");
  24393. return assure<Component>().emplace(entity, std::forward<Args>(args)...);
  24394. }
  24395. /**
  24396. * @brief Assigns each entity in a range the given component.
  24397. *
  24398. * @sa emplace
  24399. *
  24400. * @tparam Component Type of component to create.
  24401. * @tparam It Type of input iterator.
  24402. * @param first An iterator to the first element of the range of entities.
  24403. * @param last An iterator past the last element of the range of entities.
  24404. * @param value An instance of the component to assign.
  24405. */
  24406. template<typename Component, typename It>
  24407. void insert(It first, It last, const Component &value = {}) {
  24408. ENTT_ASSERT(std::all_of(first, last, [this](const auto entity) { return valid(entity); }), "Invalid entity");
  24409. assure<Component>().insert(first, last, value);
  24410. }
  24411. /**
  24412. * @brief Assigns each entity in a range the given components.
  24413. *
  24414. * @sa emplace
  24415. *
  24416. * @tparam Component Type of component to create.
  24417. * @tparam EIt Type of input iterator.
  24418. * @tparam CIt Type of input iterator.
  24419. * @param first An iterator to the first element of the range of entities.
  24420. * @param last An iterator past the last element of the range of entities.
  24421. * @param from An iterator to the first element of the range of components.
  24422. */
  24423. template<typename Component, typename EIt, typename CIt, typename = std::enable_if_t<std::is_same_v<typename std::iterator_traits<CIt>::value_type, Component>>>
  24424. void insert(EIt first, EIt last, CIt from) {
  24425. ENTT_ASSERT(std::all_of(first, last, [this](const auto entity) { return valid(entity); }), "Invalid entity");
  24426. assure<Component>().insert(first, last, from);
  24427. }
  24428. /**
  24429. * @brief Assigns or replaces the given component for an entity.
  24430. *
  24431. * @warning
  24432. * Attempting to use an invalid entity results in undefined behavior.
  24433. *
  24434. * @tparam Component Type of component to assign or replace.
  24435. * @tparam Args Types of arguments to use to construct the component.
  24436. * @param entity A valid identifier.
  24437. * @param args Parameters to use to initialize the component.
  24438. * @return A reference to the newly created component.
  24439. */
  24440. template<typename Component, typename... Args>
  24441. decltype(auto) emplace_or_replace(const entity_type entity, Args &&...args) {
  24442. ENTT_ASSERT(valid(entity), "Invalid entity");
  24443. auto &cpool = assure<Component>();
  24444. return cpool.contains(entity)
  24445. ? cpool.patch(entity, [&args...](auto &...curr) { ((curr = Component{std::forward<Args>(args)...}), ...); })
  24446. : cpool.emplace(entity, std::forward<Args>(args)...);
  24447. }
  24448. /**
  24449. * @brief Patches the given component for an entity.
  24450. *
  24451. * The signature of the function should be equivalent to the following:
  24452. *
  24453. * @code{.cpp}
  24454. * void(Component &);
  24455. * @endcode
  24456. *
  24457. * @note
  24458. * Empty types aren't explicitly instantiated and therefore they are never
  24459. * returned. However, this function can be used to trigger an update signal
  24460. * for them.
  24461. *
  24462. * @warning
  24463. * Attempting to use an invalid entity or to patch a component of an entity
  24464. * that doesn't own it results in undefined behavior.
  24465. *
  24466. * @tparam Component Type of component to patch.
  24467. * @tparam Func Types of the function objects to invoke.
  24468. * @param entity A valid identifier.
  24469. * @param func Valid function objects.
  24470. * @return A reference to the patched component.
  24471. */
  24472. template<typename Component, typename... Func>
  24473. decltype(auto) patch(const entity_type entity, Func &&...func) {
  24474. ENTT_ASSERT(valid(entity), "Invalid entity");
  24475. return assure<Component>().patch(entity, std::forward<Func>(func)...);
  24476. }
  24477. /**
  24478. * @brief Replaces the given component for an entity.
  24479. *
  24480. * The component must have a proper constructor or be of aggregate type.
  24481. *
  24482. * @warning
  24483. * Attempting to use an invalid entity or to replace a component of an
  24484. * entity that doesn't own it results in undefined behavior.
  24485. *
  24486. * @tparam Component Type of component to replace.
  24487. * @tparam Args Types of arguments to use to construct the component.
  24488. * @param entity A valid identifier.
  24489. * @param args Parameters to use to initialize the component.
  24490. * @return A reference to the component being replaced.
  24491. */
  24492. template<typename Component, typename... Args>
  24493. decltype(auto) replace(const entity_type entity, Args &&...args) {
  24494. ENTT_ASSERT(valid(entity), "Invalid entity");
  24495. return assure<Component>().patch(entity, [&args...](auto &...curr) { ((curr = Component{std::forward<Args>(args)...}), ...); });
  24496. }
  24497. /**
  24498. * @brief Removes the given components from an entity.
  24499. *
  24500. * @warning
  24501. * Attempting to use an invalid entity results in undefined behavior.
  24502. *
  24503. * @tparam Component Type of component to remove.
  24504. * @tparam Other Other types of components to remove.
  24505. * @param entity A valid identifier.
  24506. * @return The number of components actually removed.
  24507. */
  24508. template<typename Component, typename... Other>
  24509. size_type remove(const entity_type entity) {
  24510. ENTT_ASSERT(valid(entity), "Invalid entity");
  24511. return (assure<Component>().remove(entity) + ... + assure<Other>().remove(entity));
  24512. }
  24513. /**
  24514. * @brief Removes the given components from all the entities in a range.
  24515. *
  24516. * @sa remove
  24517. *
  24518. * @tparam Component Type of component to remove.
  24519. * @tparam Other Other types of components to remove.
  24520. * @tparam It Type of input iterator.
  24521. * @param first An iterator to the first element of the range of entities.
  24522. * @param last An iterator past the last element of the range of entities.
  24523. * @return The number of components actually removed.
  24524. */
  24525. template<typename Component, typename... Other, typename It>
  24526. size_type remove(It first, It last) {
  24527. if constexpr(sizeof...(Other) == 0u) {
  24528. ENTT_ASSERT(std::all_of(first, last, [this](const auto entity) { return valid(entity); }), "Invalid entity");
  24529. return assure<Component>().remove(std::move(first), std::move(last));
  24530. } else {
  24531. size_type count{};
  24532. for(auto cpools = std::forward_as_tuple(assure<Component>(), assure<Other>()...); first != last; ++first) {
  24533. ENTT_ASSERT(valid(*first), "Invalid entity");
  24534. count += std::apply([entt = *first](auto &...curr) { return (curr.remove(entt) + ... + 0u); }, cpools);
  24535. }
  24536. return count;
  24537. }
  24538. }
  24539. /**
  24540. * @brief Erases the given components from an entity.
  24541. *
  24542. * @warning
  24543. * Attempting to use an invalid entity or to erase a component from an
  24544. * entity that doesn't own it results in undefined behavior.
  24545. *
  24546. * @tparam Component Types of components to erase.
  24547. * @tparam Other Other types of components to erase.
  24548. * @param entity A valid identifier.
  24549. */
  24550. template<typename Component, typename... Other>
  24551. void erase(const entity_type entity) {
  24552. ENTT_ASSERT(valid(entity), "Invalid entity");
  24553. (assure<Component>().erase(entity), (assure<Other>().erase(entity), ...));
  24554. }
  24555. /**
  24556. * @brief Erases the given components from all the entities in a range.
  24557. *
  24558. * @sa erase
  24559. *
  24560. * @tparam Component Types of components to erase.
  24561. * @tparam Other Other types of components to erase.
  24562. * @tparam It Type of input iterator.
  24563. * @param first An iterator to the first element of the range of entities.
  24564. * @param last An iterator past the last element of the range of entities.
  24565. */
  24566. template<typename Component, typename... Other, typename It>
  24567. void erase(It first, It last) {
  24568. if constexpr(sizeof...(Other) == 0u) {
  24569. ENTT_ASSERT(std::all_of(first, last, [this](const auto entity) { return valid(entity); }), "Invalid entity");
  24570. assure<Component>().erase(std::move(first), std::move(last));
  24571. } else {
  24572. for(auto cpools = std::forward_as_tuple(assure<Component>(), assure<Other>()...); first != last; ++first) {
  24573. ENTT_ASSERT(valid(*first), "Invalid entity");
  24574. std::apply([entt = *first](auto &...curr) { (curr.erase(entt), ...); }, cpools);
  24575. }
  24576. }
  24577. }
  24578. /**
  24579. * @brief Removes all tombstones from a registry or only the pools for the
  24580. * given components.
  24581. * @tparam Component Types of components for which to clear all tombstones.
  24582. */
  24583. template<typename... Component>
  24584. void compact() {
  24585. if constexpr(sizeof...(Component) == 0) {
  24586. for(auto &&curr: pools) {
  24587. curr.second->compact();
  24588. }
  24589. } else {
  24590. (assure<Component>().compact(), ...);
  24591. }
  24592. }
  24593. /**
  24594. * @brief Checks if an entity has all the given components.
  24595. *
  24596. * @warning
  24597. * Attempting to use an invalid entity results in undefined behavior.
  24598. *
  24599. * @tparam Component Components for which to perform the check.
  24600. * @param entity A valid identifier.
  24601. * @return True if the entity has all the components, false otherwise.
  24602. */
  24603. template<typename... Component>
  24604. [[nodiscard]] bool all_of(const entity_type entity) const {
  24605. ENTT_ASSERT(valid(entity), "Invalid entity");
  24606. return (assure<std::remove_const_t<Component>>().contains(entity) && ...);
  24607. }
  24608. /**
  24609. * @brief Checks if an entity has at least one of the given components.
  24610. *
  24611. * @warning
  24612. * Attempting to use an invalid entity results in undefined behavior.
  24613. *
  24614. * @tparam Component Components for which to perform the check.
  24615. * @param entity A valid identifier.
  24616. * @return True if the entity has at least one of the given components,
  24617. * false otherwise.
  24618. */
  24619. template<typename... Component>
  24620. [[nodiscard]] bool any_of(const entity_type entity) const {
  24621. ENTT_ASSERT(valid(entity), "Invalid entity");
  24622. return (assure<std::remove_const_t<Component>>().contains(entity) || ...);
  24623. }
  24624. /**
  24625. * @brief Returns references to the given components for an entity.
  24626. *
  24627. * @warning
  24628. * Attempting to use an invalid entity or to get a component from an entity
  24629. * that doesn't own it results in undefined behavior.
  24630. *
  24631. * @tparam Component Types of components to get.
  24632. * @param entity A valid identifier.
  24633. * @return References to the components owned by the entity.
  24634. */
  24635. template<typename... Component>
  24636. [[nodiscard]] decltype(auto) get([[maybe_unused]] const entity_type entity) const {
  24637. ENTT_ASSERT(valid(entity), "Invalid entity");
  24638. return view<Component...>().template get<const Component...>(entity);
  24639. }
  24640. /*! @copydoc get */
  24641. template<typename... Component>
  24642. [[nodiscard]] decltype(auto) get([[maybe_unused]] const entity_type entity) {
  24643. ENTT_ASSERT(valid(entity), "Invalid entity");
  24644. return view<Component...>().template get<Component...>(entity);
  24645. }
  24646. /**
  24647. * @brief Returns a reference to the given component for an entity.
  24648. *
  24649. * In case the entity doesn't own the component, the parameters provided are
  24650. * used to construct it.
  24651. *
  24652. * @warning
  24653. * Attempting to use an invalid entity results in undefined behavior.
  24654. *
  24655. * @tparam Component Type of component to get.
  24656. * @tparam Args Types of arguments to use to construct the component.
  24657. * @param entity A valid identifier.
  24658. * @param args Parameters to use to initialize the component.
  24659. * @return Reference to the component owned by the entity.
  24660. */
  24661. template<typename Component, typename... Args>
  24662. [[nodiscard]] decltype(auto) get_or_emplace(const entity_type entity, Args &&...args) {
  24663. ENTT_ASSERT(valid(entity), "Invalid entity");
  24664. auto &cpool = assure<Component>();
  24665. return cpool.contains(entity) ? cpool.get(entity) : cpool.emplace(entity, std::forward<Args>(args)...);
  24666. }
  24667. /**
  24668. * @brief Returns pointers to the given components for an entity.
  24669. *
  24670. * @warning
  24671. * Attempting to use an invalid entity results in undefined behavior.
  24672. *
  24673. * @note
  24674. * The registry retains ownership of the pointed-to components.
  24675. *
  24676. * @tparam Component Types of components to get.
  24677. * @param entity A valid identifier.
  24678. * @return Pointers to the components owned by the entity.
  24679. */
  24680. template<typename... Component>
  24681. [[nodiscard]] auto try_get([[maybe_unused]] const entity_type entity) const {
  24682. ENTT_ASSERT(valid(entity), "Invalid entity");
  24683. if constexpr(sizeof...(Component) == 1) {
  24684. const auto &cpool = assure<std::remove_const_t<Component>...>();
  24685. return cpool.contains(entity) ? std::addressof(cpool.get(entity)) : nullptr;
  24686. } else {
  24687. return std::make_tuple(try_get<Component>(entity)...);
  24688. }
  24689. }
  24690. /*! @copydoc try_get */
  24691. template<typename... Component>
  24692. [[nodiscard]] auto try_get([[maybe_unused]] const entity_type entity) {
  24693. if constexpr(sizeof...(Component) == 1) {
  24694. return (const_cast<Component *>(std::as_const(*this).template try_get<Component>(entity)), ...);
  24695. } else {
  24696. return std::make_tuple(try_get<Component>(entity)...);
  24697. }
  24698. }
  24699. /**
  24700. * @brief Clears a whole registry or the pools for the given components.
  24701. * @tparam Component Types of components to remove from their entities.
  24702. */
  24703. template<typename... Component>
  24704. void clear() {
  24705. if constexpr(sizeof...(Component) == 0) {
  24706. for(auto &&curr: pools) {
  24707. curr.second->clear();
  24708. }
  24709. each([this](const auto entity) { this->release(entity); });
  24710. } else {
  24711. (assure<Component>().clear(), ...);
  24712. }
  24713. }
  24714. /**
  24715. * @brief Iterates all the entities that are still in use.
  24716. *
  24717. * The signature of the function should be equivalent to the following:
  24718. *
  24719. * @code{.cpp}
  24720. * void(const Entity);
  24721. * @endcode
  24722. *
  24723. * It's not defined whether entities created during iteration are returned.
  24724. *
  24725. * @tparam Func Type of the function object to invoke.
  24726. * @param func A valid function object.
  24727. */
  24728. template<typename Func>
  24729. void each(Func func) const {
  24730. if(free_list == null) {
  24731. for(auto pos = entities.size(); pos; --pos) {
  24732. func(entities[pos - 1]);
  24733. }
  24734. } else {
  24735. for(auto pos = entities.size(); pos; --pos) {
  24736. if(const auto entity = entities[pos - 1]; entity_traits::to_entity(entity) == (pos - 1)) {
  24737. func(entity);
  24738. }
  24739. }
  24740. }
  24741. }
  24742. /**
  24743. * @brief Checks if an entity has components assigned.
  24744. * @param entity A valid identifier.
  24745. * @return True if the entity has no components assigned, false otherwise.
  24746. */
  24747. [[nodiscard]] bool orphan(const entity_type entity) const {
  24748. ENTT_ASSERT(valid(entity), "Invalid entity");
  24749. return std::none_of(pools.cbegin(), pools.cend(), [entity](auto &&curr) { return curr.second->contains(entity); });
  24750. }
  24751. /**
  24752. * @brief Returns a sink object for the given component.
  24753. *
  24754. * Use this function to receive notifications whenever a new instance of the
  24755. * given component is created and assigned to an entity.<br/>
  24756. * The function type for a listener is equivalent to:
  24757. *
  24758. * @code{.cpp}
  24759. * void(basic_registry<Entity> &, Entity);
  24760. * @endcode
  24761. *
  24762. * Listeners are invoked **after** assigning the component to the entity.
  24763. *
  24764. * @sa sink
  24765. *
  24766. * @tparam Component Type of component of which to get the sink.
  24767. * @return A temporary sink object.
  24768. */
  24769. template<typename Component>
  24770. [[nodiscard]] auto on_construct() {
  24771. return assure<Component>().on_construct();
  24772. }
  24773. /**
  24774. * @brief Returns a sink object for the given component.
  24775. *
  24776. * Use this function to receive notifications whenever an instance of the
  24777. * given component is explicitly updated.<br/>
  24778. * The function type for a listener is equivalent to:
  24779. *
  24780. * @code{.cpp}
  24781. * void(basic_registry<Entity> &, Entity);
  24782. * @endcode
  24783. *
  24784. * Listeners are invoked **after** updating the component.
  24785. *
  24786. * @sa sink
  24787. *
  24788. * @tparam Component Type of component of which to get the sink.
  24789. * @return A temporary sink object.
  24790. */
  24791. template<typename Component>
  24792. [[nodiscard]] auto on_update() {
  24793. return assure<Component>().on_update();
  24794. }
  24795. /**
  24796. * @brief Returns a sink object for the given component.
  24797. *
  24798. * Use this function to receive notifications whenever an instance of the
  24799. * given component is removed from an entity and thus destroyed.<br/>
  24800. * The function type for a listener is equivalent to:
  24801. *
  24802. * @code{.cpp}
  24803. * void(basic_registry<Entity> &, Entity);
  24804. * @endcode
  24805. *
  24806. * Listeners are invoked **before** removing the component from the entity.
  24807. *
  24808. * @sa sink
  24809. *
  24810. * @tparam Component Type of component of which to get the sink.
  24811. * @return A temporary sink object.
  24812. */
  24813. template<typename Component>
  24814. [[nodiscard]] auto on_destroy() {
  24815. return assure<Component>().on_destroy();
  24816. }
  24817. /**
  24818. * @brief Returns a view for the given components.
  24819. *
  24820. * Views are created on the fly and share with the registry its internal
  24821. * data structures. Feel free to discard them after the use.<br/>
  24822. * Creating and destroying a view is an incredibly cheap operation. As a
  24823. * rule of thumb, storing a view should never be an option.
  24824. *
  24825. * @tparam Component Type of component used to construct the view.
  24826. * @tparam Other Other types of components used to construct the view.
  24827. * @tparam Exclude Types of components used to filter the view.
  24828. * @return A newly created view.
  24829. */
  24830. template<typename Component, typename... Other, typename... Exclude>
  24831. [[nodiscard]] basic_view<entity_type, get_t<std::add_const_t<Component>, std::add_const_t<Other>...>, exclude_t<Exclude...>> view(exclude_t<Exclude...> = {}) const {
  24832. return {assure<std::remove_const_t<Component>>(), assure<std::remove_const_t<Other>>()..., assure<Exclude>()...};
  24833. }
  24834. /*! @copydoc view */
  24835. template<typename Component, typename... Other, typename... Exclude>
  24836. [[nodiscard]] basic_view<entity_type, get_t<Component, Other...>, exclude_t<Exclude...>> view(exclude_t<Exclude...> = {}) {
  24837. return {assure<std::remove_const_t<Component>>(), assure<std::remove_const_t<Other>>()..., assure<Exclude>()...};
  24838. }
  24839. /**
  24840. * @brief Returns a group for the given components.
  24841. *
  24842. * Groups are created on the fly and share with the registry its internal
  24843. * data structures. Feel free to discard them after the use.<br/>
  24844. * Creating and destroying a group is an incredibly cheap operation. As a
  24845. * rule of thumb, storing a group should never be an option.
  24846. *
  24847. * Groups support exclusion lists and can own types of components. The more
  24848. * types are owned by a group, the faster it is to iterate entities and
  24849. * components.<br/>
  24850. * However, groups also affect some features of the registry such as the
  24851. * creation and destruction of components.
  24852. *
  24853. * @note
  24854. * Pools of components that are owned by a group cannot be sorted anymore.
  24855. * The group takes the ownership of the pools and arrange components so as
  24856. * to iterate them as fast as possible.
  24857. *
  24858. * @tparam Owned Types of components owned by the group.
  24859. * @tparam Get Types of components observed by the group.
  24860. * @tparam Exclude Types of components used to filter the group.
  24861. * @return A newly created group.
  24862. */
  24863. template<typename... Owned, typename... Get, typename... Exclude>
  24864. [[nodiscard]] basic_group<entity_type, owned_t<Owned...>, get_t<Get...>, exclude_t<Exclude...>> group(get_t<Get...>, exclude_t<Exclude...> = {}) {
  24865. static_assert(sizeof...(Owned) + sizeof...(Get) > 0, "Exclusion-only groups are not supported");
  24866. static_assert(sizeof...(Owned) + sizeof...(Get) + sizeof...(Exclude) > 1, "Single component groups are not allowed");
  24867. using handler_type = group_handler<exclude_t<std::remove_const_t<Exclude>...>, get_t<std::remove_const_t<Get>...>, std::remove_const_t<Owned>...>;
  24868. const auto cpools = std::forward_as_tuple(assure<std::remove_const_t<Owned>>()..., assure<std::remove_const_t<Get>>()...);
  24869. constexpr auto size = sizeof...(Owned) + sizeof...(Get) + sizeof...(Exclude);
  24870. handler_type *handler = nullptr;
  24871. auto it = std::find_if(groups.cbegin(), groups.cend(), [size](const auto &gdata) {
  24872. return gdata.size == size
  24873. && (gdata.owned(type_hash<std::remove_const_t<Owned>>::value()) && ...)
  24874. && (gdata.get(type_hash<std::remove_const_t<Get>>::value()) && ...)
  24875. && (gdata.exclude(type_hash<Exclude>::value()) && ...);
  24876. });
  24877. if(it != groups.cend()) {
  24878. handler = static_cast<handler_type *>(it->group.get());
  24879. } else {
  24880. group_data candidate = {
  24881. size,
  24882. {new handler_type{}, [](void *instance) { delete static_cast<handler_type *>(instance); }},
  24883. []([[maybe_unused]] const id_type ctype) ENTT_NOEXCEPT { return ((ctype == type_hash<std::remove_const_t<Owned>>::value()) || ...); },
  24884. []([[maybe_unused]] const id_type ctype) ENTT_NOEXCEPT { return ((ctype == type_hash<std::remove_const_t<Get>>::value()) || ...); },
  24885. []([[maybe_unused]] const id_type ctype) ENTT_NOEXCEPT { return ((ctype == type_hash<Exclude>::value()) || ...); },
  24886. };
  24887. handler = static_cast<handler_type *>(candidate.group.get());
  24888. const void *maybe_valid_if = nullptr;
  24889. const void *discard_if = nullptr;
  24890. if constexpr(sizeof...(Owned) == 0) {
  24891. groups.push_back(std::move(candidate));
  24892. } else {
  24893. [[maybe_unused]] auto has_conflict = [size](const auto &gdata) {
  24894. const auto overlapping = (0u + ... + gdata.owned(type_hash<std::remove_const_t<Owned>>::value()));
  24895. const auto sz = overlapping + (0u + ... + gdata.get(type_hash<std::remove_const_t<Get>>::value())) + (0u + ... + gdata.exclude(type_hash<Exclude>::value()));
  24896. return !overlapping || ((sz == size) || (sz == gdata.size));
  24897. };
  24898. ENTT_ASSERT(std::all_of(groups.cbegin(), groups.cend(), std::move(has_conflict)), "Conflicting groups");
  24899. const auto next = std::find_if_not(groups.cbegin(), groups.cend(), [size](const auto &gdata) {
  24900. return !(0u + ... + gdata.owned(type_hash<std::remove_const_t<Owned>>::value())) || (size > gdata.size);
  24901. });
  24902. const auto prev = std::find_if(std::make_reverse_iterator(next), groups.crend(), [](const auto &gdata) {
  24903. return (0u + ... + gdata.owned(type_hash<std::remove_const_t<Owned>>::value()));
  24904. });
  24905. maybe_valid_if = (next == groups.cend() ? maybe_valid_if : next->group.get());
  24906. discard_if = (prev == groups.crend() ? discard_if : prev->group.get());
  24907. groups.insert(next, std::move(candidate));
  24908. }
  24909. (on_construct<std::remove_const_t<Owned>>().before(maybe_valid_if).template connect<&handler_type::template maybe_valid_if<std::remove_const_t<Owned>>>(*handler), ...);
  24910. (on_construct<std::remove_const_t<Get>>().before(maybe_valid_if).template connect<&handler_type::template maybe_valid_if<std::remove_const_t<Get>>>(*handler), ...);
  24911. (on_destroy<Exclude>().before(maybe_valid_if).template connect<&handler_type::template maybe_valid_if<Exclude>>(*handler), ...);
  24912. (on_destroy<std::remove_const_t<Owned>>().before(discard_if).template connect<&handler_type::discard_if>(*handler), ...);
  24913. (on_destroy<std::remove_const_t<Get>>().before(discard_if).template connect<&handler_type::discard_if>(*handler), ...);
  24914. (on_construct<Exclude>().before(discard_if).template connect<&handler_type::discard_if>(*handler), ...);
  24915. if constexpr(sizeof...(Owned) == 0) {
  24916. for(const auto entity: view<Owned..., Get...>(exclude<Exclude...>)) {
  24917. handler->current.emplace(entity);
  24918. }
  24919. } else {
  24920. // we cannot iterate backwards because we want to leave behind valid entities in case of owned types
  24921. for(auto *first = std::get<0>(cpools).data(), *last = first + std::get<0>(cpools).size(); first != last; ++first) {
  24922. handler->template maybe_valid_if<type_list_element_t<0, type_list<std::remove_const_t<Owned>...>>>(*this, *first);
  24923. }
  24924. }
  24925. }
  24926. return {handler->current, std::get<storage_type<std::remove_const_t<Owned>> &>(cpools)..., std::get<storage_type<std::remove_const_t<Get>> &>(cpools)...};
  24927. }
  24928. /*! @copydoc group */
  24929. template<typename... Owned, typename... Get, typename... Exclude>
  24930. [[nodiscard]] basic_group<entity_type, owned_t<std::add_const_t<Owned>...>, get_t<std::add_const_t<Get>...>, exclude_t<Exclude...>> group_if_exists(get_t<Get...>, exclude_t<Exclude...> = {}) const {
  24931. auto it = std::find_if(groups.cbegin(), groups.cend(), [](const auto &gdata) {
  24932. return gdata.size == (sizeof...(Owned) + sizeof...(Get) + sizeof...(Exclude))
  24933. && (gdata.owned(type_hash<std::remove_const_t<Owned>>::value()) && ...)
  24934. && (gdata.get(type_hash<std::remove_const_t<Get>>::value()) && ...)
  24935. && (gdata.exclude(type_hash<Exclude>::value()) && ...);
  24936. });
  24937. if(it == groups.cend()) {
  24938. return {};
  24939. } else {
  24940. using handler_type = group_handler<exclude_t<std::remove_const_t<Exclude>...>, get_t<std::remove_const_t<Get>...>, std::remove_const_t<Owned>...>;
  24941. return {static_cast<handler_type *>(it->group.get())->current, assure<std::remove_const_t<Owned>>()..., assure<std::remove_const_t<Get>>()...};
  24942. }
  24943. }
  24944. /*! @copydoc group */
  24945. template<typename... Owned, typename... Exclude>
  24946. [[nodiscard]] basic_group<entity_type, owned_t<Owned...>, get_t<>, exclude_t<Exclude...>> group(exclude_t<Exclude...> = {}) {
  24947. return group<Owned...>(get_t<>{}, exclude<Exclude...>);
  24948. }
  24949. /*! @copydoc group */
  24950. template<typename... Owned, typename... Exclude>
  24951. [[nodiscard]] basic_group<entity_type, owned_t<std::add_const_t<Owned>...>, get_t<>, exclude_t<Exclude...>> group_if_exists(exclude_t<Exclude...> = {}) const {
  24952. return group_if_exists<std::add_const_t<Owned>...>(get_t<>{}, exclude<Exclude...>);
  24953. }
  24954. /**
  24955. * @brief Checks whether the given components belong to any group.
  24956. * @tparam Component Types of components in which one is interested.
  24957. * @return True if the pools of the given components are _free_, false
  24958. * otherwise.
  24959. */
  24960. template<typename... Component>
  24961. [[nodiscard]] bool owned() const {
  24962. return std::any_of(groups.cbegin(), groups.cend(), [](auto &&gdata) { return (gdata.owned(type_hash<std::remove_const_t<Component>>::value()) || ...); });
  24963. }
  24964. /**
  24965. * @brief Checks whether a group can be sorted.
  24966. * @tparam Owned Types of components owned by the group.
  24967. * @tparam Get Types of components observed by the group.
  24968. * @tparam Exclude Types of components used to filter the group.
  24969. * @return True if the group can be sorted, false otherwise.
  24970. */
  24971. template<typename... Owned, typename... Get, typename... Exclude>
  24972. [[nodiscard]] bool sortable(const basic_group<entity_type, owned_t<Owned...>, get_t<Get...>, exclude_t<Exclude...>> &) ENTT_NOEXCEPT {
  24973. constexpr auto size = sizeof...(Owned) + sizeof...(Get) + sizeof...(Exclude);
  24974. auto pred = [size](const auto &gdata) { return (0u + ... + gdata.owned(type_hash<std::remove_const_t<Owned>>::value())) && (size < gdata.size); };
  24975. return std::find_if(groups.cbegin(), groups.cend(), std::move(pred)) == groups.cend();
  24976. }
  24977. /**
  24978. * @brief Sorts the elements of a given component.
  24979. *
  24980. * The order remains valid until a component of the given type is assigned
  24981. * to or removed from an entity.<br/>
  24982. * The comparison function object returns `true` if the first element is
  24983. * _less_ than the second one, `false` otherwise. Its signature is also
  24984. * equivalent to one of the following:
  24985. *
  24986. * @code{.cpp}
  24987. * bool(const Entity, const Entity);
  24988. * bool(const Component &, const Component &);
  24989. * @endcode
  24990. *
  24991. * Moreover, it shall induce a _strict weak ordering_ on the values.<br/>
  24992. * The sort function object offers an `operator()` that accepts:
  24993. *
  24994. * * An iterator to the first element of the range to sort.
  24995. * * An iterator past the last element of the range to sort.
  24996. * * A comparison function object to use to compare the elements.
  24997. *
  24998. * The comparison function object hasn't necessarily the type of the one
  24999. * passed along with the other parameters to this member function.
  25000. *
  25001. * @warning
  25002. * Pools of components owned by a group cannot be sorted.
  25003. *
  25004. * @tparam Component Type of components to sort.
  25005. * @tparam Compare Type of comparison function object.
  25006. * @tparam Sort Type of sort function object.
  25007. * @tparam Args Types of arguments to forward to the sort function object.
  25008. * @param compare A valid comparison function object.
  25009. * @param algo A valid sort function object.
  25010. * @param args Arguments to forward to the sort function object, if any.
  25011. */
  25012. template<typename Component, typename Compare, typename Sort = std_sort, typename... Args>
  25013. void sort(Compare compare, Sort algo = Sort{}, Args &&...args) {
  25014. ENTT_ASSERT(!owned<Component>(), "Cannot sort owned storage");
  25015. auto &cpool = assure<Component>();
  25016. if constexpr(std::is_invocable_v<Compare, decltype(cpool.get({})), decltype(cpool.get({}))>) {
  25017. 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))); };
  25018. cpool.sort(std::move(comp), std::move(algo), std::forward<Args>(args)...);
  25019. } else {
  25020. cpool.sort(std::move(compare), std::move(algo), std::forward<Args>(args)...);
  25021. }
  25022. }
  25023. /**
  25024. * @brief Sorts two pools of components in the same way.
  25025. *
  25026. * Being `To` and `From` the two sets, after invoking this function an
  25027. * iterator for `To` returns elements according to the following rules:
  25028. *
  25029. * * All entities in `To` that are also in `From` are returned first
  25030. * according to the order they have in `From`.
  25031. * * All entities in `To` that are not in `From` are returned in no
  25032. * particular order after all the other entities.
  25033. *
  25034. * Any subsequent change to `From` won't affect the order in `To`.
  25035. *
  25036. * @warning
  25037. * Pools of components owned by a group cannot be sorted.
  25038. *
  25039. * @tparam To Type of components to sort.
  25040. * @tparam From Type of components to use to sort.
  25041. */
  25042. template<typename To, typename From>
  25043. void sort() {
  25044. ENTT_ASSERT(!owned<To>(), "Cannot sort owned storage");
  25045. assure<To>().respect(assure<From>());
  25046. }
  25047. /**
  25048. * @brief Returns the context object, that is, a general purpose container.
  25049. * @return The context object, that is, a general purpose container.
  25050. */
  25051. context &ctx() ENTT_NOEXCEPT {
  25052. return vars;
  25053. }
  25054. /*! @copydoc ctx */
  25055. const context &ctx() const ENTT_NOEXCEPT {
  25056. return vars;
  25057. }
  25058. private:
  25059. dense_map<id_type, std::unique_ptr<base_type>, identity> pools;
  25060. std::vector<group_data> groups;
  25061. std::vector<entity_type> entities;
  25062. entity_type free_list;
  25063. context vars;
  25064. };
  25065. } // namespace entt
  25066. #endif
  25067. // #include "entity/runtime_view.hpp"
  25068. #ifndef ENTT_ENTITY_RUNTIME_VIEW_HPP
  25069. #define ENTT_ENTITY_RUNTIME_VIEW_HPP
  25070. #include <algorithm>
  25071. #include <iterator>
  25072. #include <type_traits>
  25073. #include <utility>
  25074. #include <vector>
  25075. // #include "../config/config.h"
  25076. // #include "entity.hpp"
  25077. // #include "fwd.hpp"
  25078. // #include "sparse_set.hpp"
  25079. namespace entt {
  25080. /**
  25081. * @cond TURN_OFF_DOXYGEN
  25082. * Internal details not to be documented.
  25083. */
  25084. namespace internal {
  25085. template<typename Set>
  25086. class runtime_view_iterator final {
  25087. using iterator_type = typename Set::iterator;
  25088. [[nodiscard]] bool valid() const {
  25089. return (!tombstone_check || *it != tombstone)
  25090. && std::all_of(++pools->begin(), pools->end(), [entt = *it](const auto *curr) { return curr->contains(entt); })
  25091. && std::none_of(filter->cbegin(), filter->cend(), [entt = *it](const auto *curr) { return curr && curr->contains(entt); });
  25092. }
  25093. public:
  25094. using difference_type = typename iterator_type::difference_type;
  25095. using value_type = typename iterator_type::value_type;
  25096. using pointer = typename iterator_type::pointer;
  25097. using reference = typename iterator_type::reference;
  25098. using iterator_category = std::bidirectional_iterator_tag;
  25099. runtime_view_iterator() ENTT_NOEXCEPT
  25100. : pools{},
  25101. filter{},
  25102. it{},
  25103. tombstone_check{} {}
  25104. runtime_view_iterator(const std::vector<const Set *> &cpools, const std::vector<const Set *> &ignore, iterator_type curr) ENTT_NOEXCEPT
  25105. : pools{&cpools},
  25106. filter{&ignore},
  25107. it{curr},
  25108. tombstone_check{pools->size() == 1u && (*pools)[0u]->policy() == deletion_policy::in_place} {
  25109. if(it != (*pools)[0]->end() && !valid()) {
  25110. ++(*this);
  25111. }
  25112. }
  25113. runtime_view_iterator &operator++() {
  25114. while(++it != (*pools)[0]->end() && !valid()) {}
  25115. return *this;
  25116. }
  25117. runtime_view_iterator operator++(int) {
  25118. runtime_view_iterator orig = *this;
  25119. return ++(*this), orig;
  25120. }
  25121. runtime_view_iterator &operator--() {
  25122. while(--it != (*pools)[0]->begin() && !valid()) {}
  25123. return *this;
  25124. }
  25125. runtime_view_iterator operator--(int) {
  25126. runtime_view_iterator orig = *this;
  25127. return operator--(), orig;
  25128. }
  25129. [[nodiscard]] pointer operator->() const ENTT_NOEXCEPT {
  25130. return it.operator->();
  25131. }
  25132. [[nodiscard]] reference operator*() const ENTT_NOEXCEPT {
  25133. return *operator->();
  25134. }
  25135. [[nodiscard]] bool operator==(const runtime_view_iterator &other) const ENTT_NOEXCEPT {
  25136. return it == other.it;
  25137. }
  25138. [[nodiscard]] bool operator!=(const runtime_view_iterator &other) const ENTT_NOEXCEPT {
  25139. return !(*this == other);
  25140. }
  25141. private:
  25142. const std::vector<const Set *> *pools;
  25143. const std::vector<const Set *> *filter;
  25144. iterator_type it;
  25145. bool tombstone_check;
  25146. };
  25147. } // namespace internal
  25148. /**
  25149. * Internal details not to be documented.
  25150. * @endcond
  25151. */
  25152. /**
  25153. * @brief Runtime view implementation.
  25154. *
  25155. * Primary template isn't defined on purpose. All the specializations give a
  25156. * compile-time error, but for a few reasonable cases.
  25157. */
  25158. template<typename>
  25159. struct basic_runtime_view;
  25160. /**
  25161. * @brief Generic runtime view.
  25162. *
  25163. * Runtime views iterate over those entities that have at least all the given
  25164. * components in their bags. During initialization, a runtime view looks at the
  25165. * number of entities available for each component and picks up a reference to
  25166. * the smallest set of candidate entities in order to get a performance boost
  25167. * when iterate.<br/>
  25168. * Order of elements during iterations are highly dependent on the order of the
  25169. * underlying data structures. See sparse_set and its specializations for more
  25170. * details.
  25171. *
  25172. * @b Important
  25173. *
  25174. * Iterators aren't invalidated if:
  25175. *
  25176. * * New instances of the given components are created and assigned to entities.
  25177. * * The entity currently pointed is modified (as an example, if one of the
  25178. * given components is removed from the entity to which the iterator points).
  25179. * * The entity currently pointed is destroyed.
  25180. *
  25181. * In all the other cases, modifying the pools of the given components in any
  25182. * way invalidates all the iterators and using them results in undefined
  25183. * behavior.
  25184. *
  25185. * @note
  25186. * Views share references to the underlying data structures of the registry that
  25187. * generated them. Therefore any change to the entities and to the components
  25188. * made by means of the registry are immediately reflected by the views, unless
  25189. * a pool was missing when the view was built (in this case, the view won't
  25190. * have a valid reference and won't be updated accordingly).
  25191. *
  25192. * @warning
  25193. * Lifetime of a view must not overcome that of the registry that generated it.
  25194. * In any other case, attempting to use a view results in undefined behavior.
  25195. *
  25196. * @tparam Entity A valid entity type (see entt_traits for more details).
  25197. * @tparam Allocator Type of allocator used to manage memory and elements.
  25198. */
  25199. template<typename Entity, typename Allocator>
  25200. struct basic_runtime_view<basic_sparse_set<Entity, Allocator>> {
  25201. /*! @brief Underlying entity identifier. */
  25202. using entity_type = Entity;
  25203. /*! @brief Unsigned integer type. */
  25204. using size_type = std::size_t;
  25205. /*! @brief Common type among all storage types. */
  25206. using base_type = basic_sparse_set<Entity, Allocator>;
  25207. /*! @brief Bidirectional iterator type. */
  25208. using iterator = internal::runtime_view_iterator<base_type>;
  25209. /*! @brief Default constructor to use to create empty, invalid views. */
  25210. basic_runtime_view() ENTT_NOEXCEPT
  25211. : pools{},
  25212. filter{} {}
  25213. /**
  25214. * @brief Appends an opaque storage object to a runtime view.
  25215. * @param base An opaque reference to a storage object.
  25216. * @return This runtime view.
  25217. */
  25218. basic_runtime_view &iterate(const base_type &base) {
  25219. if(pools.empty() || !(base.size() < pools[0u]->size())) {
  25220. pools.push_back(&base);
  25221. } else {
  25222. pools.push_back(std::exchange(pools[0u], &base));
  25223. }
  25224. return *this;
  25225. }
  25226. /**
  25227. * @brief Adds an opaque storage object as a filter of a runtime view.
  25228. * @param base An opaque reference to a storage object.
  25229. * @return This runtime view.
  25230. */
  25231. basic_runtime_view &exclude(const base_type &base) {
  25232. filter.push_back(&base);
  25233. return *this;
  25234. }
  25235. /**
  25236. * @brief Estimates the number of entities iterated by the view.
  25237. * @return Estimated number of entities iterated by the view.
  25238. */
  25239. [[nodiscard]] size_type size_hint() const {
  25240. return pools.empty() ? size_type{} : pools.front()->size();
  25241. }
  25242. /**
  25243. * @brief Returns an iterator to the first entity that has the given
  25244. * components.
  25245. *
  25246. * The returned iterator points to the first entity that has the given
  25247. * components. If the view is empty, the returned iterator will be equal to
  25248. * `end()`.
  25249. *
  25250. * @return An iterator to the first entity that has the given components.
  25251. */
  25252. [[nodiscard]] iterator begin() const {
  25253. return pools.empty() ? iterator{} : iterator{pools, filter, pools[0]->begin()};
  25254. }
  25255. /**
  25256. * @brief Returns an iterator that is past the last entity that has the
  25257. * given components.
  25258. *
  25259. * The returned iterator points to the entity following the last entity that
  25260. * has the given components. Attempting to dereference the returned iterator
  25261. * results in undefined behavior.
  25262. *
  25263. * @return An iterator to the entity following the last entity that has the
  25264. * given components.
  25265. */
  25266. [[nodiscard]] iterator end() const {
  25267. return pools.empty() ? iterator{} : iterator{pools, filter, pools[0]->end()};
  25268. }
  25269. /**
  25270. * @brief Checks if a view contains an entity.
  25271. * @param entt A valid identifier.
  25272. * @return True if the view contains the given entity, false otherwise.
  25273. */
  25274. [[nodiscard]] bool contains(const entity_type entt) const {
  25275. return !pools.empty()
  25276. && std::all_of(pools.cbegin(), pools.cend(), [entt](const auto *curr) { return curr->contains(entt); })
  25277. && std::none_of(filter.cbegin(), filter.cend(), [entt](const auto *curr) { return curr && curr->contains(entt); });
  25278. }
  25279. /**
  25280. * @brief Iterates entities and applies the given function object to them.
  25281. *
  25282. * The function object is invoked for each entity. It is provided only with
  25283. * the entity itself. To get the components, users can use the registry with
  25284. * which the view was built.<br/>
  25285. * The signature of the function should be equivalent to the following:
  25286. *
  25287. * @code{.cpp}
  25288. * void(const entity_type);
  25289. * @endcode
  25290. *
  25291. * @tparam Func Type of the function object to invoke.
  25292. * @param func A valid function object.
  25293. */
  25294. template<typename Func>
  25295. void each(Func func) const {
  25296. for(const auto entity: *this) {
  25297. func(entity);
  25298. }
  25299. }
  25300. private:
  25301. std::vector<const base_type *> pools;
  25302. std::vector<const base_type *> filter;
  25303. };
  25304. } // namespace entt
  25305. #endif
  25306. // #include "entity/sigh_storage_mixin.hpp"
  25307. #ifndef ENTT_ENTITY_SIGH_STORAGE_MIXIN_HPP
  25308. #define ENTT_ENTITY_SIGH_STORAGE_MIXIN_HPP
  25309. #include <utility>
  25310. // #include "../config/config.h"
  25311. // #include "../core/any.hpp"
  25312. // #include "../signal/sigh.hpp"
  25313. // #include "fwd.hpp"
  25314. namespace entt {
  25315. /**
  25316. * @brief Mixin type used to add signal support to storage types.
  25317. *
  25318. * The function type of a listener is equivalent to:
  25319. *
  25320. * @code{.cpp}
  25321. * void(basic_registry<entity_type> &, entity_type);
  25322. * @endcode
  25323. *
  25324. * This applies to all signals made available.
  25325. *
  25326. * @tparam Type The type of the underlying storage.
  25327. */
  25328. template<typename Type>
  25329. class sigh_storage_mixin final: public Type {
  25330. using basic_iterator = typename Type::basic_iterator;
  25331. template<typename Func>
  25332. void notify_destruction(basic_iterator first, basic_iterator last, Func func) {
  25333. ENTT_ASSERT(owner != nullptr, "Invalid pointer to registry");
  25334. for(; first != last; ++first) {
  25335. const auto entt = *first;
  25336. destruction.publish(*owner, entt);
  25337. const auto it = Type::find(entt);
  25338. func(it, it + 1u);
  25339. }
  25340. }
  25341. void swap_and_pop(basic_iterator first, basic_iterator last) final {
  25342. notify_destruction(std::move(first), std::move(last), [this](auto... args) { Type::swap_and_pop(args...); });
  25343. }
  25344. void in_place_pop(basic_iterator first, basic_iterator last) final {
  25345. notify_destruction(std::move(first), std::move(last), [this](auto... args) { Type::in_place_pop(args...); });
  25346. }
  25347. basic_iterator try_emplace(const typename Type::entity_type entt, const bool force_back, const void *value) final {
  25348. ENTT_ASSERT(owner != nullptr, "Invalid pointer to registry");
  25349. Type::try_emplace(entt, force_back, value);
  25350. construction.publish(*owner, entt);
  25351. return Type::find(entt);
  25352. }
  25353. public:
  25354. /*! @brief Underlying entity identifier. */
  25355. using entity_type = typename Type::entity_type;
  25356. /*! @brief Inherited constructors. */
  25357. using Type::Type;
  25358. /**
  25359. * @brief Returns a sink object.
  25360. *
  25361. * The sink returned by this function can be used to receive notifications
  25362. * whenever a new instance is created and assigned to an entity.<br/>
  25363. * Listeners are invoked after the object has been assigned to the entity.
  25364. *
  25365. * @sa sink
  25366. *
  25367. * @return A temporary sink object.
  25368. */
  25369. [[nodiscard]] auto on_construct() ENTT_NOEXCEPT {
  25370. return sink{construction};
  25371. }
  25372. /**
  25373. * @brief Returns a sink object.
  25374. *
  25375. * The sink returned by this function can be used to receive notifications
  25376. * whenever an instance is explicitly updated.<br/>
  25377. * Listeners are invoked after the object has been updated.
  25378. *
  25379. * @sa sink
  25380. *
  25381. * @return A temporary sink object.
  25382. */
  25383. [[nodiscard]] auto on_update() ENTT_NOEXCEPT {
  25384. return sink{update};
  25385. }
  25386. /**
  25387. * @brief Returns a sink object.
  25388. *
  25389. * The sink returned by this function can be used to receive notifications
  25390. * whenever an instance is removed from an entity and thus destroyed.<br/>
  25391. * Listeners are invoked before the object has been removed from the entity.
  25392. *
  25393. * @sa sink
  25394. *
  25395. * @return A temporary sink object.
  25396. */
  25397. [[nodiscard]] auto on_destroy() ENTT_NOEXCEPT {
  25398. return sink{destruction};
  25399. }
  25400. /**
  25401. * @brief Assigns entities to a storage.
  25402. * @tparam Args Types of arguments to use to construct the object.
  25403. * @param entt A valid identifier.
  25404. * @param args Parameters to use to initialize the object.
  25405. * @return A reference to the newly created object.
  25406. */
  25407. template<typename... Args>
  25408. decltype(auto) emplace(const entity_type entt, Args &&...args) {
  25409. ENTT_ASSERT(owner != nullptr, "Invalid pointer to registry");
  25410. Type::emplace(entt, std::forward<Args>(args)...);
  25411. construction.publish(*owner, entt);
  25412. return this->get(entt);
  25413. }
  25414. /**
  25415. * @brief Patches the given instance for an entity.
  25416. * @tparam Func Types of the function objects to invoke.
  25417. * @param entt A valid identifier.
  25418. * @param func Valid function objects.
  25419. * @return A reference to the patched instance.
  25420. */
  25421. template<typename... Func>
  25422. decltype(auto) patch(const entity_type entt, Func &&...func) {
  25423. ENTT_ASSERT(owner != nullptr, "Invalid pointer to registry");
  25424. Type::patch(entt, std::forward<Func>(func)...);
  25425. update.publish(*owner, entt);
  25426. return this->get(entt);
  25427. }
  25428. /**
  25429. * @brief Assigns entities to a storage.
  25430. * @tparam It Type of input iterator.
  25431. * @tparam Args Types of arguments to use to construct the objects assigned
  25432. * to the entities.
  25433. * @param first An iterator to the first element of the range of entities.
  25434. * @param last An iterator past the last element of the range of entities.
  25435. * @param args Parameters to use to initialize the objects assigned to the
  25436. * entities.
  25437. */
  25438. template<typename It, typename... Args>
  25439. void insert(It first, It last, Args &&...args) {
  25440. ENTT_ASSERT(owner != nullptr, "Invalid pointer to registry");
  25441. Type::insert(first, last, std::forward<Args>(args)...);
  25442. for(auto it = construction.empty() ? last : first; it != last; ++it) {
  25443. construction.publish(*owner, *it);
  25444. }
  25445. }
  25446. /**
  25447. * @brief Forwards variables to mixins, if any.
  25448. * @param value A variable wrapped in an opaque container.
  25449. */
  25450. void bind(any value) ENTT_NOEXCEPT final {
  25451. auto *reg = any_cast<basic_registry<entity_type>>(&value);
  25452. owner = reg ? reg : owner;
  25453. Type::bind(std::move(value));
  25454. }
  25455. private:
  25456. sigh<void(basic_registry<entity_type> &, const entity_type)> construction{};
  25457. sigh<void(basic_registry<entity_type> &, const entity_type)> destruction{};
  25458. sigh<void(basic_registry<entity_type> &, const entity_type)> update{};
  25459. basic_registry<entity_type> *owner{};
  25460. };
  25461. } // namespace entt
  25462. #endif
  25463. // #include "entity/snapshot.hpp"
  25464. #ifndef ENTT_ENTITY_SNAPSHOT_HPP
  25465. #define ENTT_ENTITY_SNAPSHOT_HPP
  25466. #include <array>
  25467. #include <cstddef>
  25468. #include <iterator>
  25469. #include <tuple>
  25470. #include <type_traits>
  25471. #include <utility>
  25472. #include <vector>
  25473. // #include "../config/config.h"
  25474. // #include "../container/dense_map.hpp"
  25475. // #include "../core/type_traits.hpp"
  25476. // #include "component.hpp"
  25477. // #include "entity.hpp"
  25478. // #include "fwd.hpp"
  25479. // #include "registry.hpp"
  25480. namespace entt {
  25481. /**
  25482. * @brief Utility class to create snapshots from a registry.
  25483. *
  25484. * A _snapshot_ can be either a dump of the entire registry or a narrower
  25485. * selection of components of interest.<br/>
  25486. * This type can be used in both cases if provided with a correctly configured
  25487. * output archive.
  25488. *
  25489. * @tparam Entity A valid entity type (see entt_traits for more details).
  25490. */
  25491. template<typename Entity>
  25492. class basic_snapshot {
  25493. using entity_traits = entt_traits<Entity>;
  25494. template<typename Component, typename Archive, typename It>
  25495. void get(Archive &archive, std::size_t sz, It first, It last) const {
  25496. const auto view = reg->template view<std::add_const_t<Component>>();
  25497. archive(typename entity_traits::entity_type(sz));
  25498. while(first != last) {
  25499. const auto entt = *(first++);
  25500. if(reg->template all_of<Component>(entt)) {
  25501. std::apply(archive, std::tuple_cat(std::make_tuple(entt), view.get(entt)));
  25502. }
  25503. }
  25504. }
  25505. template<typename... Component, typename Archive, typename It, std::size_t... Index>
  25506. void component(Archive &archive, It first, It last, std::index_sequence<Index...>) const {
  25507. std::array<std::size_t, sizeof...(Index)> size{};
  25508. auto begin = first;
  25509. while(begin != last) {
  25510. const auto entt = *(begin++);
  25511. ((reg->template all_of<Component>(entt) ? ++size[Index] : 0u), ...);
  25512. }
  25513. (get<Component>(archive, size[Index], first, last), ...);
  25514. }
  25515. public:
  25516. /*! @brief Underlying entity identifier. */
  25517. using entity_type = Entity;
  25518. /**
  25519. * @brief Constructs an instance that is bound to a given registry.
  25520. * @param source A valid reference to a registry.
  25521. */
  25522. basic_snapshot(const basic_registry<entity_type> &source) ENTT_NOEXCEPT
  25523. : reg{&source} {}
  25524. /*! @brief Default move constructor. */
  25525. basic_snapshot(basic_snapshot &&) ENTT_NOEXCEPT = default;
  25526. /*! @brief Default move assignment operator. @return This snapshot. */
  25527. basic_snapshot &operator=(basic_snapshot &&) ENTT_NOEXCEPT = default;
  25528. /**
  25529. * @brief Puts aside all the entities from the underlying registry.
  25530. *
  25531. * Entities are serialized along with their versions. Destroyed entities are
  25532. * taken in consideration as well by this function.
  25533. *
  25534. * @tparam Archive Type of output archive.
  25535. * @param archive A valid reference to an output archive.
  25536. * @return An object of this type to continue creating the snapshot.
  25537. */
  25538. template<typename Archive>
  25539. const basic_snapshot &entities(Archive &archive) const {
  25540. const auto sz = reg->size();
  25541. archive(typename entity_traits::entity_type(sz + 1u));
  25542. archive(reg->released());
  25543. for(auto first = reg->data(), last = first + sz; first != last; ++first) {
  25544. archive(*first);
  25545. }
  25546. return *this;
  25547. }
  25548. /**
  25549. * @brief Puts aside the given components.
  25550. *
  25551. * Each instance is serialized together with the entity to which it belongs.
  25552. * Entities are serialized along with their versions.
  25553. *
  25554. * @tparam Component Types of components to serialize.
  25555. * @tparam Archive Type of output archive.
  25556. * @param archive A valid reference to an output archive.
  25557. * @return An object of this type to continue creating the snapshot.
  25558. */
  25559. template<typename... Component, typename Archive>
  25560. const basic_snapshot &component(Archive &archive) const {
  25561. if constexpr(sizeof...(Component) == 1u) {
  25562. const auto view = reg->template view<const Component...>();
  25563. (component<Component>(archive, view.rbegin(), view.rend()), ...);
  25564. return *this;
  25565. } else {
  25566. (component<Component>(archive), ...);
  25567. return *this;
  25568. }
  25569. }
  25570. /**
  25571. * @brief Puts aside the given components for the entities in a range.
  25572. *
  25573. * Each instance is serialized together with the entity to which it belongs.
  25574. * Entities are serialized along with their versions.
  25575. *
  25576. * @tparam Component Types of components to serialize.
  25577. * @tparam Archive Type of output archive.
  25578. * @tparam It Type of input iterator.
  25579. * @param archive A valid reference to an output archive.
  25580. * @param first An iterator to the first element of the range to serialize.
  25581. * @param last An iterator past the last element of the range to serialize.
  25582. * @return An object of this type to continue creating the snapshot.
  25583. */
  25584. template<typename... Component, typename Archive, typename It>
  25585. const basic_snapshot &component(Archive &archive, It first, It last) const {
  25586. component<Component...>(archive, first, last, std::index_sequence_for<Component...>{});
  25587. return *this;
  25588. }
  25589. private:
  25590. const basic_registry<entity_type> *reg;
  25591. };
  25592. /**
  25593. * @brief Utility class to restore a snapshot as a whole.
  25594. *
  25595. * A snapshot loader requires that the destination registry be empty and loads
  25596. * all the data at once while keeping intact the identifiers that the entities
  25597. * originally had.<br/>
  25598. * An example of use is the implementation of a save/restore utility.
  25599. *
  25600. * @tparam Entity A valid entity type (see entt_traits for more details).
  25601. */
  25602. template<typename Entity>
  25603. class basic_snapshot_loader {
  25604. using entity_traits = entt_traits<Entity>;
  25605. template<typename Type, typename Archive>
  25606. void assign(Archive &archive) const {
  25607. typename entity_traits::entity_type length{};
  25608. entity_type entt;
  25609. archive(length);
  25610. if constexpr(ignore_as_empty_v<Type>) {
  25611. while(length--) {
  25612. archive(entt);
  25613. const auto entity = reg->valid(entt) ? entt : reg->create(entt);
  25614. ENTT_ASSERT(entity == entt, "Entity not available for use");
  25615. reg->template emplace<Type>(entt);
  25616. }
  25617. } else {
  25618. Type instance;
  25619. while(length--) {
  25620. archive(entt, instance);
  25621. const auto entity = reg->valid(entt) ? entt : reg->create(entt);
  25622. ENTT_ASSERT(entity == entt, "Entity not available for use");
  25623. reg->template emplace<Type>(entt, std::move(instance));
  25624. }
  25625. }
  25626. }
  25627. public:
  25628. /*! @brief Underlying entity identifier. */
  25629. using entity_type = Entity;
  25630. /**
  25631. * @brief Constructs an instance that is bound to a given registry.
  25632. * @param source A valid reference to a registry.
  25633. */
  25634. basic_snapshot_loader(basic_registry<entity_type> &source) ENTT_NOEXCEPT
  25635. : reg{&source} {
  25636. // restoring a snapshot as a whole requires a clean registry
  25637. ENTT_ASSERT(reg->empty(), "Registry must be empty");
  25638. }
  25639. /*! @brief Default move constructor. */
  25640. basic_snapshot_loader(basic_snapshot_loader &&) ENTT_NOEXCEPT = default;
  25641. /*! @brief Default move assignment operator. @return This loader. */
  25642. basic_snapshot_loader &operator=(basic_snapshot_loader &&) ENTT_NOEXCEPT = default;
  25643. /**
  25644. * @brief Restores entities that were in use during serialization.
  25645. *
  25646. * This function restores the entities that were in use during serialization
  25647. * and gives them the versions they originally had.
  25648. *
  25649. * @tparam Archive Type of input archive.
  25650. * @param archive A valid reference to an input archive.
  25651. * @return A valid loader to continue restoring data.
  25652. */
  25653. template<typename Archive>
  25654. const basic_snapshot_loader &entities(Archive &archive) const {
  25655. typename entity_traits::entity_type length{};
  25656. archive(length);
  25657. std::vector<entity_type> all(length);
  25658. for(std::size_t pos{}; pos < length; ++pos) {
  25659. archive(all[pos]);
  25660. }
  25661. reg->assign(++all.cbegin(), all.cend(), all[0u]);
  25662. return *this;
  25663. }
  25664. /**
  25665. * @brief Restores components and assigns them to the right entities.
  25666. *
  25667. * The template parameter list must be exactly the same used during
  25668. * serialization. In the event that the entity to which the component is
  25669. * assigned doesn't exist yet, the loader will take care to create it with
  25670. * the version it originally had.
  25671. *
  25672. * @tparam Component Types of components to restore.
  25673. * @tparam Archive Type of input archive.
  25674. * @param archive A valid reference to an input archive.
  25675. * @return A valid loader to continue restoring data.
  25676. */
  25677. template<typename... Component, typename Archive>
  25678. const basic_snapshot_loader &component(Archive &archive) const {
  25679. (assign<Component>(archive), ...);
  25680. return *this;
  25681. }
  25682. /**
  25683. * @brief Destroys those entities that have no components.
  25684. *
  25685. * In case all the entities were serialized but only part of the components
  25686. * was saved, it could happen that some of the entities have no components
  25687. * once restored.<br/>
  25688. * This functions helps to identify and destroy those entities.
  25689. *
  25690. * @return A valid loader to continue restoring data.
  25691. */
  25692. const basic_snapshot_loader &orphans() const {
  25693. reg->each([this](const auto entt) {
  25694. if(reg->orphan(entt)) {
  25695. reg->release(entt);
  25696. }
  25697. });
  25698. return *this;
  25699. }
  25700. private:
  25701. basic_registry<entity_type> *reg;
  25702. };
  25703. /**
  25704. * @brief Utility class for _continuous loading_.
  25705. *
  25706. * A _continuous loader_ is designed to load data from a source registry to a
  25707. * (possibly) non-empty destination. The loader can accommodate in a registry
  25708. * more than one snapshot in a sort of _continuous loading_ that updates the
  25709. * destination one step at a time.<br/>
  25710. * Identifiers that entities originally had are not transferred to the target.
  25711. * Instead, the loader maps remote identifiers to local ones while restoring a
  25712. * snapshot.<br/>
  25713. * An example of use is the implementation of a client-server applications with
  25714. * the requirement of transferring somehow parts of the representation side to
  25715. * side.
  25716. *
  25717. * @tparam Entity A valid entity type (see entt_traits for more details).
  25718. */
  25719. template<typename Entity>
  25720. class basic_continuous_loader {
  25721. using entity_traits = entt_traits<Entity>;
  25722. void destroy(Entity entt) {
  25723. if(const auto it = remloc.find(entt); it == remloc.cend()) {
  25724. const auto local = reg->create();
  25725. remloc.emplace(entt, std::make_pair(local, true));
  25726. reg->destroy(local);
  25727. }
  25728. }
  25729. void restore(Entity entt) {
  25730. const auto it = remloc.find(entt);
  25731. if(it == remloc.cend()) {
  25732. const auto local = reg->create();
  25733. remloc.emplace(entt, std::make_pair(local, true));
  25734. } else {
  25735. if(!reg->valid(remloc[entt].first)) {
  25736. remloc[entt].first = reg->create();
  25737. }
  25738. // set the dirty flag
  25739. remloc[entt].second = true;
  25740. }
  25741. }
  25742. template<typename Container>
  25743. auto update(int, Container &container) -> decltype(typename Container::mapped_type{}, void()) {
  25744. // map like container
  25745. Container other;
  25746. for(auto &&pair: container) {
  25747. using first_type = std::remove_const_t<typename std::decay_t<decltype(pair)>::first_type>;
  25748. using second_type = typename std::decay_t<decltype(pair)>::second_type;
  25749. if constexpr(std::is_same_v<first_type, entity_type> && std::is_same_v<second_type, entity_type>) {
  25750. other.emplace(map(pair.first), map(pair.second));
  25751. } else if constexpr(std::is_same_v<first_type, entity_type>) {
  25752. other.emplace(map(pair.first), std::move(pair.second));
  25753. } else {
  25754. static_assert(std::is_same_v<second_type, entity_type>, "Neither the key nor the value are of entity type");
  25755. other.emplace(std::move(pair.first), map(pair.second));
  25756. }
  25757. }
  25758. using std::swap;
  25759. swap(container, other);
  25760. }
  25761. template<typename Container>
  25762. auto update(char, Container &container) -> decltype(typename Container::value_type{}, void()) {
  25763. // vector like container
  25764. static_assert(std::is_same_v<typename Container::value_type, entity_type>, "Invalid value type");
  25765. for(auto &&entt: container) {
  25766. entt = map(entt);
  25767. }
  25768. }
  25769. template<typename Other, typename Type, typename Member>
  25770. void update([[maybe_unused]] Other &instance, [[maybe_unused]] Member Type::*member) {
  25771. if constexpr(!std::is_same_v<Other, Type>) {
  25772. return;
  25773. } else if constexpr(std::is_same_v<Member, entity_type>) {
  25774. instance.*member = map(instance.*member);
  25775. } else {
  25776. // maybe a container? let's try...
  25777. update(0, instance.*member);
  25778. }
  25779. }
  25780. template<typename Component>
  25781. void remove_if_exists() {
  25782. for(auto &&ref: remloc) {
  25783. const auto local = ref.second.first;
  25784. if(reg->valid(local)) {
  25785. reg->template remove<Component>(local);
  25786. }
  25787. }
  25788. }
  25789. template<typename Other, typename Archive, typename... Type, typename... Member>
  25790. void assign(Archive &archive, [[maybe_unused]] Member Type::*...member) {
  25791. typename entity_traits::entity_type length{};
  25792. entity_type entt;
  25793. archive(length);
  25794. if constexpr(ignore_as_empty_v<Other>) {
  25795. while(length--) {
  25796. archive(entt);
  25797. restore(entt);
  25798. reg->template emplace_or_replace<Other>(map(entt));
  25799. }
  25800. } else {
  25801. Other instance;
  25802. while(length--) {
  25803. archive(entt, instance);
  25804. (update(instance, member), ...);
  25805. restore(entt);
  25806. reg->template emplace_or_replace<Other>(map(entt), std::move(instance));
  25807. }
  25808. }
  25809. }
  25810. public:
  25811. /*! @brief Underlying entity identifier. */
  25812. using entity_type = Entity;
  25813. /**
  25814. * @brief Constructs an instance that is bound to a given registry.
  25815. * @param source A valid reference to a registry.
  25816. */
  25817. basic_continuous_loader(basic_registry<entity_type> &source) ENTT_NOEXCEPT
  25818. : reg{&source} {}
  25819. /*! @brief Default move constructor. */
  25820. basic_continuous_loader(basic_continuous_loader &&) = default;
  25821. /*! @brief Default move assignment operator. @return This loader. */
  25822. basic_continuous_loader &operator=(basic_continuous_loader &&) = default;
  25823. /**
  25824. * @brief Restores entities that were in use during serialization.
  25825. *
  25826. * This function restores the entities that were in use during serialization
  25827. * and creates local counterparts for them if required.
  25828. *
  25829. * @tparam Archive Type of input archive.
  25830. * @param archive A valid reference to an input archive.
  25831. * @return A non-const reference to this loader.
  25832. */
  25833. template<typename Archive>
  25834. basic_continuous_loader &entities(Archive &archive) {
  25835. typename entity_traits::entity_type length{};
  25836. entity_type entt{};
  25837. archive(length);
  25838. // discards the head of the list of destroyed entities
  25839. archive(entt);
  25840. for(std::size_t pos{}, last = length - 1u; pos < last; ++pos) {
  25841. archive(entt);
  25842. if(const auto entity = entity_traits::to_entity(entt); entity == pos) {
  25843. restore(entt);
  25844. } else {
  25845. destroy(entt);
  25846. }
  25847. }
  25848. return *this;
  25849. }
  25850. /**
  25851. * @brief Restores components and assigns them to the right entities.
  25852. *
  25853. * The template parameter list must be exactly the same used during
  25854. * serialization. In the event that the entity to which the component is
  25855. * assigned doesn't exist yet, the loader will take care to create a local
  25856. * counterpart for it.<br/>
  25857. * Members can be either data members of type entity_type or containers of
  25858. * entities. In both cases, the loader will visit them and update the
  25859. * entities by replacing each one with its local counterpart.
  25860. *
  25861. * @tparam Component Type of component to restore.
  25862. * @tparam Archive Type of input archive.
  25863. * @tparam Type Types of components to update with local counterparts.
  25864. * @tparam Member Types of members to update with their local counterparts.
  25865. * @param archive A valid reference to an input archive.
  25866. * @param member Members to update with their local counterparts.
  25867. * @return A non-const reference to this loader.
  25868. */
  25869. template<typename... Component, typename Archive, typename... Type, typename... Member>
  25870. basic_continuous_loader &component(Archive &archive, Member Type::*...member) {
  25871. (remove_if_exists<Component>(), ...);
  25872. (assign<Component>(archive, member...), ...);
  25873. return *this;
  25874. }
  25875. /**
  25876. * @brief Helps to purge entities that no longer have a conterpart.
  25877. *
  25878. * Users should invoke this member function after restoring each snapshot,
  25879. * unless they know exactly what they are doing.
  25880. *
  25881. * @return A non-const reference to this loader.
  25882. */
  25883. basic_continuous_loader &shrink() {
  25884. auto it = remloc.begin();
  25885. while(it != remloc.cend()) {
  25886. const auto local = it->second.first;
  25887. bool &dirty = it->second.second;
  25888. if(dirty) {
  25889. dirty = false;
  25890. ++it;
  25891. } else {
  25892. if(reg->valid(local)) {
  25893. reg->destroy(local);
  25894. }
  25895. it = remloc.erase(it);
  25896. }
  25897. }
  25898. return *this;
  25899. }
  25900. /**
  25901. * @brief Destroys those entities that have no components.
  25902. *
  25903. * In case all the entities were serialized but only part of the components
  25904. * was saved, it could happen that some of the entities have no components
  25905. * once restored.<br/>
  25906. * This functions helps to identify and destroy those entities.
  25907. *
  25908. * @return A non-const reference to this loader.
  25909. */
  25910. basic_continuous_loader &orphans() {
  25911. reg->each([this](const auto entt) {
  25912. if(reg->orphan(entt)) {
  25913. reg->release(entt);
  25914. }
  25915. });
  25916. return *this;
  25917. }
  25918. /**
  25919. * @brief Tests if a loader knows about a given entity.
  25920. * @param entt A valid identifier.
  25921. * @return True if `entity` is managed by the loader, false otherwise.
  25922. */
  25923. [[nodiscard]] bool contains(entity_type entt) const ENTT_NOEXCEPT {
  25924. return (remloc.find(entt) != remloc.cend());
  25925. }
  25926. /**
  25927. * @brief Returns the identifier to which an entity refers.
  25928. * @param entt A valid identifier.
  25929. * @return The local identifier if any, the null entity otherwise.
  25930. */
  25931. [[nodiscard]] entity_type map(entity_type entt) const ENTT_NOEXCEPT {
  25932. const auto it = remloc.find(entt);
  25933. entity_type other = null;
  25934. if(it != remloc.cend()) {
  25935. other = it->second.first;
  25936. }
  25937. return other;
  25938. }
  25939. private:
  25940. dense_map<entity_type, std::pair<entity_type, bool>> remloc;
  25941. basic_registry<entity_type> *reg;
  25942. };
  25943. } // namespace entt
  25944. #endif
  25945. // #include "entity/sparse_set.hpp"
  25946. #ifndef ENTT_ENTITY_SPARSE_SET_HPP
  25947. #define ENTT_ENTITY_SPARSE_SET_HPP
  25948. #include <cstddef>
  25949. #include <iterator>
  25950. #include <memory>
  25951. #include <type_traits>
  25952. #include <utility>
  25953. #include <vector>
  25954. // #include "../config/config.h"
  25955. // #include "../core/algorithm.hpp"
  25956. // #include "../core/any.hpp"
  25957. // #include "../core/memory.hpp"
  25958. // #include "../core/type_info.hpp"
  25959. // #include "entity.hpp"
  25960. // #include "fwd.hpp"
  25961. namespace entt {
  25962. /**
  25963. * @cond TURN_OFF_DOXYGEN
  25964. * Internal details not to be documented.
  25965. */
  25966. namespace internal {
  25967. template<typename Container>
  25968. struct sparse_set_iterator final {
  25969. using value_type = typename Container::value_type;
  25970. using pointer = typename Container::const_pointer;
  25971. using reference = typename Container::const_reference;
  25972. using difference_type = typename Container::difference_type;
  25973. using iterator_category = std::random_access_iterator_tag;
  25974. sparse_set_iterator() ENTT_NOEXCEPT
  25975. : packed{},
  25976. offset{} {}
  25977. sparse_set_iterator(const Container &ref, const difference_type idx) ENTT_NOEXCEPT
  25978. : packed{std::addressof(ref)},
  25979. offset{idx} {}
  25980. sparse_set_iterator &operator++() ENTT_NOEXCEPT {
  25981. return --offset, *this;
  25982. }
  25983. sparse_set_iterator operator++(int) ENTT_NOEXCEPT {
  25984. sparse_set_iterator orig = *this;
  25985. return ++(*this), orig;
  25986. }
  25987. sparse_set_iterator &operator--() ENTT_NOEXCEPT {
  25988. return ++offset, *this;
  25989. }
  25990. sparse_set_iterator operator--(int) ENTT_NOEXCEPT {
  25991. sparse_set_iterator orig = *this;
  25992. return operator--(), orig;
  25993. }
  25994. sparse_set_iterator &operator+=(const difference_type value) ENTT_NOEXCEPT {
  25995. offset -= value;
  25996. return *this;
  25997. }
  25998. sparse_set_iterator operator+(const difference_type value) const ENTT_NOEXCEPT {
  25999. sparse_set_iterator copy = *this;
  26000. return (copy += value);
  26001. }
  26002. sparse_set_iterator &operator-=(const difference_type value) ENTT_NOEXCEPT {
  26003. return (*this += -value);
  26004. }
  26005. sparse_set_iterator operator-(const difference_type value) const ENTT_NOEXCEPT {
  26006. return (*this + -value);
  26007. }
  26008. [[nodiscard]] reference operator[](const difference_type value) const ENTT_NOEXCEPT {
  26009. return packed->data()[index() - value];
  26010. }
  26011. [[nodiscard]] pointer operator->() const ENTT_NOEXCEPT {
  26012. return packed->data() + index();
  26013. }
  26014. [[nodiscard]] reference operator*() const ENTT_NOEXCEPT {
  26015. return *operator->();
  26016. }
  26017. [[nodiscard]] difference_type index() const ENTT_NOEXCEPT {
  26018. return offset - 1;
  26019. }
  26020. private:
  26021. const Container *packed;
  26022. difference_type offset;
  26023. };
  26024. template<typename Type, typename Other>
  26025. [[nodiscard]] std::ptrdiff_t operator-(const sparse_set_iterator<Type> &lhs, const sparse_set_iterator<Other> &rhs) ENTT_NOEXCEPT {
  26026. return rhs.index() - lhs.index();
  26027. }
  26028. template<typename Type, typename Other>
  26029. [[nodiscard]] bool operator==(const sparse_set_iterator<Type> &lhs, const sparse_set_iterator<Other> &rhs) ENTT_NOEXCEPT {
  26030. return lhs.index() == rhs.index();
  26031. }
  26032. template<typename Type, typename Other>
  26033. [[nodiscard]] bool operator!=(const sparse_set_iterator<Type> &lhs, const sparse_set_iterator<Other> &rhs) ENTT_NOEXCEPT {
  26034. return !(lhs == rhs);
  26035. }
  26036. template<typename Type, typename Other>
  26037. [[nodiscard]] bool operator<(const sparse_set_iterator<Type> &lhs, const sparse_set_iterator<Other> &rhs) ENTT_NOEXCEPT {
  26038. return lhs.index() > rhs.index();
  26039. }
  26040. template<typename Type, typename Other>
  26041. [[nodiscard]] bool operator>(const sparse_set_iterator<Type> &lhs, const sparse_set_iterator<Other> &rhs) ENTT_NOEXCEPT {
  26042. return lhs.index() < rhs.index();
  26043. }
  26044. template<typename Type, typename Other>
  26045. [[nodiscard]] bool operator<=(const sparse_set_iterator<Type> &lhs, const sparse_set_iterator<Other> &rhs) ENTT_NOEXCEPT {
  26046. return !(lhs > rhs);
  26047. }
  26048. template<typename Type, typename Other>
  26049. [[nodiscard]] bool operator>=(const sparse_set_iterator<Type> &lhs, const sparse_set_iterator<Other> &rhs) ENTT_NOEXCEPT {
  26050. return !(lhs < rhs);
  26051. }
  26052. } // namespace internal
  26053. /**
  26054. * Internal details not to be documented.
  26055. * @endcond
  26056. */
  26057. /*! @brief Sparse set deletion policy. */
  26058. enum class deletion_policy : std::uint8_t {
  26059. /*! @brief Swap-and-pop deletion policy. */
  26060. swap_and_pop = 0u,
  26061. /*! @brief In-place deletion policy. */
  26062. in_place = 1u
  26063. };
  26064. /**
  26065. * @brief Basic sparse set implementation.
  26066. *
  26067. * Sparse set or packed array or whatever is the name users give it.<br/>
  26068. * Two arrays: an _external_ one and an _internal_ one; a _sparse_ one and a
  26069. * _packed_ one; one used for direct access through contiguous memory, the other
  26070. * one used to get the data through an extra level of indirection.<br/>
  26071. * This is largely used by the registry to offer users the fastest access ever
  26072. * to the components. Views and groups in general are almost entirely designed
  26073. * around sparse sets.
  26074. *
  26075. * This type of data structure is widely documented in the literature and on the
  26076. * web. This is nothing more than a customized implementation suitable for the
  26077. * purpose of the framework.
  26078. *
  26079. * @note
  26080. * Internal data structures arrange elements to maximize performance. There are
  26081. * no guarantees that entities are returned in the insertion order when iterate
  26082. * a sparse set. Do not make assumption on the order in any case.
  26083. *
  26084. * @tparam Entity A valid entity type (see entt_traits for more details).
  26085. * @tparam Allocator Type of allocator used to manage memory and elements.
  26086. */
  26087. template<typename Entity, typename Allocator>
  26088. class basic_sparse_set {
  26089. using alloc_traits = std::allocator_traits<Allocator>;
  26090. static_assert(std::is_same_v<typename alloc_traits::value_type, Entity>, "Invalid value type");
  26091. using sparse_container_type = std::vector<typename alloc_traits::pointer, typename alloc_traits::template rebind_alloc<typename alloc_traits::pointer>>;
  26092. using packed_container_type = std::vector<Entity, Allocator>;
  26093. using entity_traits = entt_traits<Entity>;
  26094. [[nodiscard]] auto sparse_ptr(const Entity entt) const {
  26095. const auto pos = static_cast<size_type>(entity_traits::to_entity(entt));
  26096. const auto page = pos / entity_traits::page_size;
  26097. return (page < sparse.size() && sparse[page]) ? (sparse[page] + fast_mod(pos, entity_traits::page_size)) : nullptr;
  26098. }
  26099. [[nodiscard]] auto &sparse_ref(const Entity entt) const {
  26100. ENTT_ASSERT(sparse_ptr(entt), "Invalid element");
  26101. const auto pos = static_cast<size_type>(entity_traits::to_entity(entt));
  26102. return sparse[pos / entity_traits::page_size][fast_mod(pos, entity_traits::page_size)];
  26103. }
  26104. [[nodiscard]] auto &assure_at_least(const Entity entt) {
  26105. const auto pos = static_cast<size_type>(entity_traits::to_entity(entt));
  26106. const auto page = pos / entity_traits::page_size;
  26107. if(!(page < sparse.size())) {
  26108. sparse.resize(page + 1u, nullptr);
  26109. }
  26110. if(!sparse[page]) {
  26111. auto page_allocator{packed.get_allocator()};
  26112. sparse[page] = alloc_traits::allocate(page_allocator, entity_traits::page_size);
  26113. std::uninitialized_fill(sparse[page], sparse[page] + entity_traits::page_size, null);
  26114. }
  26115. auto &elem = sparse[page][fast_mod(pos, entity_traits::page_size)];
  26116. ENTT_ASSERT(entity_traits::to_version(elem) == entity_traits::to_version(tombstone), "Slot not available");
  26117. return elem;
  26118. }
  26119. void release_sparse_pages() {
  26120. auto page_allocator{packed.get_allocator()};
  26121. for(auto &&page: sparse) {
  26122. if(page != nullptr) {
  26123. std::destroy(page, page + entity_traits::page_size);
  26124. alloc_traits::deallocate(page_allocator, page, entity_traits::page_size);
  26125. page = nullptr;
  26126. }
  26127. }
  26128. }
  26129. private:
  26130. virtual const void *get_at(const std::size_t) const {
  26131. return nullptr;
  26132. }
  26133. virtual void swap_at(const std::size_t, const std::size_t) {}
  26134. virtual void move_element(const std::size_t, const std::size_t) {}
  26135. protected:
  26136. /*! @brief Random access iterator type. */
  26137. using basic_iterator = internal::sparse_set_iterator<packed_container_type>;
  26138. /**
  26139. * @brief Erases entities from a sparse set.
  26140. * @param first An iterator to the first element of the range of entities.
  26141. * @param last An iterator past the last element of the range of entities.
  26142. */
  26143. virtual void swap_and_pop(basic_iterator first, basic_iterator last) {
  26144. for(; first != last; ++first) {
  26145. auto &self = sparse_ref(*first);
  26146. const auto entt = entity_traits::to_entity(self);
  26147. sparse_ref(packed.back()) = entity_traits::combine(entt, entity_traits::to_integral(packed.back()));
  26148. packed[static_cast<size_type>(entt)] = packed.back();
  26149. // unnecessary but it helps to detect nasty bugs
  26150. ENTT_ASSERT((packed.back() = tombstone, true), "");
  26151. // lazy self-assignment guard
  26152. self = null;
  26153. packed.pop_back();
  26154. }
  26155. }
  26156. /**
  26157. * @brief Erases entities from a sparse set.
  26158. * @param first An iterator to the first element of the range of entities.
  26159. * @param last An iterator past the last element of the range of entities.
  26160. */
  26161. virtual void in_place_pop(basic_iterator first, basic_iterator last) {
  26162. for(; first != last; ++first) {
  26163. const auto entt = entity_traits::to_entity(std::exchange(sparse_ref(*first), null));
  26164. packed[static_cast<size_type>(entt)] = std::exchange(free_list, entity_traits::combine(entt, entity_traits::reserved));
  26165. }
  26166. }
  26167. /**
  26168. * @brief Assigns an entity to a sparse set.
  26169. * @param entt A valid identifier.
  26170. * @param force_back Force back insertion.
  26171. * @return Iterator pointing to the emplaced element.
  26172. */
  26173. virtual basic_iterator try_emplace(const Entity entt, const bool force_back, const void * = nullptr) {
  26174. ENTT_ASSERT(!contains(entt), "Set already contains entity");
  26175. if(auto &elem = assure_at_least(entt); free_list == null || force_back) {
  26176. packed.push_back(entt);
  26177. elem = entity_traits::combine(static_cast<typename entity_traits::entity_type>(packed.size() - 1u), entity_traits::to_integral(entt));
  26178. return begin();
  26179. } else {
  26180. const auto pos = static_cast<size_type>(entity_traits::to_entity(free_list));
  26181. elem = entity_traits::combine(entity_traits::to_integral(free_list), entity_traits::to_integral(entt));
  26182. free_list = std::exchange(packed[pos], entt);
  26183. return --(end() - pos);
  26184. }
  26185. }
  26186. public:
  26187. /*! @brief Allocator type. */
  26188. using allocator_type = Allocator;
  26189. /*! @brief Underlying entity identifier. */
  26190. using entity_type = Entity;
  26191. /*! @brief Underlying version type. */
  26192. using version_type = typename entity_traits::version_type;
  26193. /*! @brief Unsigned integer type. */
  26194. using size_type = typename packed_container_type::size_type;
  26195. /*! @brief Pointer type to contained entities. */
  26196. using pointer = typename packed_container_type::const_pointer;
  26197. /*! @brief Random access iterator type. */
  26198. using iterator = basic_iterator;
  26199. /*! @brief Constant random access iterator type. */
  26200. using const_iterator = iterator;
  26201. /*! @brief Reverse iterator type. */
  26202. using reverse_iterator = std::reverse_iterator<iterator>;
  26203. /*! @brief Constant reverse iterator type. */
  26204. using const_reverse_iterator = reverse_iterator;
  26205. /*! @brief Default constructor. */
  26206. basic_sparse_set()
  26207. : basic_sparse_set{type_id<void>()} {}
  26208. /**
  26209. * @brief Constructs an empty container with a given allocator.
  26210. * @param allocator The allocator to use.
  26211. */
  26212. explicit basic_sparse_set(const allocator_type &allocator)
  26213. : basic_sparse_set{type_id<void>(), deletion_policy::swap_and_pop, allocator} {}
  26214. /**
  26215. * @brief Constructs an empty container with the given policy and allocator.
  26216. * @param pol Type of deletion policy.
  26217. * @param allocator The allocator to use (possibly default-constructed).
  26218. */
  26219. explicit basic_sparse_set(deletion_policy pol, const allocator_type &allocator = {})
  26220. : basic_sparse_set{type_id<void>(), pol, allocator} {}
  26221. /**
  26222. * @brief Constructs an empty container with the given value type, policy
  26223. * and allocator.
  26224. * @param value Returned value type, if any.
  26225. * @param pol Type of deletion policy.
  26226. * @param allocator The allocator to use (possibly default-constructed).
  26227. */
  26228. explicit basic_sparse_set(const type_info &value, deletion_policy pol = deletion_policy::swap_and_pop, const allocator_type &allocator = {})
  26229. : sparse{allocator},
  26230. packed{allocator},
  26231. info{&value},
  26232. free_list{tombstone},
  26233. mode{pol} {}
  26234. /**
  26235. * @brief Move constructor.
  26236. * @param other The instance to move from.
  26237. */
  26238. basic_sparse_set(basic_sparse_set &&other) ENTT_NOEXCEPT
  26239. : sparse{std::move(other.sparse)},
  26240. packed{std::move(other.packed)},
  26241. info{other.info},
  26242. free_list{std::exchange(other.free_list, tombstone)},
  26243. mode{other.mode} {}
  26244. /**
  26245. * @brief Allocator-extended move constructor.
  26246. * @param other The instance to move from.
  26247. * @param allocator The allocator to use.
  26248. */
  26249. basic_sparse_set(basic_sparse_set &&other, const allocator_type &allocator) ENTT_NOEXCEPT
  26250. : sparse{std::move(other.sparse), allocator},
  26251. packed{std::move(other.packed), allocator},
  26252. info{other.info},
  26253. free_list{std::exchange(other.free_list, tombstone)},
  26254. mode{other.mode} {
  26255. ENTT_ASSERT(alloc_traits::is_always_equal::value || packed.get_allocator() == other.packed.get_allocator(), "Copying a sparse set is not allowed");
  26256. }
  26257. /*! @brief Default destructor. */
  26258. virtual ~basic_sparse_set() {
  26259. release_sparse_pages();
  26260. }
  26261. /**
  26262. * @brief Move assignment operator.
  26263. * @param other The instance to move from.
  26264. * @return This sparse set.
  26265. */
  26266. basic_sparse_set &operator=(basic_sparse_set &&other) ENTT_NOEXCEPT {
  26267. ENTT_ASSERT(alloc_traits::is_always_equal::value || packed.get_allocator() == other.packed.get_allocator(), "Copying a sparse set is not allowed");
  26268. release_sparse_pages();
  26269. sparse = std::move(other.sparse);
  26270. packed = std::move(other.packed);
  26271. info = other.info;
  26272. free_list = std::exchange(other.free_list, tombstone);
  26273. mode = other.mode;
  26274. return *this;
  26275. }
  26276. /**
  26277. * @brief Exchanges the contents with those of a given sparse set.
  26278. * @param other Sparse set to exchange the content with.
  26279. */
  26280. void swap(basic_sparse_set &other) {
  26281. using std::swap;
  26282. swap(sparse, other.sparse);
  26283. swap(packed, other.packed);
  26284. swap(info, other.info);
  26285. swap(free_list, other.free_list);
  26286. swap(mode, other.mode);
  26287. }
  26288. /**
  26289. * @brief Returns the associated allocator.
  26290. * @return The associated allocator.
  26291. */
  26292. [[nodiscard]] constexpr allocator_type get_allocator() const ENTT_NOEXCEPT {
  26293. return packed.get_allocator();
  26294. }
  26295. /**
  26296. * @brief Returns the deletion policy of a sparse set.
  26297. * @return The deletion policy of the sparse set.
  26298. */
  26299. [[nodiscard]] deletion_policy policy() const ENTT_NOEXCEPT {
  26300. return mode;
  26301. }
  26302. /**
  26303. * @brief Increases the capacity of a sparse set.
  26304. *
  26305. * If the new capacity is greater than the current capacity, new storage is
  26306. * allocated, otherwise the method does nothing.
  26307. *
  26308. * @param cap Desired capacity.
  26309. */
  26310. virtual void reserve(const size_type cap) {
  26311. packed.reserve(cap);
  26312. }
  26313. /**
  26314. * @brief Returns the number of elements that a sparse set has currently
  26315. * allocated space for.
  26316. * @return Capacity of the sparse set.
  26317. */
  26318. [[nodiscard]] virtual size_type capacity() const ENTT_NOEXCEPT {
  26319. return packed.capacity();
  26320. }
  26321. /*! @brief Requests the removal of unused capacity. */
  26322. virtual void shrink_to_fit() {
  26323. packed.shrink_to_fit();
  26324. }
  26325. /**
  26326. * @brief Returns the extent of a sparse set.
  26327. *
  26328. * The extent of a sparse set is also the size of the internal sparse array.
  26329. * There is no guarantee that the internal packed array has the same size.
  26330. * Usually the size of the internal sparse array is equal or greater than
  26331. * the one of the internal packed array.
  26332. *
  26333. * @return Extent of the sparse set.
  26334. */
  26335. [[nodiscard]] size_type extent() const ENTT_NOEXCEPT {
  26336. return sparse.size() * entity_traits::page_size;
  26337. }
  26338. /**
  26339. * @brief Returns the number of elements in a sparse set.
  26340. *
  26341. * The number of elements is also the size of the internal packed array.
  26342. * There is no guarantee that the internal sparse array has the same size.
  26343. * Usually the size of the internal sparse array is equal or greater than
  26344. * the one of the internal packed array.
  26345. *
  26346. * @return Number of elements.
  26347. */
  26348. [[nodiscard]] size_type size() const ENTT_NOEXCEPT {
  26349. return packed.size();
  26350. }
  26351. /**
  26352. * @brief Checks whether a sparse set is empty.
  26353. * @return True if the sparse set is empty, false otherwise.
  26354. */
  26355. [[nodiscard]] bool empty() const ENTT_NOEXCEPT {
  26356. return packed.empty();
  26357. }
  26358. /**
  26359. * @brief Direct access to the internal packed array.
  26360. * @return A pointer to the internal packed array.
  26361. */
  26362. [[nodiscard]] pointer data() const ENTT_NOEXCEPT {
  26363. return packed.data();
  26364. }
  26365. /**
  26366. * @brief Returns an iterator to the beginning.
  26367. *
  26368. * The returned iterator points to the first entity of the internal packed
  26369. * array. If the sparse set is empty, the returned iterator will be equal to
  26370. * `end()`.
  26371. *
  26372. * @return An iterator to the first entity of the sparse set.
  26373. */
  26374. [[nodiscard]] const_iterator begin() const ENTT_NOEXCEPT {
  26375. const auto pos = static_cast<typename iterator::difference_type>(packed.size());
  26376. return iterator{packed, pos};
  26377. }
  26378. /*! @copydoc begin */
  26379. [[nodiscard]] const_iterator cbegin() const ENTT_NOEXCEPT {
  26380. return begin();
  26381. }
  26382. /**
  26383. * @brief Returns an iterator to the end.
  26384. *
  26385. * The returned iterator points to the element following the last entity in
  26386. * a sparse set. Attempting to dereference the returned iterator results in
  26387. * undefined behavior.
  26388. *
  26389. * @return An iterator to the element following the last entity of a sparse
  26390. * set.
  26391. */
  26392. [[nodiscard]] iterator end() const ENTT_NOEXCEPT {
  26393. return iterator{packed, {}};
  26394. }
  26395. /*! @copydoc end */
  26396. [[nodiscard]] const_iterator cend() const ENTT_NOEXCEPT {
  26397. return end();
  26398. }
  26399. /**
  26400. * @brief Returns a reverse iterator to the beginning.
  26401. *
  26402. * The returned iterator points to the first entity of the reversed internal
  26403. * packed array. If the sparse set is empty, the returned iterator will be
  26404. * equal to `rend()`.
  26405. *
  26406. * @return An iterator to the first entity of the reversed internal packed
  26407. * array.
  26408. */
  26409. [[nodiscard]] const_reverse_iterator rbegin() const ENTT_NOEXCEPT {
  26410. return std::make_reverse_iterator(end());
  26411. }
  26412. /*! @copydoc rbegin */
  26413. [[nodiscard]] const_reverse_iterator crbegin() const ENTT_NOEXCEPT {
  26414. return rbegin();
  26415. }
  26416. /**
  26417. * @brief Returns a reverse iterator to the end.
  26418. *
  26419. * The returned iterator points to the element following the last entity in
  26420. * the reversed sparse set. Attempting to dereference the returned iterator
  26421. * results in undefined behavior.
  26422. *
  26423. * @return An iterator to the element following the last entity of the
  26424. * reversed sparse set.
  26425. */
  26426. [[nodiscard]] reverse_iterator rend() const ENTT_NOEXCEPT {
  26427. return std::make_reverse_iterator(begin());
  26428. }
  26429. /*! @copydoc rend */
  26430. [[nodiscard]] const_reverse_iterator crend() const ENTT_NOEXCEPT {
  26431. return rend();
  26432. }
  26433. /**
  26434. * @brief Finds an entity.
  26435. * @param entt A valid identifier.
  26436. * @return An iterator to the given entity if it's found, past the end
  26437. * iterator otherwise.
  26438. */
  26439. [[nodiscard]] iterator find(const entity_type entt) const ENTT_NOEXCEPT {
  26440. return contains(entt) ? --(end() - index(entt)) : end();
  26441. }
  26442. /**
  26443. * @brief Checks if a sparse set contains an entity.
  26444. * @param entt A valid identifier.
  26445. * @return True if the sparse set contains the entity, false otherwise.
  26446. */
  26447. [[nodiscard]] bool contains(const entity_type entt) const ENTT_NOEXCEPT {
  26448. const auto elem = sparse_ptr(entt);
  26449. constexpr auto cap = entity_traits::to_entity(null);
  26450. // testing versions permits to avoid accessing the packed array
  26451. return elem && (((~cap & entity_traits::to_integral(entt)) ^ entity_traits::to_integral(*elem)) < cap);
  26452. }
  26453. /**
  26454. * @brief Returns the contained version for an identifier.
  26455. * @param entt A valid identifier.
  26456. * @return The version for the given identifier if present, the tombstone
  26457. * version otherwise.
  26458. */
  26459. [[nodiscard]] version_type current(const entity_type entt) const ENTT_NOEXCEPT {
  26460. const auto elem = sparse_ptr(entt);
  26461. constexpr auto fallback = entity_traits::to_version(tombstone);
  26462. return elem ? entity_traits::to_version(*elem) : fallback;
  26463. }
  26464. /**
  26465. * @brief Returns the position of an entity in a sparse set.
  26466. *
  26467. * @warning
  26468. * Attempting to get the position of an entity that doesn't belong to the
  26469. * sparse set results in undefined behavior.
  26470. *
  26471. * @param entt A valid identifier.
  26472. * @return The position of the entity in the sparse set.
  26473. */
  26474. [[nodiscard]] size_type index(const entity_type entt) const ENTT_NOEXCEPT {
  26475. ENTT_ASSERT(contains(entt), "Set does not contain entity");
  26476. return static_cast<size_type>(entity_traits::to_entity(sparse_ref(entt)));
  26477. }
  26478. /**
  26479. * @brief Returns the entity at specified location, with bounds checking.
  26480. * @param pos The position for which to return the entity.
  26481. * @return The entity at specified location if any, a null entity otherwise.
  26482. */
  26483. [[nodiscard]] entity_type at(const size_type pos) const ENTT_NOEXCEPT {
  26484. return pos < packed.size() ? packed[pos] : null;
  26485. }
  26486. /**
  26487. * @brief Returns the entity at specified location, without bounds checking.
  26488. * @param pos The position for which to return the entity.
  26489. * @return The entity at specified location.
  26490. */
  26491. [[nodiscard]] entity_type operator[](const size_type pos) const ENTT_NOEXCEPT {
  26492. ENTT_ASSERT(pos < packed.size(), "Position is out of bounds");
  26493. return packed[pos];
  26494. }
  26495. /**
  26496. * @brief Returns the element assigned to an entity, if any.
  26497. *
  26498. * @warning
  26499. * Attempting to use an entity that doesn't belong to the sparse set results
  26500. * in undefined behavior.
  26501. *
  26502. * @param entt A valid identifier.
  26503. * @return An opaque pointer to the element assigned to the entity, if any.
  26504. */
  26505. const void *get(const entity_type entt) const ENTT_NOEXCEPT {
  26506. return get_at(index(entt));
  26507. }
  26508. /*! @copydoc get */
  26509. void *get(const entity_type entt) ENTT_NOEXCEPT {
  26510. return const_cast<void *>(std::as_const(*this).get(entt));
  26511. }
  26512. /**
  26513. * @brief Assigns an entity to a sparse set.
  26514. *
  26515. * @warning
  26516. * Attempting to assign an entity that already belongs to the sparse set
  26517. * results in undefined behavior.
  26518. *
  26519. * @param entt A valid identifier.
  26520. * @param value Optional opaque value to forward to mixins, if any.
  26521. * @return Iterator pointing to the emplaced element in case of success, the
  26522. * `end()` iterator otherwise.
  26523. */
  26524. iterator emplace(const entity_type entt, const void *value = nullptr) {
  26525. return try_emplace(entt, false, value);
  26526. }
  26527. /**
  26528. * @brief Bump the version number of an entity.
  26529. *
  26530. * @warning
  26531. * Attempting to bump the version of an entity that doesn't belong to the
  26532. * sparse set results in undefined behavior.
  26533. *
  26534. * @param entt A valid identifier.
  26535. */
  26536. void bump(const entity_type entt) {
  26537. auto &entity = sparse_ref(entt);
  26538. entity = entity_traits::combine(entity_traits::to_integral(entity), entity_traits::to_integral(entt));
  26539. packed[static_cast<size_type>(entity_traits::to_entity(entity))] = entt;
  26540. }
  26541. /**
  26542. * @brief Assigns one or more entities to a sparse set.
  26543. *
  26544. * @warning
  26545. * Attempting to assign an entity that already belongs to the sparse set
  26546. * results in undefined behavior.
  26547. *
  26548. * @tparam It Type of input iterator.
  26549. * @param first An iterator to the first element of the range of entities.
  26550. * @param last An iterator past the last element of the range of entities.
  26551. * @return Iterator pointing to the first element inserted in case of
  26552. * success, the `end()` iterator otherwise.
  26553. */
  26554. template<typename It>
  26555. iterator insert(It first, It last) {
  26556. for(auto it = first; it != last; ++it) {
  26557. try_emplace(*it, true);
  26558. }
  26559. return first == last ? end() : find(*first);
  26560. }
  26561. /**
  26562. * @brief Erases an entity from a sparse set.
  26563. *
  26564. * @warning
  26565. * Attempting to erase an entity that doesn't belong to the sparse set
  26566. * results in undefined behavior.
  26567. *
  26568. * @param entt A valid identifier.
  26569. */
  26570. void erase(const entity_type entt) {
  26571. const auto it = --(end() - index(entt));
  26572. (mode == deletion_policy::in_place) ? in_place_pop(it, it + 1u) : swap_and_pop(it, it + 1u);
  26573. }
  26574. /**
  26575. * @brief Erases entities from a set.
  26576. *
  26577. * @sa erase
  26578. *
  26579. * @tparam It Type of input iterator.
  26580. * @param first An iterator to the first element of the range of entities.
  26581. * @param last An iterator past the last element of the range of entities.
  26582. */
  26583. template<typename It>
  26584. void erase(It first, It last) {
  26585. if constexpr(std::is_same_v<It, basic_iterator>) {
  26586. (mode == deletion_policy::in_place) ? in_place_pop(first, last) : swap_and_pop(first, last);
  26587. } else {
  26588. for(; first != last; ++first) {
  26589. erase(*first);
  26590. }
  26591. }
  26592. }
  26593. /**
  26594. * @brief Removes an entity from a sparse set if it exists.
  26595. * @param entt A valid identifier.
  26596. * @return True if the entity is actually removed, false otherwise.
  26597. */
  26598. bool remove(const entity_type entt) {
  26599. return contains(entt) && (erase(entt), true);
  26600. }
  26601. /**
  26602. * @brief Removes entities from a sparse set if they exist.
  26603. * @tparam It Type of input iterator.
  26604. * @param first An iterator to the first element of the range of entities.
  26605. * @param last An iterator past the last element of the range of entities.
  26606. * @return The number of entities actually removed.
  26607. */
  26608. template<typename It>
  26609. size_type remove(It first, It last) {
  26610. size_type count{};
  26611. for(; first != last; ++first) {
  26612. count += remove(*first);
  26613. }
  26614. return count;
  26615. }
  26616. /*! @brief Removes all tombstones from the packed array of a sparse set. */
  26617. void compact() {
  26618. size_type from = packed.size();
  26619. for(; from && packed[from - 1u] == tombstone; --from) {}
  26620. for(auto *it = &free_list; *it != null && from; it = std::addressof(packed[entity_traits::to_entity(*it)])) {
  26621. if(const size_type to = entity_traits::to_entity(*it); to < from) {
  26622. --from;
  26623. move_element(from, to);
  26624. using std::swap;
  26625. swap(packed[from], packed[to]);
  26626. const auto entity = static_cast<typename entity_traits::entity_type>(to);
  26627. sparse_ref(packed[to]) = entity_traits::combine(entity, entity_traits::to_integral(packed[to]));
  26628. *it = entity_traits::combine(static_cast<typename entity_traits::entity_type>(from), entity_traits::reserved);
  26629. for(; from && packed[from - 1u] == tombstone; --from) {}
  26630. }
  26631. }
  26632. free_list = tombstone;
  26633. packed.resize(from);
  26634. }
  26635. /**
  26636. * @brief Swaps two entities in a sparse set.
  26637. *
  26638. * For what it's worth, this function affects both the internal sparse array
  26639. * and the internal packed array. Users should not care of that anyway.
  26640. *
  26641. * @warning
  26642. * Attempting to swap entities that don't belong to the sparse set results
  26643. * in undefined behavior.
  26644. *
  26645. * @param lhs A valid identifier.
  26646. * @param rhs A valid identifier.
  26647. */
  26648. void swap_elements(const entity_type lhs, const entity_type rhs) {
  26649. ENTT_ASSERT(contains(lhs) && contains(rhs), "Set does not contain entities");
  26650. auto &entt = sparse_ref(lhs);
  26651. auto &other = sparse_ref(rhs);
  26652. const auto from = entity_traits::to_entity(entt);
  26653. const auto to = entity_traits::to_entity(other);
  26654. // basic no-leak guarantee (with invalid state) if swapping throws
  26655. swap_at(static_cast<size_type>(from), static_cast<size_type>(to));
  26656. entt = entity_traits::combine(to, entity_traits::to_integral(packed[from]));
  26657. other = entity_traits::combine(from, entity_traits::to_integral(packed[to]));
  26658. using std::swap;
  26659. swap(packed[from], packed[to]);
  26660. }
  26661. /**
  26662. * @brief Sort the first count elements according to the given comparison
  26663. * function.
  26664. *
  26665. * The comparison function object must return `true` if the first element
  26666. * is _less_ than the second one, `false` otherwise. The signature of the
  26667. * comparison function should be equivalent to the following:
  26668. *
  26669. * @code{.cpp}
  26670. * bool(const Entity, const Entity);
  26671. * @endcode
  26672. *
  26673. * Moreover, the comparison function object shall induce a
  26674. * _strict weak ordering_ on the values.
  26675. *
  26676. * The sort function object must offer a member function template
  26677. * `operator()` that accepts three arguments:
  26678. *
  26679. * * An iterator to the first element of the range to sort.
  26680. * * An iterator past the last element of the range to sort.
  26681. * * A comparison function to use to compare the elements.
  26682. *
  26683. * @tparam Compare Type of comparison function object.
  26684. * @tparam Sort Type of sort function object.
  26685. * @tparam Args Types of arguments to forward to the sort function object.
  26686. * @param length Number of elements to sort.
  26687. * @param compare A valid comparison function object.
  26688. * @param algo A valid sort function object.
  26689. * @param args Arguments to forward to the sort function object, if any.
  26690. */
  26691. template<typename Compare, typename Sort = std_sort, typename... Args>
  26692. void sort_n(const size_type length, Compare compare, Sort algo = Sort{}, Args &&...args) {
  26693. ENTT_ASSERT(!(length > packed.size()), "Length exceeds the number of elements");
  26694. ENTT_ASSERT(free_list == null, "Partial sorting with tombstones is not supported");
  26695. algo(packed.rend() - length, packed.rend(), std::move(compare), std::forward<Args>(args)...);
  26696. for(size_type pos{}; pos < length; ++pos) {
  26697. auto curr = pos;
  26698. auto next = index(packed[curr]);
  26699. while(curr != next) {
  26700. const auto idx = index(packed[next]);
  26701. const auto entt = packed[curr];
  26702. swap_at(next, idx);
  26703. const auto entity = static_cast<typename entity_traits::entity_type>(curr);
  26704. sparse_ref(entt) = entity_traits::combine(entity, entity_traits::to_integral(packed[curr]));
  26705. curr = std::exchange(next, idx);
  26706. }
  26707. }
  26708. }
  26709. /**
  26710. * @brief Sort all elements according to the given comparison function.
  26711. *
  26712. * @sa sort_n
  26713. *
  26714. * @tparam Compare Type of comparison function object.
  26715. * @tparam Sort Type of sort function object.
  26716. * @tparam Args Types of arguments to forward to the sort function object.
  26717. * @param compare A valid comparison function object.
  26718. * @param algo A valid sort function object.
  26719. * @param args Arguments to forward to the sort function object, if any.
  26720. */
  26721. template<typename Compare, typename Sort = std_sort, typename... Args>
  26722. void sort(Compare compare, Sort algo = Sort{}, Args &&...args) {
  26723. compact();
  26724. sort_n(packed.size(), std::move(compare), std::move(algo), std::forward<Args>(args)...);
  26725. }
  26726. /**
  26727. * @brief Sort entities according to their order in another sparse set.
  26728. *
  26729. * Entities that are part of both the sparse sets are ordered internally
  26730. * according to the order they have in `other`. All the other entities goes
  26731. * to the end of the list and there are no guarantees on their order.<br/>
  26732. * In other terms, this function can be used to impose the same order on two
  26733. * sets by using one of them as a master and the other one as a slave.
  26734. *
  26735. * Iterating the sparse set with a couple of iterators returns elements in
  26736. * the expected order after a call to `respect`. See `begin` and `end` for
  26737. * more details.
  26738. *
  26739. * @param other The sparse sets that imposes the order of the entities.
  26740. */
  26741. void respect(const basic_sparse_set &other) {
  26742. compact();
  26743. const auto to = other.end();
  26744. auto from = other.begin();
  26745. for(size_type pos = packed.size() - 1; pos && from != to; ++from) {
  26746. if(contains(*from)) {
  26747. if(*from != packed[pos]) {
  26748. // basic no-leak guarantee (with invalid state) if swapping throws
  26749. swap_elements(packed[pos], *from);
  26750. }
  26751. --pos;
  26752. }
  26753. }
  26754. }
  26755. /*! @brief Clears a sparse set. */
  26756. void clear() {
  26757. if(const auto last = end(); free_list == null) {
  26758. in_place_pop(begin(), last);
  26759. } else {
  26760. for(auto &&entity: *this) {
  26761. // tombstone filter on itself
  26762. if(const auto it = find(entity); it != last) {
  26763. in_place_pop(it, it + 1u);
  26764. }
  26765. }
  26766. }
  26767. free_list = tombstone;
  26768. packed.clear();
  26769. }
  26770. /**
  26771. * @brief Returned value type, if any.
  26772. * @return Returned value type, if any.
  26773. */
  26774. const type_info &type() const ENTT_NOEXCEPT {
  26775. return *info;
  26776. }
  26777. /*! @brief Forwards variables to mixins, if any. */
  26778. virtual void bind(any) ENTT_NOEXCEPT {}
  26779. private:
  26780. sparse_container_type sparse;
  26781. packed_container_type packed;
  26782. const type_info *info;
  26783. entity_type free_list;
  26784. deletion_policy mode;
  26785. };
  26786. } // namespace entt
  26787. #endif
  26788. // #include "entity/storage.hpp"
  26789. #ifndef ENTT_ENTITY_STORAGE_HPP
  26790. #define ENTT_ENTITY_STORAGE_HPP
  26791. #include <cstddef>
  26792. #include <iterator>
  26793. #include <memory>
  26794. #include <tuple>
  26795. #include <type_traits>
  26796. #include <utility>
  26797. #include <vector>
  26798. // #include "../config/config.h"
  26799. // #include "../core/compressed_pair.hpp"
  26800. // #include "../core/iterator.hpp"
  26801. // #include "../core/memory.hpp"
  26802. // #include "../core/type_info.hpp"
  26803. // #include "component.hpp"
  26804. // #include "entity.hpp"
  26805. // #include "fwd.hpp"
  26806. // #include "sigh_storage_mixin.hpp"
  26807. // #include "sparse_set.hpp"
  26808. namespace entt {
  26809. /**
  26810. * @cond TURN_OFF_DOXYGEN
  26811. * Internal details not to be documented.
  26812. */
  26813. namespace internal {
  26814. template<typename Container>
  26815. class storage_iterator final {
  26816. friend storage_iterator<const Container>;
  26817. using container_type = std::remove_const_t<Container>;
  26818. using alloc_traits = std::allocator_traits<typename container_type::allocator_type>;
  26819. using comp_traits = component_traits<typename container_type::value_type>;
  26820. using iterator_traits = std::iterator_traits<std::conditional_t<
  26821. std::is_const_v<Container>,
  26822. typename alloc_traits::template rebind_traits<typename std::pointer_traits<typename container_type::value_type>::element_type>::const_pointer,
  26823. typename alloc_traits::template rebind_traits<typename std::pointer_traits<typename container_type::value_type>::element_type>::pointer>>;
  26824. public:
  26825. using value_type = typename iterator_traits::value_type;
  26826. using pointer = typename iterator_traits::pointer;
  26827. using reference = typename iterator_traits::reference;
  26828. using difference_type = typename iterator_traits::difference_type;
  26829. using iterator_category = std::random_access_iterator_tag;
  26830. storage_iterator() ENTT_NOEXCEPT = default;
  26831. storage_iterator(Container *ref, difference_type idx) ENTT_NOEXCEPT
  26832. : packed{ref},
  26833. offset{idx} {}
  26834. template<bool Const = std::is_const_v<Container>, typename = std::enable_if_t<Const>>
  26835. storage_iterator(const storage_iterator<std::remove_const_t<Container>> &other) ENTT_NOEXCEPT
  26836. : packed{other.packed},
  26837. offset{other.offset} {}
  26838. storage_iterator &operator++() ENTT_NOEXCEPT {
  26839. return --offset, *this;
  26840. }
  26841. storage_iterator operator++(int) ENTT_NOEXCEPT {
  26842. storage_iterator orig = *this;
  26843. return ++(*this), orig;
  26844. }
  26845. storage_iterator &operator--() ENTT_NOEXCEPT {
  26846. return ++offset, *this;
  26847. }
  26848. storage_iterator operator--(int) ENTT_NOEXCEPT {
  26849. storage_iterator orig = *this;
  26850. return operator--(), orig;
  26851. }
  26852. storage_iterator &operator+=(const difference_type value) ENTT_NOEXCEPT {
  26853. offset -= value;
  26854. return *this;
  26855. }
  26856. storage_iterator operator+(const difference_type value) const ENTT_NOEXCEPT {
  26857. storage_iterator copy = *this;
  26858. return (copy += value);
  26859. }
  26860. storage_iterator &operator-=(const difference_type value) ENTT_NOEXCEPT {
  26861. return (*this += -value);
  26862. }
  26863. storage_iterator operator-(const difference_type value) const ENTT_NOEXCEPT {
  26864. return (*this + -value);
  26865. }
  26866. [[nodiscard]] reference operator[](const difference_type value) const ENTT_NOEXCEPT {
  26867. const auto pos = index() - value;
  26868. return (*packed)[pos / comp_traits::page_size][fast_mod(pos, comp_traits::page_size)];
  26869. }
  26870. [[nodiscard]] pointer operator->() const ENTT_NOEXCEPT {
  26871. const auto pos = index();
  26872. return (*packed)[pos / comp_traits::page_size] + fast_mod(pos, comp_traits::page_size);
  26873. }
  26874. [[nodiscard]] reference operator*() const ENTT_NOEXCEPT {
  26875. return *operator->();
  26876. }
  26877. [[nodiscard]] difference_type index() const ENTT_NOEXCEPT {
  26878. return offset - 1;
  26879. }
  26880. private:
  26881. Container *packed;
  26882. difference_type offset;
  26883. };
  26884. template<typename CLhs, typename CRhs>
  26885. [[nodiscard]] std::ptrdiff_t operator-(const storage_iterator<CLhs> &lhs, const storage_iterator<CRhs> &rhs) ENTT_NOEXCEPT {
  26886. return rhs.index() - lhs.index();
  26887. }
  26888. template<typename CLhs, typename CRhs>
  26889. [[nodiscard]] bool operator==(const storage_iterator<CLhs> &lhs, const storage_iterator<CRhs> &rhs) ENTT_NOEXCEPT {
  26890. return lhs.index() == rhs.index();
  26891. }
  26892. template<typename CLhs, typename CRhs>
  26893. [[nodiscard]] bool operator!=(const storage_iterator<CLhs> &lhs, const storage_iterator<CRhs> &rhs) ENTT_NOEXCEPT {
  26894. return !(lhs == rhs);
  26895. }
  26896. template<typename CLhs, typename CRhs>
  26897. [[nodiscard]] bool operator<(const storage_iterator<CLhs> &lhs, const storage_iterator<CRhs> &rhs) ENTT_NOEXCEPT {
  26898. return lhs.index() > rhs.index();
  26899. }
  26900. template<typename CLhs, typename CRhs>
  26901. [[nodiscard]] bool operator>(const storage_iterator<CLhs> &lhs, const storage_iterator<CRhs> &rhs) ENTT_NOEXCEPT {
  26902. return lhs.index() < rhs.index();
  26903. }
  26904. template<typename CLhs, typename CRhs>
  26905. [[nodiscard]] bool operator<=(const storage_iterator<CLhs> &lhs, const storage_iterator<CRhs> &rhs) ENTT_NOEXCEPT {
  26906. return !(lhs > rhs);
  26907. }
  26908. template<typename CLhs, typename CRhs>
  26909. [[nodiscard]] bool operator>=(const storage_iterator<CLhs> &lhs, const storage_iterator<CRhs> &rhs) ENTT_NOEXCEPT {
  26910. return !(lhs < rhs);
  26911. }
  26912. template<typename It, typename... Other>
  26913. class extended_storage_iterator final {
  26914. template<typename Iter, typename... Args>
  26915. friend class extended_storage_iterator;
  26916. public:
  26917. using value_type = decltype(std::tuple_cat(std::make_tuple(*std::declval<It>()), std::forward_as_tuple(*std::declval<Other>()...)));
  26918. using pointer = input_iterator_pointer<value_type>;
  26919. using reference = value_type;
  26920. using difference_type = std::ptrdiff_t;
  26921. using iterator_category = std::input_iterator_tag;
  26922. extended_storage_iterator() = default;
  26923. extended_storage_iterator(It base, Other... other)
  26924. : it{base, other...} {}
  26925. template<typename... Args, typename = std::enable_if_t<(!std::is_same_v<Other, Args> && ...) && (std::is_constructible_v<Other, Args> && ...)>>
  26926. extended_storage_iterator(const extended_storage_iterator<It, Args...> &other)
  26927. : it{other.it} {}
  26928. extended_storage_iterator &operator++() ENTT_NOEXCEPT {
  26929. return ++std::get<It>(it), (++std::get<Other>(it), ...), *this;
  26930. }
  26931. extended_storage_iterator operator++(int) ENTT_NOEXCEPT {
  26932. extended_storage_iterator orig = *this;
  26933. return ++(*this), orig;
  26934. }
  26935. [[nodiscard]] pointer operator->() const ENTT_NOEXCEPT {
  26936. return operator*();
  26937. }
  26938. [[nodiscard]] reference operator*() const ENTT_NOEXCEPT {
  26939. return {*std::get<It>(it), *std::get<Other>(it)...};
  26940. }
  26941. template<typename... CLhs, typename... CRhs>
  26942. friend bool operator==(const extended_storage_iterator<CLhs...> &, const extended_storage_iterator<CRhs...> &) ENTT_NOEXCEPT;
  26943. private:
  26944. std::tuple<It, Other...> it;
  26945. };
  26946. template<typename... CLhs, typename... CRhs>
  26947. [[nodiscard]] bool operator==(const extended_storage_iterator<CLhs...> &lhs, const extended_storage_iterator<CRhs...> &rhs) ENTT_NOEXCEPT {
  26948. return std::get<0>(lhs.it) == std::get<0>(rhs.it);
  26949. }
  26950. template<typename... CLhs, typename... CRhs>
  26951. [[nodiscard]] bool operator!=(const extended_storage_iterator<CLhs...> &lhs, const extended_storage_iterator<CRhs...> &rhs) ENTT_NOEXCEPT {
  26952. return !(lhs == rhs);
  26953. }
  26954. } // namespace internal
  26955. /**
  26956. * Internal details not to be documented.
  26957. * @endcond
  26958. */
  26959. /**
  26960. * @brief Basic storage implementation.
  26961. *
  26962. * Internal data structures arrange elements to maximize performance. There are
  26963. * no guarantees that objects are returned in the insertion order when iterate
  26964. * a storage. Do not make assumption on the order in any case.
  26965. *
  26966. * @warning
  26967. * Empty types aren't explicitly instantiated. Therefore, many of the functions
  26968. * normally available for non-empty types will not be available for empty ones.
  26969. *
  26970. * @tparam Entity A valid entity type (see entt_traits for more details).
  26971. * @tparam Type Type of objects assigned to the entities.
  26972. * @tparam Allocator Type of allocator used to manage memory and elements.
  26973. */
  26974. template<typename Entity, typename Type, typename Allocator, typename>
  26975. class basic_storage: public basic_sparse_set<Entity, typename std::allocator_traits<Allocator>::template rebind_alloc<Entity>> {
  26976. static_assert(std::is_move_constructible_v<Type> && std::is_move_assignable_v<Type>, "The type must be at least move constructible/assignable");
  26977. using alloc_traits = std::allocator_traits<Allocator>;
  26978. static_assert(std::is_same_v<typename alloc_traits::value_type, Type>, "Invalid value type");
  26979. using underlying_type = basic_sparse_set<Entity, typename alloc_traits::template rebind_alloc<Entity>>;
  26980. using container_type = std::vector<typename alloc_traits::pointer, typename alloc_traits::template rebind_alloc<typename alloc_traits::pointer>>;
  26981. using comp_traits = component_traits<Type>;
  26982. [[nodiscard]] auto &element_at(const std::size_t pos) const {
  26983. return packed.first()[pos / comp_traits::page_size][fast_mod(pos, comp_traits::page_size)];
  26984. }
  26985. auto assure_at_least(const std::size_t pos) {
  26986. auto &&container = packed.first();
  26987. const auto idx = pos / comp_traits::page_size;
  26988. if(!(idx < container.size())) {
  26989. auto curr = container.size();
  26990. container.resize(idx + 1u, nullptr);
  26991. ENTT_TRY {
  26992. for(const auto last = container.size(); curr < last; ++curr) {
  26993. container[curr] = alloc_traits::allocate(packed.second(), comp_traits::page_size);
  26994. }
  26995. }
  26996. ENTT_CATCH {
  26997. container.resize(curr);
  26998. ENTT_THROW;
  26999. }
  27000. }
  27001. return container[idx] + fast_mod(pos, comp_traits::page_size);
  27002. }
  27003. template<typename... Args>
  27004. auto emplace_element(const Entity entt, const bool force_back, Args &&...args) {
  27005. const auto it = base_type::try_emplace(entt, force_back);
  27006. ENTT_TRY {
  27007. auto elem = assure_at_least(static_cast<size_type>(it.index()));
  27008. entt::uninitialized_construct_using_allocator(to_address(elem), packed.second(), std::forward<Args>(args)...);
  27009. }
  27010. ENTT_CATCH {
  27011. if constexpr(comp_traits::in_place_delete) {
  27012. base_type::in_place_pop(it, it + 1u);
  27013. } else {
  27014. base_type::swap_and_pop(it, it + 1u);
  27015. }
  27016. ENTT_THROW;
  27017. }
  27018. return it;
  27019. }
  27020. void shrink_to_size(const std::size_t sz) {
  27021. for(auto pos = sz, length = base_type::size(); pos < length; ++pos) {
  27022. if constexpr(comp_traits::in_place_delete) {
  27023. if(base_type::at(pos) != tombstone) {
  27024. std::destroy_at(std::addressof(element_at(pos)));
  27025. }
  27026. } else {
  27027. std::destroy_at(std::addressof(element_at(pos)));
  27028. }
  27029. }
  27030. auto &&container = packed.first();
  27031. auto page_allocator{packed.second()};
  27032. const auto from = (sz + comp_traits::page_size - 1u) / comp_traits::page_size;
  27033. for(auto pos = from, last = container.size(); pos < last; ++pos) {
  27034. alloc_traits::deallocate(page_allocator, container[pos], comp_traits::page_size);
  27035. }
  27036. container.resize(from);
  27037. }
  27038. private:
  27039. const void *get_at(const std::size_t pos) const final {
  27040. return std::addressof(element_at(pos));
  27041. }
  27042. void swap_at(const std::size_t lhs, const std::size_t rhs) final {
  27043. using std::swap;
  27044. swap(element_at(lhs), element_at(rhs));
  27045. }
  27046. void move_element(const std::size_t from, const std::size_t to) final {
  27047. auto &elem = element_at(from);
  27048. entt::uninitialized_construct_using_allocator(to_address(assure_at_least(to)), packed.second(), std::move(elem));
  27049. std::destroy_at(std::addressof(elem));
  27050. }
  27051. protected:
  27052. /**
  27053. * @brief Erases elements from a storage.
  27054. * @param first An iterator to the first element to erase.
  27055. * @param last An iterator past the last element to erase.
  27056. */
  27057. void swap_and_pop(typename underlying_type::basic_iterator first, typename underlying_type::basic_iterator last) override {
  27058. for(; first != last; ++first) {
  27059. // cannot use first::index() because it would break with cross iterators
  27060. const auto pos = base_type::index(*first);
  27061. auto &elem = element_at(base_type::size() - 1u);
  27062. // destroying on exit allows reentrant destructors
  27063. [[maybe_unused]] auto unused = std::exchange(element_at(pos), std::move(elem));
  27064. std::destroy_at(std::addressof(elem));
  27065. base_type::swap_and_pop(first, first + 1u);
  27066. }
  27067. }
  27068. /**
  27069. * @brief Erases elements from a storage.
  27070. * @param first An iterator to the first element to erase.
  27071. * @param last An iterator past the last element to erase.
  27072. */
  27073. void in_place_pop(typename underlying_type::basic_iterator first, typename underlying_type::basic_iterator last) override {
  27074. for(; first != last; ++first) {
  27075. // cannot use first::index() because it would break with cross iterators
  27076. const auto pos = base_type::index(*first);
  27077. base_type::in_place_pop(first, first + 1u);
  27078. std::destroy_at(std::addressof(element_at(pos)));
  27079. }
  27080. }
  27081. /**
  27082. * @brief Assigns an entity to a storage.
  27083. * @param entt A valid identifier.
  27084. * @param value Optional opaque value.
  27085. * @param force_back Force back insertion.
  27086. * @return Iterator pointing to the emplaced element.
  27087. */
  27088. typename underlying_type::basic_iterator try_emplace([[maybe_unused]] const Entity entt, const bool force_back, const void *value) override {
  27089. if(value) {
  27090. if constexpr(std::is_copy_constructible_v<value_type>) {
  27091. return emplace_element(entt, force_back, *static_cast<const value_type *>(value));
  27092. } else {
  27093. return base_type::end();
  27094. }
  27095. } else {
  27096. if constexpr(std::is_default_constructible_v<value_type>) {
  27097. return emplace_element(entt, force_back);
  27098. } else {
  27099. return base_type::end();
  27100. }
  27101. }
  27102. }
  27103. public:
  27104. /*! @brief Base type. */
  27105. using base_type = underlying_type;
  27106. /*! @brief Allocator type. */
  27107. using allocator_type = Allocator;
  27108. /*! @brief Type of the objects assigned to entities. */
  27109. using value_type = Type;
  27110. /*! @brief Underlying entity identifier. */
  27111. using entity_type = Entity;
  27112. /*! @brief Unsigned integer type. */
  27113. using size_type = std::size_t;
  27114. /*! @brief Pointer type to contained elements. */
  27115. using pointer = typename container_type::pointer;
  27116. /*! @brief Constant pointer type to contained elements. */
  27117. using const_pointer = typename alloc_traits::template rebind_traits<typename alloc_traits::const_pointer>::const_pointer;
  27118. /*! @brief Random access iterator type. */
  27119. using iterator = internal::storage_iterator<container_type>;
  27120. /*! @brief Constant random access iterator type. */
  27121. using const_iterator = internal::storage_iterator<const container_type>;
  27122. /*! @brief Reverse iterator type. */
  27123. using reverse_iterator = std::reverse_iterator<iterator>;
  27124. /*! @brief Constant reverse iterator type. */
  27125. using const_reverse_iterator = std::reverse_iterator<const_iterator>;
  27126. /*! @brief Extended iterable storage proxy. */
  27127. using iterable = iterable_adaptor<internal::extended_storage_iterator<typename base_type::iterator, iterator>>;
  27128. /*! @brief Constant extended iterable storage proxy. */
  27129. using const_iterable = iterable_adaptor<internal::extended_storage_iterator<typename base_type::const_iterator, const_iterator>>;
  27130. /*! @brief Default constructor. */
  27131. basic_storage()
  27132. : basic_storage{allocator_type{}} {}
  27133. /**
  27134. * @brief Constructs an empty storage with a given allocator.
  27135. * @param allocator The allocator to use.
  27136. */
  27137. explicit basic_storage(const allocator_type &allocator)
  27138. : base_type{type_id<value_type>(), deletion_policy{comp_traits::in_place_delete}, allocator},
  27139. packed{container_type{allocator}, allocator} {}
  27140. /**
  27141. * @brief Move constructor.
  27142. * @param other The instance to move from.
  27143. */
  27144. basic_storage(basic_storage &&other) ENTT_NOEXCEPT
  27145. : base_type{std::move(other)},
  27146. packed{std::move(other.packed)} {}
  27147. /**
  27148. * @brief Allocator-extended move constructor.
  27149. * @param other The instance to move from.
  27150. * @param allocator The allocator to use.
  27151. */
  27152. basic_storage(basic_storage &&other, const allocator_type &allocator) ENTT_NOEXCEPT
  27153. : base_type{std::move(other), allocator},
  27154. packed{container_type{std::move(other.packed.first()), allocator}, allocator} {
  27155. ENTT_ASSERT(alloc_traits::is_always_equal::value || packed.second() == other.packed.second(), "Copying a storage is not allowed");
  27156. }
  27157. /*! @brief Default destructor. */
  27158. ~basic_storage() override {
  27159. shrink_to_size(0u);
  27160. }
  27161. /**
  27162. * @brief Move assignment operator.
  27163. * @param other The instance to move from.
  27164. * @return This storage.
  27165. */
  27166. basic_storage &operator=(basic_storage &&other) ENTT_NOEXCEPT {
  27167. ENTT_ASSERT(alloc_traits::is_always_equal::value || packed.second() == other.packed.second(), "Copying a storage is not allowed");
  27168. shrink_to_size(0u);
  27169. base_type::operator=(std::move(other));
  27170. packed.first() = std::move(other.packed.first());
  27171. propagate_on_container_move_assignment(packed.second(), other.packed.second());
  27172. return *this;
  27173. }
  27174. /**
  27175. * @brief Exchanges the contents with those of a given storage.
  27176. * @param other Storage to exchange the content with.
  27177. */
  27178. void swap(basic_storage &other) {
  27179. using std::swap;
  27180. underlying_type::swap(other);
  27181. propagate_on_container_swap(packed.second(), other.packed.second());
  27182. swap(packed.first(), other.packed.first());
  27183. }
  27184. /**
  27185. * @brief Returns the associated allocator.
  27186. * @return The associated allocator.
  27187. */
  27188. [[nodiscard]] constexpr allocator_type get_allocator() const ENTT_NOEXCEPT {
  27189. return allocator_type{packed.second()};
  27190. }
  27191. /**
  27192. * @brief Increases the capacity of a storage.
  27193. *
  27194. * If the new capacity is greater than the current capacity, new storage is
  27195. * allocated, otherwise the method does nothing.
  27196. *
  27197. * @param cap Desired capacity.
  27198. */
  27199. void reserve(const size_type cap) override {
  27200. if(cap != 0u) {
  27201. base_type::reserve(cap);
  27202. assure_at_least(cap - 1u);
  27203. }
  27204. }
  27205. /**
  27206. * @brief Returns the number of elements that a storage has currently
  27207. * allocated space for.
  27208. * @return Capacity of the storage.
  27209. */
  27210. [[nodiscard]] size_type capacity() const ENTT_NOEXCEPT override {
  27211. return packed.first().size() * comp_traits::page_size;
  27212. }
  27213. /*! @brief Requests the removal of unused capacity. */
  27214. void shrink_to_fit() override {
  27215. base_type::shrink_to_fit();
  27216. shrink_to_size(base_type::size());
  27217. }
  27218. /**
  27219. * @brief Direct access to the array of objects.
  27220. * @return A pointer to the array of objects.
  27221. */
  27222. [[nodiscard]] const_pointer raw() const ENTT_NOEXCEPT {
  27223. return packed.first().data();
  27224. }
  27225. /*! @copydoc raw */
  27226. [[nodiscard]] pointer raw() ENTT_NOEXCEPT {
  27227. return packed.first().data();
  27228. }
  27229. /**
  27230. * @brief Returns an iterator to the beginning.
  27231. *
  27232. * The returned iterator points to the first instance of the internal array.
  27233. * If the storage is empty, the returned iterator will be equal to `end()`.
  27234. *
  27235. * @return An iterator to the first instance of the internal array.
  27236. */
  27237. [[nodiscard]] const_iterator cbegin() const ENTT_NOEXCEPT {
  27238. const auto pos = static_cast<typename iterator::difference_type>(base_type::size());
  27239. return const_iterator{&packed.first(), pos};
  27240. }
  27241. /*! @copydoc cbegin */
  27242. [[nodiscard]] const_iterator begin() const ENTT_NOEXCEPT {
  27243. return cbegin();
  27244. }
  27245. /*! @copydoc begin */
  27246. [[nodiscard]] iterator begin() ENTT_NOEXCEPT {
  27247. const auto pos = static_cast<typename iterator::difference_type>(base_type::size());
  27248. return iterator{&packed.first(), pos};
  27249. }
  27250. /**
  27251. * @brief Returns an iterator to the end.
  27252. *
  27253. * The returned iterator points to the element following the last instance
  27254. * of the internal array. Attempting to dereference the returned iterator
  27255. * results in undefined behavior.
  27256. *
  27257. * @return An iterator to the element following the last instance of the
  27258. * internal array.
  27259. */
  27260. [[nodiscard]] const_iterator cend() const ENTT_NOEXCEPT {
  27261. return const_iterator{&packed.first(), {}};
  27262. }
  27263. /*! @copydoc cend */
  27264. [[nodiscard]] const_iterator end() const ENTT_NOEXCEPT {
  27265. return cend();
  27266. }
  27267. /*! @copydoc end */
  27268. [[nodiscard]] iterator end() ENTT_NOEXCEPT {
  27269. return iterator{&packed.first(), {}};
  27270. }
  27271. /**
  27272. * @brief Returns a reverse iterator to the beginning.
  27273. *
  27274. * The returned iterator points to the first instance of the reversed
  27275. * internal array. If the storage is empty, the returned iterator will be
  27276. * equal to `rend()`.
  27277. *
  27278. * @return An iterator to the first instance of the reversed internal array.
  27279. */
  27280. [[nodiscard]] const_reverse_iterator crbegin() const ENTT_NOEXCEPT {
  27281. return std::make_reverse_iterator(cend());
  27282. }
  27283. /*! @copydoc crbegin */
  27284. [[nodiscard]] const_reverse_iterator rbegin() const ENTT_NOEXCEPT {
  27285. return crbegin();
  27286. }
  27287. /*! @copydoc rbegin */
  27288. [[nodiscard]] reverse_iterator rbegin() ENTT_NOEXCEPT {
  27289. return std::make_reverse_iterator(end());
  27290. }
  27291. /**
  27292. * @brief Returns a reverse iterator to the end.
  27293. *
  27294. * The returned iterator points to the element following the last instance
  27295. * of the reversed internal array. Attempting to dereference the returned
  27296. * iterator results in undefined behavior.
  27297. *
  27298. * @return An iterator to the element following the last instance of the
  27299. * reversed internal array.
  27300. */
  27301. [[nodiscard]] const_reverse_iterator crend() const ENTT_NOEXCEPT {
  27302. return std::make_reverse_iterator(cbegin());
  27303. }
  27304. /*! @copydoc crend */
  27305. [[nodiscard]] const_reverse_iterator rend() const ENTT_NOEXCEPT {
  27306. return crend();
  27307. }
  27308. /*! @copydoc rend */
  27309. [[nodiscard]] reverse_iterator rend() ENTT_NOEXCEPT {
  27310. return std::make_reverse_iterator(begin());
  27311. }
  27312. /**
  27313. * @brief Returns the object assigned to an entity.
  27314. *
  27315. * @warning
  27316. * Attempting to use an entity that doesn't belong to the storage results in
  27317. * undefined behavior.
  27318. *
  27319. * @param entt A valid identifier.
  27320. * @return The object assigned to the entity.
  27321. */
  27322. [[nodiscard]] const value_type &get(const entity_type entt) const ENTT_NOEXCEPT {
  27323. return element_at(base_type::index(entt));
  27324. }
  27325. /*! @copydoc get */
  27326. [[nodiscard]] value_type &get(const entity_type entt) ENTT_NOEXCEPT {
  27327. return const_cast<value_type &>(std::as_const(*this).get(entt));
  27328. }
  27329. /**
  27330. * @brief Returns the object assigned to an entity as a tuple.
  27331. * @param entt A valid identifier.
  27332. * @return The object assigned to the entity as a tuple.
  27333. */
  27334. [[nodiscard]] std::tuple<const value_type &> get_as_tuple(const entity_type entt) const ENTT_NOEXCEPT {
  27335. return std::forward_as_tuple(get(entt));
  27336. }
  27337. /*! @copydoc get_as_tuple */
  27338. [[nodiscard]] std::tuple<value_type &> get_as_tuple(const entity_type entt) ENTT_NOEXCEPT {
  27339. return std::forward_as_tuple(get(entt));
  27340. }
  27341. /**
  27342. * @brief Assigns an entity to a storage and constructs its object.
  27343. *
  27344. * @warning
  27345. * Attempting to use an entity that already belongs to the storage results
  27346. * in undefined behavior.
  27347. *
  27348. * @tparam Args Types of arguments to use to construct the object.
  27349. * @param entt A valid identifier.
  27350. * @param args Parameters to use to construct an object for the entity.
  27351. * @return A reference to the newly created object.
  27352. */
  27353. template<typename... Args>
  27354. value_type &emplace(const entity_type entt, Args &&...args) {
  27355. if constexpr(std::is_aggregate_v<value_type>) {
  27356. const auto it = emplace_element(entt, false, Type{std::forward<Args>(args)...});
  27357. return element_at(static_cast<size_type>(it.index()));
  27358. } else {
  27359. const auto it = emplace_element(entt, false, std::forward<Args>(args)...);
  27360. return element_at(static_cast<size_type>(it.index()));
  27361. }
  27362. }
  27363. /**
  27364. * @brief Updates the instance assigned to a given entity in-place.
  27365. * @tparam Func Types of the function objects to invoke.
  27366. * @param entt A valid identifier.
  27367. * @param func Valid function objects.
  27368. * @return A reference to the updated instance.
  27369. */
  27370. template<typename... Func>
  27371. value_type &patch(const entity_type entt, Func &&...func) {
  27372. const auto idx = base_type::index(entt);
  27373. auto &elem = element_at(idx);
  27374. (std::forward<Func>(func)(elem), ...);
  27375. return elem;
  27376. }
  27377. /**
  27378. * @brief Assigns one or more entities to a storage and constructs their
  27379. * objects from a given instance.
  27380. *
  27381. * @warning
  27382. * Attempting to assign an entity that already belongs to the storage
  27383. * results in undefined behavior.
  27384. *
  27385. * @tparam It Type of input iterator.
  27386. * @param first An iterator to the first element of the range of entities.
  27387. * @param last An iterator past the last element of the range of entities.
  27388. * @param value An instance of the object to construct.
  27389. */
  27390. template<typename It>
  27391. void insert(It first, It last, const value_type &value = {}) {
  27392. for(; first != last; ++first) {
  27393. emplace_element(*first, true, value);
  27394. }
  27395. }
  27396. /**
  27397. * @brief Assigns one or more entities to a storage and constructs their
  27398. * objects from a given range.
  27399. *
  27400. * @sa construct
  27401. *
  27402. * @tparam EIt Type of input iterator.
  27403. * @tparam CIt Type of input iterator.
  27404. * @param first An iterator to the first element of the range of entities.
  27405. * @param last An iterator past the last element of the range of entities.
  27406. * @param from An iterator to the first element of the range of objects.
  27407. */
  27408. template<typename EIt, typename CIt, typename = std::enable_if_t<std::is_same_v<typename std::iterator_traits<CIt>::value_type, value_type>>>
  27409. void insert(EIt first, EIt last, CIt from) {
  27410. for(; first != last; ++first, ++from) {
  27411. emplace_element(*first, true, *from);
  27412. }
  27413. }
  27414. /**
  27415. * @brief Returns an iterable object to use to _visit_ a storage.
  27416. *
  27417. * The iterable object returns a tuple that contains the current entity and
  27418. * a reference to its component.
  27419. *
  27420. * @return An iterable object to use to _visit_ the storage.
  27421. */
  27422. [[nodiscard]] iterable each() ENTT_NOEXCEPT {
  27423. return {internal::extended_storage_iterator{base_type::begin(), begin()}, internal::extended_storage_iterator{base_type::end(), end()}};
  27424. }
  27425. /*! @copydoc each */
  27426. [[nodiscard]] const_iterable each() const ENTT_NOEXCEPT {
  27427. return {internal::extended_storage_iterator{base_type::cbegin(), cbegin()}, internal::extended_storage_iterator{base_type::cend(), cend()}};
  27428. }
  27429. private:
  27430. compressed_pair<container_type, allocator_type> packed;
  27431. };
  27432. /*! @copydoc basic_storage */
  27433. template<typename Entity, typename Type, typename Allocator>
  27434. class basic_storage<Entity, Type, Allocator, std::enable_if_t<ignore_as_empty_v<Type>>>
  27435. : public basic_sparse_set<Entity, typename std::allocator_traits<Allocator>::template rebind_alloc<Entity>> {
  27436. using alloc_traits = std::allocator_traits<Allocator>;
  27437. static_assert(std::is_same_v<typename alloc_traits::value_type, Type>, "Invalid value type");
  27438. using underlying_type = basic_sparse_set<Entity, typename alloc_traits::template rebind_alloc<Entity>>;
  27439. using comp_traits = component_traits<Type>;
  27440. public:
  27441. /*! @brief Base type. */
  27442. using base_type = underlying_type;
  27443. /*! @brief Allocator type. */
  27444. using allocator_type = Allocator;
  27445. /*! @brief Type of the objects assigned to entities. */
  27446. using value_type = Type;
  27447. /*! @brief Underlying entity identifier. */
  27448. using entity_type = Entity;
  27449. /*! @brief Unsigned integer type. */
  27450. using size_type = std::size_t;
  27451. /*! @brief Extended iterable storage proxy. */
  27452. using iterable = iterable_adaptor<internal::extended_storage_iterator<typename base_type::iterator>>;
  27453. /*! @brief Constant extended iterable storage proxy. */
  27454. using const_iterable = iterable_adaptor<internal::extended_storage_iterator<typename base_type::const_iterator>>;
  27455. /*! @brief Default constructor. */
  27456. basic_storage()
  27457. : basic_storage{allocator_type{}} {}
  27458. /**
  27459. * @brief Constructs an empty container with a given allocator.
  27460. * @param allocator The allocator to use.
  27461. */
  27462. explicit basic_storage(const allocator_type &allocator)
  27463. : base_type{type_id<value_type>(), deletion_policy{comp_traits::in_place_delete}, allocator} {}
  27464. /**
  27465. * @brief Move constructor.
  27466. * @param other The instance to move from.
  27467. */
  27468. basic_storage(basic_storage &&other) ENTT_NOEXCEPT = default;
  27469. /**
  27470. * @brief Allocator-extended move constructor.
  27471. * @param other The instance to move from.
  27472. * @param allocator The allocator to use.
  27473. */
  27474. basic_storage(basic_storage &&other, const allocator_type &allocator) ENTT_NOEXCEPT
  27475. : base_type{std::move(other), allocator} {}
  27476. /**
  27477. * @brief Move assignment operator.
  27478. * @param other The instance to move from.
  27479. * @return This storage.
  27480. */
  27481. basic_storage &operator=(basic_storage &&other) ENTT_NOEXCEPT = default;
  27482. /**
  27483. * @brief Returns the associated allocator.
  27484. * @return The associated allocator.
  27485. */
  27486. [[nodiscard]] constexpr allocator_type get_allocator() const ENTT_NOEXCEPT {
  27487. return allocator_type{base_type::get_allocator()};
  27488. }
  27489. /**
  27490. * @brief Returns the object assigned to an entity, that is `void`.
  27491. *
  27492. * @warning
  27493. * Attempting to use an entity that doesn't belong to the storage results in
  27494. * undefined behavior.
  27495. *
  27496. * @param entt A valid identifier.
  27497. */
  27498. void get([[maybe_unused]] const entity_type entt) const ENTT_NOEXCEPT {
  27499. ENTT_ASSERT(base_type::contains(entt), "Storage does not contain entity");
  27500. }
  27501. /**
  27502. * @brief Returns an empty tuple.
  27503. *
  27504. * @warning
  27505. * Attempting to use an entity that doesn't belong to the storage results in
  27506. * undefined behavior.
  27507. *
  27508. * @param entt A valid identifier.
  27509. * @return Returns an empty tuple.
  27510. */
  27511. [[nodiscard]] std::tuple<> get_as_tuple([[maybe_unused]] const entity_type entt) const ENTT_NOEXCEPT {
  27512. ENTT_ASSERT(base_type::contains(entt), "Storage does not contain entity");
  27513. return std::tuple{};
  27514. }
  27515. /**
  27516. * @brief Assigns an entity to a storage and constructs its object.
  27517. *
  27518. * @warning
  27519. * Attempting to use an entity that already belongs to the storage results
  27520. * in undefined behavior.
  27521. *
  27522. * @tparam Args Types of arguments to use to construct the object.
  27523. * @param entt A valid identifier.
  27524. */
  27525. template<typename... Args>
  27526. void emplace(const entity_type entt, Args &&...) {
  27527. base_type::try_emplace(entt, false);
  27528. }
  27529. /**
  27530. * @brief Updates the instance assigned to a given entity in-place.
  27531. * @tparam Func Types of the function objects to invoke.
  27532. * @param entt A valid identifier.
  27533. * @param func Valid function objects.
  27534. */
  27535. template<typename... Func>
  27536. void patch([[maybe_unused]] const entity_type entt, Func &&...func) {
  27537. ENTT_ASSERT(base_type::contains(entt), "Storage does not contain entity");
  27538. (std::forward<Func>(func)(), ...);
  27539. }
  27540. /**
  27541. * @brief Assigns entities to a storage.
  27542. * @tparam It Type of input iterator.
  27543. * @tparam Args Types of optional arguments.
  27544. * @param first An iterator to the first element of the range of entities.
  27545. * @param last An iterator past the last element of the range of entities.
  27546. */
  27547. template<typename It, typename... Args>
  27548. void insert(It first, It last, Args &&...) {
  27549. for(; first != last; ++first) {
  27550. base_type::try_emplace(*first, true);
  27551. }
  27552. }
  27553. /**
  27554. * @brief Returns an iterable object to use to _visit_ a storage.
  27555. *
  27556. * The iterable object returns a tuple that contains the current entity.
  27557. *
  27558. * @return An iterable object to use to _visit_ the storage.
  27559. */
  27560. [[nodiscard]] iterable each() ENTT_NOEXCEPT {
  27561. return {internal::extended_storage_iterator{base_type::begin()}, internal::extended_storage_iterator{base_type::end()}};
  27562. }
  27563. /*! @copydoc each */
  27564. [[nodiscard]] const_iterable each() const ENTT_NOEXCEPT {
  27565. return {internal::extended_storage_iterator{base_type::cbegin()}, internal::extended_storage_iterator{base_type::cend()}};
  27566. }
  27567. };
  27568. /**
  27569. * @brief Provides a common way to access certain properties of storage types.
  27570. * @tparam Entity A valid entity type (see entt_traits for more details).
  27571. * @tparam Type Type of objects managed by the storage class.
  27572. */
  27573. template<typename Entity, typename Type, typename = void>
  27574. struct storage_traits {
  27575. /*! @brief Resulting type after component-to-storage conversion. */
  27576. using storage_type = sigh_storage_mixin<basic_storage<Entity, Type>>;
  27577. };
  27578. } // namespace entt
  27579. #endif
  27580. // #include "entity/utility.hpp"
  27581. #ifndef ENTT_ENTITY_UTILITY_HPP
  27582. #define ENTT_ENTITY_UTILITY_HPP
  27583. // #include "../core/type_traits.hpp"
  27584. namespace entt {
  27585. /**
  27586. * @brief Alias for exclusion lists.
  27587. * @tparam Type List of types.
  27588. */
  27589. template<typename... Type>
  27590. struct exclude_t: type_list<Type...> {};
  27591. /**
  27592. * @brief Variable template for exclusion lists.
  27593. * @tparam Type List of types.
  27594. */
  27595. template<typename... Type>
  27596. inline constexpr exclude_t<Type...> exclude{};
  27597. /**
  27598. * @brief Alias for lists of observed components.
  27599. * @tparam Type List of types.
  27600. */
  27601. template<typename... Type>
  27602. struct get_t: type_list<Type...> {};
  27603. /**
  27604. * @brief Variable template for lists of observed components.
  27605. * @tparam Type List of types.
  27606. */
  27607. template<typename... Type>
  27608. inline constexpr get_t<Type...> get{};
  27609. /**
  27610. * @brief Alias for lists of owned components.
  27611. * @tparam Type List of types.
  27612. */
  27613. template<typename... Type>
  27614. struct owned_t: type_list<Type...> {};
  27615. /**
  27616. * @brief Variable template for lists of owned components.
  27617. * @tparam Type List of types.
  27618. */
  27619. template<typename... Type>
  27620. inline constexpr owned_t<Type...> owned{};
  27621. } // namespace entt
  27622. #endif
  27623. // #include "entity/view.hpp"
  27624. #ifndef ENTT_ENTITY_VIEW_HPP
  27625. #define ENTT_ENTITY_VIEW_HPP
  27626. #include <algorithm>
  27627. #include <array>
  27628. #include <iterator>
  27629. #include <tuple>
  27630. #include <type_traits>
  27631. #include <utility>
  27632. // #include "../config/config.h"
  27633. // #include "../core/iterator.hpp"
  27634. // #include "../core/type_traits.hpp"
  27635. // #include "component.hpp"
  27636. // #include "entity.hpp"
  27637. // #include "fwd.hpp"
  27638. // #include "sparse_set.hpp"
  27639. // #include "storage.hpp"
  27640. // #include "utility.hpp"
  27641. namespace entt {
  27642. /**
  27643. * @cond TURN_OFF_DOXYGEN
  27644. * Internal details not to be documented.
  27645. */
  27646. namespace internal {
  27647. template<typename Type, std::size_t Component, std::size_t Exclude>
  27648. class view_iterator final {
  27649. using iterator_type = typename Type::const_iterator;
  27650. [[nodiscard]] bool valid() const ENTT_NOEXCEPT {
  27651. return ((Component != 0u) || (*it != tombstone))
  27652. && std::apply([entt = *it](const auto *...curr) { return (curr->contains(entt) && ...); }, pools)
  27653. && std::apply([entt = *it](const auto *...curr) { return (!curr->contains(entt) && ...); }, filter);
  27654. }
  27655. public:
  27656. using value_type = typename iterator_type::value_type;
  27657. using pointer = typename iterator_type::pointer;
  27658. using reference = typename iterator_type::reference;
  27659. using difference_type = typename iterator_type::difference_type;
  27660. using iterator_category = std::forward_iterator_tag;
  27661. view_iterator() ENTT_NOEXCEPT = default;
  27662. view_iterator(iterator_type curr, iterator_type to, std::array<const Type *, Component> all_of, std::array<const Type *, Exclude> none_of) ENTT_NOEXCEPT
  27663. : it{curr},
  27664. last{to},
  27665. pools{all_of},
  27666. filter{none_of} {
  27667. if(it != last && !valid()) {
  27668. ++(*this);
  27669. }
  27670. }
  27671. view_iterator &operator++() ENTT_NOEXCEPT {
  27672. while(++it != last && !valid()) {}
  27673. return *this;
  27674. }
  27675. view_iterator operator++(int) ENTT_NOEXCEPT {
  27676. view_iterator orig = *this;
  27677. return ++(*this), orig;
  27678. }
  27679. [[nodiscard]] pointer operator->() const ENTT_NOEXCEPT {
  27680. return &*it;
  27681. }
  27682. [[nodiscard]] reference operator*() const ENTT_NOEXCEPT {
  27683. return *operator->();
  27684. }
  27685. template<typename LhsType, auto... LhsArgs, typename RhsType, auto... RhsArgs>
  27686. friend bool operator==(const view_iterator<LhsType, LhsArgs...> &, const view_iterator<RhsType, RhsArgs...> &) ENTT_NOEXCEPT;
  27687. private:
  27688. iterator_type it;
  27689. iterator_type last;
  27690. std::array<const Type *, Component> pools;
  27691. std::array<const Type *, Exclude> filter;
  27692. };
  27693. template<typename LhsType, auto... LhsArgs, typename RhsType, auto... RhsArgs>
  27694. [[nodiscard]] bool operator==(const view_iterator<LhsType, LhsArgs...> &lhs, const view_iterator<RhsType, RhsArgs...> &rhs) ENTT_NOEXCEPT {
  27695. return lhs.it == rhs.it;
  27696. }
  27697. template<typename LhsType, auto... LhsArgs, typename RhsType, auto... RhsArgs>
  27698. [[nodiscard]] bool operator!=(const view_iterator<LhsType, LhsArgs...> &lhs, const view_iterator<RhsType, RhsArgs...> &rhs) ENTT_NOEXCEPT {
  27699. return !(lhs == rhs);
  27700. }
  27701. template<typename It, typename... Storage>
  27702. struct extended_view_iterator final {
  27703. using difference_type = std::ptrdiff_t;
  27704. using value_type = decltype(std::tuple_cat(std::make_tuple(*std::declval<It>()), std::declval<Storage>().get_as_tuple({})...));
  27705. using pointer = input_iterator_pointer<value_type>;
  27706. using reference = value_type;
  27707. using iterator_category = std::input_iterator_tag;
  27708. extended_view_iterator() = default;
  27709. extended_view_iterator(It from, std::tuple<Storage *...> storage)
  27710. : it{from},
  27711. pools{storage} {}
  27712. extended_view_iterator &operator++() ENTT_NOEXCEPT {
  27713. return ++it, *this;
  27714. }
  27715. extended_view_iterator operator++(int) ENTT_NOEXCEPT {
  27716. extended_view_iterator orig = *this;
  27717. return ++(*this), orig;
  27718. }
  27719. [[nodiscard]] reference operator*() const ENTT_NOEXCEPT {
  27720. return std::apply([entt = *it](auto *...curr) { return std::tuple_cat(std::make_tuple(entt), curr->get_as_tuple(entt)...); }, pools);
  27721. }
  27722. [[nodiscard]] pointer operator->() const ENTT_NOEXCEPT {
  27723. return operator*();
  27724. }
  27725. template<typename... Lhs, typename... Rhs>
  27726. friend bool operator==(const extended_view_iterator<Lhs...> &, const extended_view_iterator<Rhs...> &) ENTT_NOEXCEPT;
  27727. private:
  27728. It it;
  27729. std::tuple<Storage *...> pools;
  27730. };
  27731. template<typename... Lhs, typename... Rhs>
  27732. [[nodiscard]] bool operator==(const extended_view_iterator<Lhs...> &lhs, const extended_view_iterator<Rhs...> &rhs) ENTT_NOEXCEPT {
  27733. return lhs.it == rhs.it;
  27734. }
  27735. template<typename... Lhs, typename... Rhs>
  27736. [[nodiscard]] bool operator!=(const extended_view_iterator<Lhs...> &lhs, const extended_view_iterator<Rhs...> &rhs) ENTT_NOEXCEPT {
  27737. return !(lhs == rhs);
  27738. }
  27739. } // namespace internal
  27740. /**
  27741. * Internal details not to be documented.
  27742. * @endcond
  27743. */
  27744. /**
  27745. * @brief View implementation.
  27746. *
  27747. * Primary template isn't defined on purpose. All the specializations give a
  27748. * compile-time error, but for a few reasonable cases.
  27749. */
  27750. template<typename, typename, typename, typename>
  27751. class basic_view;
  27752. /**
  27753. * @brief Multi component view.
  27754. *
  27755. * Multi component views iterate over those entities that have at least all the
  27756. * given components in their bags. During initialization, a multi component view
  27757. * looks at the number of entities available for each component and uses the
  27758. * smallest set in order to get a performance boost when iterate.
  27759. *
  27760. * @b Important
  27761. *
  27762. * Iterators aren't invalidated if:
  27763. *
  27764. * * New instances of the given components are created and assigned to entities.
  27765. * * The entity currently pointed is modified (as an example, if one of the
  27766. * given components is removed from the entity to which the iterator points).
  27767. * * The entity currently pointed is destroyed.
  27768. *
  27769. * In all other cases, modifying the pools iterated by the view in any way
  27770. * invalidates all the iterators and using them results in undefined behavior.
  27771. *
  27772. * @tparam Entity A valid entity type (see entt_traits for more details).
  27773. * @tparam Component Types of components iterated by the view.
  27774. * @tparam Exclude Types of components used to filter the view.
  27775. */
  27776. template<typename Entity, typename... Component, typename... Exclude>
  27777. class basic_view<Entity, get_t<Component...>, exclude_t<Exclude...>> {
  27778. template<typename, typename, typename, typename>
  27779. friend class basic_view;
  27780. template<typename Comp>
  27781. using storage_type = constness_as_t<typename storage_traits<Entity, std::remove_const_t<Comp>>::storage_type, Comp>;
  27782. template<std::size_t... Index>
  27783. [[nodiscard]] auto pools_to_array(std::index_sequence<Index...>) const ENTT_NOEXCEPT {
  27784. std::size_t pos{};
  27785. std::array<const base_type *, sizeof...(Component) - 1u> other{};
  27786. (static_cast<void>(std::get<Index>(pools) == view ? void() : void(other[pos++] = std::get<Index>(pools))), ...);
  27787. return other;
  27788. }
  27789. template<std::size_t Comp, std::size_t Other, typename... Args>
  27790. [[nodiscard]] auto dispatch_get(const std::tuple<Entity, Args...> &curr) const {
  27791. if constexpr(Comp == Other) {
  27792. return std::forward_as_tuple(std::get<Args>(curr)...);
  27793. } else {
  27794. return std::get<Other>(pools)->get_as_tuple(std::get<0>(curr));
  27795. }
  27796. }
  27797. template<std::size_t Comp, typename Func, std::size_t... Index>
  27798. void each(Func func, std::index_sequence<Index...>) const {
  27799. for(const auto curr: std::get<Comp>(pools)->each()) {
  27800. const auto entt = std::get<0>(curr);
  27801. if(((sizeof...(Component) != 1u) || (entt != tombstone))
  27802. && ((Comp == Index || std::get<Index>(pools)->contains(entt)) && ...)
  27803. && std::apply([entt](const auto *...cpool) { return (!cpool->contains(entt) && ...); }, filter)) {
  27804. if constexpr(is_applicable_v<Func, decltype(std::tuple_cat(std::tuple<entity_type>{}, std::declval<basic_view>().get({})))>) {
  27805. std::apply(func, std::tuple_cat(std::make_tuple(entt), dispatch_get<Comp, Index>(curr)...));
  27806. } else {
  27807. std::apply(func, std::tuple_cat(dispatch_get<Comp, Index>(curr)...));
  27808. }
  27809. }
  27810. }
  27811. }
  27812. template<typename Func, std::size_t... Index>
  27813. void pick_and_each(Func func, std::index_sequence<Index...> seq) const {
  27814. ((std::get<Index>(pools) == view ? each<Index>(std::move(func), seq) : void()), ...);
  27815. }
  27816. public:
  27817. /*! @brief Underlying entity identifier. */
  27818. using entity_type = Entity;
  27819. /*! @brief Unsigned integer type. */
  27820. using size_type = std::size_t;
  27821. /*! @brief Common type among all storage types. */
  27822. using base_type = std::common_type_t<typename storage_type<Component>::base_type...>;
  27823. /*! @brief Bidirectional iterator type. */
  27824. using iterator = internal::view_iterator<base_type, sizeof...(Component) - 1u, sizeof...(Exclude)>;
  27825. /*! @brief Iterable view type. */
  27826. using iterable = iterable_adaptor<internal::extended_view_iterator<iterator, storage_type<Component>...>>;
  27827. /*! @brief Default constructor to use to create empty, invalid views. */
  27828. basic_view() ENTT_NOEXCEPT
  27829. : pools{},
  27830. filter{},
  27831. view{} {}
  27832. /**
  27833. * @brief Constructs a multi-type view from a set of storage classes.
  27834. * @param component The storage for the types to iterate.
  27835. * @param epool The storage for the types used to filter the view.
  27836. */
  27837. basic_view(storage_type<Component> &...component, const storage_type<Exclude> &...epool) ENTT_NOEXCEPT
  27838. : pools{&component...},
  27839. filter{&epool...},
  27840. view{(std::min)({&static_cast<const base_type &>(component)...}, [](auto *lhs, auto *rhs) { return lhs->size() < rhs->size(); })} {}
  27841. /**
  27842. * @brief Creates a new view driven by a given component in its iterations.
  27843. * @tparam Comp Type of component used to drive the iteration.
  27844. * @return A new view driven by the given component in its iterations.
  27845. */
  27846. template<typename Comp>
  27847. [[nodiscard]] basic_view use() const ENTT_NOEXCEPT {
  27848. basic_view other{*this};
  27849. other.view = std::get<storage_type<Comp> *>(pools);
  27850. return other;
  27851. }
  27852. /**
  27853. * @brief Creates a new view driven by a given component in its iterations.
  27854. * @tparam Comp Index of the component used to drive the iteration.
  27855. * @return A new view driven by the given component in its iterations.
  27856. */
  27857. template<std::size_t Comp>
  27858. [[nodiscard]] basic_view use() const ENTT_NOEXCEPT {
  27859. basic_view other{*this};
  27860. other.view = std::get<Comp>(pools);
  27861. return other;
  27862. }
  27863. /**
  27864. * @brief Returns the leading storage of a view.
  27865. * @return The leading storage of the view.
  27866. */
  27867. const base_type &handle() const ENTT_NOEXCEPT {
  27868. return *view;
  27869. }
  27870. /**
  27871. * @brief Returns the storage for a given component type.
  27872. * @tparam Comp Type of component of which to return the storage.
  27873. * @return The storage for the given component type.
  27874. */
  27875. template<typename Comp>
  27876. [[nodiscard]] decltype(auto) storage() const ENTT_NOEXCEPT {
  27877. return *std::get<storage_type<Comp> *>(pools);
  27878. }
  27879. /**
  27880. * @brief Returns the storage for a given component type.
  27881. * @tparam Comp Index of component of which to return the storage.
  27882. * @return The storage for the given component type.
  27883. */
  27884. template<std::size_t Comp>
  27885. [[nodiscard]] decltype(auto) storage() const ENTT_NOEXCEPT {
  27886. return *std::get<Comp>(pools);
  27887. }
  27888. /**
  27889. * @brief Estimates the number of entities iterated by the view.
  27890. * @return Estimated number of entities iterated by the view.
  27891. */
  27892. [[nodiscard]] size_type size_hint() const ENTT_NOEXCEPT {
  27893. return view->size();
  27894. }
  27895. /**
  27896. * @brief Returns an iterator to the first entity of the view.
  27897. *
  27898. * The returned iterator points to the first entity of the view. If the view
  27899. * is empty, the returned iterator will be equal to `end()`.
  27900. *
  27901. * @return An iterator to the first entity of the view.
  27902. */
  27903. [[nodiscard]] iterator begin() const ENTT_NOEXCEPT {
  27904. return iterator{view->begin(), view->end(), pools_to_array(std::index_sequence_for<Component...>{}), filter};
  27905. }
  27906. /**
  27907. * @brief Returns an iterator that is past the last entity of the view.
  27908. *
  27909. * The returned iterator points to the entity following the last entity of
  27910. * the view. Attempting to dereference the returned iterator results in
  27911. * undefined behavior.
  27912. *
  27913. * @return An iterator to the entity following the last entity of the view.
  27914. */
  27915. [[nodiscard]] iterator end() const ENTT_NOEXCEPT {
  27916. return iterator{view->end(), view->end(), pools_to_array(std::index_sequence_for<Component...>{}), filter};
  27917. }
  27918. /**
  27919. * @brief Returns the first entity of the view, if any.
  27920. * @return The first entity of the view if one exists, the null entity
  27921. * otherwise.
  27922. */
  27923. [[nodiscard]] entity_type front() const ENTT_NOEXCEPT {
  27924. const auto it = begin();
  27925. return it != end() ? *it : null;
  27926. }
  27927. /**
  27928. * @brief Returns the last entity of the view, if any.
  27929. * @return The last entity of the view if one exists, the null entity
  27930. * otherwise.
  27931. */
  27932. [[nodiscard]] entity_type back() const ENTT_NOEXCEPT {
  27933. auto it = view->rbegin();
  27934. for(const auto last = view->rend(); it != last && !contains(*it); ++it) {}
  27935. return it == view->rend() ? null : *it;
  27936. }
  27937. /**
  27938. * @brief Finds an entity.
  27939. * @param entt A valid identifier.
  27940. * @return An iterator to the given entity if it's found, past the end
  27941. * iterator otherwise.
  27942. */
  27943. [[nodiscard]] iterator find(const entity_type entt) const ENTT_NOEXCEPT {
  27944. return contains(entt) ? iterator{view->find(entt), view->end(), pools_to_array(std::index_sequence_for<Component...>{}), filter} : end();
  27945. }
  27946. /**
  27947. * @brief Returns the components assigned to the given entity.
  27948. * @param entt A valid identifier.
  27949. * @return The components assigned to the given entity.
  27950. */
  27951. [[nodiscard]] decltype(auto) operator[](const entity_type entt) const {
  27952. return get<Component...>(entt);
  27953. }
  27954. /**
  27955. * @brief Checks if a view is properly initialized.
  27956. * @return True if the view is properly initialized, false otherwise.
  27957. */
  27958. [[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
  27959. return view != nullptr;
  27960. }
  27961. /**
  27962. * @brief Checks if a view contains an entity.
  27963. * @param entt A valid identifier.
  27964. * @return True if the view contains the given entity, false otherwise.
  27965. */
  27966. [[nodiscard]] bool contains(const entity_type entt) const ENTT_NOEXCEPT {
  27967. return std::apply([entt](const auto *...curr) { return (curr->contains(entt) && ...); }, pools)
  27968. && std::apply([entt](const auto *...curr) { return (!curr->contains(entt) && ...); }, filter);
  27969. }
  27970. /**
  27971. * @brief Returns the components assigned to the given entity.
  27972. *
  27973. * @warning
  27974. * Attempting to use an entity that doesn't belong to the view results in
  27975. * undefined behavior.
  27976. *
  27977. * @tparam Comp Types of components to get.
  27978. * @param entt A valid identifier.
  27979. * @return The components assigned to the entity.
  27980. */
  27981. template<typename... Comp>
  27982. [[nodiscard]] decltype(auto) get(const entity_type entt) const {
  27983. ENTT_ASSERT(contains(entt), "View does not contain entity");
  27984. if constexpr(sizeof...(Comp) == 0) {
  27985. return std::apply([entt](auto *...curr) { return std::tuple_cat(curr->get_as_tuple(entt)...); }, pools);
  27986. } else if constexpr(sizeof...(Comp) == 1) {
  27987. return (std::get<storage_type<Comp> *>(pools)->get(entt), ...);
  27988. } else {
  27989. return std::tuple_cat(std::get<storage_type<Comp> *>(pools)->get_as_tuple(entt)...);
  27990. }
  27991. }
  27992. /**
  27993. * @brief Returns the components assigned to the given entity.
  27994. *
  27995. * @warning
  27996. * Attempting to use an entity that doesn't belong to the view results in
  27997. * undefined behavior.
  27998. *
  27999. * @tparam First Index of a component to get.
  28000. * @tparam Other Indexes of other components to get.
  28001. * @param entt A valid identifier.
  28002. * @return The components assigned to the entity.
  28003. */
  28004. template<std::size_t First, std::size_t... Other>
  28005. [[nodiscard]] decltype(auto) get(const entity_type entt) const {
  28006. ENTT_ASSERT(contains(entt), "View does not contain entity");
  28007. if constexpr(sizeof...(Other) == 0) {
  28008. return std::get<First>(pools)->get(entt);
  28009. } else {
  28010. return std::tuple_cat(std::get<First>(pools)->get_as_tuple(entt), std::get<Other>(pools)->get_as_tuple(entt)...);
  28011. }
  28012. }
  28013. /**
  28014. * @brief Iterates entities and components and applies the given function
  28015. * object to them.
  28016. *
  28017. * The function object is invoked for each entity. It is provided with the
  28018. * entity itself and a set of references to non-empty components. The
  28019. * _constness_ of the components is as requested.<br/>
  28020. * The signature of the function must be equivalent to one of the following
  28021. * forms:
  28022. *
  28023. * @code{.cpp}
  28024. * void(const entity_type, Type &...);
  28025. * void(Type &...);
  28026. * @endcode
  28027. *
  28028. * @tparam Func Type of the function object to invoke.
  28029. * @param func A valid function object.
  28030. */
  28031. template<typename Func>
  28032. void each(Func func) const {
  28033. pick_and_each(std::move(func), std::index_sequence_for<Component...>{});
  28034. }
  28035. /**
  28036. * @brief Returns an iterable object to use to _visit_ a view.
  28037. *
  28038. * The iterable object returns a tuple that contains the current entity and
  28039. * a set of references to its non-empty components. The _constness_ of the
  28040. * components is as requested.
  28041. *
  28042. * @return An iterable object to use to _visit_ the view.
  28043. */
  28044. [[nodiscard]] iterable each() const ENTT_NOEXCEPT {
  28045. return {internal::extended_view_iterator{begin(), pools}, internal::extended_view_iterator{end(), pools}};
  28046. }
  28047. /**
  28048. * @brief Combines two views in a _more specific_ one (friend function).
  28049. * @tparam Get Component list of the view to combine with.
  28050. * @tparam Excl Filter list of the view to combine with.
  28051. * @param other The view to combine with.
  28052. * @return A more specific view.
  28053. */
  28054. template<typename... Get, typename... Excl>
  28055. [[nodiscard]] auto operator|(const basic_view<Entity, get_t<Get...>, exclude_t<Excl...>> &other) const ENTT_NOEXCEPT {
  28056. using view_type = basic_view<Entity, get_t<Component..., Get...>, exclude_t<Exclude..., Excl...>>;
  28057. return std::make_from_tuple<view_type>(std::tuple_cat(
  28058. std::apply([](auto *...curr) { return std::forward_as_tuple(*curr...); }, pools),
  28059. std::apply([](auto *...curr) { return std::forward_as_tuple(*curr...); }, other.pools),
  28060. std::apply([](const auto *...curr) { return std::forward_as_tuple(static_cast<const storage_type<Exclude> &>(*curr)...); }, filter),
  28061. std::apply([](const auto *...curr) { return std::forward_as_tuple(static_cast<const storage_type<Excl> &>(*curr)...); }, other.filter)));
  28062. }
  28063. private:
  28064. std::tuple<storage_type<Component> *...> pools;
  28065. std::array<const base_type *, sizeof...(Exclude)> filter;
  28066. const base_type *view;
  28067. };
  28068. /**
  28069. * @brief Single component view specialization.
  28070. *
  28071. * Single component views are specialized in order to get a boost in terms of
  28072. * performance. This kind of views can access the underlying data structure
  28073. * directly and avoid superfluous checks.
  28074. *
  28075. * @b Important
  28076. *
  28077. * Iterators aren't invalidated if:
  28078. *
  28079. * * New instances of the given component are created and assigned to entities.
  28080. * * The entity currently pointed is modified (as an example, the given
  28081. * component is removed from the entity to which the iterator points).
  28082. * * The entity currently pointed is destroyed.
  28083. *
  28084. * In all other cases, modifying the pool iterated by the view in any way
  28085. * invalidates all the iterators and using them results in undefined behavior.
  28086. *
  28087. * @tparam Entity A valid entity type (see entt_traits for more details).
  28088. * @tparam Component Type of component iterated by the view.
  28089. */
  28090. template<typename Entity, typename Component>
  28091. class basic_view<Entity, get_t<Component>, exclude_t<>, std::void_t<std::enable_if_t<!component_traits<std::remove_const_t<Component>>::in_place_delete>>> {
  28092. template<typename, typename, typename, typename>
  28093. friend class basic_view;
  28094. using storage_type = constness_as_t<typename storage_traits<Entity, std::remove_const_t<Component>>::storage_type, Component>;
  28095. public:
  28096. /*! @brief Underlying entity identifier. */
  28097. using entity_type = Entity;
  28098. /*! @brief Unsigned integer type. */
  28099. using size_type = std::size_t;
  28100. /*! @brief Common type among all storage types. */
  28101. using base_type = typename storage_type::base_type;
  28102. /*! @brief Random access iterator type. */
  28103. using iterator = typename base_type::iterator;
  28104. /*! @brief Reversed iterator type. */
  28105. using reverse_iterator = typename base_type::reverse_iterator;
  28106. /*! @brief Iterable view type. */
  28107. using iterable = decltype(std::declval<storage_type>().each());
  28108. /*! @brief Default constructor to use to create empty, invalid views. */
  28109. basic_view() ENTT_NOEXCEPT
  28110. : pools{},
  28111. filter{},
  28112. view{} {}
  28113. /**
  28114. * @brief Constructs a single-type view from a storage class.
  28115. * @param ref The storage for the type to iterate.
  28116. */
  28117. basic_view(storage_type &ref) ENTT_NOEXCEPT
  28118. : pools{&ref},
  28119. filter{},
  28120. view{&ref} {}
  28121. /**
  28122. * @brief Returns the leading storage of a view.
  28123. * @return The leading storage of the view.
  28124. */
  28125. const base_type &handle() const ENTT_NOEXCEPT {
  28126. return *view;
  28127. }
  28128. /**
  28129. * @brief Returns the storage for a given component type.
  28130. * @tparam Comp Type of component of which to return the storage.
  28131. * @return The storage for the given component type.
  28132. */
  28133. template<typename Comp = Component>
  28134. [[nodiscard]] decltype(auto) storage() const ENTT_NOEXCEPT {
  28135. static_assert(std::is_same_v<Comp, Component>, "Invalid component type");
  28136. return *std::get<0>(pools);
  28137. }
  28138. /**
  28139. * @brief Returns the storage for a given component type.
  28140. * @tparam Comp Index of component of which to return the storage.
  28141. * @return The storage for the given component type.
  28142. */
  28143. template<std::size_t Comp>
  28144. [[nodiscard]] decltype(auto) storage() const ENTT_NOEXCEPT {
  28145. return *std::get<Comp>(pools);
  28146. }
  28147. /**
  28148. * @brief Returns the number of entities that have the given component.
  28149. * @return Number of entities that have the given component.
  28150. */
  28151. [[nodiscard]] size_type size() const ENTT_NOEXCEPT {
  28152. return view->size();
  28153. }
  28154. /**
  28155. * @brief Checks whether a view is empty.
  28156. * @return True if the view is empty, false otherwise.
  28157. */
  28158. [[nodiscard]] bool empty() const ENTT_NOEXCEPT {
  28159. return view->empty();
  28160. }
  28161. /**
  28162. * @brief Returns an iterator to the first entity of the view.
  28163. *
  28164. * The returned iterator points to the first entity of the view. If the view
  28165. * is empty, the returned iterator will be equal to `end()`.
  28166. *
  28167. * @return An iterator to the first entity of the view.
  28168. */
  28169. [[nodiscard]] iterator begin() const ENTT_NOEXCEPT {
  28170. return view->begin();
  28171. }
  28172. /**
  28173. * @brief Returns an iterator that is past the last entity of the view.
  28174. *
  28175. * The returned iterator points to the entity following the last entity of
  28176. * the view. Attempting to dereference the returned iterator results in
  28177. * undefined behavior.
  28178. *
  28179. * @return An iterator to the entity following the last entity of the view.
  28180. */
  28181. [[nodiscard]] iterator end() const ENTT_NOEXCEPT {
  28182. return view->end();
  28183. }
  28184. /**
  28185. * @brief Returns an iterator to the first entity of the reversed view.
  28186. *
  28187. * The returned iterator points to the first entity of the reversed view. If
  28188. * the view is empty, the returned iterator will be equal to `rend()`.
  28189. *
  28190. * @return An iterator to the first entity of the reversed view.
  28191. */
  28192. [[nodiscard]] reverse_iterator rbegin() const ENTT_NOEXCEPT {
  28193. return view->rbegin();
  28194. }
  28195. /**
  28196. * @brief Returns an iterator that is past the last entity of the reversed
  28197. * view.
  28198. *
  28199. * The returned iterator points to the entity following the last entity of
  28200. * the reversed view. Attempting to dereference the returned iterator
  28201. * results in undefined behavior.
  28202. *
  28203. * @return An iterator to the entity following the last entity of the
  28204. * reversed view.
  28205. */
  28206. [[nodiscard]] reverse_iterator rend() const ENTT_NOEXCEPT {
  28207. return view->rend();
  28208. }
  28209. /**
  28210. * @brief Returns the first entity of the view, if any.
  28211. * @return The first entity of the view if one exists, the null entity
  28212. * otherwise.
  28213. */
  28214. [[nodiscard]] entity_type front() const ENTT_NOEXCEPT {
  28215. return empty() ? null : *begin();
  28216. }
  28217. /**
  28218. * @brief Returns the last entity of the view, if any.
  28219. * @return The last entity of the view if one exists, the null entity
  28220. * otherwise.
  28221. */
  28222. [[nodiscard]] entity_type back() const ENTT_NOEXCEPT {
  28223. return empty() ? null : *rbegin();
  28224. }
  28225. /**
  28226. * @brief Finds an entity.
  28227. * @param entt A valid identifier.
  28228. * @return An iterator to the given entity if it's found, past the end
  28229. * iterator otherwise.
  28230. */
  28231. [[nodiscard]] iterator find(const entity_type entt) const ENTT_NOEXCEPT {
  28232. return contains(entt) ? view->find(entt) : end();
  28233. }
  28234. /**
  28235. * @brief Returns the identifier that occupies the given position.
  28236. * @param pos Position of the element to return.
  28237. * @return The identifier that occupies the given position.
  28238. */
  28239. [[nodiscard]] entity_type operator[](const size_type pos) const {
  28240. return begin()[pos];
  28241. }
  28242. /**
  28243. * @brief Returns the component assigned to the given entity.
  28244. * @param entt A valid identifier.
  28245. * @return The component assigned to the given entity.
  28246. */
  28247. [[nodiscard]] decltype(auto) operator[](const entity_type entt) const {
  28248. return get<Component>(entt);
  28249. }
  28250. /**
  28251. * @brief Checks if a view is properly initialized.
  28252. * @return True if the view is properly initialized, false otherwise.
  28253. */
  28254. [[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
  28255. return view != nullptr;
  28256. }
  28257. /**
  28258. * @brief Checks if a view contains an entity.
  28259. * @param entt A valid identifier.
  28260. * @return True if the view contains the given entity, false otherwise.
  28261. */
  28262. [[nodiscard]] bool contains(const entity_type entt) const ENTT_NOEXCEPT {
  28263. return view->contains(entt);
  28264. }
  28265. /**
  28266. * @brief Returns the component assigned to the given entity.
  28267. *
  28268. * @warning
  28269. * Attempting to use an entity that doesn't belong to the view results in
  28270. * undefined behavior.
  28271. *
  28272. * @tparam Comp Type or index of the component to get.
  28273. * @param entt A valid identifier.
  28274. * @return The component assigned to the entity.
  28275. */
  28276. template<typename... Comp>
  28277. [[nodiscard]] decltype(auto) get(const entity_type entt) const {
  28278. ENTT_ASSERT(contains(entt), "View does not contain entity");
  28279. if constexpr(sizeof...(Comp) == 0) {
  28280. return std::get<0>(pools)->get_as_tuple(entt);
  28281. } else {
  28282. static_assert(std::is_same_v<Comp..., Component>, "Invalid component type");
  28283. return std::get<0>(pools)->get(entt);
  28284. }
  28285. }
  28286. /*! @copydoc get */
  28287. template<std::size_t Comp>
  28288. [[nodiscard]] decltype(auto) get(const entity_type entt) const {
  28289. ENTT_ASSERT(contains(entt), "View does not contain entity");
  28290. return std::get<0>(pools)->get(entt);
  28291. }
  28292. /**
  28293. * @brief Iterates entities and components and applies the given function
  28294. * object to them.
  28295. *
  28296. * The function object is invoked for each entity. It is provided with the
  28297. * entity itself and a reference to the component if it's a non-empty one.
  28298. * The _constness_ of the component is as requested.<br/>
  28299. * The signature of the function must be equivalent to one of the following
  28300. * forms:
  28301. *
  28302. * @code{.cpp}
  28303. * void(const entity_type, Component &);
  28304. * void(Component &);
  28305. * @endcode
  28306. *
  28307. * @tparam Func Type of the function object to invoke.
  28308. * @param func A valid function object.
  28309. */
  28310. template<typename Func>
  28311. void each(Func func) const {
  28312. if constexpr(is_applicable_v<Func, decltype(*each().begin())>) {
  28313. for(const auto pack: each()) {
  28314. std::apply(func, pack);
  28315. }
  28316. } else if constexpr(std::is_invocable_v<Func, Component &>) {
  28317. for(auto &&component: *std::get<0>(pools)) {
  28318. func(component);
  28319. }
  28320. } else if constexpr(std::is_invocable_v<Func, Entity>) {
  28321. for(auto entity: *view) {
  28322. func(entity);
  28323. }
  28324. } else {
  28325. for(size_type pos{}, last = size(); pos < last; ++pos) {
  28326. func();
  28327. }
  28328. }
  28329. }
  28330. /**
  28331. * @brief Returns an iterable object to use to _visit_ a view.
  28332. *
  28333. * The iterable object returns a tuple that contains the current entity and
  28334. * a reference to its component if it's a non-empty one. The _constness_ of
  28335. * the component is as requested.
  28336. *
  28337. * @return An iterable object to use to _visit_ the view.
  28338. */
  28339. [[nodiscard]] iterable each() const ENTT_NOEXCEPT {
  28340. return std::get<0>(pools)->each();
  28341. }
  28342. /**
  28343. * @brief Combines two views in a _more specific_ one (friend function).
  28344. * @tparam Get Component list of the view to combine with.
  28345. * @tparam Excl Filter list of the view to combine with.
  28346. * @param other The view to combine with.
  28347. * @return A more specific view.
  28348. */
  28349. template<typename... Get, typename... Excl>
  28350. [[nodiscard]] auto operator|(const basic_view<Entity, get_t<Get...>, exclude_t<Excl...>> &other) const ENTT_NOEXCEPT {
  28351. using view_type = basic_view<Entity, get_t<Component, Get...>, exclude_t<Excl...>>;
  28352. return std::make_from_tuple<view_type>(std::tuple_cat(
  28353. std::forward_as_tuple(*std::get<0>(pools)),
  28354. std::apply([](auto *...curr) { return std::forward_as_tuple(*curr...); }, other.pools),
  28355. std::apply([](const auto *...curr) { return std::forward_as_tuple(static_cast<const typename view_type::template storage_type<Excl> &>(*curr)...); }, other.filter)));
  28356. }
  28357. private:
  28358. std::tuple<storage_type *> pools;
  28359. std::array<const base_type *, 0u> filter;
  28360. const base_type *view;
  28361. };
  28362. /**
  28363. * @brief Deduction guide.
  28364. * @tparam Storage Type of storage classes used to create the view.
  28365. * @param storage The storage for the types to iterate.
  28366. */
  28367. template<typename... Storage>
  28368. basic_view(Storage &...storage) -> basic_view<std::common_type_t<typename Storage::entity_type...>, get_t<constness_as_t<typename Storage::value_type, Storage>...>, exclude_t<>>;
  28369. } // namespace entt
  28370. #endif
  28371. // #include "locator/locator.hpp"
  28372. #ifndef ENTT_LOCATOR_LOCATOR_HPP
  28373. #define ENTT_LOCATOR_LOCATOR_HPP
  28374. #include <memory>
  28375. #include <utility>
  28376. // #include "../config/config.h"
  28377. #ifndef ENTT_CONFIG_CONFIG_H
  28378. #define ENTT_CONFIG_CONFIG_H
  28379. // #include "version.h"
  28380. #ifndef ENTT_CONFIG_VERSION_H
  28381. #define ENTT_CONFIG_VERSION_H
  28382. // #include "macro.h"
  28383. #ifndef ENTT_CONFIG_MACRO_H
  28384. #define ENTT_CONFIG_MACRO_H
  28385. #define ENTT_STR(arg) #arg
  28386. #define ENTT_XSTR(arg) ENTT_STR(arg)
  28387. #endif
  28388. #define ENTT_VERSION_MAJOR 3
  28389. #define ENTT_VERSION_MINOR 10
  28390. #define ENTT_VERSION_PATCH 3
  28391. #define ENTT_VERSION \
  28392. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  28393. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  28394. #endif
  28395. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  28396. # define ENTT_THROW throw
  28397. # define ENTT_TRY try
  28398. # define ENTT_CATCH catch(...)
  28399. #else
  28400. # define ENTT_THROW
  28401. # define ENTT_TRY if(true)
  28402. # define ENTT_CATCH if(false)
  28403. #endif
  28404. #ifndef ENTT_NOEXCEPT
  28405. # define ENTT_NOEXCEPT noexcept
  28406. # define ENTT_NOEXCEPT_IF(expr) noexcept(expr)
  28407. # else
  28408. # define ENTT_NOEXCEPT_IF(...)
  28409. #endif
  28410. #ifdef ENTT_USE_ATOMIC
  28411. # include <atomic>
  28412. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  28413. #else
  28414. # define ENTT_MAYBE_ATOMIC(Type) Type
  28415. #endif
  28416. #ifndef ENTT_ID_TYPE
  28417. # include <cstdint>
  28418. # define ENTT_ID_TYPE std::uint32_t
  28419. #endif
  28420. #ifndef ENTT_SPARSE_PAGE
  28421. # define ENTT_SPARSE_PAGE 4096
  28422. #endif
  28423. #ifndef ENTT_PACKED_PAGE
  28424. # define ENTT_PACKED_PAGE 1024
  28425. #endif
  28426. #ifdef ENTT_DISABLE_ASSERT
  28427. # undef ENTT_ASSERT
  28428. # define ENTT_ASSERT(...) (void(0))
  28429. #elif !defined ENTT_ASSERT
  28430. # include <cassert>
  28431. # define ENTT_ASSERT(condition, ...) assert(condition)
  28432. #endif
  28433. #ifdef ENTT_NO_ETO
  28434. # define ENTT_IGNORE_IF_EMPTY false
  28435. #else
  28436. # define ENTT_IGNORE_IF_EMPTY true
  28437. #endif
  28438. #ifdef ENTT_STANDARD_CPP
  28439. # define ENTT_NONSTD false
  28440. #else
  28441. # define ENTT_NONSTD true
  28442. # if defined __clang__ || defined __GNUC__
  28443. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  28444. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  28445. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  28446. # elif defined _MSC_VER
  28447. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  28448. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  28449. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  28450. # endif
  28451. #endif
  28452. #if defined _MSC_VER
  28453. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  28454. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  28455. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  28456. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  28457. #endif
  28458. #endif
  28459. namespace entt {
  28460. /**
  28461. * @brief Service locator, nothing more.
  28462. *
  28463. * A service locator is used to do what it promises: locate services.<br/>
  28464. * Usually service locators are tightly bound to the services they expose and
  28465. * thus it's hard to define a general purpose class to do that. This tiny class
  28466. * tries to fill the gap and to get rid of the burden of defining a different
  28467. * specific locator for each application.
  28468. *
  28469. * @note
  28470. * Users shouldn't retain references to a service. The recommended way is to
  28471. * retrieve the service implementation currently set each and every time the
  28472. * need for it arises. The risk is to incur in unexpected behaviors otherwise.
  28473. *
  28474. * @tparam Service Service type.
  28475. */
  28476. template<typename Service>
  28477. struct locator final {
  28478. /*! @brief Service type. */
  28479. using type = Service;
  28480. /*! @brief Default constructor, deleted on purpose. */
  28481. locator() = delete;
  28482. /*! @brief Default destructor, deleted on purpose. */
  28483. ~locator() = delete;
  28484. /**
  28485. * @brief Checks whether a service locator contains a value.
  28486. * @return True if the service locator contains a value, false otherwise.
  28487. */
  28488. [[nodiscard]] static bool has_value() ENTT_NOEXCEPT {
  28489. return (service != nullptr);
  28490. }
  28491. /**
  28492. * @brief Returns a reference to a valid service, if any.
  28493. *
  28494. * @warning
  28495. * Invoking this function can result in undefined behavior if the service
  28496. * hasn't been set yet.
  28497. *
  28498. * @return A reference to the service currently set, if any.
  28499. */
  28500. [[nodiscard]] static Service &value() ENTT_NOEXCEPT {
  28501. ENTT_ASSERT(has_value(), "Service not available");
  28502. return *service;
  28503. }
  28504. /**
  28505. * @brief Returns a service if available or sets it from a fallback type.
  28506. *
  28507. * Arguments are used only if a service doesn't already exist. In all other
  28508. * cases, they are discarded.
  28509. *
  28510. * @tparam Args Types of arguments to use to construct the fallback service.
  28511. * @tparam Impl Fallback service type.
  28512. * @param args Parameters to use to construct the fallback service.
  28513. * @return A reference to a valid service.
  28514. */
  28515. template<typename Impl = Service, typename... Args>
  28516. [[nodiscard]] static Service &value_or(Args &&...args) {
  28517. return service ? *service : emplace<Impl>(std::forward<Args>(args)...);
  28518. }
  28519. /**
  28520. * @brief Sets or replaces a service.
  28521. * @tparam Impl Service type.
  28522. * @tparam Args Types of arguments to use to construct the service.
  28523. * @param args Parameters to use to construct the service.
  28524. * @return A reference to a valid service.
  28525. */
  28526. template<typename Impl = Service, typename... Args>
  28527. static Service &emplace(Args &&...args) {
  28528. service = std::make_shared<Impl>(std::forward<Args>(args)...);
  28529. return *service;
  28530. }
  28531. /**
  28532. * @brief Sets or replaces a service using a given allocator.
  28533. * @tparam Impl Service type.
  28534. * @tparam Allocator Type of allocator used to manage memory and elements.
  28535. * @tparam Args Types of arguments to use to construct the service.
  28536. * @param alloc The allocator to use.
  28537. * @param args Parameters to use to construct the service.
  28538. * @return A reference to a valid service.
  28539. */
  28540. template<typename Impl = Service, typename Allocator, typename... Args>
  28541. static Service &allocate_emplace(Allocator alloc, Args &&...args) {
  28542. service = std::allocate_shared<Impl>(alloc, std::forward<Args>(args)...);
  28543. return *service;
  28544. }
  28545. /*! @brief Resets a service. */
  28546. static void reset() ENTT_NOEXCEPT {
  28547. service.reset();
  28548. }
  28549. private:
  28550. // std::shared_ptr because of its type erased allocator which is pretty useful here
  28551. inline static std::shared_ptr<Service> service = nullptr;
  28552. };
  28553. } // namespace entt
  28554. #endif
  28555. // #include "meta/adl_pointer.hpp"
  28556. #ifndef ENTT_META_ADL_POINTER_HPP
  28557. #define ENTT_META_ADL_POINTER_HPP
  28558. namespace entt {
  28559. /**
  28560. * @brief ADL based lookup function for dereferencing meta pointer-like types.
  28561. * @tparam Type Element type.
  28562. * @param value A pointer-like object.
  28563. * @return The value returned from the dereferenced pointer.
  28564. */
  28565. template<typename Type>
  28566. decltype(auto) dereference_meta_pointer_like(const Type &value) {
  28567. return *value;
  28568. }
  28569. /**
  28570. * @brief Fake ADL based lookup function for meta pointer-like types.
  28571. * @tparam Type Element type.
  28572. */
  28573. template<typename Type>
  28574. struct adl_meta_pointer_like {
  28575. /**
  28576. * @brief Uses the default ADL based lookup method to resolve the call.
  28577. * @param value A pointer-like object.
  28578. * @return The value returned from the dereferenced pointer.
  28579. */
  28580. static decltype(auto) dereference(const Type &value) {
  28581. return dereference_meta_pointer_like(value);
  28582. }
  28583. };
  28584. } // namespace entt
  28585. #endif
  28586. // #include "meta/container.hpp"
  28587. #ifndef ENTT_META_CONTAINER_HPP
  28588. #define ENTT_META_CONTAINER_HPP
  28589. #include <array>
  28590. #include <map>
  28591. #include <set>
  28592. #include <type_traits>
  28593. #include <unordered_map>
  28594. #include <unordered_set>
  28595. #include <vector>
  28596. // #include "../container/dense_map.hpp"
  28597. #ifndef ENTT_CONTAINER_DENSE_MAP_HPP
  28598. #define ENTT_CONTAINER_DENSE_MAP_HPP
  28599. #include <algorithm>
  28600. #include <cmath>
  28601. #include <cstddef>
  28602. #include <functional>
  28603. #include <iterator>
  28604. #include <limits>
  28605. #include <memory>
  28606. #include <tuple>
  28607. #include <type_traits>
  28608. #include <utility>
  28609. #include <vector>
  28610. // #include "../config/config.h"
  28611. #ifndef ENTT_CONFIG_CONFIG_H
  28612. #define ENTT_CONFIG_CONFIG_H
  28613. // #include "version.h"
  28614. #ifndef ENTT_CONFIG_VERSION_H
  28615. #define ENTT_CONFIG_VERSION_H
  28616. // #include "macro.h"
  28617. #ifndef ENTT_CONFIG_MACRO_H
  28618. #define ENTT_CONFIG_MACRO_H
  28619. #define ENTT_STR(arg) #arg
  28620. #define ENTT_XSTR(arg) ENTT_STR(arg)
  28621. #endif
  28622. #define ENTT_VERSION_MAJOR 3
  28623. #define ENTT_VERSION_MINOR 10
  28624. #define ENTT_VERSION_PATCH 3
  28625. #define ENTT_VERSION \
  28626. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  28627. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  28628. #endif
  28629. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  28630. # define ENTT_THROW throw
  28631. # define ENTT_TRY try
  28632. # define ENTT_CATCH catch(...)
  28633. #else
  28634. # define ENTT_THROW
  28635. # define ENTT_TRY if(true)
  28636. # define ENTT_CATCH if(false)
  28637. #endif
  28638. #ifndef ENTT_NOEXCEPT
  28639. # define ENTT_NOEXCEPT noexcept
  28640. # define ENTT_NOEXCEPT_IF(expr) noexcept(expr)
  28641. # else
  28642. # define ENTT_NOEXCEPT_IF(...)
  28643. #endif
  28644. #ifdef ENTT_USE_ATOMIC
  28645. # include <atomic>
  28646. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  28647. #else
  28648. # define ENTT_MAYBE_ATOMIC(Type) Type
  28649. #endif
  28650. #ifndef ENTT_ID_TYPE
  28651. # include <cstdint>
  28652. # define ENTT_ID_TYPE std::uint32_t
  28653. #endif
  28654. #ifndef ENTT_SPARSE_PAGE
  28655. # define ENTT_SPARSE_PAGE 4096
  28656. #endif
  28657. #ifndef ENTT_PACKED_PAGE
  28658. # define ENTT_PACKED_PAGE 1024
  28659. #endif
  28660. #ifdef ENTT_DISABLE_ASSERT
  28661. # undef ENTT_ASSERT
  28662. # define ENTT_ASSERT(...) (void(0))
  28663. #elif !defined ENTT_ASSERT
  28664. # include <cassert>
  28665. # define ENTT_ASSERT(condition, ...) assert(condition)
  28666. #endif
  28667. #ifdef ENTT_NO_ETO
  28668. # define ENTT_IGNORE_IF_EMPTY false
  28669. #else
  28670. # define ENTT_IGNORE_IF_EMPTY true
  28671. #endif
  28672. #ifdef ENTT_STANDARD_CPP
  28673. # define ENTT_NONSTD false
  28674. #else
  28675. # define ENTT_NONSTD true
  28676. # if defined __clang__ || defined __GNUC__
  28677. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  28678. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  28679. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  28680. # elif defined _MSC_VER
  28681. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  28682. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  28683. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  28684. # endif
  28685. #endif
  28686. #if defined _MSC_VER
  28687. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  28688. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  28689. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  28690. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  28691. #endif
  28692. #endif
  28693. // #include "../core/compressed_pair.hpp"
  28694. #ifndef ENTT_CORE_COMPRESSED_PAIR_HPP
  28695. #define ENTT_CORE_COMPRESSED_PAIR_HPP
  28696. #include <cstddef>
  28697. #include <tuple>
  28698. #include <type_traits>
  28699. #include <utility>
  28700. // #include "../config/config.h"
  28701. #ifndef ENTT_CONFIG_CONFIG_H
  28702. #define ENTT_CONFIG_CONFIG_H
  28703. // #include "version.h"
  28704. #ifndef ENTT_CONFIG_VERSION_H
  28705. #define ENTT_CONFIG_VERSION_H
  28706. // #include "macro.h"
  28707. #ifndef ENTT_CONFIG_MACRO_H
  28708. #define ENTT_CONFIG_MACRO_H
  28709. #define ENTT_STR(arg) #arg
  28710. #define ENTT_XSTR(arg) ENTT_STR(arg)
  28711. #endif
  28712. #define ENTT_VERSION_MAJOR 3
  28713. #define ENTT_VERSION_MINOR 10
  28714. #define ENTT_VERSION_PATCH 3
  28715. #define ENTT_VERSION \
  28716. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  28717. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  28718. #endif
  28719. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  28720. # define ENTT_THROW throw
  28721. # define ENTT_TRY try
  28722. # define ENTT_CATCH catch(...)
  28723. #else
  28724. # define ENTT_THROW
  28725. # define ENTT_TRY if(true)
  28726. # define ENTT_CATCH if(false)
  28727. #endif
  28728. #ifndef ENTT_NOEXCEPT
  28729. # define ENTT_NOEXCEPT noexcept
  28730. # define ENTT_NOEXCEPT_IF(expr) noexcept(expr)
  28731. # else
  28732. # define ENTT_NOEXCEPT_IF(...)
  28733. #endif
  28734. #ifdef ENTT_USE_ATOMIC
  28735. # include <atomic>
  28736. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  28737. #else
  28738. # define ENTT_MAYBE_ATOMIC(Type) Type
  28739. #endif
  28740. #ifndef ENTT_ID_TYPE
  28741. # include <cstdint>
  28742. # define ENTT_ID_TYPE std::uint32_t
  28743. #endif
  28744. #ifndef ENTT_SPARSE_PAGE
  28745. # define ENTT_SPARSE_PAGE 4096
  28746. #endif
  28747. #ifndef ENTT_PACKED_PAGE
  28748. # define ENTT_PACKED_PAGE 1024
  28749. #endif
  28750. #ifdef ENTT_DISABLE_ASSERT
  28751. # undef ENTT_ASSERT
  28752. # define ENTT_ASSERT(...) (void(0))
  28753. #elif !defined ENTT_ASSERT
  28754. # include <cassert>
  28755. # define ENTT_ASSERT(condition, ...) assert(condition)
  28756. #endif
  28757. #ifdef ENTT_NO_ETO
  28758. # define ENTT_IGNORE_IF_EMPTY false
  28759. #else
  28760. # define ENTT_IGNORE_IF_EMPTY true
  28761. #endif
  28762. #ifdef ENTT_STANDARD_CPP
  28763. # define ENTT_NONSTD false
  28764. #else
  28765. # define ENTT_NONSTD true
  28766. # if defined __clang__ || defined __GNUC__
  28767. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  28768. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  28769. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  28770. # elif defined _MSC_VER
  28771. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  28772. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  28773. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  28774. # endif
  28775. #endif
  28776. #if defined _MSC_VER
  28777. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  28778. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  28779. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  28780. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  28781. #endif
  28782. #endif
  28783. // #include "type_traits.hpp"
  28784. #ifndef ENTT_CORE_TYPE_TRAITS_HPP
  28785. #define ENTT_CORE_TYPE_TRAITS_HPP
  28786. #include <cstddef>
  28787. #include <iterator>
  28788. #include <type_traits>
  28789. #include <utility>
  28790. // #include "../config/config.h"
  28791. // #include "fwd.hpp"
  28792. #ifndef ENTT_CORE_FWD_HPP
  28793. #define ENTT_CORE_FWD_HPP
  28794. #include <cstdint>
  28795. #include <type_traits>
  28796. // #include "../config/config.h"
  28797. namespace entt {
  28798. template<std::size_t Len = sizeof(double[2]), std::size_t = alignof(typename std::aligned_storage_t<Len + !Len>)>
  28799. class basic_any;
  28800. /*! @brief Alias declaration for type identifiers. */
  28801. using id_type = ENTT_ID_TYPE;
  28802. /*! @brief Alias declaration for the most common use case. */
  28803. using any = basic_any<>;
  28804. } // namespace entt
  28805. #endif
  28806. namespace entt {
  28807. /**
  28808. * @brief Utility class to disambiguate overloaded functions.
  28809. * @tparam N Number of choices available.
  28810. */
  28811. template<std::size_t N>
  28812. struct choice_t
  28813. // Unfortunately, doxygen cannot parse such a construct.
  28814. : /*! @cond TURN_OFF_DOXYGEN */ choice_t<N - 1> /*! @endcond */
  28815. {};
  28816. /*! @copybrief choice_t */
  28817. template<>
  28818. struct choice_t<0> {};
  28819. /**
  28820. * @brief Variable template for the choice trick.
  28821. * @tparam N Number of choices available.
  28822. */
  28823. template<std::size_t N>
  28824. inline constexpr choice_t<N> choice{};
  28825. /**
  28826. * @brief Identity type trait.
  28827. *
  28828. * Useful to establish non-deduced contexts in template argument deduction
  28829. * (waiting for C++20) or to provide types through function arguments.
  28830. *
  28831. * @tparam Type A type.
  28832. */
  28833. template<typename Type>
  28834. struct type_identity {
  28835. /*! @brief Identity type. */
  28836. using type = Type;
  28837. };
  28838. /**
  28839. * @brief Helper type.
  28840. * @tparam Type A type.
  28841. */
  28842. template<typename Type>
  28843. using type_identity_t = typename type_identity<Type>::type;
  28844. /**
  28845. * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains.
  28846. * @tparam Type The type of which to return the size.
  28847. * @tparam The size of the type if `sizeof` accepts it, 0 otherwise.
  28848. */
  28849. template<typename Type, typename = void>
  28850. struct size_of: std::integral_constant<std::size_t, 0u> {};
  28851. /*! @copydoc size_of */
  28852. template<typename Type>
  28853. struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
  28854. : std::integral_constant<std::size_t, sizeof(Type)> {};
  28855. /**
  28856. * @brief Helper variable template.
  28857. * @tparam Type The type of which to return the size.
  28858. */
  28859. template<typename Type>
  28860. inline constexpr std::size_t size_of_v = size_of<Type>::value;
  28861. /**
  28862. * @brief Using declaration to be used to _repeat_ the same type a number of
  28863. * times equal to the size of a given parameter pack.
  28864. * @tparam Type A type to repeat.
  28865. */
  28866. template<typename Type, typename>
  28867. using unpack_as_type = Type;
  28868. /**
  28869. * @brief Helper variable template to be used to _repeat_ the same value a
  28870. * number of times equal to the size of a given parameter pack.
  28871. * @tparam Value A value to repeat.
  28872. */
  28873. template<auto Value, typename>
  28874. inline constexpr auto unpack_as_value = Value;
  28875. /**
  28876. * @brief Wraps a static constant.
  28877. * @tparam Value A static constant.
  28878. */
  28879. template<auto Value>
  28880. using integral_constant = std::integral_constant<decltype(Value), Value>;
  28881. /**
  28882. * @brief Alias template to facilitate the creation of named values.
  28883. * @tparam Value A constant value at least convertible to `id_type`.
  28884. */
  28885. template<id_type Value>
  28886. using tag = integral_constant<Value>;
  28887. /**
  28888. * @brief A class to use to push around lists of types, nothing more.
  28889. * @tparam Type Types provided by the type list.
  28890. */
  28891. template<typename... Type>
  28892. struct type_list {
  28893. /*! @brief Type list type. */
  28894. using type = type_list;
  28895. /*! @brief Compile-time number of elements in the type list. */
  28896. static constexpr auto size = sizeof...(Type);
  28897. };
  28898. /*! @brief Primary template isn't defined on purpose. */
  28899. template<std::size_t, typename>
  28900. struct type_list_element;
  28901. /**
  28902. * @brief Provides compile-time indexed access to the types of a type list.
  28903. * @tparam Index Index of the type to return.
  28904. * @tparam Type First type provided by the type list.
  28905. * @tparam Other Other types provided by the type list.
  28906. */
  28907. template<std::size_t Index, typename Type, typename... Other>
  28908. struct type_list_element<Index, type_list<Type, Other...>>
  28909. : type_list_element<Index - 1u, type_list<Other...>> {};
  28910. /**
  28911. * @brief Provides compile-time indexed access to the types of a type list.
  28912. * @tparam Type First type provided by the type list.
  28913. * @tparam Other Other types provided by the type list.
  28914. */
  28915. template<typename Type, typename... Other>
  28916. struct type_list_element<0u, type_list<Type, Other...>> {
  28917. /*! @brief Searched type. */
  28918. using type = Type;
  28919. };
  28920. /**
  28921. * @brief Helper type.
  28922. * @tparam Index Index of the type to return.
  28923. * @tparam List Type list to search into.
  28924. */
  28925. template<std::size_t Index, typename List>
  28926. using type_list_element_t = typename type_list_element<Index, List>::type;
  28927. /**
  28928. * @brief Concatenates multiple type lists.
  28929. * @tparam Type Types provided by the first type list.
  28930. * @tparam Other Types provided by the second type list.
  28931. * @return A type list composed by the types of both the type lists.
  28932. */
  28933. template<typename... Type, typename... Other>
  28934. constexpr type_list<Type..., Other...> operator+(type_list<Type...>, type_list<Other...>) {
  28935. return {};
  28936. }
  28937. /*! @brief Primary template isn't defined on purpose. */
  28938. template<typename...>
  28939. struct type_list_cat;
  28940. /*! @brief Concatenates multiple type lists. */
  28941. template<>
  28942. struct type_list_cat<> {
  28943. /*! @brief A type list composed by the types of all the type lists. */
  28944. using type = type_list<>;
  28945. };
  28946. /**
  28947. * @brief Concatenates multiple type lists.
  28948. * @tparam Type Types provided by the first type list.
  28949. * @tparam Other Types provided by the second type list.
  28950. * @tparam List Other type lists, if any.
  28951. */
  28952. template<typename... Type, typename... Other, typename... List>
  28953. struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
  28954. /*! @brief A type list composed by the types of all the type lists. */
  28955. using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
  28956. };
  28957. /**
  28958. * @brief Concatenates multiple type lists.
  28959. * @tparam Type Types provided by the type list.
  28960. */
  28961. template<typename... Type>
  28962. struct type_list_cat<type_list<Type...>> {
  28963. /*! @brief A type list composed by the types of all the type lists. */
  28964. using type = type_list<Type...>;
  28965. };
  28966. /**
  28967. * @brief Helper type.
  28968. * @tparam List Type lists to concatenate.
  28969. */
  28970. template<typename... List>
  28971. using type_list_cat_t = typename type_list_cat<List...>::type;
  28972. /*! @brief Primary template isn't defined on purpose. */
  28973. template<typename>
  28974. struct type_list_unique;
  28975. /**
  28976. * @brief Removes duplicates types from a type list.
  28977. * @tparam Type One of the types provided by the given type list.
  28978. * @tparam Other The other types provided by the given type list.
  28979. */
  28980. template<typename Type, typename... Other>
  28981. struct type_list_unique<type_list<Type, Other...>> {
  28982. /*! @brief A type list without duplicate types. */
  28983. using type = std::conditional_t<
  28984. (std::is_same_v<Type, Other> || ...),
  28985. typename type_list_unique<type_list<Other...>>::type,
  28986. type_list_cat_t<type_list<Type>, typename type_list_unique<type_list<Other...>>::type>>;
  28987. };
  28988. /*! @brief Removes duplicates types from a type list. */
  28989. template<>
  28990. struct type_list_unique<type_list<>> {
  28991. /*! @brief A type list without duplicate types. */
  28992. using type = type_list<>;
  28993. };
  28994. /**
  28995. * @brief Helper type.
  28996. * @tparam Type A type list.
  28997. */
  28998. template<typename Type>
  28999. using type_list_unique_t = typename type_list_unique<Type>::type;
  29000. /**
  29001. * @brief Provides the member constant `value` to true if a type list contains a
  29002. * given type, false otherwise.
  29003. * @tparam List Type list.
  29004. * @tparam Type Type to look for.
  29005. */
  29006. template<typename List, typename Type>
  29007. struct type_list_contains;
  29008. /**
  29009. * @copybrief type_list_contains
  29010. * @tparam Type Types provided by the type list.
  29011. * @tparam Other Type to look for.
  29012. */
  29013. template<typename... Type, typename Other>
  29014. struct type_list_contains<type_list<Type...>, Other>: std::disjunction<std::is_same<Type, Other>...> {};
  29015. /**
  29016. * @brief Helper variable template.
  29017. * @tparam List Type list.
  29018. * @tparam Type Type to look for.
  29019. */
  29020. template<typename List, typename Type>
  29021. inline constexpr bool type_list_contains_v = type_list_contains<List, Type>::value;
  29022. /*! @brief Primary template isn't defined on purpose. */
  29023. template<typename...>
  29024. struct type_list_diff;
  29025. /**
  29026. * @brief Computes the difference between two type lists.
  29027. * @tparam Type Types provided by the first type list.
  29028. * @tparam Other Types provided by the second type list.
  29029. */
  29030. template<typename... Type, typename... Other>
  29031. struct type_list_diff<type_list<Type...>, type_list<Other...>> {
  29032. /*! @brief A type list that is the difference between the two type lists. */
  29033. using type = type_list_cat_t<std::conditional_t<type_list_contains_v<type_list<Other...>, Type>, type_list<>, type_list<Type>>...>;
  29034. };
  29035. /**
  29036. * @brief Helper type.
  29037. * @tparam List Type lists between which to compute the difference.
  29038. */
  29039. template<typename... List>
  29040. using type_list_diff_t = typename type_list_diff<List...>::type;
  29041. /**
  29042. * @brief A class to use to push around lists of constant values, nothing more.
  29043. * @tparam Value Values provided by the value list.
  29044. */
  29045. template<auto... Value>
  29046. struct value_list {
  29047. /*! @brief Value list type. */
  29048. using type = value_list;
  29049. /*! @brief Compile-time number of elements in the value list. */
  29050. static constexpr auto size = sizeof...(Value);
  29051. };
  29052. /*! @brief Primary template isn't defined on purpose. */
  29053. template<std::size_t, typename>
  29054. struct value_list_element;
  29055. /**
  29056. * @brief Provides compile-time indexed access to the values of a value list.
  29057. * @tparam Index Index of the value to return.
  29058. * @tparam Value First value provided by the value list.
  29059. * @tparam Other Other values provided by the value list.
  29060. */
  29061. template<std::size_t Index, auto Value, auto... Other>
  29062. struct value_list_element<Index, value_list<Value, Other...>>
  29063. : value_list_element<Index - 1u, value_list<Other...>> {};
  29064. /**
  29065. * @brief Provides compile-time indexed access to the types of a type list.
  29066. * @tparam Value First value provided by the value list.
  29067. * @tparam Other Other values provided by the value list.
  29068. */
  29069. template<auto Value, auto... Other>
  29070. struct value_list_element<0u, value_list<Value, Other...>> {
  29071. /*! @brief Searched value. */
  29072. static constexpr auto value = Value;
  29073. };
  29074. /**
  29075. * @brief Helper type.
  29076. * @tparam Index Index of the value to return.
  29077. * @tparam List Value list to search into.
  29078. */
  29079. template<std::size_t Index, typename List>
  29080. inline constexpr auto value_list_element_v = value_list_element<Index, List>::value;
  29081. /**
  29082. * @brief Concatenates multiple value lists.
  29083. * @tparam Value Values provided by the first value list.
  29084. * @tparam Other Values provided by the second value list.
  29085. * @return A value list composed by the values of both the value lists.
  29086. */
  29087. template<auto... Value, auto... Other>
  29088. constexpr value_list<Value..., Other...> operator+(value_list<Value...>, value_list<Other...>) {
  29089. return {};
  29090. }
  29091. /*! @brief Primary template isn't defined on purpose. */
  29092. template<typename...>
  29093. struct value_list_cat;
  29094. /*! @brief Concatenates multiple value lists. */
  29095. template<>
  29096. struct value_list_cat<> {
  29097. /*! @brief A value list composed by the values of all the value lists. */
  29098. using type = value_list<>;
  29099. };
  29100. /**
  29101. * @brief Concatenates multiple value lists.
  29102. * @tparam Value Values provided by the first value list.
  29103. * @tparam Other Values provided by the second value list.
  29104. * @tparam List Other value lists, if any.
  29105. */
  29106. template<auto... Value, auto... Other, typename... List>
  29107. struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
  29108. /*! @brief A value list composed by the values of all the value lists. */
  29109. using type = typename value_list_cat<value_list<Value..., Other...>, List...>::type;
  29110. };
  29111. /**
  29112. * @brief Concatenates multiple value lists.
  29113. * @tparam Value Values provided by the value list.
  29114. */
  29115. template<auto... Value>
  29116. struct value_list_cat<value_list<Value...>> {
  29117. /*! @brief A value list composed by the values of all the value lists. */
  29118. using type = value_list<Value...>;
  29119. };
  29120. /**
  29121. * @brief Helper type.
  29122. * @tparam List Value lists to concatenate.
  29123. */
  29124. template<typename... List>
  29125. using value_list_cat_t = typename value_list_cat<List...>::type;
  29126. /*! @brief Same as std::is_invocable, but with tuples. */
  29127. template<typename, typename>
  29128. struct is_applicable: std::false_type {};
  29129. /**
  29130. * @copybrief is_applicable
  29131. * @tparam Func A valid function type.
  29132. * @tparam Tuple Tuple-like type.
  29133. * @tparam Args The list of arguments to use to probe the function type.
  29134. */
  29135. template<typename Func, template<typename...> class Tuple, typename... Args>
  29136. struct is_applicable<Func, Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  29137. /**
  29138. * @copybrief is_applicable
  29139. * @tparam Func A valid function type.
  29140. * @tparam Tuple Tuple-like type.
  29141. * @tparam Args The list of arguments to use to probe the function type.
  29142. */
  29143. template<typename Func, template<typename...> class Tuple, typename... Args>
  29144. struct is_applicable<Func, const Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  29145. /**
  29146. * @brief Helper variable template.
  29147. * @tparam Func A valid function type.
  29148. * @tparam Args The list of arguments to use to probe the function type.
  29149. */
  29150. template<typename Func, typename Args>
  29151. inline constexpr bool is_applicable_v = is_applicable<Func, Args>::value;
  29152. /*! @brief Same as std::is_invocable_r, but with tuples for arguments. */
  29153. template<typename, typename, typename>
  29154. struct is_applicable_r: std::false_type {};
  29155. /**
  29156. * @copybrief is_applicable_r
  29157. * @tparam Ret The type to which the return type of the function should be
  29158. * convertible.
  29159. * @tparam Func A valid function type.
  29160. * @tparam Args The list of arguments to use to probe the function type.
  29161. */
  29162. template<typename Ret, typename Func, typename... Args>
  29163. struct is_applicable_r<Ret, Func, std::tuple<Args...>>: std::is_invocable_r<Ret, Func, Args...> {};
  29164. /**
  29165. * @brief Helper variable template.
  29166. * @tparam Ret The type to which the return type of the function should be
  29167. * convertible.
  29168. * @tparam Func A valid function type.
  29169. * @tparam Args The list of arguments to use to probe the function type.
  29170. */
  29171. template<typename Ret, typename Func, typename Args>
  29172. inline constexpr bool is_applicable_r_v = is_applicable_r<Ret, Func, Args>::value;
  29173. /**
  29174. * @brief Provides the member constant `value` to true if a given type is
  29175. * complete, false otherwise.
  29176. * @tparam Type The type to test.
  29177. */
  29178. template<typename Type, typename = void>
  29179. struct is_complete: std::false_type {};
  29180. /*! @copydoc is_complete */
  29181. template<typename Type>
  29182. struct is_complete<Type, std::void_t<decltype(sizeof(Type))>>: std::true_type {};
  29183. /**
  29184. * @brief Helper variable template.
  29185. * @tparam Type The type to test.
  29186. */
  29187. template<typename Type>
  29188. inline constexpr bool is_complete_v = is_complete<Type>::value;
  29189. /**
  29190. * @brief Provides the member constant `value` to true if a given type is an
  29191. * iterator, false otherwise.
  29192. * @tparam Type The type to test.
  29193. */
  29194. template<typename Type, typename = void>
  29195. struct is_iterator: std::false_type {};
  29196. /**
  29197. * @cond TURN_OFF_DOXYGEN
  29198. * Internal details not to be documented.
  29199. */
  29200. namespace internal {
  29201. template<typename, typename = void>
  29202. struct has_iterator_category: std::false_type {};
  29203. template<typename Type>
  29204. struct has_iterator_category<Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>: std::true_type {};
  29205. } // namespace internal
  29206. /**
  29207. * Internal details not to be documented.
  29208. * @endcond
  29209. */
  29210. /*! @copydoc is_iterator */
  29211. template<typename Type>
  29212. struct is_iterator<Type, std::enable_if_t<!std::is_same_v<std::remove_const_t<std::remove_pointer_t<Type>>, void>>>
  29213. : internal::has_iterator_category<Type> {};
  29214. /**
  29215. * @brief Helper variable template.
  29216. * @tparam Type The type to test.
  29217. */
  29218. template<typename Type>
  29219. inline constexpr bool is_iterator_v = is_iterator<Type>::value;
  29220. /**
  29221. * @brief Provides the member constant `value` to true if a given type is both
  29222. * an empty and non-final class, false otherwise.
  29223. * @tparam Type The type to test
  29224. */
  29225. template<typename Type>
  29226. struct is_ebco_eligible
  29227. : std::conjunction<std::is_empty<Type>, std::negation<std::is_final<Type>>> {};
  29228. /**
  29229. * @brief Helper variable template.
  29230. * @tparam Type The type to test.
  29231. */
  29232. template<typename Type>
  29233. inline constexpr bool is_ebco_eligible_v = is_ebco_eligible<Type>::value;
  29234. /**
  29235. * @brief Provides the member constant `value` to true if `Type::is_transparent`
  29236. * is valid and denotes a type, false otherwise.
  29237. * @tparam Type The type to test.
  29238. */
  29239. template<typename Type, typename = void>
  29240. struct is_transparent: std::false_type {};
  29241. /*! @copydoc is_transparent */
  29242. template<typename Type>
  29243. struct is_transparent<Type, std::void_t<typename Type::is_transparent>>: std::true_type {};
  29244. /**
  29245. * @brief Helper variable template.
  29246. * @tparam Type The type to test.
  29247. */
  29248. template<typename Type>
  29249. inline constexpr bool is_transparent_v = is_transparent<Type>::value;
  29250. /**
  29251. * @brief Provides the member constant `value` to true if a given type is
  29252. * equality comparable, false otherwise.
  29253. * @tparam Type The type to test.
  29254. */
  29255. template<typename Type, typename = void>
  29256. struct is_equality_comparable: std::false_type {};
  29257. /**
  29258. * @cond TURN_OFF_DOXYGEN
  29259. * Internal details not to be documented.
  29260. */
  29261. namespace internal {
  29262. template<typename, typename = void>
  29263. struct has_tuple_size_value: std::false_type {};
  29264. template<typename Type>
  29265. struct has_tuple_size_value<Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>: std::true_type {};
  29266. template<typename Type, std::size_t... Index>
  29267. [[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
  29268. return (is_equality_comparable<std::tuple_element_t<Index, Type>>::value && ...);
  29269. }
  29270. template<typename>
  29271. [[nodiscard]] constexpr bool maybe_equality_comparable(choice_t<0>) {
  29272. return true;
  29273. }
  29274. template<typename Type>
  29275. [[nodiscard]] constexpr auto maybe_equality_comparable(choice_t<1>) -> decltype(std::declval<typename Type::value_type>(), bool{}) {
  29276. if constexpr(is_iterator_v<Type>) {
  29277. return true;
  29278. } else if constexpr(std::is_same_v<typename Type::value_type, Type>) {
  29279. return maybe_equality_comparable<Type>(choice<0>);
  29280. } else {
  29281. return is_equality_comparable<typename Type::value_type>::value;
  29282. }
  29283. }
  29284. template<typename Type>
  29285. [[nodiscard]] constexpr std::enable_if_t<is_complete_v<std::tuple_size<std::remove_const_t<Type>>>, bool> maybe_equality_comparable(choice_t<2>) {
  29286. if constexpr(has_tuple_size_value<Type>::value) {
  29287. return unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
  29288. } else {
  29289. return maybe_equality_comparable<Type>(choice<1>);
  29290. }
  29291. }
  29292. } // namespace internal
  29293. /**
  29294. * Internal details not to be documented.
  29295. * @endcond
  29296. */
  29297. /*! @copydoc is_equality_comparable */
  29298. template<typename Type>
  29299. struct is_equality_comparable<Type, std::void_t<decltype(std::declval<Type>() == std::declval<Type>())>>
  29300. : std::bool_constant<internal::maybe_equality_comparable<Type>(choice<2>)> {};
  29301. /**
  29302. * @brief Helper variable template.
  29303. * @tparam Type The type to test.
  29304. */
  29305. template<typename Type>
  29306. inline constexpr bool is_equality_comparable_v = is_equality_comparable<Type>::value;
  29307. /**
  29308. * @brief Transcribes the constness of a type to another type.
  29309. * @tparam To The type to which to transcribe the constness.
  29310. * @tparam From The type from which to transcribe the constness.
  29311. */
  29312. template<typename To, typename From>
  29313. struct constness_as {
  29314. /*! @brief The type resulting from the transcription of the constness. */
  29315. using type = std::remove_const_t<To>;
  29316. };
  29317. /*! @copydoc constness_as */
  29318. template<typename To, typename From>
  29319. struct constness_as<To, const From> {
  29320. /*! @brief The type resulting from the transcription of the constness. */
  29321. using type = std::add_const_t<To>;
  29322. };
  29323. /**
  29324. * @brief Alias template to facilitate the transcription of the constness.
  29325. * @tparam To The type to which to transcribe the constness.
  29326. * @tparam From The type from which to transcribe the constness.
  29327. */
  29328. template<typename To, typename From>
  29329. using constness_as_t = typename constness_as<To, From>::type;
  29330. /**
  29331. * @brief Extracts the class of a non-static member object or function.
  29332. * @tparam Member A pointer to a non-static member object or function.
  29333. */
  29334. template<typename Member>
  29335. class member_class {
  29336. static_assert(std::is_member_pointer_v<Member>, "Invalid pointer type to non-static member object or function");
  29337. template<typename Class, typename Ret, typename... Args>
  29338. static Class *clazz(Ret (Class::*)(Args...));
  29339. template<typename Class, typename Ret, typename... Args>
  29340. static Class *clazz(Ret (Class::*)(Args...) const);
  29341. template<typename Class, typename Type>
  29342. static Class *clazz(Type Class::*);
  29343. public:
  29344. /*! @brief The class of the given non-static member object or function. */
  29345. using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
  29346. };
  29347. /**
  29348. * @brief Helper type.
  29349. * @tparam Member A pointer to a non-static member object or function.
  29350. */
  29351. template<typename Member>
  29352. using member_class_t = typename member_class<Member>::type;
  29353. } // namespace entt
  29354. #endif
  29355. namespace entt {
  29356. /**
  29357. * @cond TURN_OFF_DOXYGEN
  29358. * Internal details not to be documented.
  29359. */
  29360. namespace internal {
  29361. template<typename Type, std::size_t, typename = void>
  29362. struct compressed_pair_element {
  29363. using reference = Type &;
  29364. using const_reference = const Type &;
  29365. template<bool Dummy = true, typename = std::enable_if_t<Dummy && std::is_default_constructible_v<Type>>>
  29366. compressed_pair_element()
  29367. : value{} {}
  29368. template<typename Args, typename = std::enable_if_t<!std::is_same_v<std::remove_cv_t<std::remove_reference_t<Args>>, compressed_pair_element>>>
  29369. compressed_pair_element(Args &&args)
  29370. : value{std::forward<Args>(args)} {}
  29371. template<typename... Args, std::size_t... Index>
  29372. compressed_pair_element(std::tuple<Args...> args, std::index_sequence<Index...>)
  29373. : value{std::forward<Args>(std::get<Index>(args))...} {}
  29374. [[nodiscard]] reference get() ENTT_NOEXCEPT {
  29375. return value;
  29376. }
  29377. [[nodiscard]] const_reference get() const ENTT_NOEXCEPT {
  29378. return value;
  29379. }
  29380. private:
  29381. Type value;
  29382. };
  29383. template<typename Type, std::size_t Tag>
  29384. struct compressed_pair_element<Type, Tag, std::enable_if_t<is_ebco_eligible_v<Type>>>: Type {
  29385. using reference = Type &;
  29386. using const_reference = const Type &;
  29387. using base_type = Type;
  29388. template<bool Dummy = true, typename = std::enable_if_t<Dummy && std::is_default_constructible_v<base_type>>>
  29389. compressed_pair_element()
  29390. : base_type{} {}
  29391. template<typename Args, typename = std::enable_if_t<!std::is_same_v<std::remove_cv_t<std::remove_reference_t<Args>>, compressed_pair_element>>>
  29392. compressed_pair_element(Args &&args)
  29393. : base_type{std::forward<Args>(args)} {}
  29394. template<typename... Args, std::size_t... Index>
  29395. compressed_pair_element(std::tuple<Args...> args, std::index_sequence<Index...>)
  29396. : base_type{std::forward<Args>(std::get<Index>(args))...} {}
  29397. [[nodiscard]] reference get() ENTT_NOEXCEPT {
  29398. return *this;
  29399. }
  29400. [[nodiscard]] const_reference get() const ENTT_NOEXCEPT {
  29401. return *this;
  29402. }
  29403. };
  29404. } // namespace internal
  29405. /**
  29406. * Internal details not to be documented.
  29407. * @endcond
  29408. */
  29409. /**
  29410. * @brief A compressed pair.
  29411. *
  29412. * A pair that exploits the _Empty Base Class Optimization_ (or _EBCO_) to
  29413. * reduce its final size to a minimum.
  29414. *
  29415. * @tparam First The type of the first element that the pair stores.
  29416. * @tparam Second The type of the second element that the pair stores.
  29417. */
  29418. template<typename First, typename Second>
  29419. class compressed_pair final
  29420. : internal::compressed_pair_element<First, 0u>,
  29421. internal::compressed_pair_element<Second, 1u> {
  29422. using first_base = internal::compressed_pair_element<First, 0u>;
  29423. using second_base = internal::compressed_pair_element<Second, 1u>;
  29424. public:
  29425. /*! @brief The type of the first element that the pair stores. */
  29426. using first_type = First;
  29427. /*! @brief The type of the second element that the pair stores. */
  29428. using second_type = Second;
  29429. /**
  29430. * @brief Default constructor, conditionally enabled.
  29431. *
  29432. * This constructor is only available when the types that the pair stores
  29433. * are both at least default constructible.
  29434. *
  29435. * @tparam Dummy Dummy template parameter used for internal purposes.
  29436. */
  29437. template<bool Dummy = true, typename = std::enable_if_t<Dummy && std::is_default_constructible_v<first_type> && std::is_default_constructible_v<second_type>>>
  29438. constexpr compressed_pair()
  29439. : first_base{},
  29440. second_base{} {}
  29441. /**
  29442. * @brief Copy constructor.
  29443. * @param other The instance to copy from.
  29444. */
  29445. constexpr compressed_pair(const compressed_pair &other) = default;
  29446. /**
  29447. * @brief Move constructor.
  29448. * @param other The instance to move from.
  29449. */
  29450. constexpr compressed_pair(compressed_pair &&other) = default;
  29451. /**
  29452. * @brief Constructs a pair from its values.
  29453. * @tparam Arg Type of value to use to initialize the first element.
  29454. * @tparam Other Type of value to use to initialize the second element.
  29455. * @param arg Value to use to initialize the first element.
  29456. * @param other Value to use to initialize the second element.
  29457. */
  29458. template<typename Arg, typename Other>
  29459. constexpr compressed_pair(Arg &&arg, Other &&other)
  29460. : first_base{std::forward<Arg>(arg)},
  29461. second_base{std::forward<Other>(other)} {}
  29462. /**
  29463. * @brief Constructs a pair by forwarding the arguments to its parts.
  29464. * @tparam Args Types of arguments to use to initialize the first element.
  29465. * @tparam Other Types of arguments to use to initialize the second element.
  29466. * @param args Arguments to use to initialize the first element.
  29467. * @param other Arguments to use to initialize the second element.
  29468. */
  29469. template<typename... Args, typename... Other>
  29470. constexpr compressed_pair(std::piecewise_construct_t, std::tuple<Args...> args, std::tuple<Other...> other)
  29471. : first_base{std::move(args), std::index_sequence_for<Args...>{}},
  29472. second_base{std::move(other), std::index_sequence_for<Other...>{}} {}
  29473. /**
  29474. * @brief Copy assignment operator.
  29475. * @param other The instance to copy from.
  29476. * @return This compressed pair object.
  29477. */
  29478. constexpr compressed_pair &operator=(const compressed_pair &other) = default;
  29479. /**
  29480. * @brief Move assignment operator.
  29481. * @param other The instance to move from.
  29482. * @return This compressed pair object.
  29483. */
  29484. constexpr compressed_pair &operator=(compressed_pair &&other) = default;
  29485. /**
  29486. * @brief Returns the first element that a pair stores.
  29487. * @return The first element that a pair stores.
  29488. */
  29489. [[nodiscard]] first_type &first() ENTT_NOEXCEPT {
  29490. return static_cast<first_base &>(*this).get();
  29491. }
  29492. /*! @copydoc first */
  29493. [[nodiscard]] const first_type &first() const ENTT_NOEXCEPT {
  29494. return static_cast<const first_base &>(*this).get();
  29495. }
  29496. /**
  29497. * @brief Returns the second element that a pair stores.
  29498. * @return The second element that a pair stores.
  29499. */
  29500. [[nodiscard]] second_type &second() ENTT_NOEXCEPT {
  29501. return static_cast<second_base &>(*this).get();
  29502. }
  29503. /*! @copydoc second */
  29504. [[nodiscard]] const second_type &second() const ENTT_NOEXCEPT {
  29505. return static_cast<const second_base &>(*this).get();
  29506. }
  29507. /**
  29508. * @brief Swaps two compressed pair objects.
  29509. * @param other The compressed pair to swap with.
  29510. */
  29511. void swap(compressed_pair &other) {
  29512. using std::swap;
  29513. swap(first(), other.first());
  29514. swap(second(), other.second());
  29515. }
  29516. /**
  29517. * @brief Extracts an element from the compressed pair.
  29518. * @tparam Index An integer value that is either 0 or 1.
  29519. * @return Returns a reference to the first element if `Index` is 0 and a
  29520. * reference to the second element if `Index` is 1.
  29521. */
  29522. template<std::size_t Index>
  29523. decltype(auto) get() ENTT_NOEXCEPT {
  29524. if constexpr(Index == 0u) {
  29525. return first();
  29526. } else {
  29527. static_assert(Index == 1u, "Index out of bounds");
  29528. return second();
  29529. }
  29530. }
  29531. /*! @copydoc get */
  29532. template<std::size_t Index>
  29533. decltype(auto) get() const ENTT_NOEXCEPT {
  29534. if constexpr(Index == 0u) {
  29535. return first();
  29536. } else {
  29537. static_assert(Index == 1u, "Index out of bounds");
  29538. return second();
  29539. }
  29540. }
  29541. };
  29542. /**
  29543. * @brief Deduction guide.
  29544. * @tparam Type Type of value to use to initialize the first element.
  29545. * @tparam Other Type of value to use to initialize the second element.
  29546. */
  29547. template<typename Type, typename Other>
  29548. compressed_pair(Type &&, Other &&) -> compressed_pair<std::decay_t<Type>, std::decay_t<Other>>;
  29549. /**
  29550. * @brief Swaps two compressed pair objects.
  29551. * @tparam First The type of the first element that the pairs store.
  29552. * @tparam Second The type of the second element that the pairs store.
  29553. * @param lhs A valid compressed pair object.
  29554. * @param rhs A valid compressed pair object.
  29555. */
  29556. template<typename First, typename Second>
  29557. inline void swap(compressed_pair<First, Second> &lhs, compressed_pair<First, Second> &rhs) {
  29558. lhs.swap(rhs);
  29559. }
  29560. } // namespace entt
  29561. // disable structured binding support for clang 6, it messes when specializing tuple_size
  29562. #if !defined __clang_major__ || __clang_major__ > 6
  29563. namespace std {
  29564. /**
  29565. * @brief `std::tuple_size` specialization for `compressed_pair`s.
  29566. * @tparam First The type of the first element that the pair stores.
  29567. * @tparam Second The type of the second element that the pair stores.
  29568. */
  29569. template<typename First, typename Second>
  29570. struct tuple_size<entt::compressed_pair<First, Second>>: integral_constant<size_t, 2u> {};
  29571. /**
  29572. * @brief `std::tuple_element` specialization for `compressed_pair`s.
  29573. * @tparam Index The index of the type to return.
  29574. * @tparam First The type of the first element that the pair stores.
  29575. * @tparam Second The type of the second element that the pair stores.
  29576. */
  29577. template<size_t Index, typename First, typename Second>
  29578. struct tuple_element<Index, entt::compressed_pair<First, Second>>: conditional<Index == 0u, First, Second> {
  29579. static_assert(Index < 2u, "Index out of bounds");
  29580. };
  29581. } // namespace std
  29582. #endif
  29583. #endif
  29584. // #include "../core/iterator.hpp"
  29585. #ifndef ENTT_CORE_ITERATOR_HPP
  29586. #define ENTT_CORE_ITERATOR_HPP
  29587. #include <iterator>
  29588. #include <memory>
  29589. #include <utility>
  29590. // #include "../config/config.h"
  29591. namespace entt {
  29592. /**
  29593. * @brief Helper type to use as pointer with input iterators.
  29594. * @tparam Type of wrapped value.
  29595. */
  29596. template<typename Type>
  29597. struct input_iterator_pointer final {
  29598. /*! @brief Pointer type. */
  29599. using pointer = Type *;
  29600. /*! @brief Default copy constructor, deleted on purpose. */
  29601. input_iterator_pointer(const input_iterator_pointer &) = delete;
  29602. /*! @brief Default move constructor. */
  29603. input_iterator_pointer(input_iterator_pointer &&) = default;
  29604. /**
  29605. * @brief Constructs a proxy object by move.
  29606. * @param val Value to use to initialize the proxy object.
  29607. */
  29608. input_iterator_pointer(Type &&val)
  29609. : value{std::move(val)} {}
  29610. /**
  29611. * @brief Default copy assignment operator, deleted on purpose.
  29612. * @return This proxy object.
  29613. */
  29614. input_iterator_pointer &operator=(const input_iterator_pointer &) = delete;
  29615. /**
  29616. * @brief Default move assignment operator.
  29617. * @return This proxy object.
  29618. */
  29619. input_iterator_pointer &operator=(input_iterator_pointer &&) = default;
  29620. /**
  29621. * @brief Access operator for accessing wrapped values.
  29622. * @return A pointer to the wrapped value.
  29623. */
  29624. [[nodiscard]] pointer operator->() ENTT_NOEXCEPT {
  29625. return std::addressof(value);
  29626. }
  29627. private:
  29628. Type value;
  29629. };
  29630. /**
  29631. * @brief Utility class to create an iterable object from a pair of iterators.
  29632. * @tparam It Type of iterator.
  29633. * @tparam Sentinel Type of sentinel.
  29634. */
  29635. template<typename It, typename Sentinel = It>
  29636. struct iterable_adaptor final {
  29637. /*! @brief Value type. */
  29638. using value_type = typename std::iterator_traits<It>::value_type;
  29639. /*! @brief Iterator type. */
  29640. using iterator = It;
  29641. /*! @brief Sentinel type. */
  29642. using sentinel = Sentinel;
  29643. /*! @brief Default constructor. */
  29644. iterable_adaptor() = default;
  29645. /**
  29646. * @brief Creates an iterable object from a pair of iterators.
  29647. * @param from Begin iterator.
  29648. * @param to End iterator.
  29649. */
  29650. iterable_adaptor(iterator from, sentinel to)
  29651. : first{from},
  29652. last{to} {}
  29653. /**
  29654. * @brief Returns an iterator to the beginning.
  29655. * @return An iterator to the first element of the range.
  29656. */
  29657. [[nodiscard]] iterator begin() const ENTT_NOEXCEPT {
  29658. return first;
  29659. }
  29660. /**
  29661. * @brief Returns an iterator to the end.
  29662. * @return An iterator to the element following the last element of the
  29663. * range.
  29664. */
  29665. [[nodiscard]] sentinel end() const ENTT_NOEXCEPT {
  29666. return last;
  29667. }
  29668. /*! @copydoc begin */
  29669. [[nodiscard]] iterator cbegin() const ENTT_NOEXCEPT {
  29670. return begin();
  29671. }
  29672. /*! @copydoc end */
  29673. [[nodiscard]] sentinel cend() const ENTT_NOEXCEPT {
  29674. return end();
  29675. }
  29676. private:
  29677. It first;
  29678. Sentinel last;
  29679. };
  29680. } // namespace entt
  29681. #endif
  29682. // #include "../core/memory.hpp"
  29683. #ifndef ENTT_CORE_MEMORY_HPP
  29684. #define ENTT_CORE_MEMORY_HPP
  29685. #include <cstddef>
  29686. #include <limits>
  29687. #include <memory>
  29688. #include <tuple>
  29689. #include <type_traits>
  29690. #include <utility>
  29691. // #include "../config/config.h"
  29692. namespace entt {
  29693. /**
  29694. * @brief Unwraps fancy pointers, does nothing otherwise (waiting for C++20).
  29695. * @tparam Type Pointer type.
  29696. * @param ptr Fancy or raw pointer.
  29697. * @return A raw pointer that represents the address of the original pointer.
  29698. */
  29699. template<typename Type>
  29700. [[nodiscard]] constexpr auto to_address(Type &&ptr) ENTT_NOEXCEPT {
  29701. if constexpr(std::is_pointer_v<std::remove_cv_t<std::remove_reference_t<Type>>>) {
  29702. return ptr;
  29703. } else {
  29704. return to_address(std::forward<Type>(ptr).operator->());
  29705. }
  29706. }
  29707. /**
  29708. * @brief Utility function to design allocation-aware containers.
  29709. * @tparam Allocator Type of allocator.
  29710. * @param lhs A valid allocator.
  29711. * @param rhs Another valid allocator.
  29712. */
  29713. template<typename Allocator>
  29714. constexpr void propagate_on_container_copy_assignment([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) ENTT_NOEXCEPT {
  29715. if constexpr(std::allocator_traits<Allocator>::propagate_on_container_copy_assignment::value) {
  29716. lhs = rhs;
  29717. }
  29718. }
  29719. /**
  29720. * @brief Utility function to design allocation-aware containers.
  29721. * @tparam Allocator Type of allocator.
  29722. * @param lhs A valid allocator.
  29723. * @param rhs Another valid allocator.
  29724. */
  29725. template<typename Allocator>
  29726. constexpr void propagate_on_container_move_assignment([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) ENTT_NOEXCEPT {
  29727. if constexpr(std::allocator_traits<Allocator>::propagate_on_container_move_assignment::value) {
  29728. lhs = std::move(rhs);
  29729. }
  29730. }
  29731. /**
  29732. * @brief Utility function to design allocation-aware containers.
  29733. * @tparam Allocator Type of allocator.
  29734. * @param lhs A valid allocator.
  29735. * @param rhs Another valid allocator.
  29736. */
  29737. template<typename Allocator>
  29738. constexpr void propagate_on_container_swap([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) ENTT_NOEXCEPT {
  29739. ENTT_ASSERT(std::allocator_traits<Allocator>::propagate_on_container_swap::value || lhs == rhs, "Cannot swap the containers");
  29740. if constexpr(std::allocator_traits<Allocator>::propagate_on_container_swap::value) {
  29741. using std::swap;
  29742. swap(lhs, rhs);
  29743. }
  29744. }
  29745. /**
  29746. * @brief Checks whether a value is a power of two or not.
  29747. * @param value A value that may or may not be a power of two.
  29748. * @return True if the value is a power of two, false otherwise.
  29749. */
  29750. [[nodiscard]] inline constexpr bool is_power_of_two(const std::size_t value) ENTT_NOEXCEPT {
  29751. return value && ((value & (value - 1)) == 0);
  29752. }
  29753. /**
  29754. * @brief Computes the smallest power of two greater than or equal to a value.
  29755. * @param value The value to use.
  29756. * @return The smallest power of two greater than or equal to the given value.
  29757. */
  29758. [[nodiscard]] inline constexpr std::size_t next_power_of_two(const std::size_t value) ENTT_NOEXCEPT {
  29759. ENTT_ASSERT(value < (std::size_t{1u} << (std::numeric_limits<std::size_t>::digits - 1)), "Numeric limits exceeded");
  29760. std::size_t curr = value - (value != 0u);
  29761. for(int next = 1; next < std::numeric_limits<std::size_t>::digits; next = next * 2) {
  29762. curr |= curr >> next;
  29763. }
  29764. return ++curr;
  29765. }
  29766. /**
  29767. * @brief Fast module utility function (powers of two only).
  29768. * @param value A value for which to calculate the modulus.
  29769. * @param mod _Modulus_, it must be a power of two.
  29770. * @return The common remainder.
  29771. */
  29772. [[nodiscard]] inline constexpr std::size_t fast_mod(const std::size_t value, const std::size_t mod) ENTT_NOEXCEPT {
  29773. ENTT_ASSERT(is_power_of_two(mod), "Value must be a power of two");
  29774. return value & (mod - 1u);
  29775. }
  29776. /**
  29777. * @brief Deleter for allocator-aware unique pointers (waiting for C++20).
  29778. * @tparam Args Types of arguments to use to construct the object.
  29779. */
  29780. template<typename Allocator>
  29781. struct allocation_deleter: private Allocator {
  29782. /*! @brief Allocator type. */
  29783. using allocator_type = Allocator;
  29784. /*! @brief Pointer type. */
  29785. using pointer = typename std::allocator_traits<Allocator>::pointer;
  29786. /**
  29787. * @brief Inherited constructors.
  29788. * @param alloc The allocator to use.
  29789. */
  29790. allocation_deleter(const allocator_type &alloc)
  29791. : Allocator{alloc} {}
  29792. /**
  29793. * @brief Destroys the pointed object and deallocates its memory.
  29794. * @param ptr A valid pointer to an object of the given type.
  29795. */
  29796. void operator()(pointer ptr) {
  29797. using alloc_traits = typename std::allocator_traits<Allocator>;
  29798. alloc_traits::destroy(*this, to_address(ptr));
  29799. alloc_traits::deallocate(*this, ptr, 1u);
  29800. }
  29801. };
  29802. /**
  29803. * @brief Allows `std::unique_ptr` to use allocators (waiting for C++20).
  29804. * @tparam Type Type of object to allocate for and to construct.
  29805. * @tparam Allocator Type of allocator used to manage memory and elements.
  29806. * @tparam Args Types of arguments to use to construct the object.
  29807. * @param allocator The allocator to use.
  29808. * @param args Parameters to use to construct the object.
  29809. * @return A properly initialized unique pointer with a custom deleter.
  29810. */
  29811. template<typename Type, typename Allocator, typename... Args>
  29812. auto allocate_unique(Allocator &allocator, Args &&...args) {
  29813. static_assert(!std::is_array_v<Type>, "Array types are not supported");
  29814. using alloc_traits = typename std::allocator_traits<Allocator>::template rebind_traits<Type>;
  29815. using allocator_type = typename alloc_traits::allocator_type;
  29816. allocator_type alloc{allocator};
  29817. auto ptr = alloc_traits::allocate(alloc, 1u);
  29818. ENTT_TRY {
  29819. alloc_traits::construct(alloc, to_address(ptr), std::forward<Args>(args)...);
  29820. }
  29821. ENTT_CATCH {
  29822. alloc_traits::deallocate(alloc, ptr, 1u);
  29823. ENTT_THROW;
  29824. }
  29825. return std::unique_ptr<Type, allocation_deleter<allocator_type>>{ptr, alloc};
  29826. }
  29827. /**
  29828. * @cond TURN_OFF_DOXYGEN
  29829. * Internal details not to be documented.
  29830. */
  29831. namespace internal {
  29832. template<typename Type>
  29833. struct uses_allocator_construction {
  29834. template<typename Allocator, typename... Params>
  29835. static constexpr auto args([[maybe_unused]] const Allocator &allocator, Params &&...params) ENTT_NOEXCEPT {
  29836. if constexpr(!std::uses_allocator_v<Type, Allocator> && std::is_constructible_v<Type, Params...>) {
  29837. return std::forward_as_tuple(std::forward<Params>(params)...);
  29838. } else {
  29839. static_assert(std::uses_allocator_v<Type, Allocator>, "Ill-formed request");
  29840. if constexpr(std::is_constructible_v<Type, std::allocator_arg_t, const Allocator &, Params...>) {
  29841. return std::tuple<std::allocator_arg_t, const Allocator &, Params &&...>(std::allocator_arg, allocator, std::forward<Params>(params)...);
  29842. } else {
  29843. static_assert(std::is_constructible_v<Type, Params..., const Allocator &>, "Ill-formed request");
  29844. return std::forward_as_tuple(std::forward<Params>(params)..., allocator);
  29845. }
  29846. }
  29847. }
  29848. };
  29849. template<typename Type, typename Other>
  29850. struct uses_allocator_construction<std::pair<Type, Other>> {
  29851. using type = std::pair<Type, Other>;
  29852. template<typename Allocator, typename First, typename Second>
  29853. static constexpr auto args(const Allocator &allocator, std::piecewise_construct_t, First &&first, Second &&second) ENTT_NOEXCEPT {
  29854. return std::make_tuple(
  29855. std::piecewise_construct,
  29856. std::apply([&allocator](auto &&...curr) { return uses_allocator_construction<Type>::args(allocator, std::forward<decltype(curr)>(curr)...); }, std::forward<First>(first)),
  29857. std::apply([&allocator](auto &&...curr) { return uses_allocator_construction<Other>::args(allocator, std::forward<decltype(curr)>(curr)...); }, std::forward<Second>(second)));
  29858. }
  29859. template<typename Allocator>
  29860. static constexpr auto args(const Allocator &allocator) ENTT_NOEXCEPT {
  29861. return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::tuple<>{}, std::tuple<>{});
  29862. }
  29863. template<typename Allocator, typename First, typename Second>
  29864. static constexpr auto args(const Allocator &allocator, First &&first, Second &&second) ENTT_NOEXCEPT {
  29865. 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)));
  29866. }
  29867. template<typename Allocator, typename First, typename Second>
  29868. static constexpr auto args(const Allocator &allocator, const std::pair<First, Second> &value) ENTT_NOEXCEPT {
  29869. return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::forward_as_tuple(value.first), std::forward_as_tuple(value.second));
  29870. }
  29871. template<typename Allocator, typename First, typename Second>
  29872. static constexpr auto args(const Allocator &allocator, std::pair<First, Second> &&value) ENTT_NOEXCEPT {
  29873. 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)));
  29874. }
  29875. };
  29876. } // namespace internal
  29877. /**
  29878. * Internal details not to be documented.
  29879. * @endcond
  29880. */
  29881. /**
  29882. * @brief Uses-allocator construction utility (waiting for C++20).
  29883. *
  29884. * Primarily intended for internal use. Prepares the argument list needed to
  29885. * create an object of a given type by means of uses-allocator construction.
  29886. *
  29887. * @tparam Type Type to return arguments for.
  29888. * @tparam Allocator Type of allocator used to manage memory and elements.
  29889. * @tparam Args Types of arguments to use to construct the object.
  29890. * @param allocator The allocator to use.
  29891. * @param args Parameters to use to construct the object.
  29892. * @return The arguments needed to create an object of the given type.
  29893. */
  29894. template<typename Type, typename Allocator, typename... Args>
  29895. constexpr auto uses_allocator_construction_args(const Allocator &allocator, Args &&...args) ENTT_NOEXCEPT {
  29896. return internal::uses_allocator_construction<Type>::args(allocator, std::forward<Args>(args)...);
  29897. }
  29898. /**
  29899. * @brief Uses-allocator construction utility (waiting for C++20).
  29900. *
  29901. * Primarily intended for internal use. Creates an object of a given type by
  29902. * means of uses-allocator construction.
  29903. *
  29904. * @tparam Type Type of object to create.
  29905. * @tparam Allocator Type of allocator used to manage memory and elements.
  29906. * @tparam Args Types of arguments to use to construct the object.
  29907. * @param allocator The allocator to use.
  29908. * @param args Parameters to use to construct the object.
  29909. * @return A newly created object of the given type.
  29910. */
  29911. template<typename Type, typename Allocator, typename... Args>
  29912. constexpr Type make_obj_using_allocator(const Allocator &allocator, Args &&...args) {
  29913. return std::make_from_tuple<Type>(internal::uses_allocator_construction<Type>::args(allocator, std::forward<Args>(args)...));
  29914. }
  29915. /**
  29916. * @brief Uses-allocator construction utility (waiting for C++20).
  29917. *
  29918. * Primarily intended for internal use. Creates an object of a given type by
  29919. * means of uses-allocator construction at an uninitialized memory location.
  29920. *
  29921. * @tparam Type Type of object to create.
  29922. * @tparam Allocator Type of allocator used to manage memory and elements.
  29923. * @tparam Args Types of arguments to use to construct the object.
  29924. * @param value Memory location in which to place the object.
  29925. * @param allocator The allocator to use.
  29926. * @param args Parameters to use to construct the object.
  29927. * @return A pointer to the newly created object of the given type.
  29928. */
  29929. template<typename Type, typename Allocator, typename... Args>
  29930. constexpr Type *uninitialized_construct_using_allocator(Type *value, const Allocator &allocator, Args &&...args) {
  29931. return std::apply([&](auto &&...curr) { return new(value) Type(std::forward<decltype(curr)>(curr)...); }, internal::uses_allocator_construction<Type>::args(allocator, std::forward<Args>(args)...));
  29932. }
  29933. } // namespace entt
  29934. #endif
  29935. // #include "../core/type_traits.hpp"
  29936. #ifndef ENTT_CORE_TYPE_TRAITS_HPP
  29937. #define ENTT_CORE_TYPE_TRAITS_HPP
  29938. #include <cstddef>
  29939. #include <iterator>
  29940. #include <type_traits>
  29941. #include <utility>
  29942. // #include "../config/config.h"
  29943. // #include "fwd.hpp"
  29944. namespace entt {
  29945. /**
  29946. * @brief Utility class to disambiguate overloaded functions.
  29947. * @tparam N Number of choices available.
  29948. */
  29949. template<std::size_t N>
  29950. struct choice_t
  29951. // Unfortunately, doxygen cannot parse such a construct.
  29952. : /*! @cond TURN_OFF_DOXYGEN */ choice_t<N - 1> /*! @endcond */
  29953. {};
  29954. /*! @copybrief choice_t */
  29955. template<>
  29956. struct choice_t<0> {};
  29957. /**
  29958. * @brief Variable template for the choice trick.
  29959. * @tparam N Number of choices available.
  29960. */
  29961. template<std::size_t N>
  29962. inline constexpr choice_t<N> choice{};
  29963. /**
  29964. * @brief Identity type trait.
  29965. *
  29966. * Useful to establish non-deduced contexts in template argument deduction
  29967. * (waiting for C++20) or to provide types through function arguments.
  29968. *
  29969. * @tparam Type A type.
  29970. */
  29971. template<typename Type>
  29972. struct type_identity {
  29973. /*! @brief Identity type. */
  29974. using type = Type;
  29975. };
  29976. /**
  29977. * @brief Helper type.
  29978. * @tparam Type A type.
  29979. */
  29980. template<typename Type>
  29981. using type_identity_t = typename type_identity<Type>::type;
  29982. /**
  29983. * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains.
  29984. * @tparam Type The type of which to return the size.
  29985. * @tparam The size of the type if `sizeof` accepts it, 0 otherwise.
  29986. */
  29987. template<typename Type, typename = void>
  29988. struct size_of: std::integral_constant<std::size_t, 0u> {};
  29989. /*! @copydoc size_of */
  29990. template<typename Type>
  29991. struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
  29992. : std::integral_constant<std::size_t, sizeof(Type)> {};
  29993. /**
  29994. * @brief Helper variable template.
  29995. * @tparam Type The type of which to return the size.
  29996. */
  29997. template<typename Type>
  29998. inline constexpr std::size_t size_of_v = size_of<Type>::value;
  29999. /**
  30000. * @brief Using declaration to be used to _repeat_ the same type a number of
  30001. * times equal to the size of a given parameter pack.
  30002. * @tparam Type A type to repeat.
  30003. */
  30004. template<typename Type, typename>
  30005. using unpack_as_type = Type;
  30006. /**
  30007. * @brief Helper variable template to be used to _repeat_ the same value a
  30008. * number of times equal to the size of a given parameter pack.
  30009. * @tparam Value A value to repeat.
  30010. */
  30011. template<auto Value, typename>
  30012. inline constexpr auto unpack_as_value = Value;
  30013. /**
  30014. * @brief Wraps a static constant.
  30015. * @tparam Value A static constant.
  30016. */
  30017. template<auto Value>
  30018. using integral_constant = std::integral_constant<decltype(Value), Value>;
  30019. /**
  30020. * @brief Alias template to facilitate the creation of named values.
  30021. * @tparam Value A constant value at least convertible to `id_type`.
  30022. */
  30023. template<id_type Value>
  30024. using tag = integral_constant<Value>;
  30025. /**
  30026. * @brief A class to use to push around lists of types, nothing more.
  30027. * @tparam Type Types provided by the type list.
  30028. */
  30029. template<typename... Type>
  30030. struct type_list {
  30031. /*! @brief Type list type. */
  30032. using type = type_list;
  30033. /*! @brief Compile-time number of elements in the type list. */
  30034. static constexpr auto size = sizeof...(Type);
  30035. };
  30036. /*! @brief Primary template isn't defined on purpose. */
  30037. template<std::size_t, typename>
  30038. struct type_list_element;
  30039. /**
  30040. * @brief Provides compile-time indexed access to the types of a type list.
  30041. * @tparam Index Index of the type to return.
  30042. * @tparam Type First type provided by the type list.
  30043. * @tparam Other Other types provided by the type list.
  30044. */
  30045. template<std::size_t Index, typename Type, typename... Other>
  30046. struct type_list_element<Index, type_list<Type, Other...>>
  30047. : type_list_element<Index - 1u, type_list<Other...>> {};
  30048. /**
  30049. * @brief Provides compile-time indexed access to the types of a type list.
  30050. * @tparam Type First type provided by the type list.
  30051. * @tparam Other Other types provided by the type list.
  30052. */
  30053. template<typename Type, typename... Other>
  30054. struct type_list_element<0u, type_list<Type, Other...>> {
  30055. /*! @brief Searched type. */
  30056. using type = Type;
  30057. };
  30058. /**
  30059. * @brief Helper type.
  30060. * @tparam Index Index of the type to return.
  30061. * @tparam List Type list to search into.
  30062. */
  30063. template<std::size_t Index, typename List>
  30064. using type_list_element_t = typename type_list_element<Index, List>::type;
  30065. /**
  30066. * @brief Concatenates multiple type lists.
  30067. * @tparam Type Types provided by the first type list.
  30068. * @tparam Other Types provided by the second type list.
  30069. * @return A type list composed by the types of both the type lists.
  30070. */
  30071. template<typename... Type, typename... Other>
  30072. constexpr type_list<Type..., Other...> operator+(type_list<Type...>, type_list<Other...>) {
  30073. return {};
  30074. }
  30075. /*! @brief Primary template isn't defined on purpose. */
  30076. template<typename...>
  30077. struct type_list_cat;
  30078. /*! @brief Concatenates multiple type lists. */
  30079. template<>
  30080. struct type_list_cat<> {
  30081. /*! @brief A type list composed by the types of all the type lists. */
  30082. using type = type_list<>;
  30083. };
  30084. /**
  30085. * @brief Concatenates multiple type lists.
  30086. * @tparam Type Types provided by the first type list.
  30087. * @tparam Other Types provided by the second type list.
  30088. * @tparam List Other type lists, if any.
  30089. */
  30090. template<typename... Type, typename... Other, typename... List>
  30091. struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
  30092. /*! @brief A type list composed by the types of all the type lists. */
  30093. using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
  30094. };
  30095. /**
  30096. * @brief Concatenates multiple type lists.
  30097. * @tparam Type Types provided by the type list.
  30098. */
  30099. template<typename... Type>
  30100. struct type_list_cat<type_list<Type...>> {
  30101. /*! @brief A type list composed by the types of all the type lists. */
  30102. using type = type_list<Type...>;
  30103. };
  30104. /**
  30105. * @brief Helper type.
  30106. * @tparam List Type lists to concatenate.
  30107. */
  30108. template<typename... List>
  30109. using type_list_cat_t = typename type_list_cat<List...>::type;
  30110. /*! @brief Primary template isn't defined on purpose. */
  30111. template<typename>
  30112. struct type_list_unique;
  30113. /**
  30114. * @brief Removes duplicates types from a type list.
  30115. * @tparam Type One of the types provided by the given type list.
  30116. * @tparam Other The other types provided by the given type list.
  30117. */
  30118. template<typename Type, typename... Other>
  30119. struct type_list_unique<type_list<Type, Other...>> {
  30120. /*! @brief A type list without duplicate types. */
  30121. using type = std::conditional_t<
  30122. (std::is_same_v<Type, Other> || ...),
  30123. typename type_list_unique<type_list<Other...>>::type,
  30124. type_list_cat_t<type_list<Type>, typename type_list_unique<type_list<Other...>>::type>>;
  30125. };
  30126. /*! @brief Removes duplicates types from a type list. */
  30127. template<>
  30128. struct type_list_unique<type_list<>> {
  30129. /*! @brief A type list without duplicate types. */
  30130. using type = type_list<>;
  30131. };
  30132. /**
  30133. * @brief Helper type.
  30134. * @tparam Type A type list.
  30135. */
  30136. template<typename Type>
  30137. using type_list_unique_t = typename type_list_unique<Type>::type;
  30138. /**
  30139. * @brief Provides the member constant `value` to true if a type list contains a
  30140. * given type, false otherwise.
  30141. * @tparam List Type list.
  30142. * @tparam Type Type to look for.
  30143. */
  30144. template<typename List, typename Type>
  30145. struct type_list_contains;
  30146. /**
  30147. * @copybrief type_list_contains
  30148. * @tparam Type Types provided by the type list.
  30149. * @tparam Other Type to look for.
  30150. */
  30151. template<typename... Type, typename Other>
  30152. struct type_list_contains<type_list<Type...>, Other>: std::disjunction<std::is_same<Type, Other>...> {};
  30153. /**
  30154. * @brief Helper variable template.
  30155. * @tparam List Type list.
  30156. * @tparam Type Type to look for.
  30157. */
  30158. template<typename List, typename Type>
  30159. inline constexpr bool type_list_contains_v = type_list_contains<List, Type>::value;
  30160. /*! @brief Primary template isn't defined on purpose. */
  30161. template<typename...>
  30162. struct type_list_diff;
  30163. /**
  30164. * @brief Computes the difference between two type lists.
  30165. * @tparam Type Types provided by the first type list.
  30166. * @tparam Other Types provided by the second type list.
  30167. */
  30168. template<typename... Type, typename... Other>
  30169. struct type_list_diff<type_list<Type...>, type_list<Other...>> {
  30170. /*! @brief A type list that is the difference between the two type lists. */
  30171. using type = type_list_cat_t<std::conditional_t<type_list_contains_v<type_list<Other...>, Type>, type_list<>, type_list<Type>>...>;
  30172. };
  30173. /**
  30174. * @brief Helper type.
  30175. * @tparam List Type lists between which to compute the difference.
  30176. */
  30177. template<typename... List>
  30178. using type_list_diff_t = typename type_list_diff<List...>::type;
  30179. /**
  30180. * @brief A class to use to push around lists of constant values, nothing more.
  30181. * @tparam Value Values provided by the value list.
  30182. */
  30183. template<auto... Value>
  30184. struct value_list {
  30185. /*! @brief Value list type. */
  30186. using type = value_list;
  30187. /*! @brief Compile-time number of elements in the value list. */
  30188. static constexpr auto size = sizeof...(Value);
  30189. };
  30190. /*! @brief Primary template isn't defined on purpose. */
  30191. template<std::size_t, typename>
  30192. struct value_list_element;
  30193. /**
  30194. * @brief Provides compile-time indexed access to the values of a value list.
  30195. * @tparam Index Index of the value to return.
  30196. * @tparam Value First value provided by the value list.
  30197. * @tparam Other Other values provided by the value list.
  30198. */
  30199. template<std::size_t Index, auto Value, auto... Other>
  30200. struct value_list_element<Index, value_list<Value, Other...>>
  30201. : value_list_element<Index - 1u, value_list<Other...>> {};
  30202. /**
  30203. * @brief Provides compile-time indexed access to the types of a type list.
  30204. * @tparam Value First value provided by the value list.
  30205. * @tparam Other Other values provided by the value list.
  30206. */
  30207. template<auto Value, auto... Other>
  30208. struct value_list_element<0u, value_list<Value, Other...>> {
  30209. /*! @brief Searched value. */
  30210. static constexpr auto value = Value;
  30211. };
  30212. /**
  30213. * @brief Helper type.
  30214. * @tparam Index Index of the value to return.
  30215. * @tparam List Value list to search into.
  30216. */
  30217. template<std::size_t Index, typename List>
  30218. inline constexpr auto value_list_element_v = value_list_element<Index, List>::value;
  30219. /**
  30220. * @brief Concatenates multiple value lists.
  30221. * @tparam Value Values provided by the first value list.
  30222. * @tparam Other Values provided by the second value list.
  30223. * @return A value list composed by the values of both the value lists.
  30224. */
  30225. template<auto... Value, auto... Other>
  30226. constexpr value_list<Value..., Other...> operator+(value_list<Value...>, value_list<Other...>) {
  30227. return {};
  30228. }
  30229. /*! @brief Primary template isn't defined on purpose. */
  30230. template<typename...>
  30231. struct value_list_cat;
  30232. /*! @brief Concatenates multiple value lists. */
  30233. template<>
  30234. struct value_list_cat<> {
  30235. /*! @brief A value list composed by the values of all the value lists. */
  30236. using type = value_list<>;
  30237. };
  30238. /**
  30239. * @brief Concatenates multiple value lists.
  30240. * @tparam Value Values provided by the first value list.
  30241. * @tparam Other Values provided by the second value list.
  30242. * @tparam List Other value lists, if any.
  30243. */
  30244. template<auto... Value, auto... Other, typename... List>
  30245. struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
  30246. /*! @brief A value list composed by the values of all the value lists. */
  30247. using type = typename value_list_cat<value_list<Value..., Other...>, List...>::type;
  30248. };
  30249. /**
  30250. * @brief Concatenates multiple value lists.
  30251. * @tparam Value Values provided by the value list.
  30252. */
  30253. template<auto... Value>
  30254. struct value_list_cat<value_list<Value...>> {
  30255. /*! @brief A value list composed by the values of all the value lists. */
  30256. using type = value_list<Value...>;
  30257. };
  30258. /**
  30259. * @brief Helper type.
  30260. * @tparam List Value lists to concatenate.
  30261. */
  30262. template<typename... List>
  30263. using value_list_cat_t = typename value_list_cat<List...>::type;
  30264. /*! @brief Same as std::is_invocable, but with tuples. */
  30265. template<typename, typename>
  30266. struct is_applicable: std::false_type {};
  30267. /**
  30268. * @copybrief is_applicable
  30269. * @tparam Func A valid function type.
  30270. * @tparam Tuple Tuple-like type.
  30271. * @tparam Args The list of arguments to use to probe the function type.
  30272. */
  30273. template<typename Func, template<typename...> class Tuple, typename... Args>
  30274. struct is_applicable<Func, Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  30275. /**
  30276. * @copybrief is_applicable
  30277. * @tparam Func A valid function type.
  30278. * @tparam Tuple Tuple-like type.
  30279. * @tparam Args The list of arguments to use to probe the function type.
  30280. */
  30281. template<typename Func, template<typename...> class Tuple, typename... Args>
  30282. struct is_applicable<Func, const Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  30283. /**
  30284. * @brief Helper variable template.
  30285. * @tparam Func A valid function type.
  30286. * @tparam Args The list of arguments to use to probe the function type.
  30287. */
  30288. template<typename Func, typename Args>
  30289. inline constexpr bool is_applicable_v = is_applicable<Func, Args>::value;
  30290. /*! @brief Same as std::is_invocable_r, but with tuples for arguments. */
  30291. template<typename, typename, typename>
  30292. struct is_applicable_r: std::false_type {};
  30293. /**
  30294. * @copybrief is_applicable_r
  30295. * @tparam Ret The type to which the return type of the function should be
  30296. * convertible.
  30297. * @tparam Func A valid function type.
  30298. * @tparam Args The list of arguments to use to probe the function type.
  30299. */
  30300. template<typename Ret, typename Func, typename... Args>
  30301. struct is_applicable_r<Ret, Func, std::tuple<Args...>>: std::is_invocable_r<Ret, Func, Args...> {};
  30302. /**
  30303. * @brief Helper variable template.
  30304. * @tparam Ret The type to which the return type of the function should be
  30305. * convertible.
  30306. * @tparam Func A valid function type.
  30307. * @tparam Args The list of arguments to use to probe the function type.
  30308. */
  30309. template<typename Ret, typename Func, typename Args>
  30310. inline constexpr bool is_applicable_r_v = is_applicable_r<Ret, Func, Args>::value;
  30311. /**
  30312. * @brief Provides the member constant `value` to true if a given type is
  30313. * complete, false otherwise.
  30314. * @tparam Type The type to test.
  30315. */
  30316. template<typename Type, typename = void>
  30317. struct is_complete: std::false_type {};
  30318. /*! @copydoc is_complete */
  30319. template<typename Type>
  30320. struct is_complete<Type, std::void_t<decltype(sizeof(Type))>>: std::true_type {};
  30321. /**
  30322. * @brief Helper variable template.
  30323. * @tparam Type The type to test.
  30324. */
  30325. template<typename Type>
  30326. inline constexpr bool is_complete_v = is_complete<Type>::value;
  30327. /**
  30328. * @brief Provides the member constant `value` to true if a given type is an
  30329. * iterator, false otherwise.
  30330. * @tparam Type The type to test.
  30331. */
  30332. template<typename Type, typename = void>
  30333. struct is_iterator: std::false_type {};
  30334. /**
  30335. * @cond TURN_OFF_DOXYGEN
  30336. * Internal details not to be documented.
  30337. */
  30338. namespace internal {
  30339. template<typename, typename = void>
  30340. struct has_iterator_category: std::false_type {};
  30341. template<typename Type>
  30342. struct has_iterator_category<Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>: std::true_type {};
  30343. } // namespace internal
  30344. /**
  30345. * Internal details not to be documented.
  30346. * @endcond
  30347. */
  30348. /*! @copydoc is_iterator */
  30349. template<typename Type>
  30350. struct is_iterator<Type, std::enable_if_t<!std::is_same_v<std::remove_const_t<std::remove_pointer_t<Type>>, void>>>
  30351. : internal::has_iterator_category<Type> {};
  30352. /**
  30353. * @brief Helper variable template.
  30354. * @tparam Type The type to test.
  30355. */
  30356. template<typename Type>
  30357. inline constexpr bool is_iterator_v = is_iterator<Type>::value;
  30358. /**
  30359. * @brief Provides the member constant `value` to true if a given type is both
  30360. * an empty and non-final class, false otherwise.
  30361. * @tparam Type The type to test
  30362. */
  30363. template<typename Type>
  30364. struct is_ebco_eligible
  30365. : std::conjunction<std::is_empty<Type>, std::negation<std::is_final<Type>>> {};
  30366. /**
  30367. * @brief Helper variable template.
  30368. * @tparam Type The type to test.
  30369. */
  30370. template<typename Type>
  30371. inline constexpr bool is_ebco_eligible_v = is_ebco_eligible<Type>::value;
  30372. /**
  30373. * @brief Provides the member constant `value` to true if `Type::is_transparent`
  30374. * is valid and denotes a type, false otherwise.
  30375. * @tparam Type The type to test.
  30376. */
  30377. template<typename Type, typename = void>
  30378. struct is_transparent: std::false_type {};
  30379. /*! @copydoc is_transparent */
  30380. template<typename Type>
  30381. struct is_transparent<Type, std::void_t<typename Type::is_transparent>>: std::true_type {};
  30382. /**
  30383. * @brief Helper variable template.
  30384. * @tparam Type The type to test.
  30385. */
  30386. template<typename Type>
  30387. inline constexpr bool is_transparent_v = is_transparent<Type>::value;
  30388. /**
  30389. * @brief Provides the member constant `value` to true if a given type is
  30390. * equality comparable, false otherwise.
  30391. * @tparam Type The type to test.
  30392. */
  30393. template<typename Type, typename = void>
  30394. struct is_equality_comparable: std::false_type {};
  30395. /**
  30396. * @cond TURN_OFF_DOXYGEN
  30397. * Internal details not to be documented.
  30398. */
  30399. namespace internal {
  30400. template<typename, typename = void>
  30401. struct has_tuple_size_value: std::false_type {};
  30402. template<typename Type>
  30403. struct has_tuple_size_value<Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>: std::true_type {};
  30404. template<typename Type, std::size_t... Index>
  30405. [[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
  30406. return (is_equality_comparable<std::tuple_element_t<Index, Type>>::value && ...);
  30407. }
  30408. template<typename>
  30409. [[nodiscard]] constexpr bool maybe_equality_comparable(choice_t<0>) {
  30410. return true;
  30411. }
  30412. template<typename Type>
  30413. [[nodiscard]] constexpr auto maybe_equality_comparable(choice_t<1>) -> decltype(std::declval<typename Type::value_type>(), bool{}) {
  30414. if constexpr(is_iterator_v<Type>) {
  30415. return true;
  30416. } else if constexpr(std::is_same_v<typename Type::value_type, Type>) {
  30417. return maybe_equality_comparable<Type>(choice<0>);
  30418. } else {
  30419. return is_equality_comparable<typename Type::value_type>::value;
  30420. }
  30421. }
  30422. template<typename Type>
  30423. [[nodiscard]] constexpr std::enable_if_t<is_complete_v<std::tuple_size<std::remove_const_t<Type>>>, bool> maybe_equality_comparable(choice_t<2>) {
  30424. if constexpr(has_tuple_size_value<Type>::value) {
  30425. return unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
  30426. } else {
  30427. return maybe_equality_comparable<Type>(choice<1>);
  30428. }
  30429. }
  30430. } // namespace internal
  30431. /**
  30432. * Internal details not to be documented.
  30433. * @endcond
  30434. */
  30435. /*! @copydoc is_equality_comparable */
  30436. template<typename Type>
  30437. struct is_equality_comparable<Type, std::void_t<decltype(std::declval<Type>() == std::declval<Type>())>>
  30438. : std::bool_constant<internal::maybe_equality_comparable<Type>(choice<2>)> {};
  30439. /**
  30440. * @brief Helper variable template.
  30441. * @tparam Type The type to test.
  30442. */
  30443. template<typename Type>
  30444. inline constexpr bool is_equality_comparable_v = is_equality_comparable<Type>::value;
  30445. /**
  30446. * @brief Transcribes the constness of a type to another type.
  30447. * @tparam To The type to which to transcribe the constness.
  30448. * @tparam From The type from which to transcribe the constness.
  30449. */
  30450. template<typename To, typename From>
  30451. struct constness_as {
  30452. /*! @brief The type resulting from the transcription of the constness. */
  30453. using type = std::remove_const_t<To>;
  30454. };
  30455. /*! @copydoc constness_as */
  30456. template<typename To, typename From>
  30457. struct constness_as<To, const From> {
  30458. /*! @brief The type resulting from the transcription of the constness. */
  30459. using type = std::add_const_t<To>;
  30460. };
  30461. /**
  30462. * @brief Alias template to facilitate the transcription of the constness.
  30463. * @tparam To The type to which to transcribe the constness.
  30464. * @tparam From The type from which to transcribe the constness.
  30465. */
  30466. template<typename To, typename From>
  30467. using constness_as_t = typename constness_as<To, From>::type;
  30468. /**
  30469. * @brief Extracts the class of a non-static member object or function.
  30470. * @tparam Member A pointer to a non-static member object or function.
  30471. */
  30472. template<typename Member>
  30473. class member_class {
  30474. static_assert(std::is_member_pointer_v<Member>, "Invalid pointer type to non-static member object or function");
  30475. template<typename Class, typename Ret, typename... Args>
  30476. static Class *clazz(Ret (Class::*)(Args...));
  30477. template<typename Class, typename Ret, typename... Args>
  30478. static Class *clazz(Ret (Class::*)(Args...) const);
  30479. template<typename Class, typename Type>
  30480. static Class *clazz(Type Class::*);
  30481. public:
  30482. /*! @brief The class of the given non-static member object or function. */
  30483. using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
  30484. };
  30485. /**
  30486. * @brief Helper type.
  30487. * @tparam Member A pointer to a non-static member object or function.
  30488. */
  30489. template<typename Member>
  30490. using member_class_t = typename member_class<Member>::type;
  30491. } // namespace entt
  30492. #endif
  30493. // #include "fwd.hpp"
  30494. #ifndef ENTT_CONTAINER_FWD_HPP
  30495. #define ENTT_CONTAINER_FWD_HPP
  30496. #include <functional>
  30497. #include <memory>
  30498. namespace entt {
  30499. template<
  30500. typename Key,
  30501. typename Type,
  30502. typename = std::hash<Key>,
  30503. typename = std::equal_to<Key>,
  30504. typename = std::allocator<std::pair<const Key, Type>>>
  30505. class dense_map;
  30506. template<
  30507. typename Type,
  30508. typename = std::hash<Type>,
  30509. typename = std::equal_to<Type>,
  30510. typename = std::allocator<Type>>
  30511. class dense_set;
  30512. } // namespace entt
  30513. #endif
  30514. namespace entt {
  30515. /**
  30516. * @cond TURN_OFF_DOXYGEN
  30517. * Internal details not to be documented.
  30518. */
  30519. namespace internal {
  30520. template<typename Key, typename Type>
  30521. struct dense_map_node final {
  30522. using value_type = std::pair<Key, Type>;
  30523. template<typename... Args>
  30524. dense_map_node(const std::size_t pos, Args &&...args)
  30525. : next{pos},
  30526. element{std::forward<Args>(args)...} {}
  30527. template<typename Allocator, typename... Args>
  30528. dense_map_node(std::allocator_arg_t, const Allocator &allocator, const std::size_t pos, Args &&...args)
  30529. : next{pos},
  30530. element{entt::make_obj_using_allocator<value_type>(allocator, std::forward<Args>(args)...)} {}
  30531. template<typename Allocator>
  30532. dense_map_node(std::allocator_arg_t, const Allocator &allocator, const dense_map_node &other)
  30533. : next{other.next},
  30534. element{entt::make_obj_using_allocator<value_type>(allocator, other.element)} {}
  30535. template<typename Allocator>
  30536. dense_map_node(std::allocator_arg_t, const Allocator &allocator, dense_map_node &&other)
  30537. : next{other.next},
  30538. element{entt::make_obj_using_allocator<value_type>(allocator, std::move(other.element))} {}
  30539. std::size_t next;
  30540. value_type element;
  30541. };
  30542. template<typename It>
  30543. class dense_map_iterator final {
  30544. template<typename>
  30545. friend class dense_map_iterator;
  30546. using first_type = decltype(std::as_const(std::declval<It>()->element.first));
  30547. using second_type = decltype((std::declval<It>()->element.second));
  30548. public:
  30549. using value_type = std::pair<first_type, second_type>;
  30550. using pointer = input_iterator_pointer<value_type>;
  30551. using reference = value_type;
  30552. using difference_type = std::ptrdiff_t;
  30553. using iterator_category = std::input_iterator_tag;
  30554. dense_map_iterator() ENTT_NOEXCEPT
  30555. : it{} {}
  30556. dense_map_iterator(const It iter) ENTT_NOEXCEPT
  30557. : it{iter} {}
  30558. template<typename Other, typename = std::enable_if_t<!std::is_same_v<It, Other> && std::is_constructible_v<It, Other>>>
  30559. dense_map_iterator(const dense_map_iterator<Other> &other) ENTT_NOEXCEPT
  30560. : it{other.it} {}
  30561. dense_map_iterator &operator++() ENTT_NOEXCEPT {
  30562. return ++it, *this;
  30563. }
  30564. dense_map_iterator operator++(int) ENTT_NOEXCEPT {
  30565. dense_map_iterator orig = *this;
  30566. return ++(*this), orig;
  30567. }
  30568. dense_map_iterator &operator--() ENTT_NOEXCEPT {
  30569. return --it, *this;
  30570. }
  30571. dense_map_iterator operator--(int) ENTT_NOEXCEPT {
  30572. dense_map_iterator orig = *this;
  30573. return operator--(), orig;
  30574. }
  30575. dense_map_iterator &operator+=(const difference_type value) ENTT_NOEXCEPT {
  30576. it += value;
  30577. return *this;
  30578. }
  30579. dense_map_iterator operator+(const difference_type value) const ENTT_NOEXCEPT {
  30580. dense_map_iterator copy = *this;
  30581. return (copy += value);
  30582. }
  30583. dense_map_iterator &operator-=(const difference_type value) ENTT_NOEXCEPT {
  30584. return (*this += -value);
  30585. }
  30586. dense_map_iterator operator-(const difference_type value) const ENTT_NOEXCEPT {
  30587. return (*this + -value);
  30588. }
  30589. [[nodiscard]] reference operator[](const difference_type value) const ENTT_NOEXCEPT {
  30590. return {it[value].element.first, it[value].element.second};
  30591. }
  30592. [[nodiscard]] pointer operator->() const ENTT_NOEXCEPT {
  30593. return operator*();
  30594. }
  30595. [[nodiscard]] reference operator*() const ENTT_NOEXCEPT {
  30596. return {it->element.first, it->element.second};
  30597. }
  30598. template<typename ILhs, typename IRhs>
  30599. friend std::ptrdiff_t operator-(const dense_map_iterator<ILhs> &, const dense_map_iterator<IRhs> &) ENTT_NOEXCEPT;
  30600. template<typename ILhs, typename IRhs>
  30601. friend bool operator==(const dense_map_iterator<ILhs> &, const dense_map_iterator<IRhs> &) ENTT_NOEXCEPT;
  30602. template<typename ILhs, typename IRhs>
  30603. friend bool operator<(const dense_map_iterator<ILhs> &, const dense_map_iterator<IRhs> &) ENTT_NOEXCEPT;
  30604. private:
  30605. It it;
  30606. };
  30607. template<typename ILhs, typename IRhs>
  30608. [[nodiscard]] std::ptrdiff_t operator-(const dense_map_iterator<ILhs> &lhs, const dense_map_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  30609. return lhs.it - rhs.it;
  30610. }
  30611. template<typename ILhs, typename IRhs>
  30612. [[nodiscard]] bool operator==(const dense_map_iterator<ILhs> &lhs, const dense_map_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  30613. return lhs.it == rhs.it;
  30614. }
  30615. template<typename ILhs, typename IRhs>
  30616. [[nodiscard]] bool operator!=(const dense_map_iterator<ILhs> &lhs, const dense_map_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  30617. return !(lhs == rhs);
  30618. }
  30619. template<typename ILhs, typename IRhs>
  30620. [[nodiscard]] bool operator<(const dense_map_iterator<ILhs> &lhs, const dense_map_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  30621. return lhs.it < rhs.it;
  30622. }
  30623. template<typename ILhs, typename IRhs>
  30624. [[nodiscard]] bool operator>(const dense_map_iterator<ILhs> &lhs, const dense_map_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  30625. return rhs < lhs;
  30626. }
  30627. template<typename ILhs, typename IRhs>
  30628. [[nodiscard]] bool operator<=(const dense_map_iterator<ILhs> &lhs, const dense_map_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  30629. return !(lhs > rhs);
  30630. }
  30631. template<typename ILhs, typename IRhs>
  30632. [[nodiscard]] bool operator>=(const dense_map_iterator<ILhs> &lhs, const dense_map_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  30633. return !(lhs < rhs);
  30634. }
  30635. template<typename It>
  30636. class dense_map_local_iterator final {
  30637. template<typename>
  30638. friend class dense_map_local_iterator;
  30639. using first_type = decltype(std::as_const(std::declval<It>()->element.first));
  30640. using second_type = decltype((std::declval<It>()->element.second));
  30641. public:
  30642. using value_type = std::pair<first_type, second_type>;
  30643. using pointer = input_iterator_pointer<value_type>;
  30644. using reference = value_type;
  30645. using difference_type = std::ptrdiff_t;
  30646. using iterator_category = std::input_iterator_tag;
  30647. dense_map_local_iterator() ENTT_NOEXCEPT
  30648. : it{},
  30649. offset{} {}
  30650. dense_map_local_iterator(It iter, const std::size_t pos) ENTT_NOEXCEPT
  30651. : it{iter},
  30652. offset{pos} {}
  30653. template<typename Other, typename = std::enable_if_t<!std::is_same_v<It, Other> && std::is_constructible_v<It, Other>>>
  30654. dense_map_local_iterator(const dense_map_local_iterator<Other> &other) ENTT_NOEXCEPT
  30655. : it{other.it},
  30656. offset{other.offset} {}
  30657. dense_map_local_iterator &operator++() ENTT_NOEXCEPT {
  30658. return offset = it[offset].next, *this;
  30659. }
  30660. dense_map_local_iterator operator++(int) ENTT_NOEXCEPT {
  30661. dense_map_local_iterator orig = *this;
  30662. return ++(*this), orig;
  30663. }
  30664. [[nodiscard]] pointer operator->() const ENTT_NOEXCEPT {
  30665. return operator*();
  30666. }
  30667. [[nodiscard]] reference operator*() const ENTT_NOEXCEPT {
  30668. return {it[offset].element.first, it[offset].element.second};
  30669. }
  30670. [[nodiscard]] std::size_t index() const ENTT_NOEXCEPT {
  30671. return offset;
  30672. }
  30673. private:
  30674. It it;
  30675. std::size_t offset;
  30676. };
  30677. template<typename ILhs, typename IRhs>
  30678. [[nodiscard]] bool operator==(const dense_map_local_iterator<ILhs> &lhs, const dense_map_local_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  30679. return lhs.index() == rhs.index();
  30680. }
  30681. template<typename ILhs, typename IRhs>
  30682. [[nodiscard]] bool operator!=(const dense_map_local_iterator<ILhs> &lhs, const dense_map_local_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  30683. return !(lhs == rhs);
  30684. }
  30685. } // namespace internal
  30686. /**
  30687. * Internal details not to be documented.
  30688. * @endcond
  30689. */
  30690. /**
  30691. * @brief Associative container for key-value pairs with unique keys.
  30692. *
  30693. * Internally, elements are organized into buckets. Which bucket an element is
  30694. * placed into depends entirely on the hash of its key. Keys with the same hash
  30695. * code appear in the same bucket.
  30696. *
  30697. * @tparam Key Key type of the associative container.
  30698. * @tparam Type Mapped type of the associative container.
  30699. * @tparam Hash Type of function to use to hash the keys.
  30700. * @tparam KeyEqual Type of function to use to compare the keys for equality.
  30701. * @tparam Allocator Type of allocator used to manage memory and elements.
  30702. */
  30703. template<typename Key, typename Type, typename Hash, typename KeyEqual, typename Allocator>
  30704. class dense_map {
  30705. static constexpr float default_threshold = 0.875f;
  30706. static constexpr std::size_t minimum_capacity = 8u;
  30707. using node_type = internal::dense_map_node<Key, Type>;
  30708. using alloc_traits = typename std::allocator_traits<Allocator>;
  30709. static_assert(std::is_same_v<typename alloc_traits::value_type, std::pair<const Key, Type>>, "Invalid value type");
  30710. using sparse_container_type = std::vector<std::size_t, typename alloc_traits::template rebind_alloc<std::size_t>>;
  30711. using packed_container_type = std::vector<node_type, typename alloc_traits::template rebind_alloc<node_type>>;
  30712. template<typename Other>
  30713. [[nodiscard]] std::size_t key_to_bucket(const Other &key) const ENTT_NOEXCEPT {
  30714. return fast_mod(sparse.second()(key), bucket_count());
  30715. }
  30716. template<typename Other>
  30717. [[nodiscard]] auto constrained_find(const Other &key, std::size_t bucket) {
  30718. for(auto it = begin(bucket), last = end(bucket); it != last; ++it) {
  30719. if(packed.second()(it->first, key)) {
  30720. return begin() + static_cast<typename iterator::difference_type>(it.index());
  30721. }
  30722. }
  30723. return end();
  30724. }
  30725. template<typename Other>
  30726. [[nodiscard]] auto constrained_find(const Other &key, std::size_t bucket) const {
  30727. for(auto it = cbegin(bucket), last = cend(bucket); it != last; ++it) {
  30728. if(packed.second()(it->first, key)) {
  30729. return cbegin() + static_cast<typename iterator::difference_type>(it.index());
  30730. }
  30731. }
  30732. return cend();
  30733. }
  30734. template<typename Other, typename... Args>
  30735. [[nodiscard]] auto insert_or_do_nothing(Other &&key, Args &&...args) {
  30736. const auto index = key_to_bucket(key);
  30737. if(auto it = constrained_find(key, index); it != end()) {
  30738. return std::make_pair(it, false);
  30739. }
  30740. 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)...));
  30741. sparse.first()[index] = packed.first().size() - 1u;
  30742. rehash_if_required();
  30743. return std::make_pair(--end(), true);
  30744. }
  30745. template<typename Other, typename Arg>
  30746. [[nodiscard]] auto insert_or_overwrite(Other &&key, Arg &&value) {
  30747. const auto index = key_to_bucket(key);
  30748. if(auto it = constrained_find(key, index); it != end()) {
  30749. it->second = std::forward<Arg>(value);
  30750. return std::make_pair(it, false);
  30751. }
  30752. packed.first().emplace_back(sparse.first()[index], std::forward<Other>(key), std::forward<Arg>(value));
  30753. sparse.first()[index] = packed.first().size() - 1u;
  30754. rehash_if_required();
  30755. return std::make_pair(--end(), true);
  30756. }
  30757. void move_and_pop(const std::size_t pos) {
  30758. if(const auto last = size() - 1u; pos != last) {
  30759. packed.first()[pos] = std::move(packed.first().back());
  30760. size_type *curr = sparse.first().data() + key_to_bucket(packed.first().back().element.first);
  30761. for(; *curr != last; curr = &packed.first()[*curr].next) {}
  30762. *curr = pos;
  30763. }
  30764. packed.first().pop_back();
  30765. }
  30766. void rehash_if_required() {
  30767. if(size() > (bucket_count() * max_load_factor())) {
  30768. rehash(bucket_count() * 2u);
  30769. }
  30770. }
  30771. public:
  30772. /*! @brief Key type of the container. */
  30773. using key_type = Key;
  30774. /*! @brief Mapped type of the container. */
  30775. using mapped_type = Type;
  30776. /*! @brief Key-value type of the container. */
  30777. using value_type = std::pair<const Key, Type>;
  30778. /*! @brief Unsigned integer type. */
  30779. using size_type = std::size_t;
  30780. /*! @brief Type of function to use to hash the keys. */
  30781. using hasher = Hash;
  30782. /*! @brief Type of function to use to compare the keys for equality. */
  30783. using key_equal = KeyEqual;
  30784. /*! @brief Allocator type. */
  30785. using allocator_type = Allocator;
  30786. /*! @brief Input iterator type. */
  30787. using iterator = internal::dense_map_iterator<typename packed_container_type::iterator>;
  30788. /*! @brief Constant input iterator type. */
  30789. using const_iterator = internal::dense_map_iterator<typename packed_container_type::const_iterator>;
  30790. /*! @brief Input iterator type. */
  30791. using local_iterator = internal::dense_map_local_iterator<typename packed_container_type::iterator>;
  30792. /*! @brief Constant input iterator type. */
  30793. using const_local_iterator = internal::dense_map_local_iterator<typename packed_container_type::const_iterator>;
  30794. /*! @brief Default constructor. */
  30795. dense_map()
  30796. : dense_map(minimum_capacity) {}
  30797. /**
  30798. * @brief Constructs an empty container with a given allocator.
  30799. * @param allocator The allocator to use.
  30800. */
  30801. explicit dense_map(const allocator_type &allocator)
  30802. : dense_map{minimum_capacity, hasher{}, key_equal{}, allocator} {}
  30803. /**
  30804. * @brief Constructs an empty container with a given allocator and user
  30805. * supplied minimal number of buckets.
  30806. * @param bucket_count Minimal number of buckets.
  30807. * @param allocator The allocator to use.
  30808. */
  30809. dense_map(const size_type bucket_count, const allocator_type &allocator)
  30810. : dense_map{bucket_count, hasher{}, key_equal{}, allocator} {}
  30811. /**
  30812. * @brief Constructs an empty container with a given allocator, hash
  30813. * function and user supplied minimal number of buckets.
  30814. * @param bucket_count Minimal number of buckets.
  30815. * @param hash Hash function to use.
  30816. * @param allocator The allocator to use.
  30817. */
  30818. dense_map(const size_type bucket_count, const hasher &hash, const allocator_type &allocator)
  30819. : dense_map{bucket_count, hash, key_equal{}, allocator} {}
  30820. /**
  30821. * @brief Constructs an empty container with a given allocator, hash
  30822. * function, compare function and user supplied minimal number of buckets.
  30823. * @param bucket_count Minimal number of buckets.
  30824. * @param hash Hash function to use.
  30825. * @param equal Compare function to use.
  30826. * @param allocator The allocator to use.
  30827. */
  30828. explicit dense_map(const size_type bucket_count, const hasher &hash = hasher{}, const key_equal &equal = key_equal{}, const allocator_type &allocator = allocator_type{})
  30829. : sparse{allocator, hash},
  30830. packed{allocator, equal},
  30831. threshold{default_threshold} {
  30832. rehash(bucket_count);
  30833. }
  30834. /*! @brief Default copy constructor. */
  30835. dense_map(const dense_map &) = default;
  30836. /**
  30837. * @brief Allocator-extended copy constructor.
  30838. * @param other The instance to copy from.
  30839. * @param allocator The allocator to use.
  30840. */
  30841. dense_map(const dense_map &other, const allocator_type &allocator)
  30842. : sparse{std::piecewise_construct, std::forward_as_tuple(other.sparse.first(), allocator), std::forward_as_tuple(other.sparse.second())},
  30843. packed{std::piecewise_construct, std::forward_as_tuple(other.packed.first(), allocator), std::forward_as_tuple(other.packed.second())},
  30844. threshold{other.threshold} {}
  30845. /*! @brief Default move constructor. */
  30846. dense_map(dense_map &&) = default;
  30847. /**
  30848. * @brief Allocator-extended move constructor.
  30849. * @param other The instance to move from.
  30850. * @param allocator The allocator to use.
  30851. */
  30852. dense_map(dense_map &&other, const allocator_type &allocator)
  30853. : sparse{std::piecewise_construct, std::forward_as_tuple(std::move(other.sparse.first()), allocator), std::forward_as_tuple(std::move(other.sparse.second()))},
  30854. packed{std::piecewise_construct, std::forward_as_tuple(std::move(other.packed.first()), allocator), std::forward_as_tuple(std::move(other.packed.second()))},
  30855. threshold{other.threshold} {}
  30856. /**
  30857. * @brief Default copy assignment operator.
  30858. * @return This container.
  30859. */
  30860. dense_map &operator=(const dense_map &) = default;
  30861. /**
  30862. * @brief Default move assignment operator.
  30863. * @return This container.
  30864. */
  30865. dense_map &operator=(dense_map &&) = default;
  30866. /**
  30867. * @brief Returns the associated allocator.
  30868. * @return The associated allocator.
  30869. */
  30870. [[nodiscard]] constexpr allocator_type get_allocator() const ENTT_NOEXCEPT {
  30871. return sparse.first().get_allocator();
  30872. }
  30873. /**
  30874. * @brief Returns an iterator to the beginning.
  30875. *
  30876. * The returned iterator points to the first instance of the internal array.
  30877. * If the array is empty, the returned iterator will be equal to `end()`.
  30878. *
  30879. * @return An iterator to the first instance of the internal array.
  30880. */
  30881. [[nodiscard]] const_iterator cbegin() const ENTT_NOEXCEPT {
  30882. return packed.first().begin();
  30883. }
  30884. /*! @copydoc cbegin */
  30885. [[nodiscard]] const_iterator begin() const ENTT_NOEXCEPT {
  30886. return cbegin();
  30887. }
  30888. /*! @copydoc begin */
  30889. [[nodiscard]] iterator begin() ENTT_NOEXCEPT {
  30890. return packed.first().begin();
  30891. }
  30892. /**
  30893. * @brief Returns an iterator to the end.
  30894. *
  30895. * The returned iterator points to the element following the last instance
  30896. * of the internal array. Attempting to dereference the returned iterator
  30897. * results in undefined behavior.
  30898. *
  30899. * @return An iterator to the element following the last instance of the
  30900. * internal array.
  30901. */
  30902. [[nodiscard]] const_iterator cend() const ENTT_NOEXCEPT {
  30903. return packed.first().end();
  30904. }
  30905. /*! @copydoc cend */
  30906. [[nodiscard]] const_iterator end() const ENTT_NOEXCEPT {
  30907. return cend();
  30908. }
  30909. /*! @copydoc end */
  30910. [[nodiscard]] iterator end() ENTT_NOEXCEPT {
  30911. return packed.first().end();
  30912. }
  30913. /**
  30914. * @brief Checks whether a container is empty.
  30915. * @return True if the container is empty, false otherwise.
  30916. */
  30917. [[nodiscard]] bool empty() const ENTT_NOEXCEPT {
  30918. return packed.first().empty();
  30919. }
  30920. /**
  30921. * @brief Returns the number of elements in a container.
  30922. * @return Number of elements in a container.
  30923. */
  30924. [[nodiscard]] size_type size() const ENTT_NOEXCEPT {
  30925. return packed.first().size();
  30926. }
  30927. /*! @brief Clears the container. */
  30928. void clear() ENTT_NOEXCEPT {
  30929. sparse.first().clear();
  30930. packed.first().clear();
  30931. rehash(0u);
  30932. }
  30933. /**
  30934. * @brief Inserts an element into the container, if the key does not exist.
  30935. * @param value A key-value pair eventually convertible to the value type.
  30936. * @return A pair consisting of an iterator to the inserted element (or to
  30937. * the element that prevented the insertion) and a bool denoting whether the
  30938. * insertion took place.
  30939. */
  30940. std::pair<iterator, bool> insert(const value_type &value) {
  30941. return insert_or_do_nothing(value.first, value.second);
  30942. }
  30943. /*! @copydoc insert */
  30944. std::pair<iterator, bool> insert(value_type &&value) {
  30945. return insert_or_do_nothing(std::move(value.first), std::move(value.second));
  30946. }
  30947. /**
  30948. * @copydoc insert
  30949. * @tparam Arg Type of the key-value pair to insert into the container.
  30950. */
  30951. template<typename Arg>
  30952. std::enable_if_t<std::is_constructible_v<value_type, Arg &&>, std::pair<iterator, bool>>
  30953. insert(Arg &&value) {
  30954. return insert_or_do_nothing(std::forward<Arg>(value).first, std::forward<Arg>(value).second);
  30955. }
  30956. /**
  30957. * @brief Inserts elements into the container, if their keys do not exist.
  30958. * @tparam It Type of input iterator.
  30959. * @param first An iterator to the first element of the range of elements.
  30960. * @param last An iterator past the last element of the range of elements.
  30961. */
  30962. template<typename It>
  30963. void insert(It first, It last) {
  30964. for(; first != last; ++first) {
  30965. insert(*first);
  30966. }
  30967. }
  30968. /**
  30969. * @brief Inserts an element into the container or assigns to the current
  30970. * element if the key already exists.
  30971. * @tparam Arg Type of the value to insert or assign.
  30972. * @param key A key used both to look up and to insert if not found.
  30973. * @param value A value to insert or assign.
  30974. * @return A pair consisting of an iterator to the element and a bool
  30975. * denoting whether the insertion took place.
  30976. */
  30977. template<typename Arg>
  30978. std::pair<iterator, bool> insert_or_assign(const key_type &key, Arg &&value) {
  30979. return insert_or_overwrite(key, std::forward<Arg>(value));
  30980. }
  30981. /*! @copydoc insert_or_assign */
  30982. template<typename Arg>
  30983. std::pair<iterator, bool> insert_or_assign(key_type &&key, Arg &&value) {
  30984. return insert_or_overwrite(std::move(key), std::forward<Arg>(value));
  30985. }
  30986. /**
  30987. * @brief Constructs an element in-place, if the key does not exist.
  30988. *
  30989. * The element is also constructed when the container already has the key,
  30990. * in which case the newly constructed object is destroyed immediately.
  30991. *
  30992. * @tparam Args Types of arguments to forward to the constructor of the
  30993. * element.
  30994. * @param args Arguments to forward to the constructor of the element.
  30995. * @return A pair consisting of an iterator to the inserted element (or to
  30996. * the element that prevented the insertion) and a bool denoting whether the
  30997. * insertion took place.
  30998. */
  30999. template<typename... Args>
  31000. std::pair<iterator, bool> emplace([[maybe_unused]] Args &&...args) {
  31001. if constexpr(sizeof...(Args) == 0u) {
  31002. return insert_or_do_nothing(key_type{});
  31003. } else if constexpr(sizeof...(Args) == 1u) {
  31004. return insert_or_do_nothing(std::forward<Args>(args).first..., std::forward<Args>(args).second...);
  31005. } else if constexpr(sizeof...(Args) == 2u) {
  31006. return insert_or_do_nothing(std::forward<Args>(args)...);
  31007. } else {
  31008. auto &node = packed.first().emplace_back(packed.first().size(), std::forward<Args>(args)...);
  31009. const auto index = key_to_bucket(node.element.first);
  31010. if(auto it = constrained_find(node.element.first, index); it != end()) {
  31011. packed.first().pop_back();
  31012. return std::make_pair(it, false);
  31013. }
  31014. std::swap(node.next, sparse.first()[index]);
  31015. rehash_if_required();
  31016. return std::make_pair(--end(), true);
  31017. }
  31018. }
  31019. /**
  31020. * @brief Inserts in-place if the key does not exist, does nothing if the
  31021. * key exists.
  31022. * @tparam Args Types of arguments to forward to the constructor of the
  31023. * element.
  31024. * @param key A key used both to look up and to insert if not found.
  31025. * @param args Arguments to forward to the constructor of the element.
  31026. * @return A pair consisting of an iterator to the inserted element (or to
  31027. * the element that prevented the insertion) and a bool denoting whether the
  31028. * insertion took place.
  31029. */
  31030. template<typename... Args>
  31031. std::pair<iterator, bool> try_emplace(const key_type &key, Args &&...args) {
  31032. return insert_or_do_nothing(key, std::forward<Args>(args)...);
  31033. }
  31034. /*! @copydoc try_emplace */
  31035. template<typename... Args>
  31036. std::pair<iterator, bool> try_emplace(key_type &&key, Args &&...args) {
  31037. return insert_or_do_nothing(std::move(key), std::forward<Args>(args)...);
  31038. }
  31039. /**
  31040. * @brief Removes an element from a given position.
  31041. * @param pos An iterator to the element to remove.
  31042. * @return An iterator following the removed element.
  31043. */
  31044. iterator erase(const_iterator pos) {
  31045. const auto diff = pos - cbegin();
  31046. erase(pos->first);
  31047. return begin() + diff;
  31048. }
  31049. /**
  31050. * @brief Removes the given elements from a container.
  31051. * @param first An iterator to the first element of the range of elements.
  31052. * @param last An iterator past the last element of the range of elements.
  31053. * @return An iterator following the last removed element.
  31054. */
  31055. iterator erase(const_iterator first, const_iterator last) {
  31056. const auto dist = first - cbegin();
  31057. for(auto from = last - cbegin(); from != dist; --from) {
  31058. erase(packed.first()[from - 1u].element.first);
  31059. }
  31060. return (begin() + dist);
  31061. }
  31062. /**
  31063. * @brief Removes the element associated with a given key.
  31064. * @param key A key value of an element to remove.
  31065. * @return Number of elements removed (either 0 or 1).
  31066. */
  31067. size_type erase(const key_type &key) {
  31068. for(size_type *curr = sparse.first().data() + key_to_bucket(key); *curr != (std::numeric_limits<size_type>::max)(); curr = &packed.first()[*curr].next) {
  31069. if(packed.second()(packed.first()[*curr].element.first, key)) {
  31070. const auto index = *curr;
  31071. *curr = packed.first()[*curr].next;
  31072. move_and_pop(index);
  31073. return 1u;
  31074. }
  31075. }
  31076. return 0u;
  31077. }
  31078. /**
  31079. * @brief Exchanges the contents with those of a given container.
  31080. * @param other Container to exchange the content with.
  31081. */
  31082. void swap(dense_map &other) {
  31083. using std::swap;
  31084. swap(sparse, other.sparse);
  31085. swap(packed, other.packed);
  31086. swap(threshold, other.threshold);
  31087. }
  31088. /**
  31089. * @brief Accesses a given element with bounds checking.
  31090. * @param key A key of an element to find.
  31091. * @return A reference to the mapped value of the requested element.
  31092. */
  31093. [[nodiscard]] mapped_type &at(const key_type &key) {
  31094. auto it = find(key);
  31095. ENTT_ASSERT(it != end(), "Invalid key");
  31096. return it->second;
  31097. }
  31098. /*! @copydoc at */
  31099. [[nodiscard]] const mapped_type &at(const key_type &key) const {
  31100. auto it = find(key);
  31101. ENTT_ASSERT(it != cend(), "Invalid key");
  31102. return it->second;
  31103. }
  31104. /**
  31105. * @brief Accesses or inserts a given element.
  31106. * @param key A key of an element to find or insert.
  31107. * @return A reference to the mapped value of the requested element.
  31108. */
  31109. [[nodiscard]] mapped_type &operator[](const key_type &key) {
  31110. return insert_or_do_nothing(key).first->second;
  31111. }
  31112. /**
  31113. * @brief Accesses or inserts a given element.
  31114. * @param key A key of an element to find or insert.
  31115. * @return A reference to the mapped value of the requested element.
  31116. */
  31117. [[nodiscard]] mapped_type &operator[](key_type &&key) {
  31118. return insert_or_do_nothing(std::move(key)).first->second;
  31119. }
  31120. /**
  31121. * @brief Finds an element with a given key.
  31122. * @param key Key value of an element to search for.
  31123. * @return An iterator to an element with the given key. If no such element
  31124. * is found, a past-the-end iterator is returned.
  31125. */
  31126. [[nodiscard]] iterator find(const key_type &key) {
  31127. return constrained_find(key, key_to_bucket(key));
  31128. }
  31129. /*! @copydoc find */
  31130. [[nodiscard]] const_iterator find(const key_type &key) const {
  31131. return constrained_find(key, key_to_bucket(key));
  31132. }
  31133. /**
  31134. * @brief Finds an element with a key that compares _equivalent_ to a given
  31135. * value.
  31136. * @tparam Other Type of the key value of an element to search for.
  31137. * @param key Key value of an element to search for.
  31138. * @return An iterator to an element with the given key. If no such element
  31139. * is found, a past-the-end iterator is returned.
  31140. */
  31141. template<typename Other>
  31142. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, iterator>>
  31143. find(const Other &key) {
  31144. return constrained_find(key, key_to_bucket(key));
  31145. }
  31146. /*! @copydoc find */
  31147. template<typename Other>
  31148. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, const_iterator>>
  31149. find(const Other &key) const {
  31150. return constrained_find(key, key_to_bucket(key));
  31151. }
  31152. /**
  31153. * @brief Checks if the container contains an element with a given key.
  31154. * @param key Key value of an element to search for.
  31155. * @return True if there is such an element, false otherwise.
  31156. */
  31157. [[nodiscard]] bool contains(const key_type &key) const {
  31158. return (find(key) != cend());
  31159. }
  31160. /**
  31161. * @brief Checks if the container contains an element with a key that
  31162. * compares _equivalent_ to a given value.
  31163. * @tparam Other Type of the key value of an element to search for.
  31164. * @param key Key value of an element to search for.
  31165. * @return True if there is such an element, false otherwise.
  31166. */
  31167. template<typename Other>
  31168. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, bool>>
  31169. contains(const Other &key) const {
  31170. return (find(key) != cend());
  31171. }
  31172. /**
  31173. * @brief Returns an iterator to the beginning of a given bucket.
  31174. * @param index An index of a bucket to access.
  31175. * @return An iterator to the beginning of the given bucket.
  31176. */
  31177. [[nodiscard]] const_local_iterator cbegin(const size_type index) const {
  31178. return {packed.first().begin(), sparse.first()[index]};
  31179. }
  31180. /**
  31181. * @brief Returns an iterator to the beginning of a given bucket.
  31182. * @param index An index of a bucket to access.
  31183. * @return An iterator to the beginning of the given bucket.
  31184. */
  31185. [[nodiscard]] const_local_iterator begin(const size_type index) const {
  31186. return cbegin(index);
  31187. }
  31188. /**
  31189. * @brief Returns an iterator to the beginning of a given bucket.
  31190. * @param index An index of a bucket to access.
  31191. * @return An iterator to the beginning of the given bucket.
  31192. */
  31193. [[nodiscard]] local_iterator begin(const size_type index) {
  31194. return {packed.first().begin(), sparse.first()[index]};
  31195. }
  31196. /**
  31197. * @brief Returns an iterator to the end of a given bucket.
  31198. * @param index An index of a bucket to access.
  31199. * @return An iterator to the end of the given bucket.
  31200. */
  31201. [[nodiscard]] const_local_iterator cend([[maybe_unused]] const size_type index) const {
  31202. return {packed.first().begin(), (std::numeric_limits<size_type>::max)()};
  31203. }
  31204. /**
  31205. * @brief Returns an iterator to the end of a given bucket.
  31206. * @param index An index of a bucket to access.
  31207. * @return An iterator to the end of the given bucket.
  31208. */
  31209. [[nodiscard]] const_local_iterator end([[maybe_unused]] const size_type index) const {
  31210. return cend(index);
  31211. }
  31212. /**
  31213. * @brief Returns an iterator to the end of a given bucket.
  31214. * @param index An index of a bucket to access.
  31215. * @return An iterator to the end of the given bucket.
  31216. */
  31217. [[nodiscard]] local_iterator end([[maybe_unused]] const size_type index) {
  31218. return {packed.first().begin(), (std::numeric_limits<size_type>::max)()};
  31219. }
  31220. /**
  31221. * @brief Returns the number of buckets.
  31222. * @return The number of buckets.
  31223. */
  31224. [[nodiscard]] size_type bucket_count() const {
  31225. return sparse.first().size();
  31226. }
  31227. /**
  31228. * @brief Returns the maximum number of buckets.
  31229. * @return The maximum number of buckets.
  31230. */
  31231. [[nodiscard]] size_type max_bucket_count() const {
  31232. return sparse.first().max_size();
  31233. }
  31234. /**
  31235. * @brief Returns the number of elements in a given bucket.
  31236. * @param index The index of the bucket to examine.
  31237. * @return The number of elements in the given bucket.
  31238. */
  31239. [[nodiscard]] size_type bucket_size(const size_type index) const {
  31240. return static_cast<size_type>(std::distance(begin(index), end(index)));
  31241. }
  31242. /**
  31243. * @brief Returns the bucket for a given key.
  31244. * @param key The value of the key to examine.
  31245. * @return The bucket for the given key.
  31246. */
  31247. [[nodiscard]] size_type bucket(const key_type &key) const {
  31248. return key_to_bucket(key);
  31249. }
  31250. /**
  31251. * @brief Returns the average number of elements per bucket.
  31252. * @return The average number of elements per bucket.
  31253. */
  31254. [[nodiscard]] float load_factor() const {
  31255. return size() / static_cast<float>(bucket_count());
  31256. }
  31257. /**
  31258. * @brief Returns the maximum average number of elements per bucket.
  31259. * @return The maximum average number of elements per bucket.
  31260. */
  31261. [[nodiscard]] float max_load_factor() const {
  31262. return threshold;
  31263. }
  31264. /**
  31265. * @brief Sets the desired maximum average number of elements per bucket.
  31266. * @param value A desired maximum average number of elements per bucket.
  31267. */
  31268. void max_load_factor(const float value) {
  31269. ENTT_ASSERT(value > 0.f, "Invalid load factor");
  31270. threshold = value;
  31271. rehash(0u);
  31272. }
  31273. /**
  31274. * @brief Reserves at least the specified number of buckets and regenerates
  31275. * the hash table.
  31276. * @param count New number of buckets.
  31277. */
  31278. void rehash(const size_type count) {
  31279. auto value = (std::max)(count, minimum_capacity);
  31280. value = (std::max)(value, static_cast<size_type>(size() / max_load_factor()));
  31281. if(const auto sz = next_power_of_two(value); sz != bucket_count()) {
  31282. sparse.first().resize(sz);
  31283. std::fill(sparse.first().begin(), sparse.first().end(), (std::numeric_limits<size_type>::max)());
  31284. for(size_type pos{}, last = size(); pos < last; ++pos) {
  31285. const auto index = key_to_bucket(packed.first()[pos].element.first);
  31286. packed.first()[pos].next = std::exchange(sparse.first()[index], pos);
  31287. }
  31288. }
  31289. }
  31290. /**
  31291. * @brief Reserves space for at least the specified number of elements and
  31292. * regenerates the hash table.
  31293. * @param count New number of elements.
  31294. */
  31295. void reserve(const size_type count) {
  31296. packed.first().reserve(count);
  31297. rehash(static_cast<size_type>(std::ceil(count / max_load_factor())));
  31298. }
  31299. /**
  31300. * @brief Returns the function used to hash the keys.
  31301. * @return The function used to hash the keys.
  31302. */
  31303. [[nodiscard]] hasher hash_function() const {
  31304. return sparse.second();
  31305. }
  31306. /**
  31307. * @brief Returns the function used to compare keys for equality.
  31308. * @return The function used to compare keys for equality.
  31309. */
  31310. [[nodiscard]] key_equal key_eq() const {
  31311. return packed.second();
  31312. }
  31313. private:
  31314. compressed_pair<sparse_container_type, hasher> sparse;
  31315. compressed_pair<packed_container_type, key_equal> packed;
  31316. float threshold;
  31317. };
  31318. } // namespace entt
  31319. /**
  31320. * @cond TURN_OFF_DOXYGEN
  31321. * Internal details not to be documented.
  31322. */
  31323. namespace std {
  31324. template<typename Key, typename Value, typename Allocator>
  31325. struct uses_allocator<entt::internal::dense_map_node<Key, Value>, Allocator>
  31326. : std::true_type {};
  31327. } // namespace std
  31328. /**
  31329. * Internal details not to be documented.
  31330. * @endcond
  31331. */
  31332. #endif
  31333. // #include "../container/dense_set.hpp"
  31334. #ifndef ENTT_CONTAINER_DENSE_SET_HPP
  31335. #define ENTT_CONTAINER_DENSE_SET_HPP
  31336. #include <algorithm>
  31337. #include <cmath>
  31338. #include <cstddef>
  31339. #include <functional>
  31340. #include <iterator>
  31341. #include <limits>
  31342. #include <memory>
  31343. #include <tuple>
  31344. #include <type_traits>
  31345. #include <utility>
  31346. #include <vector>
  31347. // #include "../config/config.h"
  31348. // #include "../core/compressed_pair.hpp"
  31349. // #include "../core/memory.hpp"
  31350. // #include "../core/type_traits.hpp"
  31351. // #include "fwd.hpp"
  31352. namespace entt {
  31353. /**
  31354. * @cond TURN_OFF_DOXYGEN
  31355. * Internal details not to be documented.
  31356. */
  31357. namespace internal {
  31358. template<typename It>
  31359. class dense_set_iterator final {
  31360. template<typename>
  31361. friend class dense_set_iterator;
  31362. public:
  31363. using value_type = typename It::value_type::second_type;
  31364. using pointer = const value_type *;
  31365. using reference = const value_type &;
  31366. using difference_type = std::ptrdiff_t;
  31367. using iterator_category = std::random_access_iterator_tag;
  31368. dense_set_iterator() ENTT_NOEXCEPT
  31369. : it{} {}
  31370. dense_set_iterator(const It iter) ENTT_NOEXCEPT
  31371. : it{iter} {}
  31372. template<typename Other, typename = std::enable_if_t<!std::is_same_v<It, Other> && std::is_constructible_v<It, Other>>>
  31373. dense_set_iterator(const dense_set_iterator<Other> &other) ENTT_NOEXCEPT
  31374. : it{other.it} {}
  31375. dense_set_iterator &operator++() ENTT_NOEXCEPT {
  31376. return ++it, *this;
  31377. }
  31378. dense_set_iterator operator++(int) ENTT_NOEXCEPT {
  31379. dense_set_iterator orig = *this;
  31380. return ++(*this), orig;
  31381. }
  31382. dense_set_iterator &operator--() ENTT_NOEXCEPT {
  31383. return --it, *this;
  31384. }
  31385. dense_set_iterator operator--(int) ENTT_NOEXCEPT {
  31386. dense_set_iterator orig = *this;
  31387. return operator--(), orig;
  31388. }
  31389. dense_set_iterator &operator+=(const difference_type value) ENTT_NOEXCEPT {
  31390. it += value;
  31391. return *this;
  31392. }
  31393. dense_set_iterator operator+(const difference_type value) const ENTT_NOEXCEPT {
  31394. dense_set_iterator copy = *this;
  31395. return (copy += value);
  31396. }
  31397. dense_set_iterator &operator-=(const difference_type value) ENTT_NOEXCEPT {
  31398. return (*this += -value);
  31399. }
  31400. dense_set_iterator operator-(const difference_type value) const ENTT_NOEXCEPT {
  31401. return (*this + -value);
  31402. }
  31403. [[nodiscard]] reference operator[](const difference_type value) const ENTT_NOEXCEPT {
  31404. return it[value].second;
  31405. }
  31406. [[nodiscard]] pointer operator->() const ENTT_NOEXCEPT {
  31407. return std::addressof(it->second);
  31408. }
  31409. [[nodiscard]] reference operator*() const ENTT_NOEXCEPT {
  31410. return *operator->();
  31411. }
  31412. template<typename ILhs, typename IRhs>
  31413. friend std::ptrdiff_t operator-(const dense_set_iterator<ILhs> &, const dense_set_iterator<IRhs> &) ENTT_NOEXCEPT;
  31414. template<typename ILhs, typename IRhs>
  31415. friend bool operator==(const dense_set_iterator<ILhs> &, const dense_set_iterator<IRhs> &) ENTT_NOEXCEPT;
  31416. template<typename ILhs, typename IRhs>
  31417. friend bool operator<(const dense_set_iterator<ILhs> &, const dense_set_iterator<IRhs> &) ENTT_NOEXCEPT;
  31418. private:
  31419. It it;
  31420. };
  31421. template<typename ILhs, typename IRhs>
  31422. [[nodiscard]] std::ptrdiff_t operator-(const dense_set_iterator<ILhs> &lhs, const dense_set_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  31423. return lhs.it - rhs.it;
  31424. }
  31425. template<typename ILhs, typename IRhs>
  31426. [[nodiscard]] bool operator==(const dense_set_iterator<ILhs> &lhs, const dense_set_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  31427. return lhs.it == rhs.it;
  31428. }
  31429. template<typename ILhs, typename IRhs>
  31430. [[nodiscard]] bool operator!=(const dense_set_iterator<ILhs> &lhs, const dense_set_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  31431. return !(lhs == rhs);
  31432. }
  31433. template<typename ILhs, typename IRhs>
  31434. [[nodiscard]] bool operator<(const dense_set_iterator<ILhs> &lhs, const dense_set_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  31435. return lhs.it < rhs.it;
  31436. }
  31437. template<typename ILhs, typename IRhs>
  31438. [[nodiscard]] bool operator>(const dense_set_iterator<ILhs> &lhs, const dense_set_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  31439. return rhs < lhs;
  31440. }
  31441. template<typename ILhs, typename IRhs>
  31442. [[nodiscard]] bool operator<=(const dense_set_iterator<ILhs> &lhs, const dense_set_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  31443. return !(lhs > rhs);
  31444. }
  31445. template<typename ILhs, typename IRhs>
  31446. [[nodiscard]] bool operator>=(const dense_set_iterator<ILhs> &lhs, const dense_set_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  31447. return !(lhs < rhs);
  31448. }
  31449. template<typename It>
  31450. class dense_set_local_iterator final {
  31451. template<typename>
  31452. friend class dense_set_local_iterator;
  31453. public:
  31454. using value_type = typename It::value_type::second_type;
  31455. using pointer = const value_type *;
  31456. using reference = const value_type &;
  31457. using difference_type = std::ptrdiff_t;
  31458. using iterator_category = std::forward_iterator_tag;
  31459. dense_set_local_iterator() ENTT_NOEXCEPT
  31460. : it{},
  31461. offset{} {}
  31462. dense_set_local_iterator(It iter, const std::size_t pos) ENTT_NOEXCEPT
  31463. : it{iter},
  31464. offset{pos} {}
  31465. template<typename Other, typename = std::enable_if_t<!std::is_same_v<It, Other> && std::is_constructible_v<It, Other>>>
  31466. dense_set_local_iterator(const dense_set_local_iterator<Other> &other) ENTT_NOEXCEPT
  31467. : it{other.it},
  31468. offset{other.offset} {}
  31469. dense_set_local_iterator &operator++() ENTT_NOEXCEPT {
  31470. return offset = it[offset].first, *this;
  31471. }
  31472. dense_set_local_iterator operator++(int) ENTT_NOEXCEPT {
  31473. dense_set_local_iterator orig = *this;
  31474. return ++(*this), orig;
  31475. }
  31476. [[nodiscard]] pointer operator->() const ENTT_NOEXCEPT {
  31477. return std::addressof(it[offset].second);
  31478. }
  31479. [[nodiscard]] reference operator*() const ENTT_NOEXCEPT {
  31480. return *operator->();
  31481. }
  31482. [[nodiscard]] std::size_t index() const ENTT_NOEXCEPT {
  31483. return offset;
  31484. }
  31485. private:
  31486. It it;
  31487. std::size_t offset;
  31488. };
  31489. template<typename ILhs, typename IRhs>
  31490. [[nodiscard]] bool operator==(const dense_set_local_iterator<ILhs> &lhs, const dense_set_local_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  31491. return lhs.index() == rhs.index();
  31492. }
  31493. template<typename ILhs, typename IRhs>
  31494. [[nodiscard]] bool operator!=(const dense_set_local_iterator<ILhs> &lhs, const dense_set_local_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  31495. return !(lhs == rhs);
  31496. }
  31497. } // namespace internal
  31498. /**
  31499. * Internal details not to be documented.
  31500. * @endcond
  31501. */
  31502. /**
  31503. * @brief Associative container for unique objects of a given type.
  31504. *
  31505. * Internally, elements are organized into buckets. Which bucket an element is
  31506. * placed into depends entirely on its hash. Elements with the same hash code
  31507. * appear in the same bucket.
  31508. *
  31509. * @tparam Type Value type of the associative container.
  31510. * @tparam Hash Type of function to use to hash the values.
  31511. * @tparam KeyEqual Type of function to use to compare the values for equality.
  31512. * @tparam Allocator Type of allocator used to manage memory and elements.
  31513. */
  31514. template<typename Type, typename Hash, typename KeyEqual, typename Allocator>
  31515. class dense_set {
  31516. static constexpr float default_threshold = 0.875f;
  31517. static constexpr std::size_t minimum_capacity = 8u;
  31518. using node_type = std::pair<std::size_t, Type>;
  31519. using alloc_traits = std::allocator_traits<Allocator>;
  31520. static_assert(std::is_same_v<typename alloc_traits::value_type, Type>, "Invalid value type");
  31521. using sparse_container_type = std::vector<std::size_t, typename alloc_traits::template rebind_alloc<std::size_t>>;
  31522. using packed_container_type = std::vector<node_type, typename alloc_traits::template rebind_alloc<node_type>>;
  31523. template<typename Other>
  31524. [[nodiscard]] std::size_t value_to_bucket(const Other &value) const ENTT_NOEXCEPT {
  31525. return fast_mod(sparse.second()(value), bucket_count());
  31526. }
  31527. template<typename Other>
  31528. [[nodiscard]] auto constrained_find(const Other &value, std::size_t bucket) {
  31529. for(auto it = begin(bucket), last = end(bucket); it != last; ++it) {
  31530. if(packed.second()(*it, value)) {
  31531. return begin() + static_cast<typename iterator::difference_type>(it.index());
  31532. }
  31533. }
  31534. return end();
  31535. }
  31536. template<typename Other>
  31537. [[nodiscard]] auto constrained_find(const Other &value, std::size_t bucket) const {
  31538. for(auto it = cbegin(bucket), last = cend(bucket); it != last; ++it) {
  31539. if(packed.second()(*it, value)) {
  31540. return cbegin() + static_cast<typename iterator::difference_type>(it.index());
  31541. }
  31542. }
  31543. return cend();
  31544. }
  31545. template<typename Other>
  31546. [[nodiscard]] auto insert_or_do_nothing(Other &&value) {
  31547. const auto index = value_to_bucket(value);
  31548. if(auto it = constrained_find(value, index); it != end()) {
  31549. return std::make_pair(it, false);
  31550. }
  31551. packed.first().emplace_back(sparse.first()[index], std::forward<Other>(value));
  31552. sparse.first()[index] = packed.first().size() - 1u;
  31553. rehash_if_required();
  31554. return std::make_pair(--end(), true);
  31555. }
  31556. void move_and_pop(const std::size_t pos) {
  31557. if(const auto last = size() - 1u; pos != last) {
  31558. packed.first()[pos] = std::move(packed.first().back());
  31559. size_type *curr = sparse.first().data() + value_to_bucket(packed.first().back().second);
  31560. for(; *curr != last; curr = &packed.first()[*curr].first) {}
  31561. *curr = pos;
  31562. }
  31563. packed.first().pop_back();
  31564. }
  31565. void rehash_if_required() {
  31566. if(size() > (bucket_count() * max_load_factor())) {
  31567. rehash(bucket_count() * 2u);
  31568. }
  31569. }
  31570. public:
  31571. /*! @brief Key type of the container. */
  31572. using key_type = Type;
  31573. /*! @brief Value type of the container. */
  31574. using value_type = Type;
  31575. /*! @brief Unsigned integer type. */
  31576. using size_type = std::size_t;
  31577. /*! @brief Type of function to use to hash the elements. */
  31578. using hasher = Hash;
  31579. /*! @brief Type of function to use to compare the elements for equality. */
  31580. using key_equal = KeyEqual;
  31581. /*! @brief Allocator type. */
  31582. using allocator_type = Allocator;
  31583. /*! @brief Random access iterator type. */
  31584. using iterator = internal::dense_set_iterator<typename packed_container_type::iterator>;
  31585. /*! @brief Constant random access iterator type. */
  31586. using const_iterator = internal::dense_set_iterator<typename packed_container_type::const_iterator>;
  31587. /*! @brief Forward iterator type. */
  31588. using local_iterator = internal::dense_set_local_iterator<typename packed_container_type::iterator>;
  31589. /*! @brief Constant forward iterator type. */
  31590. using const_local_iterator = internal::dense_set_local_iterator<typename packed_container_type::const_iterator>;
  31591. /*! @brief Default constructor. */
  31592. dense_set()
  31593. : dense_set(minimum_capacity) {}
  31594. /**
  31595. * @brief Constructs an empty container with a given allocator.
  31596. * @param allocator The allocator to use.
  31597. */
  31598. explicit dense_set(const allocator_type &allocator)
  31599. : dense_set{minimum_capacity, hasher{}, key_equal{}, allocator} {}
  31600. /**
  31601. * @brief Constructs an empty container with a given allocator and user
  31602. * supplied minimal number of buckets.
  31603. * @param bucket_count Minimal number of buckets.
  31604. * @param allocator The allocator to use.
  31605. */
  31606. dense_set(const size_type bucket_count, const allocator_type &allocator)
  31607. : dense_set{bucket_count, hasher{}, key_equal{}, allocator} {}
  31608. /**
  31609. * @brief Constructs an empty container with a given allocator, hash
  31610. * function and user supplied minimal number of buckets.
  31611. * @param bucket_count Minimal number of buckets.
  31612. * @param hash Hash function to use.
  31613. * @param allocator The allocator to use.
  31614. */
  31615. dense_set(const size_type bucket_count, const hasher &hash, const allocator_type &allocator)
  31616. : dense_set{bucket_count, hash, key_equal{}, allocator} {}
  31617. /**
  31618. * @brief Constructs an empty container with a given allocator, hash
  31619. * function, compare function and user supplied minimal number of buckets.
  31620. * @param bucket_count Minimal number of buckets.
  31621. * @param hash Hash function to use.
  31622. * @param equal Compare function to use.
  31623. * @param allocator The allocator to use.
  31624. */
  31625. explicit dense_set(const size_type bucket_count, const hasher &hash = hasher{}, const key_equal &equal = key_equal{}, const allocator_type &allocator = allocator_type{})
  31626. : sparse{allocator, hash},
  31627. packed{allocator, equal},
  31628. threshold{default_threshold} {
  31629. rehash(bucket_count);
  31630. }
  31631. /*! @brief Default copy constructor. */
  31632. dense_set(const dense_set &) = default;
  31633. /**
  31634. * @brief Allocator-extended copy constructor.
  31635. * @param other The instance to copy from.
  31636. * @param allocator The allocator to use.
  31637. */
  31638. dense_set(const dense_set &other, const allocator_type &allocator)
  31639. : sparse{std::piecewise_construct, std::forward_as_tuple(other.sparse.first(), allocator), std::forward_as_tuple(other.sparse.second())},
  31640. packed{std::piecewise_construct, std::forward_as_tuple(other.packed.first(), allocator), std::forward_as_tuple(other.packed.second())},
  31641. threshold{other.threshold} {}
  31642. /*! @brief Default move constructor. */
  31643. dense_set(dense_set &&) = default;
  31644. /**
  31645. * @brief Allocator-extended move constructor.
  31646. * @param other The instance to move from.
  31647. * @param allocator The allocator to use.
  31648. */
  31649. dense_set(dense_set &&other, const allocator_type &allocator)
  31650. : sparse{std::piecewise_construct, std::forward_as_tuple(std::move(other.sparse.first()), allocator), std::forward_as_tuple(std::move(other.sparse.second()))},
  31651. packed{std::piecewise_construct, std::forward_as_tuple(std::move(other.packed.first()), allocator), std::forward_as_tuple(std::move(other.packed.second()))},
  31652. threshold{other.threshold} {}
  31653. /**
  31654. * @brief Default copy assignment operator.
  31655. * @return This container.
  31656. */
  31657. dense_set &operator=(const dense_set &) = default;
  31658. /**
  31659. * @brief Default move assignment operator.
  31660. * @return This container.
  31661. */
  31662. dense_set &operator=(dense_set &&) = default;
  31663. /**
  31664. * @brief Returns the associated allocator.
  31665. * @return The associated allocator.
  31666. */
  31667. [[nodiscard]] constexpr allocator_type get_allocator() const ENTT_NOEXCEPT {
  31668. return sparse.first().get_allocator();
  31669. }
  31670. /**
  31671. * @brief Returns an iterator to the beginning.
  31672. *
  31673. * The returned iterator points to the first instance of the internal array.
  31674. * If the array is empty, the returned iterator will be equal to `end()`.
  31675. *
  31676. * @return An iterator to the first instance of the internal array.
  31677. */
  31678. [[nodiscard]] const_iterator cbegin() const ENTT_NOEXCEPT {
  31679. return packed.first().begin();
  31680. }
  31681. /*! @copydoc cbegin */
  31682. [[nodiscard]] const_iterator begin() const ENTT_NOEXCEPT {
  31683. return cbegin();
  31684. }
  31685. /*! @copydoc begin */
  31686. [[nodiscard]] iterator begin() ENTT_NOEXCEPT {
  31687. return packed.first().begin();
  31688. }
  31689. /**
  31690. * @brief Returns an iterator to the end.
  31691. *
  31692. * The returned iterator points to the element following the last instance
  31693. * of the internal array. Attempting to dereference the returned iterator
  31694. * results in undefined behavior.
  31695. *
  31696. * @return An iterator to the element following the last instance of the
  31697. * internal array.
  31698. */
  31699. [[nodiscard]] const_iterator cend() const ENTT_NOEXCEPT {
  31700. return packed.first().end();
  31701. }
  31702. /*! @copydoc cend */
  31703. [[nodiscard]] const_iterator end() const ENTT_NOEXCEPT {
  31704. return cend();
  31705. }
  31706. /*! @copydoc end */
  31707. [[nodiscard]] iterator end() ENTT_NOEXCEPT {
  31708. return packed.first().end();
  31709. }
  31710. /**
  31711. * @brief Checks whether a container is empty.
  31712. * @return True if the container is empty, false otherwise.
  31713. */
  31714. [[nodiscard]] bool empty() const ENTT_NOEXCEPT {
  31715. return packed.first().empty();
  31716. }
  31717. /**
  31718. * @brief Returns the number of elements in a container.
  31719. * @return Number of elements in a container.
  31720. */
  31721. [[nodiscard]] size_type size() const ENTT_NOEXCEPT {
  31722. return packed.first().size();
  31723. }
  31724. /*! @brief Clears the container. */
  31725. void clear() ENTT_NOEXCEPT {
  31726. sparse.first().clear();
  31727. packed.first().clear();
  31728. rehash(0u);
  31729. }
  31730. /**
  31731. * @brief Inserts an element into the container, if it does not exist.
  31732. * @param value An element to insert into the container.
  31733. * @return A pair consisting of an iterator to the inserted element (or to
  31734. * the element that prevented the insertion) and a bool denoting whether the
  31735. * insertion took place.
  31736. */
  31737. std::pair<iterator, bool> insert(const value_type &value) {
  31738. return insert_or_do_nothing(value);
  31739. }
  31740. /*! @copydoc insert */
  31741. std::pair<iterator, bool> insert(value_type &&value) {
  31742. return insert_or_do_nothing(std::move(value));
  31743. }
  31744. /**
  31745. * @brief Inserts elements into the container, if they do not exist.
  31746. * @tparam It Type of input iterator.
  31747. * @param first An iterator to the first element of the range of elements.
  31748. * @param last An iterator past the last element of the range of elements.
  31749. */
  31750. template<typename It>
  31751. void insert(It first, It last) {
  31752. for(; first != last; ++first) {
  31753. insert(*first);
  31754. }
  31755. }
  31756. /**
  31757. * @brief Constructs an element in-place, if it does not exist.
  31758. *
  31759. * The element is also constructed when the container already has the key,
  31760. * in which case the newly constructed object is destroyed immediately.
  31761. *
  31762. * @tparam Args Types of arguments to forward to the constructor of the
  31763. * element.
  31764. * @param args Arguments to forward to the constructor of the element.
  31765. * @return A pair consisting of an iterator to the inserted element (or to
  31766. * the element that prevented the insertion) and a bool denoting whether the
  31767. * insertion took place.
  31768. */
  31769. template<typename... Args>
  31770. std::pair<iterator, bool> emplace(Args &&...args) {
  31771. if constexpr(((sizeof...(Args) == 1u) && ... && std::is_same_v<std::remove_cv_t<std::remove_reference_t<Args>>, value_type>)) {
  31772. return insert_or_do_nothing(std::forward<Args>(args)...);
  31773. } else {
  31774. auto &node = packed.first().emplace_back(std::piecewise_construct, std::make_tuple(packed.first().size()), std::forward_as_tuple(std::forward<Args>(args)...));
  31775. const auto index = value_to_bucket(node.second);
  31776. if(auto it = constrained_find(node.second, index); it != end()) {
  31777. packed.first().pop_back();
  31778. return std::make_pair(it, false);
  31779. }
  31780. std::swap(node.first, sparse.first()[index]);
  31781. rehash_if_required();
  31782. return std::make_pair(--end(), true);
  31783. }
  31784. }
  31785. /**
  31786. * @brief Removes an element from a given position.
  31787. * @param pos An iterator to the element to remove.
  31788. * @return An iterator following the removed element.
  31789. */
  31790. iterator erase(const_iterator pos) {
  31791. const auto diff = pos - cbegin();
  31792. erase(*pos);
  31793. return begin() + diff;
  31794. }
  31795. /**
  31796. * @brief Removes the given elements from a container.
  31797. * @param first An iterator to the first element of the range of elements.
  31798. * @param last An iterator past the last element of the range of elements.
  31799. * @return An iterator following the last removed element.
  31800. */
  31801. iterator erase(const_iterator first, const_iterator last) {
  31802. const auto dist = first - cbegin();
  31803. for(auto from = last - cbegin(); from != dist; --from) {
  31804. erase(packed.first()[from - 1u].second);
  31805. }
  31806. return (begin() + dist);
  31807. }
  31808. /**
  31809. * @brief Removes the element associated with a given value.
  31810. * @param value Value of an element to remove.
  31811. * @return Number of elements removed (either 0 or 1).
  31812. */
  31813. size_type erase(const value_type &value) {
  31814. for(size_type *curr = sparse.first().data() + value_to_bucket(value); *curr != (std::numeric_limits<size_type>::max)(); curr = &packed.first()[*curr].first) {
  31815. if(packed.second()(packed.first()[*curr].second, value)) {
  31816. const auto index = *curr;
  31817. *curr = packed.first()[*curr].first;
  31818. move_and_pop(index);
  31819. return 1u;
  31820. }
  31821. }
  31822. return 0u;
  31823. }
  31824. /**
  31825. * @brief Exchanges the contents with those of a given container.
  31826. * @param other Container to exchange the content with.
  31827. */
  31828. void swap(dense_set &other) {
  31829. using std::swap;
  31830. swap(sparse, other.sparse);
  31831. swap(packed, other.packed);
  31832. swap(threshold, other.threshold);
  31833. }
  31834. /**
  31835. * @brief Finds an element with a given value.
  31836. * @param value Value of an element to search for.
  31837. * @return An iterator to an element with the given value. If no such
  31838. * element is found, a past-the-end iterator is returned.
  31839. */
  31840. [[nodiscard]] iterator find(const value_type &value) {
  31841. return constrained_find(value, value_to_bucket(value));
  31842. }
  31843. /*! @copydoc find */
  31844. [[nodiscard]] const_iterator find(const value_type &value) const {
  31845. return constrained_find(value, value_to_bucket(value));
  31846. }
  31847. /**
  31848. * @brief Finds an element that compares _equivalent_ to a given value.
  31849. * @tparam Other Type of an element to search for.
  31850. * @param value Value of an element to search for.
  31851. * @return An iterator to an element with the given value. If no such
  31852. * element is found, a past-the-end iterator is returned.
  31853. */
  31854. template<typename Other>
  31855. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, iterator>>
  31856. find(const Other &value) {
  31857. return constrained_find(value, value_to_bucket(value));
  31858. }
  31859. /*! @copydoc find */
  31860. template<typename Other>
  31861. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, const_iterator>>
  31862. find(const Other &value) const {
  31863. return constrained_find(value, value_to_bucket(value));
  31864. }
  31865. /**
  31866. * @brief Checks if the container contains an element with a given value.
  31867. * @param value Value of an element to search for.
  31868. * @return True if there is such an element, false otherwise.
  31869. */
  31870. [[nodiscard]] bool contains(const value_type &value) const {
  31871. return (find(value) != cend());
  31872. }
  31873. /**
  31874. * @brief Checks if the container contains an element that compares
  31875. * _equivalent_ to a given value.
  31876. * @tparam Other Type of an element to search for.
  31877. * @param value Value of an element to search for.
  31878. * @return True if there is such an element, false otherwise.
  31879. */
  31880. template<typename Other>
  31881. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, bool>>
  31882. contains(const Other &value) const {
  31883. return (find(value) != cend());
  31884. }
  31885. /**
  31886. * @brief Returns an iterator to the beginning of a given bucket.
  31887. * @param index An index of a bucket to access.
  31888. * @return An iterator to the beginning of the given bucket.
  31889. */
  31890. [[nodiscard]] const_local_iterator cbegin(const size_type index) const {
  31891. return {packed.first().begin(), sparse.first()[index]};
  31892. }
  31893. /**
  31894. * @brief Returns an iterator to the beginning of a given bucket.
  31895. * @param index An index of a bucket to access.
  31896. * @return An iterator to the beginning of the given bucket.
  31897. */
  31898. [[nodiscard]] const_local_iterator begin(const size_type index) const {
  31899. return cbegin(index);
  31900. }
  31901. /**
  31902. * @brief Returns an iterator to the beginning of a given bucket.
  31903. * @param index An index of a bucket to access.
  31904. * @return An iterator to the beginning of the given bucket.
  31905. */
  31906. [[nodiscard]] local_iterator begin(const size_type index) {
  31907. return {packed.first().begin(), sparse.first()[index]};
  31908. }
  31909. /**
  31910. * @brief Returns an iterator to the end of a given bucket.
  31911. * @param index An index of a bucket to access.
  31912. * @return An iterator to the end of the given bucket.
  31913. */
  31914. [[nodiscard]] const_local_iterator cend([[maybe_unused]] const size_type index) const {
  31915. return {packed.first().begin(), (std::numeric_limits<size_type>::max)()};
  31916. }
  31917. /**
  31918. * @brief Returns an iterator to the end of a given bucket.
  31919. * @param index An index of a bucket to access.
  31920. * @return An iterator to the end of the given bucket.
  31921. */
  31922. [[nodiscard]] const_local_iterator end([[maybe_unused]] const size_type index) const {
  31923. return cend(index);
  31924. }
  31925. /**
  31926. * @brief Returns an iterator to the end of a given bucket.
  31927. * @param index An index of a bucket to access.
  31928. * @return An iterator to the end of the given bucket.
  31929. */
  31930. [[nodiscard]] local_iterator end([[maybe_unused]] const size_type index) {
  31931. return {packed.first().begin(), (std::numeric_limits<size_type>::max)()};
  31932. }
  31933. /**
  31934. * @brief Returns the number of buckets.
  31935. * @return The number of buckets.
  31936. */
  31937. [[nodiscard]] size_type bucket_count() const {
  31938. return sparse.first().size();
  31939. }
  31940. /**
  31941. * @brief Returns the maximum number of buckets.
  31942. * @return The maximum number of buckets.
  31943. */
  31944. [[nodiscard]] size_type max_bucket_count() const {
  31945. return sparse.first().max_size();
  31946. }
  31947. /**
  31948. * @brief Returns the number of elements in a given bucket.
  31949. * @param index The index of the bucket to examine.
  31950. * @return The number of elements in the given bucket.
  31951. */
  31952. [[nodiscard]] size_type bucket_size(const size_type index) const {
  31953. return static_cast<size_type>(std::distance(begin(index), end(index)));
  31954. }
  31955. /**
  31956. * @brief Returns the bucket for a given element.
  31957. * @param value The value of the element to examine.
  31958. * @return The bucket for the given element.
  31959. */
  31960. [[nodiscard]] size_type bucket(const value_type &value) const {
  31961. return value_to_bucket(value);
  31962. }
  31963. /**
  31964. * @brief Returns the average number of elements per bucket.
  31965. * @return The average number of elements per bucket.
  31966. */
  31967. [[nodiscard]] float load_factor() const {
  31968. return size() / static_cast<float>(bucket_count());
  31969. }
  31970. /**
  31971. * @brief Returns the maximum average number of elements per bucket.
  31972. * @return The maximum average number of elements per bucket.
  31973. */
  31974. [[nodiscard]] float max_load_factor() const {
  31975. return threshold;
  31976. }
  31977. /**
  31978. * @brief Sets the desired maximum average number of elements per bucket.
  31979. * @param value A desired maximum average number of elements per bucket.
  31980. */
  31981. void max_load_factor(const float value) {
  31982. ENTT_ASSERT(value > 0.f, "Invalid load factor");
  31983. threshold = value;
  31984. rehash(0u);
  31985. }
  31986. /**
  31987. * @brief Reserves at least the specified number of buckets and regenerates
  31988. * the hash table.
  31989. * @param count New number of buckets.
  31990. */
  31991. void rehash(const size_type count) {
  31992. auto value = (std::max)(count, minimum_capacity);
  31993. value = (std::max)(value, static_cast<size_type>(size() / max_load_factor()));
  31994. if(const auto sz = next_power_of_two(value); sz != bucket_count()) {
  31995. sparse.first().resize(sz);
  31996. std::fill(sparse.first().begin(), sparse.first().end(), (std::numeric_limits<size_type>::max)());
  31997. for(size_type pos{}, last = size(); pos < last; ++pos) {
  31998. const auto index = value_to_bucket(packed.first()[pos].second);
  31999. packed.first()[pos].first = std::exchange(sparse.first()[index], pos);
  32000. }
  32001. }
  32002. }
  32003. /**
  32004. * @brief Reserves space for at least the specified number of elements and
  32005. * regenerates the hash table.
  32006. * @param count New number of elements.
  32007. */
  32008. void reserve(const size_type count) {
  32009. packed.first().reserve(count);
  32010. rehash(static_cast<size_type>(std::ceil(count / max_load_factor())));
  32011. }
  32012. /**
  32013. * @brief Returns the function used to hash the elements.
  32014. * @return The function used to hash the elements.
  32015. */
  32016. [[nodiscard]] hasher hash_function() const {
  32017. return sparse.second();
  32018. }
  32019. /**
  32020. * @brief Returns the function used to compare elements for equality.
  32021. * @return The function used to compare elements for equality.
  32022. */
  32023. [[nodiscard]] key_equal key_eq() const {
  32024. return packed.second();
  32025. }
  32026. private:
  32027. compressed_pair<sparse_container_type, hasher> sparse;
  32028. compressed_pair<packed_container_type, key_equal> packed;
  32029. float threshold;
  32030. };
  32031. } // namespace entt
  32032. #endif
  32033. // #include "meta.hpp"
  32034. #ifndef ENTT_META_META_HPP
  32035. #define ENTT_META_META_HPP
  32036. #include <cstddef>
  32037. #include <iterator>
  32038. #include <memory>
  32039. #include <type_traits>
  32040. #include <utility>
  32041. // #include "../config/config.h"
  32042. #ifndef ENTT_CONFIG_CONFIG_H
  32043. #define ENTT_CONFIG_CONFIG_H
  32044. // #include "version.h"
  32045. #ifndef ENTT_CONFIG_VERSION_H
  32046. #define ENTT_CONFIG_VERSION_H
  32047. // #include "macro.h"
  32048. #ifndef ENTT_CONFIG_MACRO_H
  32049. #define ENTT_CONFIG_MACRO_H
  32050. #define ENTT_STR(arg) #arg
  32051. #define ENTT_XSTR(arg) ENTT_STR(arg)
  32052. #endif
  32053. #define ENTT_VERSION_MAJOR 3
  32054. #define ENTT_VERSION_MINOR 10
  32055. #define ENTT_VERSION_PATCH 3
  32056. #define ENTT_VERSION \
  32057. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  32058. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  32059. #endif
  32060. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  32061. # define ENTT_THROW throw
  32062. # define ENTT_TRY try
  32063. # define ENTT_CATCH catch(...)
  32064. #else
  32065. # define ENTT_THROW
  32066. # define ENTT_TRY if(true)
  32067. # define ENTT_CATCH if(false)
  32068. #endif
  32069. #ifndef ENTT_NOEXCEPT
  32070. # define ENTT_NOEXCEPT noexcept
  32071. # define ENTT_NOEXCEPT_IF(expr) noexcept(expr)
  32072. # else
  32073. # define ENTT_NOEXCEPT_IF(...)
  32074. #endif
  32075. #ifdef ENTT_USE_ATOMIC
  32076. # include <atomic>
  32077. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  32078. #else
  32079. # define ENTT_MAYBE_ATOMIC(Type) Type
  32080. #endif
  32081. #ifndef ENTT_ID_TYPE
  32082. # include <cstdint>
  32083. # define ENTT_ID_TYPE std::uint32_t
  32084. #endif
  32085. #ifndef ENTT_SPARSE_PAGE
  32086. # define ENTT_SPARSE_PAGE 4096
  32087. #endif
  32088. #ifndef ENTT_PACKED_PAGE
  32089. # define ENTT_PACKED_PAGE 1024
  32090. #endif
  32091. #ifdef ENTT_DISABLE_ASSERT
  32092. # undef ENTT_ASSERT
  32093. # define ENTT_ASSERT(...) (void(0))
  32094. #elif !defined ENTT_ASSERT
  32095. # include <cassert>
  32096. # define ENTT_ASSERT(condition, ...) assert(condition)
  32097. #endif
  32098. #ifdef ENTT_NO_ETO
  32099. # define ENTT_IGNORE_IF_EMPTY false
  32100. #else
  32101. # define ENTT_IGNORE_IF_EMPTY true
  32102. #endif
  32103. #ifdef ENTT_STANDARD_CPP
  32104. # define ENTT_NONSTD false
  32105. #else
  32106. # define ENTT_NONSTD true
  32107. # if defined __clang__ || defined __GNUC__
  32108. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  32109. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  32110. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  32111. # elif defined _MSC_VER
  32112. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  32113. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  32114. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  32115. # endif
  32116. #endif
  32117. #if defined _MSC_VER
  32118. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  32119. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  32120. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  32121. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  32122. #endif
  32123. #endif
  32124. // #include "../core/any.hpp"
  32125. #ifndef ENTT_CORE_ANY_HPP
  32126. #define ENTT_CORE_ANY_HPP
  32127. #include <cstddef>
  32128. #include <memory>
  32129. #include <type_traits>
  32130. #include <utility>
  32131. // #include "../config/config.h"
  32132. #ifndef ENTT_CONFIG_CONFIG_H
  32133. #define ENTT_CONFIG_CONFIG_H
  32134. // #include "version.h"
  32135. #ifndef ENTT_CONFIG_VERSION_H
  32136. #define ENTT_CONFIG_VERSION_H
  32137. // #include "macro.h"
  32138. #ifndef ENTT_CONFIG_MACRO_H
  32139. #define ENTT_CONFIG_MACRO_H
  32140. #define ENTT_STR(arg) #arg
  32141. #define ENTT_XSTR(arg) ENTT_STR(arg)
  32142. #endif
  32143. #define ENTT_VERSION_MAJOR 3
  32144. #define ENTT_VERSION_MINOR 10
  32145. #define ENTT_VERSION_PATCH 3
  32146. #define ENTT_VERSION \
  32147. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  32148. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  32149. #endif
  32150. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  32151. # define ENTT_THROW throw
  32152. # define ENTT_TRY try
  32153. # define ENTT_CATCH catch(...)
  32154. #else
  32155. # define ENTT_THROW
  32156. # define ENTT_TRY if(true)
  32157. # define ENTT_CATCH if(false)
  32158. #endif
  32159. #ifndef ENTT_NOEXCEPT
  32160. # define ENTT_NOEXCEPT noexcept
  32161. # define ENTT_NOEXCEPT_IF(expr) noexcept(expr)
  32162. # else
  32163. # define ENTT_NOEXCEPT_IF(...)
  32164. #endif
  32165. #ifdef ENTT_USE_ATOMIC
  32166. # include <atomic>
  32167. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  32168. #else
  32169. # define ENTT_MAYBE_ATOMIC(Type) Type
  32170. #endif
  32171. #ifndef ENTT_ID_TYPE
  32172. # include <cstdint>
  32173. # define ENTT_ID_TYPE std::uint32_t
  32174. #endif
  32175. #ifndef ENTT_SPARSE_PAGE
  32176. # define ENTT_SPARSE_PAGE 4096
  32177. #endif
  32178. #ifndef ENTT_PACKED_PAGE
  32179. # define ENTT_PACKED_PAGE 1024
  32180. #endif
  32181. #ifdef ENTT_DISABLE_ASSERT
  32182. # undef ENTT_ASSERT
  32183. # define ENTT_ASSERT(...) (void(0))
  32184. #elif !defined ENTT_ASSERT
  32185. # include <cassert>
  32186. # define ENTT_ASSERT(condition, ...) assert(condition)
  32187. #endif
  32188. #ifdef ENTT_NO_ETO
  32189. # define ENTT_IGNORE_IF_EMPTY false
  32190. #else
  32191. # define ENTT_IGNORE_IF_EMPTY true
  32192. #endif
  32193. #ifdef ENTT_STANDARD_CPP
  32194. # define ENTT_NONSTD false
  32195. #else
  32196. # define ENTT_NONSTD true
  32197. # if defined __clang__ || defined __GNUC__
  32198. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  32199. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  32200. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  32201. # elif defined _MSC_VER
  32202. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  32203. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  32204. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  32205. # endif
  32206. #endif
  32207. #if defined _MSC_VER
  32208. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  32209. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  32210. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  32211. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  32212. #endif
  32213. #endif
  32214. // #include "../core/utility.hpp"
  32215. #ifndef ENTT_CORE_UTILITY_HPP
  32216. #define ENTT_CORE_UTILITY_HPP
  32217. #include <utility>
  32218. // #include "../config/config.h"
  32219. #ifndef ENTT_CONFIG_CONFIG_H
  32220. #define ENTT_CONFIG_CONFIG_H
  32221. // #include "version.h"
  32222. #ifndef ENTT_CONFIG_VERSION_H
  32223. #define ENTT_CONFIG_VERSION_H
  32224. // #include "macro.h"
  32225. #ifndef ENTT_CONFIG_MACRO_H
  32226. #define ENTT_CONFIG_MACRO_H
  32227. #define ENTT_STR(arg) #arg
  32228. #define ENTT_XSTR(arg) ENTT_STR(arg)
  32229. #endif
  32230. #define ENTT_VERSION_MAJOR 3
  32231. #define ENTT_VERSION_MINOR 10
  32232. #define ENTT_VERSION_PATCH 3
  32233. #define ENTT_VERSION \
  32234. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  32235. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  32236. #endif
  32237. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  32238. # define ENTT_THROW throw
  32239. # define ENTT_TRY try
  32240. # define ENTT_CATCH catch(...)
  32241. #else
  32242. # define ENTT_THROW
  32243. # define ENTT_TRY if(true)
  32244. # define ENTT_CATCH if(false)
  32245. #endif
  32246. #ifndef ENTT_NOEXCEPT
  32247. # define ENTT_NOEXCEPT noexcept
  32248. # define ENTT_NOEXCEPT_IF(expr) noexcept(expr)
  32249. # else
  32250. # define ENTT_NOEXCEPT_IF(...)
  32251. #endif
  32252. #ifdef ENTT_USE_ATOMIC
  32253. # include <atomic>
  32254. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  32255. #else
  32256. # define ENTT_MAYBE_ATOMIC(Type) Type
  32257. #endif
  32258. #ifndef ENTT_ID_TYPE
  32259. # include <cstdint>
  32260. # define ENTT_ID_TYPE std::uint32_t
  32261. #endif
  32262. #ifndef ENTT_SPARSE_PAGE
  32263. # define ENTT_SPARSE_PAGE 4096
  32264. #endif
  32265. #ifndef ENTT_PACKED_PAGE
  32266. # define ENTT_PACKED_PAGE 1024
  32267. #endif
  32268. #ifdef ENTT_DISABLE_ASSERT
  32269. # undef ENTT_ASSERT
  32270. # define ENTT_ASSERT(...) (void(0))
  32271. #elif !defined ENTT_ASSERT
  32272. # include <cassert>
  32273. # define ENTT_ASSERT(condition, ...) assert(condition)
  32274. #endif
  32275. #ifdef ENTT_NO_ETO
  32276. # define ENTT_IGNORE_IF_EMPTY false
  32277. #else
  32278. # define ENTT_IGNORE_IF_EMPTY true
  32279. #endif
  32280. #ifdef ENTT_STANDARD_CPP
  32281. # define ENTT_NONSTD false
  32282. #else
  32283. # define ENTT_NONSTD true
  32284. # if defined __clang__ || defined __GNUC__
  32285. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  32286. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  32287. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  32288. # elif defined _MSC_VER
  32289. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  32290. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  32291. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  32292. # endif
  32293. #endif
  32294. #if defined _MSC_VER
  32295. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  32296. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  32297. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  32298. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  32299. #endif
  32300. #endif
  32301. namespace entt {
  32302. /*! @brief Identity function object (waiting for C++20). */
  32303. struct identity {
  32304. /*! @brief Indicates that this is a transparent function object. */
  32305. using is_transparent = void;
  32306. /**
  32307. * @brief Returns its argument unchanged.
  32308. * @tparam Type Type of the argument.
  32309. * @param value The actual argument.
  32310. * @return The submitted value as-is.
  32311. */
  32312. template<class Type>
  32313. [[nodiscard]] constexpr Type &&operator()(Type &&value) const ENTT_NOEXCEPT {
  32314. return std::forward<Type>(value);
  32315. }
  32316. };
  32317. /**
  32318. * @brief Constant utility to disambiguate overloaded members of a class.
  32319. * @tparam Type Type of the desired overload.
  32320. * @tparam Class Type of class to which the member belongs.
  32321. * @param member A valid pointer to a member.
  32322. * @return Pointer to the member.
  32323. */
  32324. template<typename Type, typename Class>
  32325. [[nodiscard]] constexpr auto overload(Type Class::*member) ENTT_NOEXCEPT {
  32326. return member;
  32327. }
  32328. /**
  32329. * @brief Constant utility to disambiguate overloaded functions.
  32330. * @tparam Func Function type of the desired overload.
  32331. * @param func A valid pointer to a function.
  32332. * @return Pointer to the function.
  32333. */
  32334. template<typename Func>
  32335. [[nodiscard]] constexpr auto overload(Func *func) ENTT_NOEXCEPT {
  32336. return func;
  32337. }
  32338. /**
  32339. * @brief Helper type for visitors.
  32340. * @tparam Func Types of function objects.
  32341. */
  32342. template<class... Func>
  32343. struct overloaded: Func... {
  32344. using Func::operator()...;
  32345. };
  32346. /**
  32347. * @brief Deduction guide.
  32348. * @tparam Func Types of function objects.
  32349. */
  32350. template<class... Func>
  32351. overloaded(Func...) -> overloaded<Func...>;
  32352. /**
  32353. * @brief Basic implementation of a y-combinator.
  32354. * @tparam Func Type of a potentially recursive function.
  32355. */
  32356. template<class Func>
  32357. struct y_combinator {
  32358. /**
  32359. * @brief Constructs a y-combinator from a given function.
  32360. * @param recursive A potentially recursive function.
  32361. */
  32362. y_combinator(Func recursive)
  32363. : func{std::move(recursive)} {}
  32364. /**
  32365. * @brief Invokes a y-combinator and therefore its underlying function.
  32366. * @tparam Args Types of arguments to use to invoke the underlying function.
  32367. * @param args Parameters to use to invoke the underlying function.
  32368. * @return Return value of the underlying function, if any.
  32369. */
  32370. template<class... Args>
  32371. decltype(auto) operator()(Args &&...args) const {
  32372. return func(*this, std::forward<Args>(args)...);
  32373. }
  32374. /*! @copydoc operator()() */
  32375. template<class... Args>
  32376. decltype(auto) operator()(Args &&...args) {
  32377. return func(*this, std::forward<Args>(args)...);
  32378. }
  32379. private:
  32380. Func func;
  32381. };
  32382. } // namespace entt
  32383. #endif
  32384. // #include "fwd.hpp"
  32385. #ifndef ENTT_CORE_FWD_HPP
  32386. #define ENTT_CORE_FWD_HPP
  32387. #include <cstdint>
  32388. #include <type_traits>
  32389. // #include "../config/config.h"
  32390. namespace entt {
  32391. template<std::size_t Len = sizeof(double[2]), std::size_t = alignof(typename std::aligned_storage_t<Len + !Len>)>
  32392. class basic_any;
  32393. /*! @brief Alias declaration for type identifiers. */
  32394. using id_type = ENTT_ID_TYPE;
  32395. /*! @brief Alias declaration for the most common use case. */
  32396. using any = basic_any<>;
  32397. } // namespace entt
  32398. #endif
  32399. // #include "type_info.hpp"
  32400. #ifndef ENTT_CORE_TYPE_INFO_HPP
  32401. #define ENTT_CORE_TYPE_INFO_HPP
  32402. #include <string_view>
  32403. #include <type_traits>
  32404. #include <utility>
  32405. // #include "../config/config.h"
  32406. // #include "../core/attribute.h"
  32407. #ifndef ENTT_CORE_ATTRIBUTE_H
  32408. #define ENTT_CORE_ATTRIBUTE_H
  32409. #ifndef ENTT_EXPORT
  32410. # if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER
  32411. # define ENTT_EXPORT __declspec(dllexport)
  32412. # define ENTT_IMPORT __declspec(dllimport)
  32413. # define ENTT_HIDDEN
  32414. # elif defined __GNUC__ && __GNUC__ >= 4
  32415. # define ENTT_EXPORT __attribute__((visibility("default")))
  32416. # define ENTT_IMPORT __attribute__((visibility("default")))
  32417. # define ENTT_HIDDEN __attribute__((visibility("hidden")))
  32418. # else /* Unsupported compiler */
  32419. # define ENTT_EXPORT
  32420. # define ENTT_IMPORT
  32421. # define ENTT_HIDDEN
  32422. # endif
  32423. #endif
  32424. #ifndef ENTT_API
  32425. # if defined ENTT_API_EXPORT
  32426. # define ENTT_API ENTT_EXPORT
  32427. # elif defined ENTT_API_IMPORT
  32428. # define ENTT_API ENTT_IMPORT
  32429. # else /* No API */
  32430. # define ENTT_API
  32431. # endif
  32432. #endif
  32433. #endif
  32434. // #include "fwd.hpp"
  32435. // #include "hashed_string.hpp"
  32436. #ifndef ENTT_CORE_HASHED_STRING_HPP
  32437. #define ENTT_CORE_HASHED_STRING_HPP
  32438. #include <cstddef>
  32439. #include <cstdint>
  32440. // #include "../config/config.h"
  32441. // #include "fwd.hpp"
  32442. namespace entt {
  32443. /**
  32444. * @cond TURN_OFF_DOXYGEN
  32445. * Internal details not to be documented.
  32446. */
  32447. namespace internal {
  32448. template<typename>
  32449. struct fnv1a_traits;
  32450. template<>
  32451. struct fnv1a_traits<std::uint32_t> {
  32452. using type = std::uint32_t;
  32453. static constexpr std::uint32_t offset = 2166136261;
  32454. static constexpr std::uint32_t prime = 16777619;
  32455. };
  32456. template<>
  32457. struct fnv1a_traits<std::uint64_t> {
  32458. using type = std::uint64_t;
  32459. static constexpr std::uint64_t offset = 14695981039346656037ull;
  32460. static constexpr std::uint64_t prime = 1099511628211ull;
  32461. };
  32462. template<typename Char>
  32463. struct basic_hashed_string {
  32464. using value_type = Char;
  32465. using size_type = std::size_t;
  32466. using hash_type = id_type;
  32467. const value_type *repr;
  32468. size_type length;
  32469. hash_type hash;
  32470. };
  32471. } // namespace internal
  32472. /**
  32473. * Internal details not to be documented.
  32474. * @endcond
  32475. */
  32476. /**
  32477. * @brief Zero overhead unique identifier.
  32478. *
  32479. * A hashed string is a compile-time tool that allows users to use
  32480. * human-readable identifiers in the codebase while using their numeric
  32481. * counterparts at runtime.<br/>
  32482. * Because of that, a hashed string can also be used in constant expressions if
  32483. * required.
  32484. *
  32485. * @warning
  32486. * This class doesn't take ownership of user-supplied strings nor does it make a
  32487. * copy of them.
  32488. *
  32489. * @tparam Char Character type.
  32490. */
  32491. template<typename Char>
  32492. class basic_hashed_string: internal::basic_hashed_string<Char> {
  32493. using base_type = internal::basic_hashed_string<Char>;
  32494. using hs_traits = internal::fnv1a_traits<id_type>;
  32495. struct const_wrapper {
  32496. // non-explicit constructor on purpose
  32497. constexpr const_wrapper(const Char *str) ENTT_NOEXCEPT: repr{str} {}
  32498. const Char *repr;
  32499. };
  32500. // Fowler–Noll–Vo hash function v. 1a - the good
  32501. [[nodiscard]] static constexpr auto helper(const Char *str) ENTT_NOEXCEPT {
  32502. base_type base{str, 0u, hs_traits::offset};
  32503. for(; str[base.length]; ++base.length) {
  32504. base.hash = (base.hash ^ static_cast<hs_traits::type>(str[base.length])) * hs_traits::prime;
  32505. }
  32506. return base;
  32507. }
  32508. // Fowler–Noll–Vo hash function v. 1a - the good
  32509. [[nodiscard]] static constexpr auto helper(const Char *str, const std::size_t len) ENTT_NOEXCEPT {
  32510. base_type base{str, len, hs_traits::offset};
  32511. for(size_type pos{}; pos < len; ++pos) {
  32512. base.hash = (base.hash ^ static_cast<hs_traits::type>(str[pos])) * hs_traits::prime;
  32513. }
  32514. return base;
  32515. }
  32516. public:
  32517. /*! @brief Character type. */
  32518. using value_type = typename base_type::value_type;
  32519. /*! @brief Unsigned integer type. */
  32520. using size_type = typename base_type::size_type;
  32521. /*! @brief Unsigned integer type. */
  32522. using hash_type = typename base_type::hash_type;
  32523. /**
  32524. * @brief Returns directly the numeric representation of a string view.
  32525. * @param str Human-readable identifier.
  32526. * @param len Length of the string to hash.
  32527. * @return The numeric representation of the string.
  32528. */
  32529. [[nodiscard]] static constexpr hash_type value(const value_type *str, const size_type len) ENTT_NOEXCEPT {
  32530. return basic_hashed_string{str, len};
  32531. }
  32532. /**
  32533. * @brief Returns directly the numeric representation of a string.
  32534. * @tparam N Number of characters of the identifier.
  32535. * @param str Human-readable identifier.
  32536. * @return The numeric representation of the string.
  32537. */
  32538. template<std::size_t N>
  32539. [[nodiscard]] static constexpr hash_type value(const value_type (&str)[N]) ENTT_NOEXCEPT {
  32540. return basic_hashed_string{str};
  32541. }
  32542. /**
  32543. * @brief Returns directly the numeric representation of a string.
  32544. * @param wrapper Helps achieving the purpose by relying on overloading.
  32545. * @return The numeric representation of the string.
  32546. */
  32547. [[nodiscard]] static constexpr hash_type value(const_wrapper wrapper) ENTT_NOEXCEPT {
  32548. return basic_hashed_string{wrapper};
  32549. }
  32550. /*! @brief Constructs an empty hashed string. */
  32551. constexpr basic_hashed_string() ENTT_NOEXCEPT
  32552. : base_type{} {}
  32553. /**
  32554. * @brief Constructs a hashed string from a string view.
  32555. * @param str Human-readable identifier.
  32556. * @param len Length of the string to hash.
  32557. */
  32558. constexpr basic_hashed_string(const value_type *str, const size_type len) ENTT_NOEXCEPT
  32559. : base_type{helper(str, len)} {}
  32560. /**
  32561. * @brief Constructs a hashed string from an array of const characters.
  32562. * @tparam N Number of characters of the identifier.
  32563. * @param str Human-readable identifier.
  32564. */
  32565. template<std::size_t N>
  32566. constexpr basic_hashed_string(const value_type (&str)[N]) ENTT_NOEXCEPT
  32567. : base_type{helper(str)} {}
  32568. /**
  32569. * @brief Explicit constructor on purpose to avoid constructing a hashed
  32570. * string directly from a `const value_type *`.
  32571. *
  32572. * @warning
  32573. * The lifetime of the string is not extended nor is it copied.
  32574. *
  32575. * @param wrapper Helps achieving the purpose by relying on overloading.
  32576. */
  32577. explicit constexpr basic_hashed_string(const_wrapper wrapper) ENTT_NOEXCEPT
  32578. : base_type{helper(wrapper.repr)} {}
  32579. /**
  32580. * @brief Returns the size a hashed string.
  32581. * @return The size of the hashed string.
  32582. */
  32583. [[nodiscard]] constexpr size_type size() const ENTT_NOEXCEPT {
  32584. return base_type::length;
  32585. }
  32586. /**
  32587. * @brief Returns the human-readable representation of a hashed string.
  32588. * @return The string used to initialize the hashed string.
  32589. */
  32590. [[nodiscard]] constexpr const value_type *data() const ENTT_NOEXCEPT {
  32591. return base_type::repr;
  32592. }
  32593. /**
  32594. * @brief Returns the numeric representation of a hashed string.
  32595. * @return The numeric representation of the hashed string.
  32596. */
  32597. [[nodiscard]] constexpr hash_type value() const ENTT_NOEXCEPT {
  32598. return base_type::hash;
  32599. }
  32600. /*! @copydoc data */
  32601. [[nodiscard]] constexpr operator const value_type *() const ENTT_NOEXCEPT {
  32602. return data();
  32603. }
  32604. /**
  32605. * @brief Returns the numeric representation of a hashed string.
  32606. * @return The numeric representation of the hashed string.
  32607. */
  32608. [[nodiscard]] constexpr operator hash_type() const ENTT_NOEXCEPT {
  32609. return value();
  32610. }
  32611. };
  32612. /**
  32613. * @brief Deduction guide.
  32614. * @tparam Char Character type.
  32615. * @param str Human-readable identifier.
  32616. * @param len Length of the string to hash.
  32617. */
  32618. template<typename Char>
  32619. basic_hashed_string(const Char *str, const std::size_t len) -> basic_hashed_string<Char>;
  32620. /**
  32621. * @brief Deduction guide.
  32622. * @tparam Char Character type.
  32623. * @tparam N Number of characters of the identifier.
  32624. * @param str Human-readable identifier.
  32625. */
  32626. template<typename Char, std::size_t N>
  32627. basic_hashed_string(const Char (&str)[N]) -> basic_hashed_string<Char>;
  32628. /**
  32629. * @brief Compares two hashed strings.
  32630. * @tparam Char Character type.
  32631. * @param lhs A valid hashed string.
  32632. * @param rhs A valid hashed string.
  32633. * @return True if the two hashed strings are identical, false otherwise.
  32634. */
  32635. template<typename Char>
  32636. [[nodiscard]] constexpr bool operator==(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) ENTT_NOEXCEPT {
  32637. return lhs.value() == rhs.value();
  32638. }
  32639. /**
  32640. * @brief Compares two hashed strings.
  32641. * @tparam Char Character type.
  32642. * @param lhs A valid hashed string.
  32643. * @param rhs A valid hashed string.
  32644. * @return True if the two hashed strings differ, false otherwise.
  32645. */
  32646. template<typename Char>
  32647. [[nodiscard]] constexpr bool operator!=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) ENTT_NOEXCEPT {
  32648. return !(lhs == rhs);
  32649. }
  32650. /**
  32651. * @brief Compares two hashed strings.
  32652. * @tparam Char Character type.
  32653. * @param lhs A valid hashed string.
  32654. * @param rhs A valid hashed string.
  32655. * @return True if the first element is less than the second, false otherwise.
  32656. */
  32657. template<typename Char>
  32658. [[nodiscard]] constexpr bool operator<(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) ENTT_NOEXCEPT {
  32659. return lhs.value() < rhs.value();
  32660. }
  32661. /**
  32662. * @brief Compares two hashed strings.
  32663. * @tparam Char Character type.
  32664. * @param lhs A valid hashed string.
  32665. * @param rhs A valid hashed string.
  32666. * @return True if the first element is less than or equal to the second, false
  32667. * otherwise.
  32668. */
  32669. template<typename Char>
  32670. [[nodiscard]] constexpr bool operator<=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) ENTT_NOEXCEPT {
  32671. return !(rhs < lhs);
  32672. }
  32673. /**
  32674. * @brief Compares two hashed strings.
  32675. * @tparam Char Character type.
  32676. * @param lhs A valid hashed string.
  32677. * @param rhs A valid hashed string.
  32678. * @return True if the first element is greater than the second, false
  32679. * otherwise.
  32680. */
  32681. template<typename Char>
  32682. [[nodiscard]] constexpr bool operator>(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) ENTT_NOEXCEPT {
  32683. return rhs < lhs;
  32684. }
  32685. /**
  32686. * @brief Compares two hashed strings.
  32687. * @tparam Char Character type.
  32688. * @param lhs A valid hashed string.
  32689. * @param rhs A valid hashed string.
  32690. * @return True if the first element is greater than or equal to the second,
  32691. * false otherwise.
  32692. */
  32693. template<typename Char>
  32694. [[nodiscard]] constexpr bool operator>=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) ENTT_NOEXCEPT {
  32695. return !(lhs < rhs);
  32696. }
  32697. /*! @brief Aliases for common character types. */
  32698. using hashed_string = basic_hashed_string<char>;
  32699. /*! @brief Aliases for common character types. */
  32700. using hashed_wstring = basic_hashed_string<wchar_t>;
  32701. inline namespace literals {
  32702. /**
  32703. * @brief User defined literal for hashed strings.
  32704. * @param str The literal without its suffix.
  32705. * @return A properly initialized hashed string.
  32706. */
  32707. [[nodiscard]] constexpr hashed_string operator"" _hs(const char *str, std::size_t) ENTT_NOEXCEPT {
  32708. return hashed_string{str};
  32709. }
  32710. /**
  32711. * @brief User defined literal for hashed wstrings.
  32712. * @param str The literal without its suffix.
  32713. * @return A properly initialized hashed wstring.
  32714. */
  32715. [[nodiscard]] constexpr hashed_wstring operator"" _hws(const wchar_t *str, std::size_t) ENTT_NOEXCEPT {
  32716. return hashed_wstring{str};
  32717. }
  32718. } // namespace literals
  32719. } // namespace entt
  32720. #endif
  32721. namespace entt {
  32722. /**
  32723. * @cond TURN_OFF_DOXYGEN
  32724. * Internal details not to be documented.
  32725. */
  32726. namespace internal {
  32727. struct ENTT_API type_index final {
  32728. [[nodiscard]] static id_type next() ENTT_NOEXCEPT {
  32729. static ENTT_MAYBE_ATOMIC(id_type) value{};
  32730. return value++;
  32731. }
  32732. };
  32733. template<typename Type>
  32734. [[nodiscard]] constexpr auto stripped_type_name() ENTT_NOEXCEPT {
  32735. #if defined ENTT_PRETTY_FUNCTION
  32736. std::string_view pretty_function{ENTT_PRETTY_FUNCTION};
  32737. auto first = pretty_function.find_first_not_of(' ', pretty_function.find_first_of(ENTT_PRETTY_FUNCTION_PREFIX) + 1);
  32738. auto value = pretty_function.substr(first, pretty_function.find_last_of(ENTT_PRETTY_FUNCTION_SUFFIX) - first);
  32739. return value;
  32740. #else
  32741. return std::string_view{""};
  32742. #endif
  32743. }
  32744. template<typename Type, auto = stripped_type_name<Type>().find_first_of('.')>
  32745. [[nodiscard]] static constexpr std::string_view type_name(int) ENTT_NOEXCEPT {
  32746. constexpr auto value = stripped_type_name<Type>();
  32747. return value;
  32748. }
  32749. template<typename Type>
  32750. [[nodiscard]] static std::string_view type_name(char) ENTT_NOEXCEPT {
  32751. static const auto value = stripped_type_name<Type>();
  32752. return value;
  32753. }
  32754. template<typename Type, auto = stripped_type_name<Type>().find_first_of('.')>
  32755. [[nodiscard]] static constexpr id_type type_hash(int) ENTT_NOEXCEPT {
  32756. constexpr auto stripped = stripped_type_name<Type>();
  32757. constexpr auto value = hashed_string::value(stripped.data(), stripped.size());
  32758. return value;
  32759. }
  32760. template<typename Type>
  32761. [[nodiscard]] static id_type type_hash(char) ENTT_NOEXCEPT {
  32762. static const auto value = [](const auto stripped) {
  32763. return hashed_string::value(stripped.data(), stripped.size());
  32764. }(stripped_type_name<Type>());
  32765. return value;
  32766. }
  32767. } // namespace internal
  32768. /**
  32769. * Internal details not to be documented.
  32770. * @endcond
  32771. */
  32772. /**
  32773. * @brief Type sequential identifier.
  32774. * @tparam Type Type for which to generate a sequential identifier.
  32775. */
  32776. template<typename Type, typename = void>
  32777. struct ENTT_API type_index final {
  32778. /**
  32779. * @brief Returns the sequential identifier of a given type.
  32780. * @return The sequential identifier of a given type.
  32781. */
  32782. [[nodiscard]] static id_type value() ENTT_NOEXCEPT {
  32783. static const id_type value = internal::type_index::next();
  32784. return value;
  32785. }
  32786. /*! @copydoc value */
  32787. [[nodiscard]] constexpr operator id_type() const ENTT_NOEXCEPT {
  32788. return value();
  32789. }
  32790. };
  32791. /**
  32792. * @brief Type hash.
  32793. * @tparam Type Type for which to generate a hash value.
  32794. */
  32795. template<typename Type, typename = void>
  32796. struct type_hash final {
  32797. /**
  32798. * @brief Returns the numeric representation of a given type.
  32799. * @return The numeric representation of the given type.
  32800. */
  32801. #if defined ENTT_PRETTY_FUNCTION
  32802. [[nodiscard]] static constexpr id_type value() ENTT_NOEXCEPT {
  32803. return internal::type_hash<Type>(0);
  32804. #else
  32805. [[nodiscard]] static constexpr id_type value() ENTT_NOEXCEPT {
  32806. return type_index<Type>::value();
  32807. #endif
  32808. }
  32809. /*! @copydoc value */
  32810. [[nodiscard]] constexpr operator id_type() const ENTT_NOEXCEPT {
  32811. return value();
  32812. }
  32813. };
  32814. /**
  32815. * @brief Type name.
  32816. * @tparam Type Type for which to generate a name.
  32817. */
  32818. template<typename Type, typename = void>
  32819. struct type_name final {
  32820. /**
  32821. * @brief Returns the name of a given type.
  32822. * @return The name of the given type.
  32823. */
  32824. [[nodiscard]] static constexpr std::string_view value() ENTT_NOEXCEPT {
  32825. return internal::type_name<Type>(0);
  32826. }
  32827. /*! @copydoc value */
  32828. [[nodiscard]] constexpr operator std::string_view() const ENTT_NOEXCEPT {
  32829. return value();
  32830. }
  32831. };
  32832. /*! @brief Implementation specific information about a type. */
  32833. struct type_info final {
  32834. /**
  32835. * @brief Constructs a type info object for a given type.
  32836. * @tparam Type Type for which to construct a type info object.
  32837. */
  32838. template<typename Type>
  32839. constexpr type_info(std::in_place_type_t<Type>) ENTT_NOEXCEPT
  32840. : seq{type_index<std::remove_cv_t<std::remove_reference_t<Type>>>::value()},
  32841. identifier{type_hash<std::remove_cv_t<std::remove_reference_t<Type>>>::value()},
  32842. alias{type_name<std::remove_cv_t<std::remove_reference_t<Type>>>::value()} {}
  32843. /**
  32844. * @brief Type index.
  32845. * @return Type index.
  32846. */
  32847. [[nodiscard]] constexpr id_type index() const ENTT_NOEXCEPT {
  32848. return seq;
  32849. }
  32850. /**
  32851. * @brief Type hash.
  32852. * @return Type hash.
  32853. */
  32854. [[nodiscard]] constexpr id_type hash() const ENTT_NOEXCEPT {
  32855. return identifier;
  32856. }
  32857. /**
  32858. * @brief Type name.
  32859. * @return Type name.
  32860. */
  32861. [[nodiscard]] constexpr std::string_view name() const ENTT_NOEXCEPT {
  32862. return alias;
  32863. }
  32864. private:
  32865. id_type seq;
  32866. id_type identifier;
  32867. std::string_view alias;
  32868. };
  32869. /**
  32870. * @brief Compares the contents of two type info objects.
  32871. * @param lhs A type info object.
  32872. * @param rhs A type info object.
  32873. * @return True if the two type info objects are identical, false otherwise.
  32874. */
  32875. [[nodiscard]] inline constexpr bool operator==(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT {
  32876. return lhs.hash() == rhs.hash();
  32877. }
  32878. /**
  32879. * @brief Compares the contents of two type info objects.
  32880. * @param lhs A type info object.
  32881. * @param rhs A type info object.
  32882. * @return True if the two type info objects differ, false otherwise.
  32883. */
  32884. [[nodiscard]] inline constexpr bool operator!=(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT {
  32885. return !(lhs == rhs);
  32886. }
  32887. /**
  32888. * @brief Compares two type info objects.
  32889. * @param lhs A valid type info object.
  32890. * @param rhs A valid type info object.
  32891. * @return True if the first element is less than the second, false otherwise.
  32892. */
  32893. [[nodiscard]] constexpr bool operator<(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT {
  32894. return lhs.index() < rhs.index();
  32895. }
  32896. /**
  32897. * @brief Compares two type info objects.
  32898. * @param lhs A valid type info object.
  32899. * @param rhs A valid type info object.
  32900. * @return True if the first element is less than or equal to the second, false
  32901. * otherwise.
  32902. */
  32903. [[nodiscard]] constexpr bool operator<=(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT {
  32904. return !(rhs < lhs);
  32905. }
  32906. /**
  32907. * @brief Compares two type info objects.
  32908. * @param lhs A valid type info object.
  32909. * @param rhs A valid type info object.
  32910. * @return True if the first element is greater than the second, false
  32911. * otherwise.
  32912. */
  32913. [[nodiscard]] constexpr bool operator>(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT {
  32914. return rhs < lhs;
  32915. }
  32916. /**
  32917. * @brief Compares two type info objects.
  32918. * @param lhs A valid type info object.
  32919. * @param rhs A valid type info object.
  32920. * @return True if the first element is greater than or equal to the second,
  32921. * false otherwise.
  32922. */
  32923. [[nodiscard]] constexpr bool operator>=(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT {
  32924. return !(lhs < rhs);
  32925. }
  32926. /**
  32927. * @brief Returns the type info object associated to a given type.
  32928. *
  32929. * The returned element refers to an object with static storage duration.<br/>
  32930. * The type doesn't need to be a complete type. If the type is a reference, the
  32931. * result refers to the referenced type. In all cases, top-level cv-qualifiers
  32932. * are ignored.
  32933. *
  32934. * @tparam Type Type for which to generate a type info object.
  32935. * @return A reference to a properly initialized type info object.
  32936. */
  32937. template<typename Type>
  32938. [[nodiscard]] const type_info &type_id() ENTT_NOEXCEPT {
  32939. if constexpr(std::is_same_v<Type, std::remove_cv_t<std::remove_reference_t<Type>>>) {
  32940. static type_info instance{std::in_place_type<Type>};
  32941. return instance;
  32942. } else {
  32943. return type_id<std::remove_cv_t<std::remove_reference_t<Type>>>();
  32944. }
  32945. }
  32946. /*! @copydoc type_id */
  32947. template<typename Type>
  32948. [[nodiscard]] const type_info &type_id(Type &&) ENTT_NOEXCEPT {
  32949. return type_id<std::remove_cv_t<std::remove_reference_t<Type>>>();
  32950. }
  32951. } // namespace entt
  32952. #endif
  32953. // #include "type_traits.hpp"
  32954. #ifndef ENTT_CORE_TYPE_TRAITS_HPP
  32955. #define ENTT_CORE_TYPE_TRAITS_HPP
  32956. #include <cstddef>
  32957. #include <iterator>
  32958. #include <type_traits>
  32959. #include <utility>
  32960. // #include "../config/config.h"
  32961. // #include "fwd.hpp"
  32962. namespace entt {
  32963. /**
  32964. * @brief Utility class to disambiguate overloaded functions.
  32965. * @tparam N Number of choices available.
  32966. */
  32967. template<std::size_t N>
  32968. struct choice_t
  32969. // Unfortunately, doxygen cannot parse such a construct.
  32970. : /*! @cond TURN_OFF_DOXYGEN */ choice_t<N - 1> /*! @endcond */
  32971. {};
  32972. /*! @copybrief choice_t */
  32973. template<>
  32974. struct choice_t<0> {};
  32975. /**
  32976. * @brief Variable template for the choice trick.
  32977. * @tparam N Number of choices available.
  32978. */
  32979. template<std::size_t N>
  32980. inline constexpr choice_t<N> choice{};
  32981. /**
  32982. * @brief Identity type trait.
  32983. *
  32984. * Useful to establish non-deduced contexts in template argument deduction
  32985. * (waiting for C++20) or to provide types through function arguments.
  32986. *
  32987. * @tparam Type A type.
  32988. */
  32989. template<typename Type>
  32990. struct type_identity {
  32991. /*! @brief Identity type. */
  32992. using type = Type;
  32993. };
  32994. /**
  32995. * @brief Helper type.
  32996. * @tparam Type A type.
  32997. */
  32998. template<typename Type>
  32999. using type_identity_t = typename type_identity<Type>::type;
  33000. /**
  33001. * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains.
  33002. * @tparam Type The type of which to return the size.
  33003. * @tparam The size of the type if `sizeof` accepts it, 0 otherwise.
  33004. */
  33005. template<typename Type, typename = void>
  33006. struct size_of: std::integral_constant<std::size_t, 0u> {};
  33007. /*! @copydoc size_of */
  33008. template<typename Type>
  33009. struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
  33010. : std::integral_constant<std::size_t, sizeof(Type)> {};
  33011. /**
  33012. * @brief Helper variable template.
  33013. * @tparam Type The type of which to return the size.
  33014. */
  33015. template<typename Type>
  33016. inline constexpr std::size_t size_of_v = size_of<Type>::value;
  33017. /**
  33018. * @brief Using declaration to be used to _repeat_ the same type a number of
  33019. * times equal to the size of a given parameter pack.
  33020. * @tparam Type A type to repeat.
  33021. */
  33022. template<typename Type, typename>
  33023. using unpack_as_type = Type;
  33024. /**
  33025. * @brief Helper variable template to be used to _repeat_ the same value a
  33026. * number of times equal to the size of a given parameter pack.
  33027. * @tparam Value A value to repeat.
  33028. */
  33029. template<auto Value, typename>
  33030. inline constexpr auto unpack_as_value = Value;
  33031. /**
  33032. * @brief Wraps a static constant.
  33033. * @tparam Value A static constant.
  33034. */
  33035. template<auto Value>
  33036. using integral_constant = std::integral_constant<decltype(Value), Value>;
  33037. /**
  33038. * @brief Alias template to facilitate the creation of named values.
  33039. * @tparam Value A constant value at least convertible to `id_type`.
  33040. */
  33041. template<id_type Value>
  33042. using tag = integral_constant<Value>;
  33043. /**
  33044. * @brief A class to use to push around lists of types, nothing more.
  33045. * @tparam Type Types provided by the type list.
  33046. */
  33047. template<typename... Type>
  33048. struct type_list {
  33049. /*! @brief Type list type. */
  33050. using type = type_list;
  33051. /*! @brief Compile-time number of elements in the type list. */
  33052. static constexpr auto size = sizeof...(Type);
  33053. };
  33054. /*! @brief Primary template isn't defined on purpose. */
  33055. template<std::size_t, typename>
  33056. struct type_list_element;
  33057. /**
  33058. * @brief Provides compile-time indexed access to the types of a type list.
  33059. * @tparam Index Index of the type to return.
  33060. * @tparam Type First type provided by the type list.
  33061. * @tparam Other Other types provided by the type list.
  33062. */
  33063. template<std::size_t Index, typename Type, typename... Other>
  33064. struct type_list_element<Index, type_list<Type, Other...>>
  33065. : type_list_element<Index - 1u, type_list<Other...>> {};
  33066. /**
  33067. * @brief Provides compile-time indexed access to the types of a type list.
  33068. * @tparam Type First type provided by the type list.
  33069. * @tparam Other Other types provided by the type list.
  33070. */
  33071. template<typename Type, typename... Other>
  33072. struct type_list_element<0u, type_list<Type, Other...>> {
  33073. /*! @brief Searched type. */
  33074. using type = Type;
  33075. };
  33076. /**
  33077. * @brief Helper type.
  33078. * @tparam Index Index of the type to return.
  33079. * @tparam List Type list to search into.
  33080. */
  33081. template<std::size_t Index, typename List>
  33082. using type_list_element_t = typename type_list_element<Index, List>::type;
  33083. /**
  33084. * @brief Concatenates multiple type lists.
  33085. * @tparam Type Types provided by the first type list.
  33086. * @tparam Other Types provided by the second type list.
  33087. * @return A type list composed by the types of both the type lists.
  33088. */
  33089. template<typename... Type, typename... Other>
  33090. constexpr type_list<Type..., Other...> operator+(type_list<Type...>, type_list<Other...>) {
  33091. return {};
  33092. }
  33093. /*! @brief Primary template isn't defined on purpose. */
  33094. template<typename...>
  33095. struct type_list_cat;
  33096. /*! @brief Concatenates multiple type lists. */
  33097. template<>
  33098. struct type_list_cat<> {
  33099. /*! @brief A type list composed by the types of all the type lists. */
  33100. using type = type_list<>;
  33101. };
  33102. /**
  33103. * @brief Concatenates multiple type lists.
  33104. * @tparam Type Types provided by the first type list.
  33105. * @tparam Other Types provided by the second type list.
  33106. * @tparam List Other type lists, if any.
  33107. */
  33108. template<typename... Type, typename... Other, typename... List>
  33109. struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
  33110. /*! @brief A type list composed by the types of all the type lists. */
  33111. using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
  33112. };
  33113. /**
  33114. * @brief Concatenates multiple type lists.
  33115. * @tparam Type Types provided by the type list.
  33116. */
  33117. template<typename... Type>
  33118. struct type_list_cat<type_list<Type...>> {
  33119. /*! @brief A type list composed by the types of all the type lists. */
  33120. using type = type_list<Type...>;
  33121. };
  33122. /**
  33123. * @brief Helper type.
  33124. * @tparam List Type lists to concatenate.
  33125. */
  33126. template<typename... List>
  33127. using type_list_cat_t = typename type_list_cat<List...>::type;
  33128. /*! @brief Primary template isn't defined on purpose. */
  33129. template<typename>
  33130. struct type_list_unique;
  33131. /**
  33132. * @brief Removes duplicates types from a type list.
  33133. * @tparam Type One of the types provided by the given type list.
  33134. * @tparam Other The other types provided by the given type list.
  33135. */
  33136. template<typename Type, typename... Other>
  33137. struct type_list_unique<type_list<Type, Other...>> {
  33138. /*! @brief A type list without duplicate types. */
  33139. using type = std::conditional_t<
  33140. (std::is_same_v<Type, Other> || ...),
  33141. typename type_list_unique<type_list<Other...>>::type,
  33142. type_list_cat_t<type_list<Type>, typename type_list_unique<type_list<Other...>>::type>>;
  33143. };
  33144. /*! @brief Removes duplicates types from a type list. */
  33145. template<>
  33146. struct type_list_unique<type_list<>> {
  33147. /*! @brief A type list without duplicate types. */
  33148. using type = type_list<>;
  33149. };
  33150. /**
  33151. * @brief Helper type.
  33152. * @tparam Type A type list.
  33153. */
  33154. template<typename Type>
  33155. using type_list_unique_t = typename type_list_unique<Type>::type;
  33156. /**
  33157. * @brief Provides the member constant `value` to true if a type list contains a
  33158. * given type, false otherwise.
  33159. * @tparam List Type list.
  33160. * @tparam Type Type to look for.
  33161. */
  33162. template<typename List, typename Type>
  33163. struct type_list_contains;
  33164. /**
  33165. * @copybrief type_list_contains
  33166. * @tparam Type Types provided by the type list.
  33167. * @tparam Other Type to look for.
  33168. */
  33169. template<typename... Type, typename Other>
  33170. struct type_list_contains<type_list<Type...>, Other>: std::disjunction<std::is_same<Type, Other>...> {};
  33171. /**
  33172. * @brief Helper variable template.
  33173. * @tparam List Type list.
  33174. * @tparam Type Type to look for.
  33175. */
  33176. template<typename List, typename Type>
  33177. inline constexpr bool type_list_contains_v = type_list_contains<List, Type>::value;
  33178. /*! @brief Primary template isn't defined on purpose. */
  33179. template<typename...>
  33180. struct type_list_diff;
  33181. /**
  33182. * @brief Computes the difference between two type lists.
  33183. * @tparam Type Types provided by the first type list.
  33184. * @tparam Other Types provided by the second type list.
  33185. */
  33186. template<typename... Type, typename... Other>
  33187. struct type_list_diff<type_list<Type...>, type_list<Other...>> {
  33188. /*! @brief A type list that is the difference between the two type lists. */
  33189. using type = type_list_cat_t<std::conditional_t<type_list_contains_v<type_list<Other...>, Type>, type_list<>, type_list<Type>>...>;
  33190. };
  33191. /**
  33192. * @brief Helper type.
  33193. * @tparam List Type lists between which to compute the difference.
  33194. */
  33195. template<typename... List>
  33196. using type_list_diff_t = typename type_list_diff<List...>::type;
  33197. /**
  33198. * @brief A class to use to push around lists of constant values, nothing more.
  33199. * @tparam Value Values provided by the value list.
  33200. */
  33201. template<auto... Value>
  33202. struct value_list {
  33203. /*! @brief Value list type. */
  33204. using type = value_list;
  33205. /*! @brief Compile-time number of elements in the value list. */
  33206. static constexpr auto size = sizeof...(Value);
  33207. };
  33208. /*! @brief Primary template isn't defined on purpose. */
  33209. template<std::size_t, typename>
  33210. struct value_list_element;
  33211. /**
  33212. * @brief Provides compile-time indexed access to the values of a value list.
  33213. * @tparam Index Index of the value to return.
  33214. * @tparam Value First value provided by the value list.
  33215. * @tparam Other Other values provided by the value list.
  33216. */
  33217. template<std::size_t Index, auto Value, auto... Other>
  33218. struct value_list_element<Index, value_list<Value, Other...>>
  33219. : value_list_element<Index - 1u, value_list<Other...>> {};
  33220. /**
  33221. * @brief Provides compile-time indexed access to the types of a type list.
  33222. * @tparam Value First value provided by the value list.
  33223. * @tparam Other Other values provided by the value list.
  33224. */
  33225. template<auto Value, auto... Other>
  33226. struct value_list_element<0u, value_list<Value, Other...>> {
  33227. /*! @brief Searched value. */
  33228. static constexpr auto value = Value;
  33229. };
  33230. /**
  33231. * @brief Helper type.
  33232. * @tparam Index Index of the value to return.
  33233. * @tparam List Value list to search into.
  33234. */
  33235. template<std::size_t Index, typename List>
  33236. inline constexpr auto value_list_element_v = value_list_element<Index, List>::value;
  33237. /**
  33238. * @brief Concatenates multiple value lists.
  33239. * @tparam Value Values provided by the first value list.
  33240. * @tparam Other Values provided by the second value list.
  33241. * @return A value list composed by the values of both the value lists.
  33242. */
  33243. template<auto... Value, auto... Other>
  33244. constexpr value_list<Value..., Other...> operator+(value_list<Value...>, value_list<Other...>) {
  33245. return {};
  33246. }
  33247. /*! @brief Primary template isn't defined on purpose. */
  33248. template<typename...>
  33249. struct value_list_cat;
  33250. /*! @brief Concatenates multiple value lists. */
  33251. template<>
  33252. struct value_list_cat<> {
  33253. /*! @brief A value list composed by the values of all the value lists. */
  33254. using type = value_list<>;
  33255. };
  33256. /**
  33257. * @brief Concatenates multiple value lists.
  33258. * @tparam Value Values provided by the first value list.
  33259. * @tparam Other Values provided by the second value list.
  33260. * @tparam List Other value lists, if any.
  33261. */
  33262. template<auto... Value, auto... Other, typename... List>
  33263. struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
  33264. /*! @brief A value list composed by the values of all the value lists. */
  33265. using type = typename value_list_cat<value_list<Value..., Other...>, List...>::type;
  33266. };
  33267. /**
  33268. * @brief Concatenates multiple value lists.
  33269. * @tparam Value Values provided by the value list.
  33270. */
  33271. template<auto... Value>
  33272. struct value_list_cat<value_list<Value...>> {
  33273. /*! @brief A value list composed by the values of all the value lists. */
  33274. using type = value_list<Value...>;
  33275. };
  33276. /**
  33277. * @brief Helper type.
  33278. * @tparam List Value lists to concatenate.
  33279. */
  33280. template<typename... List>
  33281. using value_list_cat_t = typename value_list_cat<List...>::type;
  33282. /*! @brief Same as std::is_invocable, but with tuples. */
  33283. template<typename, typename>
  33284. struct is_applicable: std::false_type {};
  33285. /**
  33286. * @copybrief is_applicable
  33287. * @tparam Func A valid function type.
  33288. * @tparam Tuple Tuple-like type.
  33289. * @tparam Args The list of arguments to use to probe the function type.
  33290. */
  33291. template<typename Func, template<typename...> class Tuple, typename... Args>
  33292. struct is_applicable<Func, Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  33293. /**
  33294. * @copybrief is_applicable
  33295. * @tparam Func A valid function type.
  33296. * @tparam Tuple Tuple-like type.
  33297. * @tparam Args The list of arguments to use to probe the function type.
  33298. */
  33299. template<typename Func, template<typename...> class Tuple, typename... Args>
  33300. struct is_applicable<Func, const Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  33301. /**
  33302. * @brief Helper variable template.
  33303. * @tparam Func A valid function type.
  33304. * @tparam Args The list of arguments to use to probe the function type.
  33305. */
  33306. template<typename Func, typename Args>
  33307. inline constexpr bool is_applicable_v = is_applicable<Func, Args>::value;
  33308. /*! @brief Same as std::is_invocable_r, but with tuples for arguments. */
  33309. template<typename, typename, typename>
  33310. struct is_applicable_r: std::false_type {};
  33311. /**
  33312. * @copybrief is_applicable_r
  33313. * @tparam Ret The type to which the return type of the function should be
  33314. * convertible.
  33315. * @tparam Func A valid function type.
  33316. * @tparam Args The list of arguments to use to probe the function type.
  33317. */
  33318. template<typename Ret, typename Func, typename... Args>
  33319. struct is_applicable_r<Ret, Func, std::tuple<Args...>>: std::is_invocable_r<Ret, Func, Args...> {};
  33320. /**
  33321. * @brief Helper variable template.
  33322. * @tparam Ret The type to which the return type of the function should be
  33323. * convertible.
  33324. * @tparam Func A valid function type.
  33325. * @tparam Args The list of arguments to use to probe the function type.
  33326. */
  33327. template<typename Ret, typename Func, typename Args>
  33328. inline constexpr bool is_applicable_r_v = is_applicable_r<Ret, Func, Args>::value;
  33329. /**
  33330. * @brief Provides the member constant `value` to true if a given type is
  33331. * complete, false otherwise.
  33332. * @tparam Type The type to test.
  33333. */
  33334. template<typename Type, typename = void>
  33335. struct is_complete: std::false_type {};
  33336. /*! @copydoc is_complete */
  33337. template<typename Type>
  33338. struct is_complete<Type, std::void_t<decltype(sizeof(Type))>>: std::true_type {};
  33339. /**
  33340. * @brief Helper variable template.
  33341. * @tparam Type The type to test.
  33342. */
  33343. template<typename Type>
  33344. inline constexpr bool is_complete_v = is_complete<Type>::value;
  33345. /**
  33346. * @brief Provides the member constant `value` to true if a given type is an
  33347. * iterator, false otherwise.
  33348. * @tparam Type The type to test.
  33349. */
  33350. template<typename Type, typename = void>
  33351. struct is_iterator: std::false_type {};
  33352. /**
  33353. * @cond TURN_OFF_DOXYGEN
  33354. * Internal details not to be documented.
  33355. */
  33356. namespace internal {
  33357. template<typename, typename = void>
  33358. struct has_iterator_category: std::false_type {};
  33359. template<typename Type>
  33360. struct has_iterator_category<Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>: std::true_type {};
  33361. } // namespace internal
  33362. /**
  33363. * Internal details not to be documented.
  33364. * @endcond
  33365. */
  33366. /*! @copydoc is_iterator */
  33367. template<typename Type>
  33368. struct is_iterator<Type, std::enable_if_t<!std::is_same_v<std::remove_const_t<std::remove_pointer_t<Type>>, void>>>
  33369. : internal::has_iterator_category<Type> {};
  33370. /**
  33371. * @brief Helper variable template.
  33372. * @tparam Type The type to test.
  33373. */
  33374. template<typename Type>
  33375. inline constexpr bool is_iterator_v = is_iterator<Type>::value;
  33376. /**
  33377. * @brief Provides the member constant `value` to true if a given type is both
  33378. * an empty and non-final class, false otherwise.
  33379. * @tparam Type The type to test
  33380. */
  33381. template<typename Type>
  33382. struct is_ebco_eligible
  33383. : std::conjunction<std::is_empty<Type>, std::negation<std::is_final<Type>>> {};
  33384. /**
  33385. * @brief Helper variable template.
  33386. * @tparam Type The type to test.
  33387. */
  33388. template<typename Type>
  33389. inline constexpr bool is_ebco_eligible_v = is_ebco_eligible<Type>::value;
  33390. /**
  33391. * @brief Provides the member constant `value` to true if `Type::is_transparent`
  33392. * is valid and denotes a type, false otherwise.
  33393. * @tparam Type The type to test.
  33394. */
  33395. template<typename Type, typename = void>
  33396. struct is_transparent: std::false_type {};
  33397. /*! @copydoc is_transparent */
  33398. template<typename Type>
  33399. struct is_transparent<Type, std::void_t<typename Type::is_transparent>>: std::true_type {};
  33400. /**
  33401. * @brief Helper variable template.
  33402. * @tparam Type The type to test.
  33403. */
  33404. template<typename Type>
  33405. inline constexpr bool is_transparent_v = is_transparent<Type>::value;
  33406. /**
  33407. * @brief Provides the member constant `value` to true if a given type is
  33408. * equality comparable, false otherwise.
  33409. * @tparam Type The type to test.
  33410. */
  33411. template<typename Type, typename = void>
  33412. struct is_equality_comparable: std::false_type {};
  33413. /**
  33414. * @cond TURN_OFF_DOXYGEN
  33415. * Internal details not to be documented.
  33416. */
  33417. namespace internal {
  33418. template<typename, typename = void>
  33419. struct has_tuple_size_value: std::false_type {};
  33420. template<typename Type>
  33421. struct has_tuple_size_value<Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>: std::true_type {};
  33422. template<typename Type, std::size_t... Index>
  33423. [[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
  33424. return (is_equality_comparable<std::tuple_element_t<Index, Type>>::value && ...);
  33425. }
  33426. template<typename>
  33427. [[nodiscard]] constexpr bool maybe_equality_comparable(choice_t<0>) {
  33428. return true;
  33429. }
  33430. template<typename Type>
  33431. [[nodiscard]] constexpr auto maybe_equality_comparable(choice_t<1>) -> decltype(std::declval<typename Type::value_type>(), bool{}) {
  33432. if constexpr(is_iterator_v<Type>) {
  33433. return true;
  33434. } else if constexpr(std::is_same_v<typename Type::value_type, Type>) {
  33435. return maybe_equality_comparable<Type>(choice<0>);
  33436. } else {
  33437. return is_equality_comparable<typename Type::value_type>::value;
  33438. }
  33439. }
  33440. template<typename Type>
  33441. [[nodiscard]] constexpr std::enable_if_t<is_complete_v<std::tuple_size<std::remove_const_t<Type>>>, bool> maybe_equality_comparable(choice_t<2>) {
  33442. if constexpr(has_tuple_size_value<Type>::value) {
  33443. return unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
  33444. } else {
  33445. return maybe_equality_comparable<Type>(choice<1>);
  33446. }
  33447. }
  33448. } // namespace internal
  33449. /**
  33450. * Internal details not to be documented.
  33451. * @endcond
  33452. */
  33453. /*! @copydoc is_equality_comparable */
  33454. template<typename Type>
  33455. struct is_equality_comparable<Type, std::void_t<decltype(std::declval<Type>() == std::declval<Type>())>>
  33456. : std::bool_constant<internal::maybe_equality_comparable<Type>(choice<2>)> {};
  33457. /**
  33458. * @brief Helper variable template.
  33459. * @tparam Type The type to test.
  33460. */
  33461. template<typename Type>
  33462. inline constexpr bool is_equality_comparable_v = is_equality_comparable<Type>::value;
  33463. /**
  33464. * @brief Transcribes the constness of a type to another type.
  33465. * @tparam To The type to which to transcribe the constness.
  33466. * @tparam From The type from which to transcribe the constness.
  33467. */
  33468. template<typename To, typename From>
  33469. struct constness_as {
  33470. /*! @brief The type resulting from the transcription of the constness. */
  33471. using type = std::remove_const_t<To>;
  33472. };
  33473. /*! @copydoc constness_as */
  33474. template<typename To, typename From>
  33475. struct constness_as<To, const From> {
  33476. /*! @brief The type resulting from the transcription of the constness. */
  33477. using type = std::add_const_t<To>;
  33478. };
  33479. /**
  33480. * @brief Alias template to facilitate the transcription of the constness.
  33481. * @tparam To The type to which to transcribe the constness.
  33482. * @tparam From The type from which to transcribe the constness.
  33483. */
  33484. template<typename To, typename From>
  33485. using constness_as_t = typename constness_as<To, From>::type;
  33486. /**
  33487. * @brief Extracts the class of a non-static member object or function.
  33488. * @tparam Member A pointer to a non-static member object or function.
  33489. */
  33490. template<typename Member>
  33491. class member_class {
  33492. static_assert(std::is_member_pointer_v<Member>, "Invalid pointer type to non-static member object or function");
  33493. template<typename Class, typename Ret, typename... Args>
  33494. static Class *clazz(Ret (Class::*)(Args...));
  33495. template<typename Class, typename Ret, typename... Args>
  33496. static Class *clazz(Ret (Class::*)(Args...) const);
  33497. template<typename Class, typename Type>
  33498. static Class *clazz(Type Class::*);
  33499. public:
  33500. /*! @brief The class of the given non-static member object or function. */
  33501. using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
  33502. };
  33503. /**
  33504. * @brief Helper type.
  33505. * @tparam Member A pointer to a non-static member object or function.
  33506. */
  33507. template<typename Member>
  33508. using member_class_t = typename member_class<Member>::type;
  33509. } // namespace entt
  33510. #endif
  33511. namespace entt {
  33512. /**
  33513. * @brief A SBO friendly, type-safe container for single values of any type.
  33514. * @tparam Len Size of the storage reserved for the small buffer optimization.
  33515. * @tparam Align Optional alignment requirement.
  33516. */
  33517. template<std::size_t Len, std::size_t Align>
  33518. class basic_any {
  33519. enum class operation : std::uint8_t {
  33520. copy,
  33521. move,
  33522. transfer,
  33523. assign,
  33524. destroy,
  33525. compare,
  33526. get
  33527. };
  33528. enum class policy : std::uint8_t {
  33529. owner,
  33530. ref,
  33531. cref
  33532. };
  33533. using storage_type = std::aligned_storage_t<Len + !Len, Align>;
  33534. using vtable_type = const void *(const operation, const basic_any &, const void *);
  33535. template<typename Type>
  33536. static constexpr bool in_situ = Len && alignof(Type) <= alignof(storage_type) && sizeof(Type) <= sizeof(storage_type) && std::is_nothrow_move_constructible_v<Type>;
  33537. template<typename Type>
  33538. static const void *basic_vtable([[maybe_unused]] const operation op, [[maybe_unused]] const basic_any &value, [[maybe_unused]] const void *other) {
  33539. static_assert(!std::is_same_v<Type, void> && std::is_same_v<std::remove_cv_t<std::remove_reference_t<Type>>, Type>, "Invalid type");
  33540. const Type *element = nullptr;
  33541. if constexpr(in_situ<Type>) {
  33542. element = value.owner() ? reinterpret_cast<const Type *>(&value.storage) : static_cast<const Type *>(value.instance);
  33543. } else {
  33544. element = static_cast<const Type *>(value.instance);
  33545. }
  33546. switch(op) {
  33547. case operation::copy:
  33548. if constexpr(std::is_copy_constructible_v<Type>) {
  33549. static_cast<basic_any *>(const_cast<void *>(other))->initialize<Type>(*element);
  33550. }
  33551. break;
  33552. case operation::move:
  33553. if constexpr(in_situ<Type>) {
  33554. if(value.owner()) {
  33555. return new(&static_cast<basic_any *>(const_cast<void *>(other))->storage) Type{std::move(*const_cast<Type *>(element))};
  33556. }
  33557. }
  33558. return (static_cast<basic_any *>(const_cast<void *>(other))->instance = std::exchange(const_cast<basic_any &>(value).instance, nullptr));
  33559. case operation::transfer:
  33560. if constexpr(std::is_move_assignable_v<Type>) {
  33561. *const_cast<Type *>(element) = std::move(*static_cast<Type *>(const_cast<void *>(other)));
  33562. return other;
  33563. }
  33564. [[fallthrough]];
  33565. case operation::assign:
  33566. if constexpr(std::is_copy_assignable_v<Type>) {
  33567. *const_cast<Type *>(element) = *static_cast<const Type *>(other);
  33568. return other;
  33569. }
  33570. break;
  33571. case operation::destroy:
  33572. if constexpr(in_situ<Type>) {
  33573. element->~Type();
  33574. } else if constexpr(std::is_array_v<Type>) {
  33575. delete[] element;
  33576. } else {
  33577. delete element;
  33578. }
  33579. break;
  33580. case operation::compare:
  33581. if constexpr(!std::is_function_v<Type> && !std::is_array_v<Type> && is_equality_comparable_v<Type>) {
  33582. return *static_cast<const Type *>(element) == *static_cast<const Type *>(other) ? other : nullptr;
  33583. } else {
  33584. return (element == other) ? other : nullptr;
  33585. }
  33586. case operation::get:
  33587. return element;
  33588. }
  33589. return nullptr;
  33590. }
  33591. template<typename Type, typename... Args>
  33592. void initialize([[maybe_unused]] Args &&...args) {
  33593. if constexpr(!std::is_void_v<Type>) {
  33594. info = &type_id<std::remove_cv_t<std::remove_reference_t<Type>>>();
  33595. vtable = basic_vtable<std::remove_cv_t<std::remove_reference_t<Type>>>;
  33596. if constexpr(std::is_lvalue_reference_v<Type>) {
  33597. static_assert(sizeof...(Args) == 1u && (std::is_lvalue_reference_v<Args> && ...), "Invalid arguments");
  33598. mode = std::is_const_v<std::remove_reference_t<Type>> ? policy::cref : policy::ref;
  33599. instance = (std::addressof(args), ...);
  33600. } else if constexpr(in_situ<Type>) {
  33601. if constexpr(sizeof...(Args) != 0u && std::is_aggregate_v<Type>) {
  33602. new(&storage) Type{std::forward<Args>(args)...};
  33603. } else {
  33604. new(&storage) Type(std::forward<Args>(args)...);
  33605. }
  33606. } else {
  33607. if constexpr(sizeof...(Args) != 0u && std::is_aggregate_v<Type>) {
  33608. instance = new Type{std::forward<Args>(args)...};
  33609. } else {
  33610. instance = new Type(std::forward<Args>(args)...);
  33611. }
  33612. }
  33613. }
  33614. }
  33615. basic_any(const basic_any &other, const policy pol) ENTT_NOEXCEPT
  33616. : instance{other.data()},
  33617. info{other.info},
  33618. vtable{other.vtable},
  33619. mode{pol} {}
  33620. public:
  33621. /*! @brief Size of the internal storage. */
  33622. static constexpr auto length = Len;
  33623. /*! @brief Alignment requirement. */
  33624. static constexpr auto alignment = Align;
  33625. /*! @brief Default constructor. */
  33626. constexpr basic_any() ENTT_NOEXCEPT
  33627. : instance{},
  33628. info{&type_id<void>()},
  33629. vtable{},
  33630. mode{policy::owner} {}
  33631. /**
  33632. * @brief Constructs a wrapper by directly initializing the new object.
  33633. * @tparam Type Type of object to use to initialize the wrapper.
  33634. * @tparam Args Types of arguments to use to construct the new instance.
  33635. * @param args Parameters to use to construct the instance.
  33636. */
  33637. template<typename Type, typename... Args>
  33638. explicit basic_any(std::in_place_type_t<Type>, Args &&...args)
  33639. : basic_any{} {
  33640. initialize<Type>(std::forward<Args>(args)...);
  33641. }
  33642. /**
  33643. * @brief Constructs a wrapper from a given value.
  33644. * @tparam Type Type of object to use to initialize the wrapper.
  33645. * @param value An instance of an object to use to initialize the wrapper.
  33646. */
  33647. template<typename Type, typename = std::enable_if_t<!std::is_same_v<std::decay_t<Type>, basic_any>>>
  33648. basic_any(Type &&value)
  33649. : basic_any{} {
  33650. initialize<std::decay_t<Type>>(std::forward<Type>(value));
  33651. }
  33652. /**
  33653. * @brief Copy constructor.
  33654. * @param other The instance to copy from.
  33655. */
  33656. basic_any(const basic_any &other)
  33657. : basic_any{} {
  33658. if(other.vtable) {
  33659. other.vtable(operation::copy, other, this);
  33660. }
  33661. }
  33662. /**
  33663. * @brief Move constructor.
  33664. * @param other The instance to move from.
  33665. */
  33666. basic_any(basic_any &&other) ENTT_NOEXCEPT
  33667. : instance{},
  33668. info{other.info},
  33669. vtable{other.vtable},
  33670. mode{other.mode} {
  33671. if(other.vtable) {
  33672. other.vtable(operation::move, other, this);
  33673. }
  33674. }
  33675. /*! @brief Frees the internal storage, whatever it means. */
  33676. ~basic_any() {
  33677. if(vtable && owner()) {
  33678. vtable(operation::destroy, *this, nullptr);
  33679. }
  33680. }
  33681. /**
  33682. * @brief Copy assignment operator.
  33683. * @param other The instance to copy from.
  33684. * @return This any object.
  33685. */
  33686. basic_any &operator=(const basic_any &other) {
  33687. reset();
  33688. if(other.vtable) {
  33689. other.vtable(operation::copy, other, this);
  33690. }
  33691. return *this;
  33692. }
  33693. /**
  33694. * @brief Move assignment operator.
  33695. * @param other The instance to move from.
  33696. * @return This any object.
  33697. */
  33698. basic_any &operator=(basic_any &&other) ENTT_NOEXCEPT {
  33699. reset();
  33700. if(other.vtable) {
  33701. other.vtable(operation::move, other, this);
  33702. info = other.info;
  33703. vtable = other.vtable;
  33704. mode = other.mode;
  33705. }
  33706. return *this;
  33707. }
  33708. /**
  33709. * @brief Value assignment operator.
  33710. * @tparam Type Type of object to use to initialize the wrapper.
  33711. * @param value An instance of an object to use to initialize the wrapper.
  33712. * @return This any object.
  33713. */
  33714. template<typename Type>
  33715. std::enable_if_t<!std::is_same_v<std::decay_t<Type>, basic_any>, basic_any &>
  33716. operator=(Type &&value) {
  33717. emplace<std::decay_t<Type>>(std::forward<Type>(value));
  33718. return *this;
  33719. }
  33720. /**
  33721. * @brief Returns the object type if any, `type_id<void>()` otherwise.
  33722. * @return The object type if any, `type_id<void>()` otherwise.
  33723. */
  33724. [[nodiscard]] const type_info &type() const ENTT_NOEXCEPT {
  33725. return *info;
  33726. }
  33727. /**
  33728. * @brief Returns an opaque pointer to the contained instance.
  33729. * @return An opaque pointer the contained instance, if any.
  33730. */
  33731. [[nodiscard]] const void *data() const ENTT_NOEXCEPT {
  33732. return vtable ? vtable(operation::get, *this, nullptr) : nullptr;
  33733. }
  33734. /**
  33735. * @brief Returns an opaque pointer to the contained instance.
  33736. * @param req Expected type.
  33737. * @return An opaque pointer the contained instance, if any.
  33738. */
  33739. [[nodiscard]] const void *data(const type_info &req) const ENTT_NOEXCEPT {
  33740. return *info == req ? data() : nullptr;
  33741. }
  33742. /**
  33743. * @brief Returns an opaque pointer to the contained instance.
  33744. * @return An opaque pointer the contained instance, if any.
  33745. */
  33746. [[nodiscard]] void *data() ENTT_NOEXCEPT {
  33747. return (!vtable || mode == policy::cref) ? nullptr : const_cast<void *>(vtable(operation::get, *this, nullptr));
  33748. }
  33749. /**
  33750. * @brief Returns an opaque pointer to the contained instance.
  33751. * @param req Expected type.
  33752. * @return An opaque pointer the contained instance, if any.
  33753. */
  33754. [[nodiscard]] void *data(const type_info &req) ENTT_NOEXCEPT {
  33755. return *info == req ? data() : nullptr;
  33756. }
  33757. /**
  33758. * @brief Replaces the contained object by creating a new instance directly.
  33759. * @tparam Type Type of object to use to initialize the wrapper.
  33760. * @tparam Args Types of arguments to use to construct the new instance.
  33761. * @param args Parameters to use to construct the instance.
  33762. */
  33763. template<typename Type, typename... Args>
  33764. void emplace(Args &&...args) {
  33765. reset();
  33766. initialize<Type>(std::forward<Args>(args)...);
  33767. }
  33768. /**
  33769. * @brief Assigns a value to the contained object without replacing it.
  33770. * @param other The value to assign to the contained object.
  33771. * @return True in case of success, false otherwise.
  33772. */
  33773. bool assign(const any &other) {
  33774. if(vtable && mode != policy::cref && *info == *other.info) {
  33775. return (vtable(operation::assign, *this, other.data()) != nullptr);
  33776. }
  33777. return false;
  33778. }
  33779. /*! @copydoc assign */
  33780. bool assign(any &&other) {
  33781. if(vtable && mode != policy::cref && *info == *other.info) {
  33782. if(auto *val = other.data(); val) {
  33783. return (vtable(operation::transfer, *this, val) != nullptr);
  33784. } else {
  33785. return (vtable(operation::assign, *this, std::as_const(other).data()) != nullptr);
  33786. }
  33787. }
  33788. return false;
  33789. }
  33790. /*! @brief Destroys contained object */
  33791. void reset() {
  33792. if(vtable && owner()) {
  33793. vtable(operation::destroy, *this, nullptr);
  33794. }
  33795. info = &type_id<void>();
  33796. vtable = nullptr;
  33797. mode = policy::owner;
  33798. }
  33799. /**
  33800. * @brief Returns false if a wrapper is empty, true otherwise.
  33801. * @return False if the wrapper is empty, true otherwise.
  33802. */
  33803. [[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
  33804. return vtable != nullptr;
  33805. }
  33806. /**
  33807. * @brief Checks if two wrappers differ in their content.
  33808. * @param other Wrapper with which to compare.
  33809. * @return False if the two objects differ in their content, true otherwise.
  33810. */
  33811. bool operator==(const basic_any &other) const ENTT_NOEXCEPT {
  33812. if(vtable && *info == *other.info) {
  33813. return (vtable(operation::compare, *this, other.data()) != nullptr);
  33814. }
  33815. return (!vtable && !other.vtable);
  33816. }
  33817. /**
  33818. * @brief Aliasing constructor.
  33819. * @return A wrapper that shares a reference to an unmanaged object.
  33820. */
  33821. [[nodiscard]] basic_any as_ref() ENTT_NOEXCEPT {
  33822. return basic_any{*this, (mode == policy::cref ? policy::cref : policy::ref)};
  33823. }
  33824. /*! @copydoc as_ref */
  33825. [[nodiscard]] basic_any as_ref() const ENTT_NOEXCEPT {
  33826. return basic_any{*this, policy::cref};
  33827. }
  33828. /**
  33829. * @brief Returns true if a wrapper owns its object, false otherwise.
  33830. * @return True if the wrapper owns its object, false otherwise.
  33831. */
  33832. [[nodiscard]] bool owner() const ENTT_NOEXCEPT {
  33833. return (mode == policy::owner);
  33834. }
  33835. private:
  33836. union {
  33837. const void *instance;
  33838. storage_type storage;
  33839. };
  33840. const type_info *info;
  33841. vtable_type *vtable;
  33842. policy mode;
  33843. };
  33844. /**
  33845. * @brief Checks if two wrappers differ in their content.
  33846. * @tparam Len Size of the storage reserved for the small buffer optimization.
  33847. * @tparam Align Alignment requirement.
  33848. * @param lhs A wrapper, either empty or not.
  33849. * @param rhs A wrapper, either empty or not.
  33850. * @return True if the two wrappers differ in their content, false otherwise.
  33851. */
  33852. template<std::size_t Len, std::size_t Align>
  33853. [[nodiscard]] inline bool operator!=(const basic_any<Len, Align> &lhs, const basic_any<Len, Align> &rhs) ENTT_NOEXCEPT {
  33854. return !(lhs == rhs);
  33855. }
  33856. /**
  33857. * @brief Performs type-safe access to the contained object.
  33858. * @tparam Type Type to which conversion is required.
  33859. * @tparam Len Size of the storage reserved for the small buffer optimization.
  33860. * @tparam Align Alignment requirement.
  33861. * @param data Target any object.
  33862. * @return The element converted to the requested type.
  33863. */
  33864. template<typename Type, std::size_t Len, std::size_t Align>
  33865. Type any_cast(const basic_any<Len, Align> &data) ENTT_NOEXCEPT {
  33866. const auto *const instance = any_cast<std::remove_reference_t<Type>>(&data);
  33867. ENTT_ASSERT(instance, "Invalid instance");
  33868. return static_cast<Type>(*instance);
  33869. }
  33870. /*! @copydoc any_cast */
  33871. template<typename Type, std::size_t Len, std::size_t Align>
  33872. Type any_cast(basic_any<Len, Align> &data) ENTT_NOEXCEPT {
  33873. // forces const on non-reference types to make them work also with wrappers for const references
  33874. auto *const instance = any_cast<std::remove_reference_t<const Type>>(&data);
  33875. ENTT_ASSERT(instance, "Invalid instance");
  33876. return static_cast<Type>(*instance);
  33877. }
  33878. /*! @copydoc any_cast */
  33879. template<typename Type, std::size_t Len, std::size_t Align>
  33880. Type any_cast(basic_any<Len, Align> &&data) ENTT_NOEXCEPT {
  33881. if constexpr(std::is_copy_constructible_v<std::remove_cv_t<std::remove_reference_t<Type>>>) {
  33882. if(auto *const instance = any_cast<std::remove_reference_t<Type>>(&data); instance) {
  33883. return static_cast<Type>(std::move(*instance));
  33884. } else {
  33885. return any_cast<Type>(data);
  33886. }
  33887. } else {
  33888. auto *const instance = any_cast<std::remove_reference_t<Type>>(&data);
  33889. ENTT_ASSERT(instance, "Invalid instance");
  33890. return static_cast<Type>(std::move(*instance));
  33891. }
  33892. }
  33893. /*! @copydoc any_cast */
  33894. template<typename Type, std::size_t Len, std::size_t Align>
  33895. const Type *any_cast(const basic_any<Len, Align> *data) ENTT_NOEXCEPT {
  33896. const auto &info = type_id<std::remove_cv_t<std::remove_reference_t<Type>>>();
  33897. return static_cast<const Type *>(data->data(info));
  33898. }
  33899. /*! @copydoc any_cast */
  33900. template<typename Type, std::size_t Len, std::size_t Align>
  33901. Type *any_cast(basic_any<Len, Align> *data) ENTT_NOEXCEPT {
  33902. const auto &info = type_id<std::remove_cv_t<std::remove_reference_t<Type>>>();
  33903. // last attempt to make wrappers for const references return their values
  33904. return static_cast<Type *>(static_cast<constness_as_t<basic_any<Len, Align>, Type> *>(data)->data(info));
  33905. }
  33906. /**
  33907. * @brief Constructs a wrapper from a given type, passing it all arguments.
  33908. * @tparam Type Type of object to use to initialize the wrapper.
  33909. * @tparam Len Size of the storage reserved for the small buffer optimization.
  33910. * @tparam Align Optional alignment requirement.
  33911. * @tparam Args Types of arguments to use to construct the new instance.
  33912. * @param args Parameters to use to construct the instance.
  33913. * @return A properly initialized wrapper for an object of the given type.
  33914. */
  33915. template<typename Type, std::size_t Len = basic_any<>::length, std::size_t Align = basic_any<Len>::alignment, typename... Args>
  33916. basic_any<Len, Align> make_any(Args &&...args) {
  33917. return basic_any<Len, Align>{std::in_place_type<Type>, std::forward<Args>(args)...};
  33918. }
  33919. /**
  33920. * @brief Forwards its argument and avoids copies for lvalue references.
  33921. * @tparam Len Size of the storage reserved for the small buffer optimization.
  33922. * @tparam Align Optional alignment requirement.
  33923. * @tparam Type Type of argument to use to construct the new instance.
  33924. * @param value Parameter to use to construct the instance.
  33925. * @return A properly initialized and not necessarily owning wrapper.
  33926. */
  33927. template<std::size_t Len = basic_any<>::length, std::size_t Align = basic_any<Len>::alignment, typename Type>
  33928. basic_any<Len, Align> forward_as_any(Type &&value) {
  33929. return basic_any<Len, Align>{std::in_place_type<std::conditional_t<std::is_rvalue_reference_v<Type>, std::decay_t<Type>, Type>>, std::forward<Type>(value)};
  33930. }
  33931. } // namespace entt
  33932. #endif
  33933. // #include "../core/fwd.hpp"
  33934. #ifndef ENTT_CORE_FWD_HPP
  33935. #define ENTT_CORE_FWD_HPP
  33936. #include <cstdint>
  33937. #include <type_traits>
  33938. // #include "../config/config.h"
  33939. namespace entt {
  33940. template<std::size_t Len = sizeof(double[2]), std::size_t = alignof(typename std::aligned_storage_t<Len + !Len>)>
  33941. class basic_any;
  33942. /*! @brief Alias declaration for type identifiers. */
  33943. using id_type = ENTT_ID_TYPE;
  33944. /*! @brief Alias declaration for the most common use case. */
  33945. using any = basic_any<>;
  33946. } // namespace entt
  33947. #endif
  33948. // #include "../core/iterator.hpp"
  33949. #ifndef ENTT_CORE_ITERATOR_HPP
  33950. #define ENTT_CORE_ITERATOR_HPP
  33951. #include <iterator>
  33952. #include <memory>
  33953. #include <utility>
  33954. // #include "../config/config.h"
  33955. namespace entt {
  33956. /**
  33957. * @brief Helper type to use as pointer with input iterators.
  33958. * @tparam Type of wrapped value.
  33959. */
  33960. template<typename Type>
  33961. struct input_iterator_pointer final {
  33962. /*! @brief Pointer type. */
  33963. using pointer = Type *;
  33964. /*! @brief Default copy constructor, deleted on purpose. */
  33965. input_iterator_pointer(const input_iterator_pointer &) = delete;
  33966. /*! @brief Default move constructor. */
  33967. input_iterator_pointer(input_iterator_pointer &&) = default;
  33968. /**
  33969. * @brief Constructs a proxy object by move.
  33970. * @param val Value to use to initialize the proxy object.
  33971. */
  33972. input_iterator_pointer(Type &&val)
  33973. : value{std::move(val)} {}
  33974. /**
  33975. * @brief Default copy assignment operator, deleted on purpose.
  33976. * @return This proxy object.
  33977. */
  33978. input_iterator_pointer &operator=(const input_iterator_pointer &) = delete;
  33979. /**
  33980. * @brief Default move assignment operator.
  33981. * @return This proxy object.
  33982. */
  33983. input_iterator_pointer &operator=(input_iterator_pointer &&) = default;
  33984. /**
  33985. * @brief Access operator for accessing wrapped values.
  33986. * @return A pointer to the wrapped value.
  33987. */
  33988. [[nodiscard]] pointer operator->() ENTT_NOEXCEPT {
  33989. return std::addressof(value);
  33990. }
  33991. private:
  33992. Type value;
  33993. };
  33994. /**
  33995. * @brief Utility class to create an iterable object from a pair of iterators.
  33996. * @tparam It Type of iterator.
  33997. * @tparam Sentinel Type of sentinel.
  33998. */
  33999. template<typename It, typename Sentinel = It>
  34000. struct iterable_adaptor final {
  34001. /*! @brief Value type. */
  34002. using value_type = typename std::iterator_traits<It>::value_type;
  34003. /*! @brief Iterator type. */
  34004. using iterator = It;
  34005. /*! @brief Sentinel type. */
  34006. using sentinel = Sentinel;
  34007. /*! @brief Default constructor. */
  34008. iterable_adaptor() = default;
  34009. /**
  34010. * @brief Creates an iterable object from a pair of iterators.
  34011. * @param from Begin iterator.
  34012. * @param to End iterator.
  34013. */
  34014. iterable_adaptor(iterator from, sentinel to)
  34015. : first{from},
  34016. last{to} {}
  34017. /**
  34018. * @brief Returns an iterator to the beginning.
  34019. * @return An iterator to the first element of the range.
  34020. */
  34021. [[nodiscard]] iterator begin() const ENTT_NOEXCEPT {
  34022. return first;
  34023. }
  34024. /**
  34025. * @brief Returns an iterator to the end.
  34026. * @return An iterator to the element following the last element of the
  34027. * range.
  34028. */
  34029. [[nodiscard]] sentinel end() const ENTT_NOEXCEPT {
  34030. return last;
  34031. }
  34032. /*! @copydoc begin */
  34033. [[nodiscard]] iterator cbegin() const ENTT_NOEXCEPT {
  34034. return begin();
  34035. }
  34036. /*! @copydoc end */
  34037. [[nodiscard]] sentinel cend() const ENTT_NOEXCEPT {
  34038. return end();
  34039. }
  34040. private:
  34041. It first;
  34042. Sentinel last;
  34043. };
  34044. } // namespace entt
  34045. #endif
  34046. // #include "../core/type_info.hpp"
  34047. #ifndef ENTT_CORE_TYPE_INFO_HPP
  34048. #define ENTT_CORE_TYPE_INFO_HPP
  34049. #include <string_view>
  34050. #include <type_traits>
  34051. #include <utility>
  34052. // #include "../config/config.h"
  34053. // #include "../core/attribute.h"
  34054. // #include "fwd.hpp"
  34055. // #include "hashed_string.hpp"
  34056. namespace entt {
  34057. /**
  34058. * @cond TURN_OFF_DOXYGEN
  34059. * Internal details not to be documented.
  34060. */
  34061. namespace internal {
  34062. struct ENTT_API type_index final {
  34063. [[nodiscard]] static id_type next() ENTT_NOEXCEPT {
  34064. static ENTT_MAYBE_ATOMIC(id_type) value{};
  34065. return value++;
  34066. }
  34067. };
  34068. template<typename Type>
  34069. [[nodiscard]] constexpr auto stripped_type_name() ENTT_NOEXCEPT {
  34070. #if defined ENTT_PRETTY_FUNCTION
  34071. std::string_view pretty_function{ENTT_PRETTY_FUNCTION};
  34072. auto first = pretty_function.find_first_not_of(' ', pretty_function.find_first_of(ENTT_PRETTY_FUNCTION_PREFIX) + 1);
  34073. auto value = pretty_function.substr(first, pretty_function.find_last_of(ENTT_PRETTY_FUNCTION_SUFFIX) - first);
  34074. return value;
  34075. #else
  34076. return std::string_view{""};
  34077. #endif
  34078. }
  34079. template<typename Type, auto = stripped_type_name<Type>().find_first_of('.')>
  34080. [[nodiscard]] static constexpr std::string_view type_name(int) ENTT_NOEXCEPT {
  34081. constexpr auto value = stripped_type_name<Type>();
  34082. return value;
  34083. }
  34084. template<typename Type>
  34085. [[nodiscard]] static std::string_view type_name(char) ENTT_NOEXCEPT {
  34086. static const auto value = stripped_type_name<Type>();
  34087. return value;
  34088. }
  34089. template<typename Type, auto = stripped_type_name<Type>().find_first_of('.')>
  34090. [[nodiscard]] static constexpr id_type type_hash(int) ENTT_NOEXCEPT {
  34091. constexpr auto stripped = stripped_type_name<Type>();
  34092. constexpr auto value = hashed_string::value(stripped.data(), stripped.size());
  34093. return value;
  34094. }
  34095. template<typename Type>
  34096. [[nodiscard]] static id_type type_hash(char) ENTT_NOEXCEPT {
  34097. static const auto value = [](const auto stripped) {
  34098. return hashed_string::value(stripped.data(), stripped.size());
  34099. }(stripped_type_name<Type>());
  34100. return value;
  34101. }
  34102. } // namespace internal
  34103. /**
  34104. * Internal details not to be documented.
  34105. * @endcond
  34106. */
  34107. /**
  34108. * @brief Type sequential identifier.
  34109. * @tparam Type Type for which to generate a sequential identifier.
  34110. */
  34111. template<typename Type, typename = void>
  34112. struct ENTT_API type_index final {
  34113. /**
  34114. * @brief Returns the sequential identifier of a given type.
  34115. * @return The sequential identifier of a given type.
  34116. */
  34117. [[nodiscard]] static id_type value() ENTT_NOEXCEPT {
  34118. static const id_type value = internal::type_index::next();
  34119. return value;
  34120. }
  34121. /*! @copydoc value */
  34122. [[nodiscard]] constexpr operator id_type() const ENTT_NOEXCEPT {
  34123. return value();
  34124. }
  34125. };
  34126. /**
  34127. * @brief Type hash.
  34128. * @tparam Type Type for which to generate a hash value.
  34129. */
  34130. template<typename Type, typename = void>
  34131. struct type_hash final {
  34132. /**
  34133. * @brief Returns the numeric representation of a given type.
  34134. * @return The numeric representation of the given type.
  34135. */
  34136. #if defined ENTT_PRETTY_FUNCTION
  34137. [[nodiscard]] static constexpr id_type value() ENTT_NOEXCEPT {
  34138. return internal::type_hash<Type>(0);
  34139. #else
  34140. [[nodiscard]] static constexpr id_type value() ENTT_NOEXCEPT {
  34141. return type_index<Type>::value();
  34142. #endif
  34143. }
  34144. /*! @copydoc value */
  34145. [[nodiscard]] constexpr operator id_type() const ENTT_NOEXCEPT {
  34146. return value();
  34147. }
  34148. };
  34149. /**
  34150. * @brief Type name.
  34151. * @tparam Type Type for which to generate a name.
  34152. */
  34153. template<typename Type, typename = void>
  34154. struct type_name final {
  34155. /**
  34156. * @brief Returns the name of a given type.
  34157. * @return The name of the given type.
  34158. */
  34159. [[nodiscard]] static constexpr std::string_view value() ENTT_NOEXCEPT {
  34160. return internal::type_name<Type>(0);
  34161. }
  34162. /*! @copydoc value */
  34163. [[nodiscard]] constexpr operator std::string_view() const ENTT_NOEXCEPT {
  34164. return value();
  34165. }
  34166. };
  34167. /*! @brief Implementation specific information about a type. */
  34168. struct type_info final {
  34169. /**
  34170. * @brief Constructs a type info object for a given type.
  34171. * @tparam Type Type for which to construct a type info object.
  34172. */
  34173. template<typename Type>
  34174. constexpr type_info(std::in_place_type_t<Type>) ENTT_NOEXCEPT
  34175. : seq{type_index<std::remove_cv_t<std::remove_reference_t<Type>>>::value()},
  34176. identifier{type_hash<std::remove_cv_t<std::remove_reference_t<Type>>>::value()},
  34177. alias{type_name<std::remove_cv_t<std::remove_reference_t<Type>>>::value()} {}
  34178. /**
  34179. * @brief Type index.
  34180. * @return Type index.
  34181. */
  34182. [[nodiscard]] constexpr id_type index() const ENTT_NOEXCEPT {
  34183. return seq;
  34184. }
  34185. /**
  34186. * @brief Type hash.
  34187. * @return Type hash.
  34188. */
  34189. [[nodiscard]] constexpr id_type hash() const ENTT_NOEXCEPT {
  34190. return identifier;
  34191. }
  34192. /**
  34193. * @brief Type name.
  34194. * @return Type name.
  34195. */
  34196. [[nodiscard]] constexpr std::string_view name() const ENTT_NOEXCEPT {
  34197. return alias;
  34198. }
  34199. private:
  34200. id_type seq;
  34201. id_type identifier;
  34202. std::string_view alias;
  34203. };
  34204. /**
  34205. * @brief Compares the contents of two type info objects.
  34206. * @param lhs A type info object.
  34207. * @param rhs A type info object.
  34208. * @return True if the two type info objects are identical, false otherwise.
  34209. */
  34210. [[nodiscard]] inline constexpr bool operator==(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT {
  34211. return lhs.hash() == rhs.hash();
  34212. }
  34213. /**
  34214. * @brief Compares the contents of two type info objects.
  34215. * @param lhs A type info object.
  34216. * @param rhs A type info object.
  34217. * @return True if the two type info objects differ, false otherwise.
  34218. */
  34219. [[nodiscard]] inline constexpr bool operator!=(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT {
  34220. return !(lhs == rhs);
  34221. }
  34222. /**
  34223. * @brief Compares two type info objects.
  34224. * @param lhs A valid type info object.
  34225. * @param rhs A valid type info object.
  34226. * @return True if the first element is less than the second, false otherwise.
  34227. */
  34228. [[nodiscard]] constexpr bool operator<(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT {
  34229. return lhs.index() < rhs.index();
  34230. }
  34231. /**
  34232. * @brief Compares two type info objects.
  34233. * @param lhs A valid type info object.
  34234. * @param rhs A valid type info object.
  34235. * @return True if the first element is less than or equal to the second, false
  34236. * otherwise.
  34237. */
  34238. [[nodiscard]] constexpr bool operator<=(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT {
  34239. return !(rhs < lhs);
  34240. }
  34241. /**
  34242. * @brief Compares two type info objects.
  34243. * @param lhs A valid type info object.
  34244. * @param rhs A valid type info object.
  34245. * @return True if the first element is greater than the second, false
  34246. * otherwise.
  34247. */
  34248. [[nodiscard]] constexpr bool operator>(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT {
  34249. return rhs < lhs;
  34250. }
  34251. /**
  34252. * @brief Compares two type info objects.
  34253. * @param lhs A valid type info object.
  34254. * @param rhs A valid type info object.
  34255. * @return True if the first element is greater than or equal to the second,
  34256. * false otherwise.
  34257. */
  34258. [[nodiscard]] constexpr bool operator>=(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT {
  34259. return !(lhs < rhs);
  34260. }
  34261. /**
  34262. * @brief Returns the type info object associated to a given type.
  34263. *
  34264. * The returned element refers to an object with static storage duration.<br/>
  34265. * The type doesn't need to be a complete type. If the type is a reference, the
  34266. * result refers to the referenced type. In all cases, top-level cv-qualifiers
  34267. * are ignored.
  34268. *
  34269. * @tparam Type Type for which to generate a type info object.
  34270. * @return A reference to a properly initialized type info object.
  34271. */
  34272. template<typename Type>
  34273. [[nodiscard]] const type_info &type_id() ENTT_NOEXCEPT {
  34274. if constexpr(std::is_same_v<Type, std::remove_cv_t<std::remove_reference_t<Type>>>) {
  34275. static type_info instance{std::in_place_type<Type>};
  34276. return instance;
  34277. } else {
  34278. return type_id<std::remove_cv_t<std::remove_reference_t<Type>>>();
  34279. }
  34280. }
  34281. /*! @copydoc type_id */
  34282. template<typename Type>
  34283. [[nodiscard]] const type_info &type_id(Type &&) ENTT_NOEXCEPT {
  34284. return type_id<std::remove_cv_t<std::remove_reference_t<Type>>>();
  34285. }
  34286. } // namespace entt
  34287. #endif
  34288. // #include "../core/type_traits.hpp"
  34289. #ifndef ENTT_CORE_TYPE_TRAITS_HPP
  34290. #define ENTT_CORE_TYPE_TRAITS_HPP
  34291. #include <cstddef>
  34292. #include <iterator>
  34293. #include <type_traits>
  34294. #include <utility>
  34295. // #include "../config/config.h"
  34296. // #include "fwd.hpp"
  34297. namespace entt {
  34298. /**
  34299. * @brief Utility class to disambiguate overloaded functions.
  34300. * @tparam N Number of choices available.
  34301. */
  34302. template<std::size_t N>
  34303. struct choice_t
  34304. // Unfortunately, doxygen cannot parse such a construct.
  34305. : /*! @cond TURN_OFF_DOXYGEN */ choice_t<N - 1> /*! @endcond */
  34306. {};
  34307. /*! @copybrief choice_t */
  34308. template<>
  34309. struct choice_t<0> {};
  34310. /**
  34311. * @brief Variable template for the choice trick.
  34312. * @tparam N Number of choices available.
  34313. */
  34314. template<std::size_t N>
  34315. inline constexpr choice_t<N> choice{};
  34316. /**
  34317. * @brief Identity type trait.
  34318. *
  34319. * Useful to establish non-deduced contexts in template argument deduction
  34320. * (waiting for C++20) or to provide types through function arguments.
  34321. *
  34322. * @tparam Type A type.
  34323. */
  34324. template<typename Type>
  34325. struct type_identity {
  34326. /*! @brief Identity type. */
  34327. using type = Type;
  34328. };
  34329. /**
  34330. * @brief Helper type.
  34331. * @tparam Type A type.
  34332. */
  34333. template<typename Type>
  34334. using type_identity_t = typename type_identity<Type>::type;
  34335. /**
  34336. * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains.
  34337. * @tparam Type The type of which to return the size.
  34338. * @tparam The size of the type if `sizeof` accepts it, 0 otherwise.
  34339. */
  34340. template<typename Type, typename = void>
  34341. struct size_of: std::integral_constant<std::size_t, 0u> {};
  34342. /*! @copydoc size_of */
  34343. template<typename Type>
  34344. struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
  34345. : std::integral_constant<std::size_t, sizeof(Type)> {};
  34346. /**
  34347. * @brief Helper variable template.
  34348. * @tparam Type The type of which to return the size.
  34349. */
  34350. template<typename Type>
  34351. inline constexpr std::size_t size_of_v = size_of<Type>::value;
  34352. /**
  34353. * @brief Using declaration to be used to _repeat_ the same type a number of
  34354. * times equal to the size of a given parameter pack.
  34355. * @tparam Type A type to repeat.
  34356. */
  34357. template<typename Type, typename>
  34358. using unpack_as_type = Type;
  34359. /**
  34360. * @brief Helper variable template to be used to _repeat_ the same value a
  34361. * number of times equal to the size of a given parameter pack.
  34362. * @tparam Value A value to repeat.
  34363. */
  34364. template<auto Value, typename>
  34365. inline constexpr auto unpack_as_value = Value;
  34366. /**
  34367. * @brief Wraps a static constant.
  34368. * @tparam Value A static constant.
  34369. */
  34370. template<auto Value>
  34371. using integral_constant = std::integral_constant<decltype(Value), Value>;
  34372. /**
  34373. * @brief Alias template to facilitate the creation of named values.
  34374. * @tparam Value A constant value at least convertible to `id_type`.
  34375. */
  34376. template<id_type Value>
  34377. using tag = integral_constant<Value>;
  34378. /**
  34379. * @brief A class to use to push around lists of types, nothing more.
  34380. * @tparam Type Types provided by the type list.
  34381. */
  34382. template<typename... Type>
  34383. struct type_list {
  34384. /*! @brief Type list type. */
  34385. using type = type_list;
  34386. /*! @brief Compile-time number of elements in the type list. */
  34387. static constexpr auto size = sizeof...(Type);
  34388. };
  34389. /*! @brief Primary template isn't defined on purpose. */
  34390. template<std::size_t, typename>
  34391. struct type_list_element;
  34392. /**
  34393. * @brief Provides compile-time indexed access to the types of a type list.
  34394. * @tparam Index Index of the type to return.
  34395. * @tparam Type First type provided by the type list.
  34396. * @tparam Other Other types provided by the type list.
  34397. */
  34398. template<std::size_t Index, typename Type, typename... Other>
  34399. struct type_list_element<Index, type_list<Type, Other...>>
  34400. : type_list_element<Index - 1u, type_list<Other...>> {};
  34401. /**
  34402. * @brief Provides compile-time indexed access to the types of a type list.
  34403. * @tparam Type First type provided by the type list.
  34404. * @tparam Other Other types provided by the type list.
  34405. */
  34406. template<typename Type, typename... Other>
  34407. struct type_list_element<0u, type_list<Type, Other...>> {
  34408. /*! @brief Searched type. */
  34409. using type = Type;
  34410. };
  34411. /**
  34412. * @brief Helper type.
  34413. * @tparam Index Index of the type to return.
  34414. * @tparam List Type list to search into.
  34415. */
  34416. template<std::size_t Index, typename List>
  34417. using type_list_element_t = typename type_list_element<Index, List>::type;
  34418. /**
  34419. * @brief Concatenates multiple type lists.
  34420. * @tparam Type Types provided by the first type list.
  34421. * @tparam Other Types provided by the second type list.
  34422. * @return A type list composed by the types of both the type lists.
  34423. */
  34424. template<typename... Type, typename... Other>
  34425. constexpr type_list<Type..., Other...> operator+(type_list<Type...>, type_list<Other...>) {
  34426. return {};
  34427. }
  34428. /*! @brief Primary template isn't defined on purpose. */
  34429. template<typename...>
  34430. struct type_list_cat;
  34431. /*! @brief Concatenates multiple type lists. */
  34432. template<>
  34433. struct type_list_cat<> {
  34434. /*! @brief A type list composed by the types of all the type lists. */
  34435. using type = type_list<>;
  34436. };
  34437. /**
  34438. * @brief Concatenates multiple type lists.
  34439. * @tparam Type Types provided by the first type list.
  34440. * @tparam Other Types provided by the second type list.
  34441. * @tparam List Other type lists, if any.
  34442. */
  34443. template<typename... Type, typename... Other, typename... List>
  34444. struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
  34445. /*! @brief A type list composed by the types of all the type lists. */
  34446. using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
  34447. };
  34448. /**
  34449. * @brief Concatenates multiple type lists.
  34450. * @tparam Type Types provided by the type list.
  34451. */
  34452. template<typename... Type>
  34453. struct type_list_cat<type_list<Type...>> {
  34454. /*! @brief A type list composed by the types of all the type lists. */
  34455. using type = type_list<Type...>;
  34456. };
  34457. /**
  34458. * @brief Helper type.
  34459. * @tparam List Type lists to concatenate.
  34460. */
  34461. template<typename... List>
  34462. using type_list_cat_t = typename type_list_cat<List...>::type;
  34463. /*! @brief Primary template isn't defined on purpose. */
  34464. template<typename>
  34465. struct type_list_unique;
  34466. /**
  34467. * @brief Removes duplicates types from a type list.
  34468. * @tparam Type One of the types provided by the given type list.
  34469. * @tparam Other The other types provided by the given type list.
  34470. */
  34471. template<typename Type, typename... Other>
  34472. struct type_list_unique<type_list<Type, Other...>> {
  34473. /*! @brief A type list without duplicate types. */
  34474. using type = std::conditional_t<
  34475. (std::is_same_v<Type, Other> || ...),
  34476. typename type_list_unique<type_list<Other...>>::type,
  34477. type_list_cat_t<type_list<Type>, typename type_list_unique<type_list<Other...>>::type>>;
  34478. };
  34479. /*! @brief Removes duplicates types from a type list. */
  34480. template<>
  34481. struct type_list_unique<type_list<>> {
  34482. /*! @brief A type list without duplicate types. */
  34483. using type = type_list<>;
  34484. };
  34485. /**
  34486. * @brief Helper type.
  34487. * @tparam Type A type list.
  34488. */
  34489. template<typename Type>
  34490. using type_list_unique_t = typename type_list_unique<Type>::type;
  34491. /**
  34492. * @brief Provides the member constant `value` to true if a type list contains a
  34493. * given type, false otherwise.
  34494. * @tparam List Type list.
  34495. * @tparam Type Type to look for.
  34496. */
  34497. template<typename List, typename Type>
  34498. struct type_list_contains;
  34499. /**
  34500. * @copybrief type_list_contains
  34501. * @tparam Type Types provided by the type list.
  34502. * @tparam Other Type to look for.
  34503. */
  34504. template<typename... Type, typename Other>
  34505. struct type_list_contains<type_list<Type...>, Other>: std::disjunction<std::is_same<Type, Other>...> {};
  34506. /**
  34507. * @brief Helper variable template.
  34508. * @tparam List Type list.
  34509. * @tparam Type Type to look for.
  34510. */
  34511. template<typename List, typename Type>
  34512. inline constexpr bool type_list_contains_v = type_list_contains<List, Type>::value;
  34513. /*! @brief Primary template isn't defined on purpose. */
  34514. template<typename...>
  34515. struct type_list_diff;
  34516. /**
  34517. * @brief Computes the difference between two type lists.
  34518. * @tparam Type Types provided by the first type list.
  34519. * @tparam Other Types provided by the second type list.
  34520. */
  34521. template<typename... Type, typename... Other>
  34522. struct type_list_diff<type_list<Type...>, type_list<Other...>> {
  34523. /*! @brief A type list that is the difference between the two type lists. */
  34524. using type = type_list_cat_t<std::conditional_t<type_list_contains_v<type_list<Other...>, Type>, type_list<>, type_list<Type>>...>;
  34525. };
  34526. /**
  34527. * @brief Helper type.
  34528. * @tparam List Type lists between which to compute the difference.
  34529. */
  34530. template<typename... List>
  34531. using type_list_diff_t = typename type_list_diff<List...>::type;
  34532. /**
  34533. * @brief A class to use to push around lists of constant values, nothing more.
  34534. * @tparam Value Values provided by the value list.
  34535. */
  34536. template<auto... Value>
  34537. struct value_list {
  34538. /*! @brief Value list type. */
  34539. using type = value_list;
  34540. /*! @brief Compile-time number of elements in the value list. */
  34541. static constexpr auto size = sizeof...(Value);
  34542. };
  34543. /*! @brief Primary template isn't defined on purpose. */
  34544. template<std::size_t, typename>
  34545. struct value_list_element;
  34546. /**
  34547. * @brief Provides compile-time indexed access to the values of a value list.
  34548. * @tparam Index Index of the value to return.
  34549. * @tparam Value First value provided by the value list.
  34550. * @tparam Other Other values provided by the value list.
  34551. */
  34552. template<std::size_t Index, auto Value, auto... Other>
  34553. struct value_list_element<Index, value_list<Value, Other...>>
  34554. : value_list_element<Index - 1u, value_list<Other...>> {};
  34555. /**
  34556. * @brief Provides compile-time indexed access to the types of a type list.
  34557. * @tparam Value First value provided by the value list.
  34558. * @tparam Other Other values provided by the value list.
  34559. */
  34560. template<auto Value, auto... Other>
  34561. struct value_list_element<0u, value_list<Value, Other...>> {
  34562. /*! @brief Searched value. */
  34563. static constexpr auto value = Value;
  34564. };
  34565. /**
  34566. * @brief Helper type.
  34567. * @tparam Index Index of the value to return.
  34568. * @tparam List Value list to search into.
  34569. */
  34570. template<std::size_t Index, typename List>
  34571. inline constexpr auto value_list_element_v = value_list_element<Index, List>::value;
  34572. /**
  34573. * @brief Concatenates multiple value lists.
  34574. * @tparam Value Values provided by the first value list.
  34575. * @tparam Other Values provided by the second value list.
  34576. * @return A value list composed by the values of both the value lists.
  34577. */
  34578. template<auto... Value, auto... Other>
  34579. constexpr value_list<Value..., Other...> operator+(value_list<Value...>, value_list<Other...>) {
  34580. return {};
  34581. }
  34582. /*! @brief Primary template isn't defined on purpose. */
  34583. template<typename...>
  34584. struct value_list_cat;
  34585. /*! @brief Concatenates multiple value lists. */
  34586. template<>
  34587. struct value_list_cat<> {
  34588. /*! @brief A value list composed by the values of all the value lists. */
  34589. using type = value_list<>;
  34590. };
  34591. /**
  34592. * @brief Concatenates multiple value lists.
  34593. * @tparam Value Values provided by the first value list.
  34594. * @tparam Other Values provided by the second value list.
  34595. * @tparam List Other value lists, if any.
  34596. */
  34597. template<auto... Value, auto... Other, typename... List>
  34598. struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
  34599. /*! @brief A value list composed by the values of all the value lists. */
  34600. using type = typename value_list_cat<value_list<Value..., Other...>, List...>::type;
  34601. };
  34602. /**
  34603. * @brief Concatenates multiple value lists.
  34604. * @tparam Value Values provided by the value list.
  34605. */
  34606. template<auto... Value>
  34607. struct value_list_cat<value_list<Value...>> {
  34608. /*! @brief A value list composed by the values of all the value lists. */
  34609. using type = value_list<Value...>;
  34610. };
  34611. /**
  34612. * @brief Helper type.
  34613. * @tparam List Value lists to concatenate.
  34614. */
  34615. template<typename... List>
  34616. using value_list_cat_t = typename value_list_cat<List...>::type;
  34617. /*! @brief Same as std::is_invocable, but with tuples. */
  34618. template<typename, typename>
  34619. struct is_applicable: std::false_type {};
  34620. /**
  34621. * @copybrief is_applicable
  34622. * @tparam Func A valid function type.
  34623. * @tparam Tuple Tuple-like type.
  34624. * @tparam Args The list of arguments to use to probe the function type.
  34625. */
  34626. template<typename Func, template<typename...> class Tuple, typename... Args>
  34627. struct is_applicable<Func, Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  34628. /**
  34629. * @copybrief is_applicable
  34630. * @tparam Func A valid function type.
  34631. * @tparam Tuple Tuple-like type.
  34632. * @tparam Args The list of arguments to use to probe the function type.
  34633. */
  34634. template<typename Func, template<typename...> class Tuple, typename... Args>
  34635. struct is_applicable<Func, const Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  34636. /**
  34637. * @brief Helper variable template.
  34638. * @tparam Func A valid function type.
  34639. * @tparam Args The list of arguments to use to probe the function type.
  34640. */
  34641. template<typename Func, typename Args>
  34642. inline constexpr bool is_applicable_v = is_applicable<Func, Args>::value;
  34643. /*! @brief Same as std::is_invocable_r, but with tuples for arguments. */
  34644. template<typename, typename, typename>
  34645. struct is_applicable_r: std::false_type {};
  34646. /**
  34647. * @copybrief is_applicable_r
  34648. * @tparam Ret The type to which the return type of the function should be
  34649. * convertible.
  34650. * @tparam Func A valid function type.
  34651. * @tparam Args The list of arguments to use to probe the function type.
  34652. */
  34653. template<typename Ret, typename Func, typename... Args>
  34654. struct is_applicable_r<Ret, Func, std::tuple<Args...>>: std::is_invocable_r<Ret, Func, Args...> {};
  34655. /**
  34656. * @brief Helper variable template.
  34657. * @tparam Ret The type to which the return type of the function should be
  34658. * convertible.
  34659. * @tparam Func A valid function type.
  34660. * @tparam Args The list of arguments to use to probe the function type.
  34661. */
  34662. template<typename Ret, typename Func, typename Args>
  34663. inline constexpr bool is_applicable_r_v = is_applicable_r<Ret, Func, Args>::value;
  34664. /**
  34665. * @brief Provides the member constant `value` to true if a given type is
  34666. * complete, false otherwise.
  34667. * @tparam Type The type to test.
  34668. */
  34669. template<typename Type, typename = void>
  34670. struct is_complete: std::false_type {};
  34671. /*! @copydoc is_complete */
  34672. template<typename Type>
  34673. struct is_complete<Type, std::void_t<decltype(sizeof(Type))>>: std::true_type {};
  34674. /**
  34675. * @brief Helper variable template.
  34676. * @tparam Type The type to test.
  34677. */
  34678. template<typename Type>
  34679. inline constexpr bool is_complete_v = is_complete<Type>::value;
  34680. /**
  34681. * @brief Provides the member constant `value` to true if a given type is an
  34682. * iterator, false otherwise.
  34683. * @tparam Type The type to test.
  34684. */
  34685. template<typename Type, typename = void>
  34686. struct is_iterator: std::false_type {};
  34687. /**
  34688. * @cond TURN_OFF_DOXYGEN
  34689. * Internal details not to be documented.
  34690. */
  34691. namespace internal {
  34692. template<typename, typename = void>
  34693. struct has_iterator_category: std::false_type {};
  34694. template<typename Type>
  34695. struct has_iterator_category<Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>: std::true_type {};
  34696. } // namespace internal
  34697. /**
  34698. * Internal details not to be documented.
  34699. * @endcond
  34700. */
  34701. /*! @copydoc is_iterator */
  34702. template<typename Type>
  34703. struct is_iterator<Type, std::enable_if_t<!std::is_same_v<std::remove_const_t<std::remove_pointer_t<Type>>, void>>>
  34704. : internal::has_iterator_category<Type> {};
  34705. /**
  34706. * @brief Helper variable template.
  34707. * @tparam Type The type to test.
  34708. */
  34709. template<typename Type>
  34710. inline constexpr bool is_iterator_v = is_iterator<Type>::value;
  34711. /**
  34712. * @brief Provides the member constant `value` to true if a given type is both
  34713. * an empty and non-final class, false otherwise.
  34714. * @tparam Type The type to test
  34715. */
  34716. template<typename Type>
  34717. struct is_ebco_eligible
  34718. : std::conjunction<std::is_empty<Type>, std::negation<std::is_final<Type>>> {};
  34719. /**
  34720. * @brief Helper variable template.
  34721. * @tparam Type The type to test.
  34722. */
  34723. template<typename Type>
  34724. inline constexpr bool is_ebco_eligible_v = is_ebco_eligible<Type>::value;
  34725. /**
  34726. * @brief Provides the member constant `value` to true if `Type::is_transparent`
  34727. * is valid and denotes a type, false otherwise.
  34728. * @tparam Type The type to test.
  34729. */
  34730. template<typename Type, typename = void>
  34731. struct is_transparent: std::false_type {};
  34732. /*! @copydoc is_transparent */
  34733. template<typename Type>
  34734. struct is_transparent<Type, std::void_t<typename Type::is_transparent>>: std::true_type {};
  34735. /**
  34736. * @brief Helper variable template.
  34737. * @tparam Type The type to test.
  34738. */
  34739. template<typename Type>
  34740. inline constexpr bool is_transparent_v = is_transparent<Type>::value;
  34741. /**
  34742. * @brief Provides the member constant `value` to true if a given type is
  34743. * equality comparable, false otherwise.
  34744. * @tparam Type The type to test.
  34745. */
  34746. template<typename Type, typename = void>
  34747. struct is_equality_comparable: std::false_type {};
  34748. /**
  34749. * @cond TURN_OFF_DOXYGEN
  34750. * Internal details not to be documented.
  34751. */
  34752. namespace internal {
  34753. template<typename, typename = void>
  34754. struct has_tuple_size_value: std::false_type {};
  34755. template<typename Type>
  34756. struct has_tuple_size_value<Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>: std::true_type {};
  34757. template<typename Type, std::size_t... Index>
  34758. [[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
  34759. return (is_equality_comparable<std::tuple_element_t<Index, Type>>::value && ...);
  34760. }
  34761. template<typename>
  34762. [[nodiscard]] constexpr bool maybe_equality_comparable(choice_t<0>) {
  34763. return true;
  34764. }
  34765. template<typename Type>
  34766. [[nodiscard]] constexpr auto maybe_equality_comparable(choice_t<1>) -> decltype(std::declval<typename Type::value_type>(), bool{}) {
  34767. if constexpr(is_iterator_v<Type>) {
  34768. return true;
  34769. } else if constexpr(std::is_same_v<typename Type::value_type, Type>) {
  34770. return maybe_equality_comparable<Type>(choice<0>);
  34771. } else {
  34772. return is_equality_comparable<typename Type::value_type>::value;
  34773. }
  34774. }
  34775. template<typename Type>
  34776. [[nodiscard]] constexpr std::enable_if_t<is_complete_v<std::tuple_size<std::remove_const_t<Type>>>, bool> maybe_equality_comparable(choice_t<2>) {
  34777. if constexpr(has_tuple_size_value<Type>::value) {
  34778. return unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
  34779. } else {
  34780. return maybe_equality_comparable<Type>(choice<1>);
  34781. }
  34782. }
  34783. } // namespace internal
  34784. /**
  34785. * Internal details not to be documented.
  34786. * @endcond
  34787. */
  34788. /*! @copydoc is_equality_comparable */
  34789. template<typename Type>
  34790. struct is_equality_comparable<Type, std::void_t<decltype(std::declval<Type>() == std::declval<Type>())>>
  34791. : std::bool_constant<internal::maybe_equality_comparable<Type>(choice<2>)> {};
  34792. /**
  34793. * @brief Helper variable template.
  34794. * @tparam Type The type to test.
  34795. */
  34796. template<typename Type>
  34797. inline constexpr bool is_equality_comparable_v = is_equality_comparable<Type>::value;
  34798. /**
  34799. * @brief Transcribes the constness of a type to another type.
  34800. * @tparam To The type to which to transcribe the constness.
  34801. * @tparam From The type from which to transcribe the constness.
  34802. */
  34803. template<typename To, typename From>
  34804. struct constness_as {
  34805. /*! @brief The type resulting from the transcription of the constness. */
  34806. using type = std::remove_const_t<To>;
  34807. };
  34808. /*! @copydoc constness_as */
  34809. template<typename To, typename From>
  34810. struct constness_as<To, const From> {
  34811. /*! @brief The type resulting from the transcription of the constness. */
  34812. using type = std::add_const_t<To>;
  34813. };
  34814. /**
  34815. * @brief Alias template to facilitate the transcription of the constness.
  34816. * @tparam To The type to which to transcribe the constness.
  34817. * @tparam From The type from which to transcribe the constness.
  34818. */
  34819. template<typename To, typename From>
  34820. using constness_as_t = typename constness_as<To, From>::type;
  34821. /**
  34822. * @brief Extracts the class of a non-static member object or function.
  34823. * @tparam Member A pointer to a non-static member object or function.
  34824. */
  34825. template<typename Member>
  34826. class member_class {
  34827. static_assert(std::is_member_pointer_v<Member>, "Invalid pointer type to non-static member object or function");
  34828. template<typename Class, typename Ret, typename... Args>
  34829. static Class *clazz(Ret (Class::*)(Args...));
  34830. template<typename Class, typename Ret, typename... Args>
  34831. static Class *clazz(Ret (Class::*)(Args...) const);
  34832. template<typename Class, typename Type>
  34833. static Class *clazz(Type Class::*);
  34834. public:
  34835. /*! @brief The class of the given non-static member object or function. */
  34836. using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
  34837. };
  34838. /**
  34839. * @brief Helper type.
  34840. * @tparam Member A pointer to a non-static member object or function.
  34841. */
  34842. template<typename Member>
  34843. using member_class_t = typename member_class<Member>::type;
  34844. } // namespace entt
  34845. #endif
  34846. // #include "../core/utility.hpp"
  34847. #ifndef ENTT_CORE_UTILITY_HPP
  34848. #define ENTT_CORE_UTILITY_HPP
  34849. #include <utility>
  34850. // #include "../config/config.h"
  34851. namespace entt {
  34852. /*! @brief Identity function object (waiting for C++20). */
  34853. struct identity {
  34854. /*! @brief Indicates that this is a transparent function object. */
  34855. using is_transparent = void;
  34856. /**
  34857. * @brief Returns its argument unchanged.
  34858. * @tparam Type Type of the argument.
  34859. * @param value The actual argument.
  34860. * @return The submitted value as-is.
  34861. */
  34862. template<class Type>
  34863. [[nodiscard]] constexpr Type &&operator()(Type &&value) const ENTT_NOEXCEPT {
  34864. return std::forward<Type>(value);
  34865. }
  34866. };
  34867. /**
  34868. * @brief Constant utility to disambiguate overloaded members of a class.
  34869. * @tparam Type Type of the desired overload.
  34870. * @tparam Class Type of class to which the member belongs.
  34871. * @param member A valid pointer to a member.
  34872. * @return Pointer to the member.
  34873. */
  34874. template<typename Type, typename Class>
  34875. [[nodiscard]] constexpr auto overload(Type Class::*member) ENTT_NOEXCEPT {
  34876. return member;
  34877. }
  34878. /**
  34879. * @brief Constant utility to disambiguate overloaded functions.
  34880. * @tparam Func Function type of the desired overload.
  34881. * @param func A valid pointer to a function.
  34882. * @return Pointer to the function.
  34883. */
  34884. template<typename Func>
  34885. [[nodiscard]] constexpr auto overload(Func *func) ENTT_NOEXCEPT {
  34886. return func;
  34887. }
  34888. /**
  34889. * @brief Helper type for visitors.
  34890. * @tparam Func Types of function objects.
  34891. */
  34892. template<class... Func>
  34893. struct overloaded: Func... {
  34894. using Func::operator()...;
  34895. };
  34896. /**
  34897. * @brief Deduction guide.
  34898. * @tparam Func Types of function objects.
  34899. */
  34900. template<class... Func>
  34901. overloaded(Func...) -> overloaded<Func...>;
  34902. /**
  34903. * @brief Basic implementation of a y-combinator.
  34904. * @tparam Func Type of a potentially recursive function.
  34905. */
  34906. template<class Func>
  34907. struct y_combinator {
  34908. /**
  34909. * @brief Constructs a y-combinator from a given function.
  34910. * @param recursive A potentially recursive function.
  34911. */
  34912. y_combinator(Func recursive)
  34913. : func{std::move(recursive)} {}
  34914. /**
  34915. * @brief Invokes a y-combinator and therefore its underlying function.
  34916. * @tparam Args Types of arguments to use to invoke the underlying function.
  34917. * @param args Parameters to use to invoke the underlying function.
  34918. * @return Return value of the underlying function, if any.
  34919. */
  34920. template<class... Args>
  34921. decltype(auto) operator()(Args &&...args) const {
  34922. return func(*this, std::forward<Args>(args)...);
  34923. }
  34924. /*! @copydoc operator()() */
  34925. template<class... Args>
  34926. decltype(auto) operator()(Args &&...args) {
  34927. return func(*this, std::forward<Args>(args)...);
  34928. }
  34929. private:
  34930. Func func;
  34931. };
  34932. } // namespace entt
  34933. #endif
  34934. // #include "adl_pointer.hpp"
  34935. #ifndef ENTT_META_ADL_POINTER_HPP
  34936. #define ENTT_META_ADL_POINTER_HPP
  34937. namespace entt {
  34938. /**
  34939. * @brief ADL based lookup function for dereferencing meta pointer-like types.
  34940. * @tparam Type Element type.
  34941. * @param value A pointer-like object.
  34942. * @return The value returned from the dereferenced pointer.
  34943. */
  34944. template<typename Type>
  34945. decltype(auto) dereference_meta_pointer_like(const Type &value) {
  34946. return *value;
  34947. }
  34948. /**
  34949. * @brief Fake ADL based lookup function for meta pointer-like types.
  34950. * @tparam Type Element type.
  34951. */
  34952. template<typename Type>
  34953. struct adl_meta_pointer_like {
  34954. /**
  34955. * @brief Uses the default ADL based lookup method to resolve the call.
  34956. * @param value A pointer-like object.
  34957. * @return The value returned from the dereferenced pointer.
  34958. */
  34959. static decltype(auto) dereference(const Type &value) {
  34960. return dereference_meta_pointer_like(value);
  34961. }
  34962. };
  34963. } // namespace entt
  34964. #endif
  34965. // #include "ctx.hpp"
  34966. #ifndef ENTT_META_CTX_HPP
  34967. #define ENTT_META_CTX_HPP
  34968. // #include "../config/config.h"
  34969. // #include "../core/attribute.h"
  34970. #ifndef ENTT_CORE_ATTRIBUTE_H
  34971. #define ENTT_CORE_ATTRIBUTE_H
  34972. #ifndef ENTT_EXPORT
  34973. # if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER
  34974. # define ENTT_EXPORT __declspec(dllexport)
  34975. # define ENTT_IMPORT __declspec(dllimport)
  34976. # define ENTT_HIDDEN
  34977. # elif defined __GNUC__ && __GNUC__ >= 4
  34978. # define ENTT_EXPORT __attribute__((visibility("default")))
  34979. # define ENTT_IMPORT __attribute__((visibility("default")))
  34980. # define ENTT_HIDDEN __attribute__((visibility("hidden")))
  34981. # else /* Unsupported compiler */
  34982. # define ENTT_EXPORT
  34983. # define ENTT_IMPORT
  34984. # define ENTT_HIDDEN
  34985. # endif
  34986. #endif
  34987. #ifndef ENTT_API
  34988. # if defined ENTT_API_EXPORT
  34989. # define ENTT_API ENTT_EXPORT
  34990. # elif defined ENTT_API_IMPORT
  34991. # define ENTT_API ENTT_IMPORT
  34992. # else /* No API */
  34993. # define ENTT_API
  34994. # endif
  34995. #endif
  34996. #endif
  34997. namespace entt {
  34998. /**
  34999. * @cond TURN_OFF_DOXYGEN
  35000. * Internal details not to be documented.
  35001. */
  35002. namespace internal {
  35003. struct meta_type_node;
  35004. struct ENTT_API meta_context {
  35005. // we could use the lines below but VS2017 returns with an ICE if combined with ENTT_API despite the code being valid C++
  35006. // inline static meta_type_node *local = nullptr;
  35007. // inline static meta_type_node **global = &local;
  35008. [[nodiscard]] static meta_type_node *&local() ENTT_NOEXCEPT {
  35009. static meta_type_node *chain = nullptr;
  35010. return chain;
  35011. }
  35012. [[nodiscard]] static meta_type_node **&global() ENTT_NOEXCEPT {
  35013. static meta_type_node **chain = &local();
  35014. return chain;
  35015. }
  35016. };
  35017. } // namespace internal
  35018. /**
  35019. * Internal details not to be documented.
  35020. * @endcond
  35021. */
  35022. /*! @brief Opaque container for a meta context. */
  35023. struct meta_ctx {
  35024. /**
  35025. * @brief Binds the meta system to a given context.
  35026. * @param other A valid context to which to bind.
  35027. */
  35028. static void bind(meta_ctx other) ENTT_NOEXCEPT {
  35029. internal::meta_context::global() = other.ctx;
  35030. }
  35031. private:
  35032. internal::meta_type_node **ctx{&internal::meta_context::local()};
  35033. };
  35034. } // namespace entt
  35035. #endif
  35036. // #include "fwd.hpp"
  35037. #ifndef ENTT_META_FWD_HPP
  35038. #define ENTT_META_FWD_HPP
  35039. namespace entt {
  35040. class meta_sequence_container;
  35041. class meta_associative_container;
  35042. class meta_any;
  35043. struct meta_handle;
  35044. struct meta_prop;
  35045. struct meta_data;
  35046. struct meta_func;
  35047. class meta_type;
  35048. } // namespace entt
  35049. #endif
  35050. // #include "node.hpp"
  35051. #ifndef ENTT_META_NODE_HPP
  35052. #define ENTT_META_NODE_HPP
  35053. #include <cstddef>
  35054. #include <type_traits>
  35055. #include <utility>
  35056. // #include "../config/config.h"
  35057. // #include "../core/attribute.h"
  35058. // #include "../core/enum.hpp"
  35059. #ifndef ENTT_CORE_ENUM_HPP
  35060. #define ENTT_CORE_ENUM_HPP
  35061. #include <type_traits>
  35062. // #include "../config/config.h"
  35063. namespace entt {
  35064. /**
  35065. * @brief Enable bitmask support for enum classes.
  35066. * @tparam Type The enum type for which to enable bitmask support.
  35067. */
  35068. template<typename Type, typename = void>
  35069. struct enum_as_bitmask: std::false_type {};
  35070. /*! @copydoc enum_as_bitmask */
  35071. template<typename Type>
  35072. struct enum_as_bitmask<Type, std::void_t<decltype(Type::_entt_enum_as_bitmask)>>: std::is_enum<Type> {};
  35073. /**
  35074. * @brief Helper variable template.
  35075. * @tparam Type The enum class type for which to enable bitmask support.
  35076. */
  35077. template<typename Type>
  35078. inline constexpr bool enum_as_bitmask_v = enum_as_bitmask<Type>::value;
  35079. } // namespace entt
  35080. /**
  35081. * @brief Operator available for enums for which bitmask support is enabled.
  35082. * @tparam Type Enum class type.
  35083. * @param lhs The first value to use.
  35084. * @param rhs The second value to use.
  35085. * @return The result of invoking the operator on the underlying types of the
  35086. * two values provided.
  35087. */
  35088. template<typename Type>
  35089. [[nodiscard]] constexpr std::enable_if_t<entt::enum_as_bitmask_v<Type>, Type>
  35090. operator|(const Type lhs, const Type rhs) ENTT_NOEXCEPT {
  35091. return static_cast<Type>(static_cast<std::underlying_type_t<Type>>(lhs) | static_cast<std::underlying_type_t<Type>>(rhs));
  35092. }
  35093. /*! @copydoc operator| */
  35094. template<typename Type>
  35095. [[nodiscard]] constexpr std::enable_if_t<entt::enum_as_bitmask_v<Type>, Type>
  35096. operator&(const Type lhs, const Type rhs) ENTT_NOEXCEPT {
  35097. return static_cast<Type>(static_cast<std::underlying_type_t<Type>>(lhs) & static_cast<std::underlying_type_t<Type>>(rhs));
  35098. }
  35099. /*! @copydoc operator| */
  35100. template<typename Type>
  35101. [[nodiscard]] constexpr std::enable_if_t<entt::enum_as_bitmask_v<Type>, Type>
  35102. operator^(const Type lhs, const Type rhs) ENTT_NOEXCEPT {
  35103. return static_cast<Type>(static_cast<std::underlying_type_t<Type>>(lhs) ^ static_cast<std::underlying_type_t<Type>>(rhs));
  35104. }
  35105. /**
  35106. * @brief Operator available for enums for which bitmask support is enabled.
  35107. * @tparam Type Enum class type.
  35108. * @param value The value to use.
  35109. * @return The result of invoking the operator on the underlying types of the
  35110. * value provided.
  35111. */
  35112. template<typename Type>
  35113. [[nodiscard]] constexpr std::enable_if_t<entt::enum_as_bitmask_v<Type>, Type>
  35114. operator~(const Type value) ENTT_NOEXCEPT {
  35115. return static_cast<Type>(~static_cast<std::underlying_type_t<Type>>(value));
  35116. }
  35117. /*! @copydoc operator~ */
  35118. template<typename Type>
  35119. [[nodiscard]] constexpr std::enable_if_t<entt::enum_as_bitmask_v<Type>, bool>
  35120. operator!(const Type value) ENTT_NOEXCEPT {
  35121. return !static_cast<std::underlying_type_t<Type>>(value);
  35122. }
  35123. /*! @copydoc operator| */
  35124. template<typename Type>
  35125. constexpr std::enable_if_t<entt::enum_as_bitmask_v<Type>, Type &>
  35126. operator|=(Type &lhs, const Type rhs) ENTT_NOEXCEPT {
  35127. return (lhs = (lhs | rhs));
  35128. }
  35129. /*! @copydoc operator| */
  35130. template<typename Type>
  35131. constexpr std::enable_if_t<entt::enum_as_bitmask_v<Type>, Type &>
  35132. operator&=(Type &lhs, const Type rhs) ENTT_NOEXCEPT {
  35133. return (lhs = (lhs & rhs));
  35134. }
  35135. /*! @copydoc operator| */
  35136. template<typename Type>
  35137. constexpr std::enable_if_t<entt::enum_as_bitmask_v<Type>, Type &>
  35138. operator^=(Type &lhs, const Type rhs) ENTT_NOEXCEPT {
  35139. return (lhs = (lhs ^ rhs));
  35140. }
  35141. #endif
  35142. // #include "../core/fwd.hpp"
  35143. // #include "../core/type_info.hpp"
  35144. // #include "../core/type_traits.hpp"
  35145. // #include "type_traits.hpp"
  35146. #ifndef ENTT_META_TYPE_TRAITS_HPP
  35147. #define ENTT_META_TYPE_TRAITS_HPP
  35148. #include <type_traits>
  35149. #include <utility>
  35150. namespace entt {
  35151. /**
  35152. * @brief Traits class template to be specialized to enable support for meta
  35153. * template information.
  35154. */
  35155. template<typename>
  35156. struct meta_template_traits;
  35157. /**
  35158. * @brief Traits class template to be specialized to enable support for meta
  35159. * sequence containers.
  35160. */
  35161. template<typename>
  35162. struct meta_sequence_container_traits;
  35163. /**
  35164. * @brief Traits class template to be specialized to enable support for meta
  35165. * associative containers.
  35166. */
  35167. template<typename>
  35168. struct meta_associative_container_traits;
  35169. /**
  35170. * @brief Provides the member constant `value` to true if a given type is a
  35171. * pointer-like type from the point of view of the meta system, false otherwise.
  35172. * @tparam Type Potentially pointer-like type.
  35173. */
  35174. template<typename>
  35175. struct is_meta_pointer_like: std::false_type {};
  35176. /**
  35177. * @brief Partial specialization to ensure that const pointer-like types are
  35178. * also accepted.
  35179. * @tparam Type Potentially pointer-like type.
  35180. */
  35181. template<typename Type>
  35182. struct is_meta_pointer_like<const Type>: is_meta_pointer_like<Type> {};
  35183. /**
  35184. * @brief Helper variable template.
  35185. * @tparam Type Potentially pointer-like type.
  35186. */
  35187. template<typename Type>
  35188. inline constexpr auto is_meta_pointer_like_v = is_meta_pointer_like<Type>::value;
  35189. } // namespace entt
  35190. #endif
  35191. namespace entt {
  35192. class meta_any;
  35193. class meta_type;
  35194. struct meta_handle;
  35195. /**
  35196. * @cond TURN_OFF_DOXYGEN
  35197. * Internal details not to be documented.
  35198. */
  35199. namespace internal {
  35200. enum class meta_traits : std::uint32_t {
  35201. is_none = 0x0000,
  35202. is_const = 0x0001,
  35203. is_static = 0x0002,
  35204. is_arithmetic = 0x0004,
  35205. is_array = 0x0008,
  35206. is_enum = 0x0010,
  35207. is_class = 0x0020,
  35208. is_pointer = 0x0040,
  35209. is_meta_pointer_like = 0x0080,
  35210. is_meta_sequence_container = 0x0100,
  35211. is_meta_associative_container = 0x0200,
  35212. _entt_enum_as_bitmask
  35213. };
  35214. struct meta_type_node;
  35215. struct meta_prop_node {
  35216. meta_prop_node *next;
  35217. const meta_any &id;
  35218. meta_any &value;
  35219. };
  35220. struct meta_base_node {
  35221. meta_base_node *next;
  35222. meta_type_node *const type;
  35223. meta_any (*const cast)(meta_any) ENTT_NOEXCEPT;
  35224. };
  35225. struct meta_conv_node {
  35226. meta_conv_node *next;
  35227. meta_type_node *const type;
  35228. meta_any (*const conv)(const meta_any &);
  35229. };
  35230. struct meta_ctor_node {
  35231. using size_type = std::size_t;
  35232. meta_ctor_node *next;
  35233. const size_type arity;
  35234. meta_type (*const arg)(const size_type) ENTT_NOEXCEPT;
  35235. meta_any (*const invoke)(meta_any *const);
  35236. };
  35237. struct meta_data_node {
  35238. using size_type = std::size_t;
  35239. id_type id;
  35240. const meta_traits traits;
  35241. meta_data_node *next;
  35242. meta_prop_node *prop;
  35243. const size_type arity;
  35244. meta_type_node *const type;
  35245. meta_type (*const arg)(const size_type) ENTT_NOEXCEPT;
  35246. bool (*const set)(meta_handle, meta_any);
  35247. meta_any (*const get)(meta_handle);
  35248. };
  35249. struct meta_func_node {
  35250. using size_type = std::size_t;
  35251. id_type id;
  35252. const meta_traits traits;
  35253. meta_func_node *next;
  35254. meta_prop_node *prop;
  35255. const size_type arity;
  35256. meta_type_node *const ret;
  35257. meta_type (*const arg)(const size_type) ENTT_NOEXCEPT;
  35258. meta_any (*const invoke)(meta_handle, meta_any *const);
  35259. };
  35260. struct meta_template_node {
  35261. using size_type = std::size_t;
  35262. const size_type arity;
  35263. meta_type_node *const type;
  35264. meta_type_node *(*const arg)(const size_type)ENTT_NOEXCEPT;
  35265. };
  35266. struct meta_type_node {
  35267. using size_type = std::size_t;
  35268. const type_info *info;
  35269. id_type id;
  35270. const meta_traits traits;
  35271. meta_type_node *next;
  35272. meta_prop_node *prop;
  35273. const size_type size_of;
  35274. meta_type_node *(*const remove_pointer)() ENTT_NOEXCEPT;
  35275. meta_any (*const default_constructor)();
  35276. double (*const conversion_helper)(void *, const void *);
  35277. const meta_template_node *const templ;
  35278. meta_ctor_node *ctor{nullptr};
  35279. meta_base_node *base{nullptr};
  35280. meta_conv_node *conv{nullptr};
  35281. meta_data_node *data{nullptr};
  35282. meta_func_node *func{nullptr};
  35283. void (*dtor)(void *){nullptr};
  35284. };
  35285. template<typename... Args>
  35286. meta_type_node *meta_arg_node(type_list<Args...>, const std::size_t index) ENTT_NOEXCEPT;
  35287. template<typename Type>
  35288. class ENTT_API meta_node {
  35289. static_assert(std::is_same_v<Type, std::remove_cv_t<std::remove_reference_t<Type>>>, "Invalid type");
  35290. [[nodiscard]] static auto *meta_default_constructor() ENTT_NOEXCEPT {
  35291. if constexpr(std::is_default_constructible_v<Type>) {
  35292. return +[]() { return meta_any{std::in_place_type<Type>}; };
  35293. } else {
  35294. return static_cast<std::decay_t<decltype(meta_type_node::default_constructor)>>(nullptr);
  35295. }
  35296. }
  35297. [[nodiscard]] static auto *meta_conversion_helper() ENTT_NOEXCEPT {
  35298. if constexpr(std::is_arithmetic_v<Type>) {
  35299. return +[](void *bin, const void *value) {
  35300. return bin ? static_cast<double>(*static_cast<Type *>(bin) = static_cast<Type>(*static_cast<const double *>(value))) : static_cast<double>(*static_cast<const Type *>(value));
  35301. };
  35302. } else if constexpr(std::is_enum_v<Type>) {
  35303. return +[](void *bin, const void *value) {
  35304. return bin ? static_cast<double>(*static_cast<Type *>(bin) = static_cast<Type>(static_cast<std::underlying_type_t<Type>>(*static_cast<const double *>(value)))) : static_cast<double>(*static_cast<const Type *>(value));
  35305. };
  35306. } else {
  35307. return static_cast<std::decay_t<decltype(meta_type_node::conversion_helper)>>(nullptr);
  35308. }
  35309. }
  35310. [[nodiscard]] static meta_template_node *meta_template_info() ENTT_NOEXCEPT {
  35311. if constexpr(is_complete_v<meta_template_traits<Type>>) {
  35312. static meta_template_node node{
  35313. meta_template_traits<Type>::args_type::size,
  35314. meta_node<typename meta_template_traits<Type>::class_type>::resolve(),
  35315. [](const std::size_t index) ENTT_NOEXCEPT { return meta_arg_node(typename meta_template_traits<Type>::args_type{}, index); }
  35316. // tricks clang-format
  35317. };
  35318. return &node;
  35319. } else {
  35320. return nullptr;
  35321. }
  35322. }
  35323. public:
  35324. [[nodiscard]] static meta_type_node *resolve() ENTT_NOEXCEPT {
  35325. static meta_type_node node{
  35326. &type_id<Type>(),
  35327. {},
  35328. internal::meta_traits::is_none
  35329. | (std::is_arithmetic_v<Type> ? internal::meta_traits::is_arithmetic : internal::meta_traits::is_none)
  35330. | (std::is_array_v<Type> ? internal::meta_traits::is_array : internal::meta_traits::is_none)
  35331. | (std::is_enum_v<Type> ? internal::meta_traits::is_enum : internal::meta_traits::is_none)
  35332. | (std::is_class_v<Type> ? internal::meta_traits::is_class : internal::meta_traits::is_none)
  35333. | (std::is_pointer_v<Type> ? internal::meta_traits::is_pointer : internal::meta_traits::is_none)
  35334. | (is_meta_pointer_like_v<Type> ? internal::meta_traits::is_meta_pointer_like : internal::meta_traits::is_none)
  35335. | (is_complete_v<meta_sequence_container_traits<Type>> ? internal::meta_traits::is_meta_sequence_container : internal::meta_traits::is_none)
  35336. | (is_complete_v<meta_associative_container_traits<Type>> ? internal::meta_traits::is_meta_associative_container : internal::meta_traits::is_none),
  35337. nullptr,
  35338. nullptr,
  35339. size_of_v<Type>,
  35340. &meta_node<std::remove_cv_t<std::remove_reference_t<std::remove_pointer_t<Type>>>>::resolve,
  35341. meta_default_constructor(),
  35342. meta_conversion_helper(),
  35343. meta_template_info()
  35344. // tricks clang-format
  35345. };
  35346. return &node;
  35347. }
  35348. };
  35349. template<typename... Args>
  35350. [[nodiscard]] meta_type_node *meta_arg_node(type_list<Args...>, const std::size_t index) ENTT_NOEXCEPT {
  35351. meta_type_node *args[sizeof...(Args) + 1u]{nullptr, internal::meta_node<std::remove_cv_t<std::remove_reference_t<Args>>>::resolve()...};
  35352. return args[index + 1u];
  35353. }
  35354. template<auto Member, typename Type>
  35355. [[nodiscard]] static std::decay_t<decltype(std::declval<internal::meta_type_node>().*Member)> find_by(const Type &info_or_id, const internal::meta_type_node *node) ENTT_NOEXCEPT {
  35356. for(auto *curr = node->*Member; curr; curr = curr->next) {
  35357. if constexpr(std::is_same_v<Type, type_info>) {
  35358. if(*curr->type->info == info_or_id) {
  35359. return curr;
  35360. }
  35361. } else if constexpr(std::is_same_v<decltype(curr), meta_base_node *>) {
  35362. if(curr->type->id == info_or_id) {
  35363. return curr;
  35364. }
  35365. } else {
  35366. if(curr->id == info_or_id) {
  35367. return curr;
  35368. }
  35369. }
  35370. }
  35371. for(auto *curr = node->base; curr; curr = curr->next) {
  35372. if(auto *ret = find_by<Member>(info_or_id, curr->type); ret) {
  35373. return ret;
  35374. }
  35375. }
  35376. return nullptr;
  35377. }
  35378. } // namespace internal
  35379. /**
  35380. * Internal details not to be documented.
  35381. * @endcond
  35382. */
  35383. } // namespace entt
  35384. #endif
  35385. // #include "range.hpp"
  35386. #ifndef ENTT_META_RANGE_HPP
  35387. #define ENTT_META_RANGE_HPP
  35388. #include <cstddef>
  35389. #include <iterator>
  35390. // #include "../core/iterator.hpp"
  35391. namespace entt {
  35392. /**
  35393. * @cond TURN_OFF_DOXYGEN
  35394. * Internal details not to be documented.
  35395. */
  35396. namespace internal {
  35397. template<typename Type, typename Node>
  35398. struct meta_range_iterator final {
  35399. using difference_type = std::ptrdiff_t;
  35400. using value_type = Type;
  35401. using pointer = input_iterator_pointer<value_type>;
  35402. using reference = value_type;
  35403. using iterator_category = std::input_iterator_tag;
  35404. using node_type = Node;
  35405. meta_range_iterator() ENTT_NOEXCEPT
  35406. : it{} {}
  35407. meta_range_iterator(node_type *head) ENTT_NOEXCEPT
  35408. : it{head} {}
  35409. meta_range_iterator &operator++() ENTT_NOEXCEPT {
  35410. return (it = it->next), *this;
  35411. }
  35412. meta_range_iterator operator++(int) ENTT_NOEXCEPT {
  35413. meta_range_iterator orig = *this;
  35414. return ++(*this), orig;
  35415. }
  35416. [[nodiscard]] reference operator*() const ENTT_NOEXCEPT {
  35417. return it;
  35418. }
  35419. [[nodiscard]] pointer operator->() const ENTT_NOEXCEPT {
  35420. return operator*();
  35421. }
  35422. [[nodiscard]] bool operator==(const meta_range_iterator &other) const ENTT_NOEXCEPT {
  35423. return it == other.it;
  35424. }
  35425. [[nodiscard]] bool operator!=(const meta_range_iterator &other) const ENTT_NOEXCEPT {
  35426. return !(*this == other);
  35427. }
  35428. private:
  35429. node_type *it;
  35430. };
  35431. } // namespace internal
  35432. /**
  35433. * Internal details not to be documented.
  35434. * @endcond
  35435. */
  35436. /**
  35437. * @brief Iterable range to use to iterate all types of meta objects.
  35438. * @tparam Type Type of meta objects returned.
  35439. * @tparam Node Type of meta nodes iterated.
  35440. */
  35441. template<typename Type, typename Node = typename Type::node_type>
  35442. struct meta_range final {
  35443. /*! @brief Node type. */
  35444. using node_type = Node;
  35445. /*! @brief Input iterator type. */
  35446. using iterator = internal::meta_range_iterator<Type, Node>;
  35447. /*! @brief Constant input iterator type. */
  35448. using const_iterator = iterator;
  35449. /*! @brief Default constructor. */
  35450. meta_range() ENTT_NOEXCEPT = default;
  35451. /**
  35452. * @brief Constructs a meta range from a given node.
  35453. * @param head The underlying node with which to construct the range.
  35454. */
  35455. meta_range(node_type *head) ENTT_NOEXCEPT
  35456. : node{head} {}
  35457. /**
  35458. * @brief Returns an iterator to the beginning.
  35459. * @return An iterator to the first meta object of the range.
  35460. */
  35461. [[nodiscard]] const_iterator cbegin() const ENTT_NOEXCEPT {
  35462. return iterator{node};
  35463. }
  35464. /*! @copydoc cbegin */
  35465. [[nodiscard]] iterator begin() const ENTT_NOEXCEPT {
  35466. return cbegin();
  35467. }
  35468. /**
  35469. * @brief Returns an iterator to the end.
  35470. * @return An iterator to the element following the last meta object of the
  35471. * range.
  35472. */
  35473. [[nodiscard]] const_iterator cend() const ENTT_NOEXCEPT {
  35474. return iterator{};
  35475. }
  35476. /*! @copydoc cend */
  35477. [[nodiscard]] iterator end() const ENTT_NOEXCEPT {
  35478. return cend();
  35479. }
  35480. private:
  35481. node_type *node{nullptr};
  35482. };
  35483. } // namespace entt
  35484. #endif
  35485. // #include "type_traits.hpp"
  35486. namespace entt {
  35487. class meta_any;
  35488. class meta_type;
  35489. /*! @brief Proxy object for sequence containers. */
  35490. class meta_sequence_container {
  35491. class meta_iterator;
  35492. public:
  35493. /*! @brief Unsigned integer type. */
  35494. using size_type = std::size_t;
  35495. /*! @brief Meta iterator type. */
  35496. using iterator = meta_iterator;
  35497. /*! @brief Default constructor. */
  35498. meta_sequence_container() ENTT_NOEXCEPT = default;
  35499. /**
  35500. * @brief Construct a proxy object for sequence containers.
  35501. * @tparam Type Type of container to wrap.
  35502. * @param instance The container to wrap.
  35503. */
  35504. template<typename Type>
  35505. meta_sequence_container(std::in_place_type_t<Type>, any instance) ENTT_NOEXCEPT
  35506. : value_type_node{internal::meta_node<std::remove_cv_t<std::remove_reference_t<typename Type::value_type>>>::resolve()},
  35507. size_fn{&meta_sequence_container_traits<Type>::size},
  35508. resize_fn{&meta_sequence_container_traits<Type>::resize},
  35509. iter_fn{&meta_sequence_container_traits<Type>::iter},
  35510. insert_fn{&meta_sequence_container_traits<Type>::insert},
  35511. erase_fn{&meta_sequence_container_traits<Type>::erase},
  35512. storage{std::move(instance)} {}
  35513. [[nodiscard]] inline meta_type value_type() const ENTT_NOEXCEPT;
  35514. [[nodiscard]] inline size_type size() const ENTT_NOEXCEPT;
  35515. inline bool resize(const size_type);
  35516. inline bool clear();
  35517. [[nodiscard]] inline iterator begin();
  35518. [[nodiscard]] inline iterator end();
  35519. inline iterator insert(iterator, meta_any);
  35520. inline iterator erase(iterator);
  35521. [[nodiscard]] inline meta_any operator[](const size_type);
  35522. [[nodiscard]] inline explicit operator bool() const ENTT_NOEXCEPT;
  35523. private:
  35524. internal::meta_type_node *value_type_node = nullptr;
  35525. size_type (*size_fn)(const any &) ENTT_NOEXCEPT = nullptr;
  35526. bool (*resize_fn)(any &, size_type) = nullptr;
  35527. iterator (*iter_fn)(any &, const bool) = nullptr;
  35528. iterator (*insert_fn)(any &, const std::ptrdiff_t, meta_any &) = nullptr;
  35529. iterator (*erase_fn)(any &, const std::ptrdiff_t) = nullptr;
  35530. any storage{};
  35531. };
  35532. /*! @brief Proxy object for associative containers. */
  35533. class meta_associative_container {
  35534. class meta_iterator;
  35535. public:
  35536. /*! @brief Unsigned integer type. */
  35537. using size_type = std::size_t;
  35538. /*! @brief Meta iterator type. */
  35539. using iterator = meta_iterator;
  35540. /*! @brief Default constructor. */
  35541. meta_associative_container() ENTT_NOEXCEPT = default;
  35542. /**
  35543. * @brief Construct a proxy object for associative containers.
  35544. * @tparam Type Type of container to wrap.
  35545. * @param instance The container to wrap.
  35546. */
  35547. template<typename Type>
  35548. meta_associative_container(std::in_place_type_t<Type>, any instance) ENTT_NOEXCEPT
  35549. : key_only_container{meta_associative_container_traits<Type>::key_only},
  35550. key_type_node{internal::meta_node<std::remove_cv_t<std::remove_reference_t<typename Type::key_type>>>::resolve()},
  35551. mapped_type_node{nullptr},
  35552. value_type_node{internal::meta_node<std::remove_cv_t<std::remove_reference_t<typename Type::value_type>>>::resolve()},
  35553. size_fn{&meta_associative_container_traits<Type>::size},
  35554. clear_fn{&meta_associative_container_traits<Type>::clear},
  35555. iter_fn{&meta_associative_container_traits<Type>::iter},
  35556. insert_fn{&meta_associative_container_traits<Type>::insert},
  35557. erase_fn{&meta_associative_container_traits<Type>::erase},
  35558. find_fn{&meta_associative_container_traits<Type>::find},
  35559. storage{std::move(instance)} {
  35560. if constexpr(!meta_associative_container_traits<Type>::key_only) {
  35561. mapped_type_node = internal::meta_node<std::remove_cv_t<std::remove_reference_t<typename Type::mapped_type>>>::resolve();
  35562. }
  35563. }
  35564. [[nodiscard]] inline bool key_only() const ENTT_NOEXCEPT;
  35565. [[nodiscard]] inline meta_type key_type() const ENTT_NOEXCEPT;
  35566. [[nodiscard]] inline meta_type mapped_type() const ENTT_NOEXCEPT;
  35567. [[nodiscard]] inline meta_type value_type() const ENTT_NOEXCEPT;
  35568. [[nodiscard]] inline size_type size() const ENTT_NOEXCEPT;
  35569. inline bool clear();
  35570. [[nodiscard]] inline iterator begin();
  35571. [[nodiscard]] inline iterator end();
  35572. inline bool insert(meta_any, meta_any);
  35573. inline bool erase(meta_any);
  35574. [[nodiscard]] inline iterator find(meta_any);
  35575. [[nodiscard]] inline explicit operator bool() const ENTT_NOEXCEPT;
  35576. private:
  35577. bool key_only_container{};
  35578. internal::meta_type_node *key_type_node = nullptr;
  35579. internal::meta_type_node *mapped_type_node = nullptr;
  35580. internal::meta_type_node *value_type_node = nullptr;
  35581. size_type (*size_fn)(const any &) ENTT_NOEXCEPT = nullptr;
  35582. bool (*clear_fn)(any &) = nullptr;
  35583. iterator (*iter_fn)(any &, const bool) = nullptr;
  35584. bool (*insert_fn)(any &, meta_any &, meta_any &) = nullptr;
  35585. bool (*erase_fn)(any &, meta_any &) = nullptr;
  35586. iterator (*find_fn)(any &, meta_any &) = nullptr;
  35587. any storage{};
  35588. };
  35589. /*! @brief Opaque wrapper for values of any type. */
  35590. class meta_any {
  35591. enum class operation : std::uint8_t {
  35592. deref,
  35593. seq,
  35594. assoc
  35595. };
  35596. using vtable_type = void(const operation, const any &, void *);
  35597. template<typename Type>
  35598. static void basic_vtable([[maybe_unused]] const operation op, [[maybe_unused]] const any &value, [[maybe_unused]] void *other) {
  35599. static_assert(std::is_same_v<std::remove_cv_t<std::remove_reference_t<Type>>, Type>, "Invalid type");
  35600. if constexpr(!std::is_void_v<Type>) {
  35601. switch(op) {
  35602. case operation::deref:
  35603. if constexpr(is_meta_pointer_like_v<Type>) {
  35604. if constexpr(std::is_function_v<std::remove_const_t<typename std::pointer_traits<Type>::element_type>>) {
  35605. *static_cast<meta_any *>(other) = any_cast<Type>(value);
  35606. } else if constexpr(!std::is_same_v<std::remove_const_t<typename std::pointer_traits<Type>::element_type>, void>) {
  35607. using in_place_type = decltype(adl_meta_pointer_like<Type>::dereference(any_cast<const Type &>(value)));
  35608. if constexpr(std::is_constructible_v<bool, Type>) {
  35609. if(const auto &pointer_like = any_cast<const Type &>(value); pointer_like) {
  35610. static_cast<meta_any *>(other)->emplace<in_place_type>(adl_meta_pointer_like<Type>::dereference(pointer_like));
  35611. }
  35612. } else {
  35613. static_cast<meta_any *>(other)->emplace<in_place_type>(adl_meta_pointer_like<Type>::dereference(any_cast<const Type &>(value)));
  35614. }
  35615. }
  35616. }
  35617. break;
  35618. case operation::seq:
  35619. if constexpr(is_complete_v<meta_sequence_container_traits<Type>>) {
  35620. *static_cast<meta_sequence_container *>(other) = {std::in_place_type<Type>, std::move(const_cast<any &>(value))};
  35621. }
  35622. break;
  35623. case operation::assoc:
  35624. if constexpr(is_complete_v<meta_associative_container_traits<Type>>) {
  35625. *static_cast<meta_associative_container *>(other) = {std::in_place_type<Type>, std::move(const_cast<any &>(value))};
  35626. }
  35627. break;
  35628. }
  35629. }
  35630. }
  35631. void release() {
  35632. if(node && node->dtor && storage.owner()) {
  35633. node->dtor(storage.data());
  35634. }
  35635. }
  35636. meta_any(const meta_any &other, any ref) ENTT_NOEXCEPT
  35637. : storage{std::move(ref)},
  35638. node{storage ? other.node : nullptr},
  35639. vtable{storage ? other.vtable : &basic_vtable<void>} {}
  35640. public:
  35641. /*! @brief Default constructor. */
  35642. meta_any() ENTT_NOEXCEPT
  35643. : storage{},
  35644. node{},
  35645. vtable{&basic_vtable<void>} {}
  35646. /**
  35647. * @brief Constructs a wrapper by directly initializing the new object.
  35648. * @tparam Type Type of object to use to initialize the wrapper.
  35649. * @tparam Args Types of arguments to use to construct the new instance.
  35650. * @param args Parameters to use to construct the instance.
  35651. */
  35652. template<typename Type, typename... Args>
  35653. explicit meta_any(std::in_place_type_t<Type>, Args &&...args)
  35654. : storage{std::in_place_type<Type>, std::forward<Args>(args)...},
  35655. node{internal::meta_node<std::remove_cv_t<std::remove_reference_t<Type>>>::resolve()},
  35656. vtable{&basic_vtable<std::remove_cv_t<std::remove_reference_t<Type>>>} {}
  35657. /**
  35658. * @brief Constructs a wrapper from a given value.
  35659. * @tparam Type Type of object to use to initialize the wrapper.
  35660. * @param value An instance of an object to use to initialize the wrapper.
  35661. */
  35662. template<typename Type, typename = std::enable_if_t<!std::is_same_v<std::decay_t<Type>, meta_any>>>
  35663. meta_any(Type &&value)
  35664. : meta_any{std::in_place_type<std::remove_cv_t<std::remove_reference_t<Type>>>, std::forward<Type>(value)} {}
  35665. /**
  35666. * @brief Copy constructor.
  35667. * @param other The instance to copy from.
  35668. */
  35669. meta_any(const meta_any &other) = default;
  35670. /**
  35671. * @brief Move constructor.
  35672. * @param other The instance to move from.
  35673. */
  35674. meta_any(meta_any &&other) ENTT_NOEXCEPT
  35675. : storage{std::move(other.storage)},
  35676. node{std::exchange(other.node, nullptr)},
  35677. vtable{std::exchange(other.vtable, &basic_vtable<void>)} {}
  35678. /*! @brief Frees the internal storage, whatever it means. */
  35679. ~meta_any() {
  35680. release();
  35681. }
  35682. /**
  35683. * @brief Copy assignment operator.
  35684. * @param other The instance to copy from.
  35685. * @return This meta any object.
  35686. */
  35687. meta_any &operator=(const meta_any &other) {
  35688. release();
  35689. vtable = other.vtable;
  35690. storage = other.storage;
  35691. node = other.node;
  35692. return *this;
  35693. }
  35694. /**
  35695. * @brief Move assignment operator.
  35696. * @param other The instance to move from.
  35697. * @return This meta any object.
  35698. */
  35699. meta_any &operator=(meta_any &&other) ENTT_NOEXCEPT {
  35700. release();
  35701. vtable = std::exchange(other.vtable, &basic_vtable<void>);
  35702. storage = std::move(other.storage);
  35703. node = std::exchange(other.node, nullptr);
  35704. return *this;
  35705. }
  35706. /**
  35707. * @brief Value assignment operator.
  35708. * @tparam Type Type of object to use to initialize the wrapper.
  35709. * @param value An instance of an object to use to initialize the wrapper.
  35710. * @return This meta any object.
  35711. */
  35712. template<typename Type>
  35713. std::enable_if_t<!std::is_same_v<std::decay_t<Type>, meta_any>, meta_any &>
  35714. operator=(Type &&value) {
  35715. emplace<std::decay_t<Type>>(std::forward<Type>(value));
  35716. return *this;
  35717. }
  35718. /*! @copydoc any::type */
  35719. [[nodiscard]] inline meta_type type() const ENTT_NOEXCEPT;
  35720. /*! @copydoc any::data */
  35721. [[nodiscard]] const void *data() const ENTT_NOEXCEPT {
  35722. return storage.data();
  35723. }
  35724. /*! @copydoc any::data */
  35725. [[nodiscard]] void *data() ENTT_NOEXCEPT {
  35726. return storage.data();
  35727. }
  35728. /**
  35729. * @brief Invokes the underlying function, if possible.
  35730. *
  35731. * @sa meta_func::invoke
  35732. *
  35733. * @tparam Args Types of arguments to use to invoke the function.
  35734. * @param id Unique identifier.
  35735. * @param args Parameters to use to invoke the function.
  35736. * @return A wrapper containing the returned value, if any.
  35737. */
  35738. template<typename... Args>
  35739. meta_any invoke(const id_type id, Args &&...args) const;
  35740. /*! @copydoc invoke */
  35741. template<typename... Args>
  35742. meta_any invoke(const id_type id, Args &&...args);
  35743. /**
  35744. * @brief Sets the value of a given variable.
  35745. *
  35746. * The type of the value is such that a cast or conversion to the type of
  35747. * the variable is possible. Otherwise, invoking the setter does nothing.
  35748. *
  35749. * @tparam Type Type of value to assign.
  35750. * @param id Unique identifier.
  35751. * @param value Parameter to use to set the underlying variable.
  35752. * @return True in case of success, false otherwise.
  35753. */
  35754. template<typename Type>
  35755. bool set(const id_type id, Type &&value);
  35756. /**
  35757. * @brief Gets the value of a given variable.
  35758. * @param id Unique identifier.
  35759. * @return A wrapper containing the value of the underlying variable.
  35760. */
  35761. [[nodiscard]] meta_any get(const id_type id) const;
  35762. /*! @copydoc get */
  35763. [[nodiscard]] meta_any get(const id_type id);
  35764. /**
  35765. * @brief Tries to cast an instance to a given type.
  35766. * @tparam Type Type to which to cast the instance.
  35767. * @return A (possibly null) pointer to the contained instance.
  35768. */
  35769. template<typename Type>
  35770. [[nodiscard]] const Type *try_cast() const {
  35771. if(const auto &info = type_id<Type>(); node && *node->info == info) {
  35772. return any_cast<Type>(&storage);
  35773. } else if(node) {
  35774. for(auto *it = node->base; it; it = it->next) {
  35775. const auto as_const = it->cast(as_ref());
  35776. if(const Type *base = as_const.template try_cast<Type>(); base) {
  35777. return base;
  35778. }
  35779. }
  35780. }
  35781. return nullptr;
  35782. }
  35783. /*! @copydoc try_cast */
  35784. template<typename Type>
  35785. [[nodiscard]] Type *try_cast() {
  35786. if(const auto &info = type_id<Type>(); node && *node->info == info) {
  35787. return any_cast<Type>(&storage);
  35788. } else if(node) {
  35789. for(auto *it = node->base; it; it = it->next) {
  35790. if(Type *base = it->cast(as_ref()).template try_cast<Type>(); base) {
  35791. return base;
  35792. }
  35793. }
  35794. }
  35795. return nullptr;
  35796. }
  35797. /**
  35798. * @brief Tries to cast an instance to a given type.
  35799. *
  35800. * The type of the instance must be such that the cast is possible.
  35801. *
  35802. * @warning
  35803. * Attempting to perform an invalid cast results is undefined behavior.
  35804. *
  35805. * @tparam Type Type to which to cast the instance.
  35806. * @return A reference to the contained instance.
  35807. */
  35808. template<typename Type>
  35809. [[nodiscard]] Type cast() const {
  35810. auto *const instance = try_cast<std::remove_reference_t<Type>>();
  35811. ENTT_ASSERT(instance, "Invalid instance");
  35812. return static_cast<Type>(*instance);
  35813. }
  35814. /*! @copydoc cast */
  35815. template<typename Type>
  35816. [[nodiscard]] Type cast() {
  35817. // forces const on non-reference types to make them work also with wrappers for const references
  35818. auto *const instance = try_cast<std::remove_reference_t<const Type>>();
  35819. ENTT_ASSERT(instance, "Invalid instance");
  35820. return static_cast<Type>(*instance);
  35821. }
  35822. /**
  35823. * @brief Converts an object in such a way that a given cast becomes viable.
  35824. * @param type Meta type to which the cast is requested.
  35825. * @return A valid meta any object if there exists a viable conversion, an
  35826. * invalid one otherwise.
  35827. */
  35828. [[nodiscard]] meta_any allow_cast(const meta_type &type) const;
  35829. /**
  35830. * @brief Converts an object in such a way that a given cast becomes viable.
  35831. * @param type Meta type to which the cast is requested.
  35832. * @return True if there exists a viable conversion, false otherwise.
  35833. */
  35834. [[nodiscard]] bool allow_cast(const meta_type &type) {
  35835. if(auto other = std::as_const(*this).allow_cast(type); other) {
  35836. if(other.storage.owner()) {
  35837. std::swap(*this, other);
  35838. }
  35839. return true;
  35840. }
  35841. return false;
  35842. }
  35843. /**
  35844. * @brief Converts an object in such a way that a given cast becomes viable.
  35845. * @tparam Type Type to which the cast is requested.
  35846. * @return A valid meta any object if there exists a viable conversion, an
  35847. * invalid one otherwise.
  35848. */
  35849. template<typename Type>
  35850. [[nodiscard]] meta_any allow_cast() const {
  35851. const auto other = allow_cast(internal::meta_node<std::remove_cv_t<std::remove_reference_t<Type>>>::resolve());
  35852. if constexpr(std::is_reference_v<Type> && !std::is_const_v<std::remove_reference_t<Type>>) {
  35853. return other.storage.owner() ? other : meta_any{};
  35854. } else {
  35855. return other;
  35856. }
  35857. }
  35858. /**
  35859. * @brief Converts an object in such a way that a given cast becomes viable.
  35860. * @tparam Type Type to which the cast is requested.
  35861. * @return True if there exists a viable conversion, false otherwise.
  35862. */
  35863. template<typename Type>
  35864. bool allow_cast() {
  35865. if(auto other = std::as_const(*this).allow_cast(internal::meta_node<std::remove_cv_t<std::remove_reference_t<Type>>>::resolve()); other) {
  35866. if(other.storage.owner()) {
  35867. std::swap(*this, other);
  35868. return true;
  35869. }
  35870. return (static_cast<constness_as_t<any, std::remove_reference_t<const Type>> &>(storage).data() != nullptr);
  35871. }
  35872. return false;
  35873. }
  35874. /*! @copydoc any::emplace */
  35875. template<typename Type, typename... Args>
  35876. void emplace(Args &&...args) {
  35877. release();
  35878. vtable = &basic_vtable<std::remove_cv_t<std::remove_reference_t<Type>>>;
  35879. storage.emplace<Type>(std::forward<Args>(args)...);
  35880. node = internal::meta_node<std::remove_cv_t<std::remove_reference_t<Type>>>::resolve();
  35881. }
  35882. /*! @copydoc any::assign */
  35883. bool assign(const meta_any &other);
  35884. /*! @copydoc any::assign */
  35885. bool assign(meta_any &&other);
  35886. /*! @copydoc any::reset */
  35887. void reset() {
  35888. release();
  35889. vtable = &basic_vtable<void>;
  35890. storage.reset();
  35891. node = nullptr;
  35892. }
  35893. /**
  35894. * @brief Returns a sequence container proxy.
  35895. * @return A sequence container proxy for the underlying object.
  35896. */
  35897. [[nodiscard]] meta_sequence_container as_sequence_container() ENTT_NOEXCEPT {
  35898. any detached = storage.as_ref();
  35899. meta_sequence_container proxy;
  35900. vtable(operation::seq, detached, &proxy);
  35901. return proxy;
  35902. }
  35903. /*! @copydoc as_sequence_container */
  35904. [[nodiscard]] meta_sequence_container as_sequence_container() const ENTT_NOEXCEPT {
  35905. any detached = storage.as_ref();
  35906. meta_sequence_container proxy;
  35907. vtable(operation::seq, detached, &proxy);
  35908. return proxy;
  35909. }
  35910. /**
  35911. * @brief Returns an associative container proxy.
  35912. * @return An associative container proxy for the underlying object.
  35913. */
  35914. [[nodiscard]] meta_associative_container as_associative_container() ENTT_NOEXCEPT {
  35915. any detached = storage.as_ref();
  35916. meta_associative_container proxy;
  35917. vtable(operation::assoc, detached, &proxy);
  35918. return proxy;
  35919. }
  35920. /*! @copydoc as_associative_container */
  35921. [[nodiscard]] meta_associative_container as_associative_container() const ENTT_NOEXCEPT {
  35922. any detached = storage.as_ref();
  35923. meta_associative_container proxy;
  35924. vtable(operation::assoc, detached, &proxy);
  35925. return proxy;
  35926. }
  35927. /**
  35928. * @brief Indirection operator for dereferencing opaque objects.
  35929. * @return A wrapper that shares a reference to an unmanaged object if the
  35930. * wrapped element is dereferenceable, an invalid meta any otherwise.
  35931. */
  35932. [[nodiscard]] meta_any operator*() const ENTT_NOEXCEPT {
  35933. meta_any ret{};
  35934. vtable(operation::deref, storage, &ret);
  35935. return ret;
  35936. }
  35937. /**
  35938. * @brief Returns false if a wrapper is invalid, true otherwise.
  35939. * @return False if the wrapper is invalid, true otherwise.
  35940. */
  35941. [[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
  35942. return !(node == nullptr);
  35943. }
  35944. /*! @copydoc any::operator== */
  35945. [[nodiscard]] bool operator==(const meta_any &other) const {
  35946. return (!node && !other.node) || (node && other.node && *node->info == *other.node->info && storage == other.storage);
  35947. }
  35948. /*! @copydoc any::as_ref */
  35949. [[nodiscard]] meta_any as_ref() ENTT_NOEXCEPT {
  35950. return meta_any{*this, storage.as_ref()};
  35951. }
  35952. /*! @copydoc any::as_ref */
  35953. [[nodiscard]] meta_any as_ref() const ENTT_NOEXCEPT {
  35954. return meta_any{*this, storage.as_ref()};
  35955. }
  35956. /*! @copydoc any::owner */
  35957. [[nodiscard]] bool owner() const ENTT_NOEXCEPT {
  35958. return storage.owner();
  35959. }
  35960. private:
  35961. any storage;
  35962. internal::meta_type_node *node;
  35963. vtable_type *vtable;
  35964. };
  35965. /**
  35966. * @brief Checks if two wrappers differ in their content.
  35967. * @param lhs A wrapper, either empty or not.
  35968. * @param rhs A wrapper, either empty or not.
  35969. * @return True if the two wrappers differ in their content, false otherwise.
  35970. */
  35971. [[nodiscard]] inline bool operator!=(const meta_any &lhs, const meta_any &rhs) ENTT_NOEXCEPT {
  35972. return !(lhs == rhs);
  35973. }
  35974. /**
  35975. * @brief Constructs a wrapper from a given type, passing it all arguments.
  35976. * @tparam Type Type of object to use to initialize the wrapper.
  35977. * @tparam Args Types of arguments to use to construct the new instance.
  35978. * @param args Parameters to use to construct the instance.
  35979. * @return A properly initialized wrapper for an object of the given type.
  35980. */
  35981. template<typename Type, typename... Args>
  35982. meta_any make_meta(Args &&...args) {
  35983. return meta_any{std::in_place_type<Type>, std::forward<Args>(args)...};
  35984. }
  35985. /**
  35986. * @brief Forwards its argument and avoids copies for lvalue references.
  35987. * @tparam Type Type of argument to use to construct the new instance.
  35988. * @param value Parameter to use to construct the instance.
  35989. * @return A properly initialized and not necessarily owning wrapper.
  35990. */
  35991. template<typename Type>
  35992. meta_any forward_as_meta(Type &&value) {
  35993. return meta_any{std::in_place_type<std::conditional_t<std::is_rvalue_reference_v<Type>, std::decay_t<Type>, Type>>, std::forward<Type>(value)};
  35994. }
  35995. /**
  35996. * @brief Opaque pointers to instances of any type.
  35997. *
  35998. * A handle doesn't perform copies and isn't responsible for the contained
  35999. * object. It doesn't prolong the lifetime of the pointed instance.<br/>
  36000. * Handles are used to generate references to actual objects when needed.
  36001. */
  36002. struct meta_handle {
  36003. /*! @brief Default constructor. */
  36004. meta_handle() = default;
  36005. /*! @brief Default copy constructor, deleted on purpose. */
  36006. meta_handle(const meta_handle &) = delete;
  36007. /*! @brief Default move constructor. */
  36008. meta_handle(meta_handle &&) = default;
  36009. /**
  36010. * @brief Default copy assignment operator, deleted on purpose.
  36011. * @return This meta handle.
  36012. */
  36013. meta_handle &operator=(const meta_handle &) = delete;
  36014. /**
  36015. * @brief Default move assignment operator.
  36016. * @return This meta handle.
  36017. */
  36018. meta_handle &operator=(meta_handle &&) = default;
  36019. /**
  36020. * @brief Creates a handle that points to an unmanaged object.
  36021. * @tparam Type Type of object to use to initialize the handle.
  36022. * @param value An instance of an object to use to initialize the handle.
  36023. */
  36024. template<typename Type, typename = std::enable_if_t<!std::is_same_v<std::decay_t<Type>, meta_handle>>>
  36025. meta_handle(Type &value) ENTT_NOEXCEPT
  36026. : meta_handle{} {
  36027. if constexpr(std::is_same_v<std::decay_t<Type>, meta_any>) {
  36028. any = value.as_ref();
  36029. } else {
  36030. any.emplace<Type &>(value);
  36031. }
  36032. }
  36033. /**
  36034. * @brief Returns false if a handle is invalid, true otherwise.
  36035. * @return False if the handle is invalid, true otherwise.
  36036. */
  36037. [[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
  36038. return static_cast<bool>(any);
  36039. }
  36040. /**
  36041. * @brief Access operator for accessing the contained opaque object.
  36042. * @return A wrapper that shares a reference to an unmanaged object.
  36043. */
  36044. [[nodiscard]] meta_any *operator->() {
  36045. return &any;
  36046. }
  36047. /*! @copydoc operator-> */
  36048. [[nodiscard]] const meta_any *operator->() const {
  36049. return &any;
  36050. }
  36051. private:
  36052. meta_any any;
  36053. };
  36054. /*! @brief Opaque wrapper for properties of any type. */
  36055. struct meta_prop {
  36056. /*! @brief Node type. */
  36057. using node_type = internal::meta_prop_node;
  36058. /**
  36059. * @brief Constructs an instance from a given node.
  36060. * @param curr The underlying node with which to construct the instance.
  36061. */
  36062. meta_prop(const node_type *curr = nullptr) ENTT_NOEXCEPT
  36063. : node{curr} {}
  36064. /**
  36065. * @brief Returns the stored key as a const reference.
  36066. * @return A wrapper containing the key stored with the property.
  36067. */
  36068. [[nodiscard]] meta_any key() const {
  36069. return node->id.as_ref();
  36070. }
  36071. /**
  36072. * @brief Returns the stored value by copy.
  36073. * @return A wrapper containing the value stored with the property.
  36074. */
  36075. [[nodiscard]] meta_any value() const {
  36076. return node->value;
  36077. }
  36078. /**
  36079. * @brief Returns true if an object is valid, false otherwise.
  36080. * @return True if the object is valid, false otherwise.
  36081. */
  36082. [[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
  36083. return !(node == nullptr);
  36084. }
  36085. private:
  36086. const node_type *node;
  36087. };
  36088. /*! @brief Opaque wrapper for data members. */
  36089. struct meta_data {
  36090. /*! @brief Node type. */
  36091. using node_type = internal::meta_data_node;
  36092. /*! @brief Unsigned integer type. */
  36093. using size_type = typename node_type::size_type;
  36094. /*! @copydoc meta_prop::meta_prop */
  36095. meta_data(const node_type *curr = nullptr) ENTT_NOEXCEPT
  36096. : node{curr} {}
  36097. /*! @copydoc meta_type::id */
  36098. [[nodiscard]] id_type id() const ENTT_NOEXCEPT {
  36099. return node->id;
  36100. }
  36101. /**
  36102. * @brief Returns the number of setters available.
  36103. * @return The number of setters available.
  36104. */
  36105. [[nodiscard]] size_type arity() const ENTT_NOEXCEPT {
  36106. return node->arity;
  36107. }
  36108. /**
  36109. * @brief Indicates whether a data member is constant or not.
  36110. * @return True if the data member is constant, false otherwise.
  36111. */
  36112. [[nodiscard]] bool is_const() const ENTT_NOEXCEPT {
  36113. return !!(node->traits & internal::meta_traits::is_const);
  36114. }
  36115. /**
  36116. * @brief Indicates whether a data member is static or not.
  36117. * @return True if the data member is static, false otherwise.
  36118. */
  36119. [[nodiscard]] bool is_static() const ENTT_NOEXCEPT {
  36120. return !!(node->traits & internal::meta_traits::is_static);
  36121. }
  36122. /*! @copydoc meta_any::type */
  36123. [[nodiscard]] inline meta_type type() const ENTT_NOEXCEPT;
  36124. /**
  36125. * @brief Sets the value of a given variable.
  36126. *
  36127. * It must be possible to cast the instance to the parent type of the data
  36128. * member.<br/>
  36129. * The type of the value is such that a cast or conversion to the type of
  36130. * the variable is possible. Otherwise, invoking the setter does nothing.
  36131. *
  36132. * @tparam Type Type of value to assign.
  36133. * @param instance An opaque instance of the underlying type.
  36134. * @param value Parameter to use to set the underlying variable.
  36135. * @return True in case of success, false otherwise.
  36136. */
  36137. template<typename Type>
  36138. bool set(meta_handle instance, Type &&value) const {
  36139. return node->set && node->set(std::move(instance), std::forward<Type>(value));
  36140. }
  36141. /**
  36142. * @brief Gets the value of a given variable.
  36143. *
  36144. * It must be possible to cast the instance to the parent type of the data
  36145. * member.
  36146. *
  36147. * @param instance An opaque instance of the underlying type.
  36148. * @return A wrapper containing the value of the underlying variable.
  36149. */
  36150. [[nodiscard]] meta_any get(meta_handle instance) const {
  36151. return node->get(std::move(instance));
  36152. }
  36153. /**
  36154. * @brief Returns the type accepted by the i-th setter.
  36155. * @param index Index of the setter of which to return the accepted type.
  36156. * @return The type accepted by the i-th setter.
  36157. */
  36158. [[nodiscard]] inline meta_type arg(const size_type index) const ENTT_NOEXCEPT;
  36159. /**
  36160. * @brief Returns a range to visit registered meta properties.
  36161. * @return An iterable range to visit registered meta properties.
  36162. */
  36163. [[nodiscard]] meta_range<meta_prop> prop() const ENTT_NOEXCEPT {
  36164. return node->prop;
  36165. }
  36166. /**
  36167. * @brief Lookup function for registered meta properties.
  36168. * @param key The key to use to search for a property.
  36169. * @return The registered meta property for the given key, if any.
  36170. */
  36171. [[nodiscard]] meta_prop prop(meta_any key) const {
  36172. for(auto curr: prop()) {
  36173. if(curr.key() == key) {
  36174. return curr;
  36175. }
  36176. }
  36177. return nullptr;
  36178. }
  36179. /**
  36180. * @brief Returns true if an object is valid, false otherwise.
  36181. * @return True if the object is valid, false otherwise.
  36182. */
  36183. [[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
  36184. return !(node == nullptr);
  36185. }
  36186. private:
  36187. const node_type *node;
  36188. };
  36189. /*! @brief Opaque wrapper for member functions. */
  36190. struct meta_func {
  36191. /*! @brief Node type. */
  36192. using node_type = internal::meta_func_node;
  36193. /*! @brief Unsigned integer type. */
  36194. using size_type = typename node_type::size_type;
  36195. /*! @copydoc meta_prop::meta_prop */
  36196. meta_func(const node_type *curr = nullptr) ENTT_NOEXCEPT
  36197. : node{curr} {}
  36198. /*! @copydoc meta_type::id */
  36199. [[nodiscard]] id_type id() const ENTT_NOEXCEPT {
  36200. return node->id;
  36201. }
  36202. /**
  36203. * @brief Returns the number of arguments accepted by a member function.
  36204. * @return The number of arguments accepted by the member function.
  36205. */
  36206. [[nodiscard]] size_type arity() const ENTT_NOEXCEPT {
  36207. return node->arity;
  36208. }
  36209. /**
  36210. * @brief Indicates whether a member function is constant or not.
  36211. * @return True if the member function is constant, false otherwise.
  36212. */
  36213. [[nodiscard]] bool is_const() const ENTT_NOEXCEPT {
  36214. return !!(node->traits & internal::meta_traits::is_const);
  36215. }
  36216. /**
  36217. * @brief Indicates whether a member function is static or not.
  36218. * @return True if the member function is static, false otherwise.
  36219. */
  36220. [[nodiscard]] bool is_static() const ENTT_NOEXCEPT {
  36221. return !!(node->traits & internal::meta_traits::is_static);
  36222. }
  36223. /**
  36224. * @brief Returns the return type of a member function.
  36225. * @return The return type of the member function.
  36226. */
  36227. [[nodiscard]] inline meta_type ret() const ENTT_NOEXCEPT;
  36228. /**
  36229. * @brief Returns the type of the i-th argument of a member function.
  36230. * @param index Index of the argument of which to return the type.
  36231. * @return The type of the i-th argument of a member function.
  36232. */
  36233. [[nodiscard]] inline meta_type arg(const size_type index) const ENTT_NOEXCEPT;
  36234. /**
  36235. * @brief Invokes the underlying function, if possible.
  36236. *
  36237. * To invoke a member function, the parameters must be such that a cast or
  36238. * conversion to the required types is possible. Otherwise, an empty and
  36239. * thus invalid wrapper is returned.<br/>
  36240. * It must be possible to cast the instance to the parent type of the member
  36241. * function.
  36242. *
  36243. * @param instance An opaque instance of the underlying type.
  36244. * @param args Parameters to use to invoke the function.
  36245. * @param sz Number of parameters to use to invoke the function.
  36246. * @return A wrapper containing the returned value, if any.
  36247. */
  36248. meta_any invoke(meta_handle instance, meta_any *const args, const size_type sz) const {
  36249. return sz == arity() ? node->invoke(std::move(instance), args) : meta_any{};
  36250. }
  36251. /**
  36252. * @copybrief invoke
  36253. *
  36254. * @sa invoke
  36255. *
  36256. * @tparam Args Types of arguments to use to invoke the function.
  36257. * @param instance An opaque instance of the underlying type.
  36258. * @param args Parameters to use to invoke the function.
  36259. * @return A wrapper containing the new instance, if any.
  36260. */
  36261. template<typename... Args>
  36262. meta_any invoke(meta_handle instance, Args &&...args) const {
  36263. meta_any arguments[sizeof...(Args) + 1u]{std::forward<Args>(args)...};
  36264. return invoke(std::move(instance), arguments, sizeof...(Args));
  36265. }
  36266. /*! @copydoc meta_data::prop */
  36267. [[nodiscard]] meta_range<meta_prop> prop() const ENTT_NOEXCEPT {
  36268. return node->prop;
  36269. }
  36270. /**
  36271. * @brief Lookup function for registered meta properties.
  36272. * @param key The key to use to search for a property.
  36273. * @return The registered meta property for the given key, if any.
  36274. */
  36275. [[nodiscard]] meta_prop prop(meta_any key) const {
  36276. for(auto curr: prop()) {
  36277. if(curr.key() == key) {
  36278. return curr;
  36279. }
  36280. }
  36281. return nullptr;
  36282. }
  36283. /**
  36284. * @brief Returns true if an object is valid, false otherwise.
  36285. * @return True if the object is valid, false otherwise.
  36286. */
  36287. [[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
  36288. return !(node == nullptr);
  36289. }
  36290. private:
  36291. const node_type *node;
  36292. };
  36293. /*! @brief Opaque wrapper for types. */
  36294. class meta_type {
  36295. template<auto Member, typename Pred>
  36296. [[nodiscard]] std::decay_t<decltype(std::declval<internal::meta_type_node>().*Member)> lookup(meta_any *const args, const typename internal::meta_type_node::size_type sz, Pred pred) const {
  36297. std::decay_t<decltype(node->*Member)> candidate{};
  36298. size_type extent{sz + 1u};
  36299. bool ambiguous{};
  36300. for(auto *curr = (node->*Member); curr; curr = curr->next) {
  36301. if(pred(curr) && curr->arity == sz) {
  36302. size_type direct{};
  36303. size_type ext{};
  36304. for(size_type next{}; next < sz && next == (direct + ext) && args[next]; ++next) {
  36305. const auto type = args[next].type();
  36306. const auto other = curr->arg(next);
  36307. if(const auto &info = other.info(); info == type.info()) {
  36308. ++direct;
  36309. } else {
  36310. ext += internal::find_by<&node_type::base>(info, type.node)
  36311. || internal::find_by<&node_type::conv>(info, type.node)
  36312. || (type.node->conversion_helper && other.node->conversion_helper);
  36313. }
  36314. }
  36315. if((direct + ext) == sz) {
  36316. if(ext < extent) {
  36317. candidate = curr;
  36318. extent = ext;
  36319. ambiguous = false;
  36320. } else if(ext == extent) {
  36321. ambiguous = true;
  36322. }
  36323. }
  36324. }
  36325. }
  36326. return (candidate && !ambiguous) ? candidate : decltype(candidate){};
  36327. }
  36328. public:
  36329. /*! @brief Node type. */
  36330. using node_type = internal::meta_type_node;
  36331. /*! @brief Node type. */
  36332. using base_node_type = internal::meta_base_node;
  36333. /*! @brief Unsigned integer type. */
  36334. using size_type = typename node_type::size_type;
  36335. /*! @copydoc meta_prop::meta_prop */
  36336. meta_type(const node_type *curr = nullptr) ENTT_NOEXCEPT
  36337. : node{curr} {}
  36338. /**
  36339. * @brief Constructs an instance from a given base node.
  36340. * @param curr The base node with which to construct the instance.
  36341. */
  36342. meta_type(const base_node_type *curr) ENTT_NOEXCEPT
  36343. : node{curr ? curr->type : nullptr} {}
  36344. /**
  36345. * @brief Returns the type info object of the underlying type.
  36346. * @return The type info object of the underlying type.
  36347. */
  36348. [[nodiscard]] const type_info &info() const ENTT_NOEXCEPT {
  36349. return *node->info;
  36350. }
  36351. /**
  36352. * @brief Returns the identifier assigned to a type.
  36353. * @return The identifier assigned to the type.
  36354. */
  36355. [[nodiscard]] id_type id() const ENTT_NOEXCEPT {
  36356. return node->id;
  36357. }
  36358. /**
  36359. * @brief Returns the size of the underlying type if known.
  36360. * @return The size of the underlying type if known, 0 otherwise.
  36361. */
  36362. [[nodiscard]] size_type size_of() const ENTT_NOEXCEPT {
  36363. return node->size_of;
  36364. }
  36365. /**
  36366. * @brief Checks whether a type refers to an arithmetic type or not.
  36367. * @return True if the underlying type is an arithmetic type, false
  36368. * otherwise.
  36369. */
  36370. [[nodiscard]] bool is_arithmetic() const ENTT_NOEXCEPT {
  36371. return !!(node->traits & internal::meta_traits::is_arithmetic);
  36372. }
  36373. /**
  36374. * @brief Checks whether a type refers to an array type or not.
  36375. * @return True if the underlying type is an array type, false otherwise.
  36376. */
  36377. [[nodiscard]] bool is_array() const ENTT_NOEXCEPT {
  36378. return !!(node->traits & internal::meta_traits::is_array);
  36379. }
  36380. /**
  36381. * @brief Checks whether a type refers to an enum or not.
  36382. * @return True if the underlying type is an enum, false otherwise.
  36383. */
  36384. [[nodiscard]] bool is_enum() const ENTT_NOEXCEPT {
  36385. return !!(node->traits & internal::meta_traits::is_enum);
  36386. }
  36387. /**
  36388. * @brief Checks whether a type refers to a class or not.
  36389. * @return True if the underlying type is a class, false otherwise.
  36390. */
  36391. [[nodiscard]] bool is_class() const ENTT_NOEXCEPT {
  36392. return !!(node->traits & internal::meta_traits::is_class);
  36393. }
  36394. /**
  36395. * @brief Checks whether a type refers to a pointer or not.
  36396. * @return True if the underlying type is a pointer, false otherwise.
  36397. */
  36398. [[nodiscard]] bool is_pointer() const ENTT_NOEXCEPT {
  36399. return !!(node->traits & internal::meta_traits::is_pointer);
  36400. }
  36401. /**
  36402. * @brief Provides the type for which the pointer is defined.
  36403. * @return The type for which the pointer is defined or this type if it
  36404. * doesn't refer to a pointer type.
  36405. */
  36406. [[nodiscard]] meta_type remove_pointer() const ENTT_NOEXCEPT {
  36407. return node->remove_pointer();
  36408. }
  36409. /**
  36410. * @brief Checks whether a type is a pointer-like type or not.
  36411. * @return True if the underlying type is a pointer-like one, false
  36412. * otherwise.
  36413. */
  36414. [[nodiscard]] bool is_pointer_like() const ENTT_NOEXCEPT {
  36415. return !!(node->traits & internal::meta_traits::is_meta_pointer_like);
  36416. }
  36417. /**
  36418. * @brief Checks whether a type refers to a sequence container or not.
  36419. * @return True if the type is a sequence container, false otherwise.
  36420. */
  36421. [[nodiscard]] bool is_sequence_container() const ENTT_NOEXCEPT {
  36422. return !!(node->traits & internal::meta_traits::is_meta_sequence_container);
  36423. }
  36424. /**
  36425. * @brief Checks whether a type refers to an associative container or not.
  36426. * @return True if the type is an associative container, false otherwise.
  36427. */
  36428. [[nodiscard]] bool is_associative_container() const ENTT_NOEXCEPT {
  36429. return !!(node->traits & internal::meta_traits::is_meta_associative_container);
  36430. }
  36431. /**
  36432. * @brief Checks whether a type refers to a recognized class template
  36433. * specialization or not.
  36434. * @return True if the type is a recognized class template specialization,
  36435. * false otherwise.
  36436. */
  36437. [[nodiscard]] bool is_template_specialization() const ENTT_NOEXCEPT {
  36438. return (node->templ != nullptr);
  36439. }
  36440. /**
  36441. * @brief Returns the number of template arguments.
  36442. * @return The number of template arguments.
  36443. */
  36444. [[nodiscard]] size_type template_arity() const ENTT_NOEXCEPT {
  36445. return node->templ ? node->templ->arity : size_type{};
  36446. }
  36447. /**
  36448. * @brief Returns a tag for the class template of the underlying type.
  36449. *
  36450. * @sa meta_class_template_tag
  36451. *
  36452. * @return The tag for the class template of the underlying type.
  36453. */
  36454. [[nodiscard]] inline meta_type template_type() const ENTT_NOEXCEPT {
  36455. return node->templ ? node->templ->type : meta_type{};
  36456. }
  36457. /**
  36458. * @brief Returns the type of the i-th template argument of a type.
  36459. * @param index Index of the template argument of which to return the type.
  36460. * @return The type of the i-th template argument of a type.
  36461. */
  36462. [[nodiscard]] inline meta_type template_arg(const size_type index) const ENTT_NOEXCEPT {
  36463. return index < template_arity() ? node->templ->arg(index) : meta_type{};
  36464. }
  36465. /**
  36466. * @brief Returns a range to visit registered top-level base meta types.
  36467. * @return An iterable range to visit registered top-level base meta types.
  36468. */
  36469. [[nodiscard]] meta_range<meta_type, internal::meta_base_node> base() const ENTT_NOEXCEPT {
  36470. return node->base;
  36471. }
  36472. /**
  36473. * @brief Lookup function for registered base meta types.
  36474. * @param id Unique identifier.
  36475. * @return The registered base meta type for the given identifier, if any.
  36476. */
  36477. [[nodiscard]] meta_type base(const id_type id) const {
  36478. return internal::find_by<&node_type::base>(id, node);
  36479. }
  36480. /**
  36481. * @brief Returns a range to visit registered top-level meta data.
  36482. * @return An iterable range to visit registered top-level meta data.
  36483. */
  36484. [[nodiscard]] meta_range<meta_data> data() const ENTT_NOEXCEPT {
  36485. return node->data;
  36486. }
  36487. /**
  36488. * @brief Lookup function for registered meta data.
  36489. *
  36490. * Registered meta data of base classes will also be visited.
  36491. *
  36492. * @param id Unique identifier.
  36493. * @return The registered meta data for the given identifier, if any.
  36494. */
  36495. [[nodiscard]] meta_data data(const id_type id) const {
  36496. return internal::find_by<&node_type::data>(id, node);
  36497. }
  36498. /**
  36499. * @brief Returns a range to visit registered top-level functions.
  36500. * @return An iterable range to visit registered top-level functions.
  36501. */
  36502. [[nodiscard]] meta_range<meta_func> func() const ENTT_NOEXCEPT {
  36503. return node->func;
  36504. }
  36505. /**
  36506. * @brief Lookup function for registered meta functions.
  36507. *
  36508. * Registered meta functions of base classes will also be visited.<br/>
  36509. * In case of overloaded functions, the first one with the required
  36510. * identifier will be returned.
  36511. *
  36512. * @param id Unique identifier.
  36513. * @return The registered meta function for the given identifier, if any.
  36514. */
  36515. [[nodiscard]] meta_func func(const id_type id) const {
  36516. return internal::find_by<&node_type::func>(id, node);
  36517. }
  36518. /**
  36519. * @brief Creates an instance of the underlying type, if possible.
  36520. *
  36521. * Parameters are such that a cast or conversion to the required types is
  36522. * possible. Otherwise, an empty and thus invalid wrapper is returned.<br/>
  36523. * If suitable, the implicitly generated default constructor is used.
  36524. *
  36525. * @param args Parameters to use to construct the instance.
  36526. * @param sz Number of parameters to use to construct the instance.
  36527. * @return A wrapper containing the new instance, if any.
  36528. */
  36529. [[nodiscard]] meta_any construct(meta_any *const args, const size_type sz) const {
  36530. const auto *candidate = lookup<&node_type::ctor>(args, sz, [](const auto *) { return true; });
  36531. return candidate ? candidate->invoke(args) : ((!sz && node->default_constructor) ? node->default_constructor() : meta_any{});
  36532. }
  36533. /**
  36534. * @copybrief construct
  36535. *
  36536. * @sa construct
  36537. *
  36538. * @tparam Args Types of arguments to use to construct the instance.
  36539. * @param args Parameters to use to construct the instance.
  36540. * @return A wrapper containing the new instance, if any.
  36541. */
  36542. template<typename... Args>
  36543. [[nodiscard]] meta_any construct(Args &&...args) const {
  36544. meta_any arguments[sizeof...(Args) + 1u]{std::forward<Args>(args)...};
  36545. return construct(arguments, sizeof...(Args));
  36546. }
  36547. /**
  36548. * @brief Invokes a function given an identifier, if possible.
  36549. *
  36550. * It must be possible to cast the instance to the parent type of the member
  36551. * function.
  36552. *
  36553. * @sa meta_func::invoke
  36554. *
  36555. * @param id Unique identifier.
  36556. * @param instance An opaque instance of the underlying type.
  36557. * @param args Parameters to use to invoke the function.
  36558. * @param sz Number of parameters to use to invoke the function.
  36559. * @return A wrapper containing the returned value, if any.
  36560. */
  36561. meta_any invoke(const id_type id, meta_handle instance, meta_any *const args, const size_type sz) const {
  36562. const auto *candidate = lookup<&node_type::func>(args, sz, [id](const auto *curr) { return curr->id == id; });
  36563. for(auto it = base().begin(), last = base().end(); it != last && !candidate; ++it) {
  36564. candidate = it->lookup<&node_type::func>(args, sz, [id](const auto *curr) { return curr->id == id; });
  36565. }
  36566. return candidate ? candidate->invoke(std::move(instance), args) : meta_any{};
  36567. }
  36568. /**
  36569. * @copybrief invoke
  36570. *
  36571. * @sa invoke
  36572. *
  36573. * @param id Unique identifier.
  36574. * @tparam Args Types of arguments to use to invoke the function.
  36575. * @param instance An opaque instance of the underlying type.
  36576. * @param args Parameters to use to invoke the function.
  36577. * @return A wrapper containing the new instance, if any.
  36578. */
  36579. template<typename... Args>
  36580. meta_any invoke(const id_type id, meta_handle instance, Args &&...args) const {
  36581. meta_any arguments[sizeof...(Args) + 1u]{std::forward<Args>(args)...};
  36582. return invoke(id, std::move(instance), arguments, sizeof...(Args));
  36583. }
  36584. /**
  36585. * @brief Sets the value of a given variable.
  36586. *
  36587. * It must be possible to cast the instance to the parent type of the data
  36588. * member.<br/>
  36589. * The type of the value is such that a cast or conversion to the type of
  36590. * the variable is possible. Otherwise, invoking the setter does nothing.
  36591. *
  36592. * @tparam Type Type of value to assign.
  36593. * @param id Unique identifier.
  36594. * @param instance An opaque instance of the underlying type.
  36595. * @param value Parameter to use to set the underlying variable.
  36596. * @return True in case of success, false otherwise.
  36597. */
  36598. template<typename Type>
  36599. bool set(const id_type id, meta_handle instance, Type &&value) const {
  36600. const auto candidate = data(id);
  36601. return candidate && candidate.set(std::move(instance), std::forward<Type>(value));
  36602. }
  36603. /**
  36604. * @brief Gets the value of a given variable.
  36605. *
  36606. * It must be possible to cast the instance to the parent type of the data
  36607. * member.
  36608. *
  36609. * @param id Unique identifier.
  36610. * @param instance An opaque instance of the underlying type.
  36611. * @return A wrapper containing the value of the underlying variable.
  36612. */
  36613. [[nodiscard]] meta_any get(const id_type id, meta_handle instance) const {
  36614. const auto candidate = data(id);
  36615. return candidate ? candidate.get(std::move(instance)) : meta_any{};
  36616. }
  36617. /**
  36618. * @brief Returns a range to visit registered top-level meta properties.
  36619. * @return An iterable range to visit registered top-level meta properties.
  36620. */
  36621. [[nodiscard]] meta_range<meta_prop> prop() const ENTT_NOEXCEPT {
  36622. return node->prop;
  36623. }
  36624. /**
  36625. * @brief Lookup function for meta properties.
  36626. *
  36627. * Properties of base classes are also visited.
  36628. *
  36629. * @param key The key to use to search for a property.
  36630. * @return The registered meta property for the given key, if any.
  36631. */
  36632. [[nodiscard]] meta_prop prop(meta_any key) const {
  36633. return internal::find_by<&internal::meta_type_node::prop>(key, node);
  36634. }
  36635. /**
  36636. * @brief Returns true if an object is valid, false otherwise.
  36637. * @return True if the object is valid, false otherwise.
  36638. */
  36639. [[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
  36640. return !(node == nullptr);
  36641. }
  36642. /**
  36643. * @brief Checks if two objects refer to the same type.
  36644. * @param other The object with which to compare.
  36645. * @return True if the objects refer to the same type, false otherwise.
  36646. */
  36647. [[nodiscard]] bool operator==(const meta_type &other) const ENTT_NOEXCEPT {
  36648. return (!node && !other.node) || (node && other.node && *node->info == *other.node->info);
  36649. }
  36650. private:
  36651. const node_type *node;
  36652. };
  36653. /**
  36654. * @brief Checks if two objects refer to the same type.
  36655. * @param lhs An object, either valid or not.
  36656. * @param rhs An object, either valid or not.
  36657. * @return False if the objects refer to the same node, true otherwise.
  36658. */
  36659. [[nodiscard]] inline bool operator!=(const meta_type &lhs, const meta_type &rhs) ENTT_NOEXCEPT {
  36660. return !(lhs == rhs);
  36661. }
  36662. [[nodiscard]] inline meta_type meta_any::type() const ENTT_NOEXCEPT {
  36663. return node;
  36664. }
  36665. template<typename... Args>
  36666. meta_any meta_any::invoke(const id_type id, Args &&...args) const {
  36667. return type().invoke(id, *this, std::forward<Args>(args)...);
  36668. }
  36669. template<typename... Args>
  36670. meta_any meta_any::invoke(const id_type id, Args &&...args) {
  36671. return type().invoke(id, *this, std::forward<Args>(args)...);
  36672. }
  36673. template<typename Type>
  36674. bool meta_any::set(const id_type id, Type &&value) {
  36675. return type().set(id, *this, std::forward<Type>(value));
  36676. }
  36677. [[nodiscard]] inline meta_any meta_any::get(const id_type id) const {
  36678. return type().get(id, *this);
  36679. }
  36680. [[nodiscard]] inline meta_any meta_any::get(const id_type id) {
  36681. return type().get(id, *this);
  36682. }
  36683. [[nodiscard]] inline meta_any meta_any::allow_cast(const meta_type &type) const {
  36684. if(const auto &info = type.info(); node && *node->info == info) {
  36685. return as_ref();
  36686. } else if(node) {
  36687. for(auto *it = node->conv; it; it = it->next) {
  36688. if(*it->type->info == info) {
  36689. return it->conv(*this);
  36690. }
  36691. }
  36692. if(node->conversion_helper && (type.is_arithmetic() || type.is_enum())) {
  36693. // exploits the fact that arithmetic types and enums are also default constructible
  36694. auto other = type.construct();
  36695. ENTT_ASSERT(other.node->conversion_helper, "Conversion helper not found");
  36696. const auto value = node->conversion_helper(nullptr, storage.data());
  36697. other.node->conversion_helper(other.storage.data(), &value);
  36698. return other;
  36699. }
  36700. for(auto *it = node->base; it; it = it->next) {
  36701. const auto as_const = it->cast(as_ref());
  36702. if(auto other = as_const.allow_cast(type); other) {
  36703. return other;
  36704. }
  36705. }
  36706. }
  36707. return {};
  36708. }
  36709. inline bool meta_any::assign(const meta_any &other) {
  36710. auto value = other.allow_cast(node);
  36711. return value && storage.assign(std::move(value.storage));
  36712. }
  36713. inline bool meta_any::assign(meta_any &&other) {
  36714. if(*node->info == *other.node->info) {
  36715. return storage.assign(std::move(other.storage));
  36716. }
  36717. return assign(std::as_const(other));
  36718. }
  36719. [[nodiscard]] inline meta_type meta_data::type() const ENTT_NOEXCEPT {
  36720. return node->type;
  36721. }
  36722. [[nodiscard]] inline meta_type meta_func::ret() const ENTT_NOEXCEPT {
  36723. return node->ret;
  36724. }
  36725. [[nodiscard]] inline meta_type meta_data::arg(const size_type index) const ENTT_NOEXCEPT {
  36726. return index < arity() ? node->arg(index) : meta_type{};
  36727. }
  36728. [[nodiscard]] inline meta_type meta_func::arg(const size_type index) const ENTT_NOEXCEPT {
  36729. return index < arity() ? node->arg(index) : meta_type{};
  36730. }
  36731. /**
  36732. * @cond TURN_OFF_DOXYGEN
  36733. * Internal details not to be documented.
  36734. */
  36735. class meta_sequence_container::meta_iterator final {
  36736. friend class meta_sequence_container;
  36737. using deref_fn_type = meta_any(const any &, const std::ptrdiff_t);
  36738. template<typename It>
  36739. static meta_any deref_fn(const any &value, const std::ptrdiff_t pos) {
  36740. return meta_any{std::in_place_type<typename std::iterator_traits<It>::reference>, any_cast<const It &>(value)[pos]};
  36741. }
  36742. public:
  36743. using difference_type = std::ptrdiff_t;
  36744. using value_type = meta_any;
  36745. using pointer = input_iterator_pointer<value_type>;
  36746. using reference = value_type;
  36747. using iterator_category = std::input_iterator_tag;
  36748. meta_iterator() ENTT_NOEXCEPT
  36749. : deref{},
  36750. offset{},
  36751. handle{} {}
  36752. template<typename Type>
  36753. explicit meta_iterator(Type &cont, const difference_type init) ENTT_NOEXCEPT
  36754. : deref{&deref_fn<decltype(cont.begin())>},
  36755. offset{init},
  36756. handle{cont.begin()} {}
  36757. meta_iterator &operator++() ENTT_NOEXCEPT {
  36758. return ++offset, *this;
  36759. }
  36760. meta_iterator operator++(int value) ENTT_NOEXCEPT {
  36761. meta_iterator orig = *this;
  36762. offset += ++value;
  36763. return orig;
  36764. }
  36765. meta_iterator &operator--() ENTT_NOEXCEPT {
  36766. return --offset, *this;
  36767. }
  36768. meta_iterator operator--(int value) ENTT_NOEXCEPT {
  36769. meta_iterator orig = *this;
  36770. offset -= ++value;
  36771. return orig;
  36772. }
  36773. [[nodiscard]] reference operator*() const {
  36774. return deref(handle, offset);
  36775. }
  36776. [[nodiscard]] pointer operator->() const {
  36777. return operator*();
  36778. }
  36779. [[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
  36780. return static_cast<bool>(handle);
  36781. }
  36782. [[nodiscard]] bool operator==(const meta_iterator &other) const ENTT_NOEXCEPT {
  36783. return offset == other.offset;
  36784. }
  36785. [[nodiscard]] bool operator!=(const meta_iterator &other) const ENTT_NOEXCEPT {
  36786. return !(*this == other);
  36787. }
  36788. private:
  36789. deref_fn_type *deref;
  36790. difference_type offset;
  36791. any handle;
  36792. };
  36793. class meta_associative_container::meta_iterator final {
  36794. enum class operation : std::uint8_t {
  36795. incr,
  36796. deref
  36797. };
  36798. using vtable_type = void(const operation, const any &, std::pair<meta_any, meta_any> *);
  36799. template<bool KeyOnly, typename It>
  36800. static void basic_vtable(const operation op, const any &value, std::pair<meta_any, meta_any> *other) {
  36801. switch(op) {
  36802. case operation::incr:
  36803. ++any_cast<It &>(const_cast<any &>(value));
  36804. break;
  36805. case operation::deref:
  36806. const auto &it = any_cast<const It &>(value);
  36807. if constexpr(KeyOnly) {
  36808. other->first.emplace<decltype(*it)>(*it);
  36809. } else {
  36810. other->first.emplace<decltype((it->first))>(it->first);
  36811. other->second.emplace<decltype((it->second))>(it->second);
  36812. }
  36813. break;
  36814. }
  36815. }
  36816. public:
  36817. using difference_type = std::ptrdiff_t;
  36818. using value_type = std::pair<meta_any, meta_any>;
  36819. using pointer = input_iterator_pointer<value_type>;
  36820. using reference = value_type;
  36821. using iterator_category = std::input_iterator_tag;
  36822. meta_iterator() ENTT_NOEXCEPT
  36823. : vtable{},
  36824. handle{} {}
  36825. template<bool KeyOnly, typename It>
  36826. meta_iterator(std::integral_constant<bool, KeyOnly>, It iter) ENTT_NOEXCEPT
  36827. : vtable{&basic_vtable<KeyOnly, It>},
  36828. handle{std::move(iter)} {}
  36829. meta_iterator &operator++() ENTT_NOEXCEPT {
  36830. vtable(operation::incr, handle, nullptr);
  36831. return *this;
  36832. }
  36833. meta_iterator operator++(int) ENTT_NOEXCEPT {
  36834. meta_iterator orig = *this;
  36835. return ++(*this), orig;
  36836. }
  36837. [[nodiscard]] reference operator*() const {
  36838. reference other;
  36839. vtable(operation::deref, handle, &other);
  36840. return other;
  36841. }
  36842. [[nodiscard]] pointer operator->() const {
  36843. return operator*();
  36844. }
  36845. [[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
  36846. return static_cast<bool>(handle);
  36847. }
  36848. [[nodiscard]] bool operator==(const meta_iterator &other) const ENTT_NOEXCEPT {
  36849. return handle == other.handle;
  36850. }
  36851. [[nodiscard]] bool operator!=(const meta_iterator &other) const ENTT_NOEXCEPT {
  36852. return !(*this == other);
  36853. }
  36854. private:
  36855. vtable_type *vtable;
  36856. any handle;
  36857. };
  36858. /**
  36859. * Internal details not to be documented.
  36860. * @endcond
  36861. */
  36862. /**
  36863. * @brief Returns the meta value type of a container.
  36864. * @return The meta value type of the container.
  36865. */
  36866. [[nodiscard]] inline meta_type meta_sequence_container::value_type() const ENTT_NOEXCEPT {
  36867. return value_type_node;
  36868. }
  36869. /**
  36870. * @brief Returns the size of a container.
  36871. * @return The size of the container.
  36872. */
  36873. [[nodiscard]] inline meta_sequence_container::size_type meta_sequence_container::size() const ENTT_NOEXCEPT {
  36874. return size_fn(storage);
  36875. }
  36876. /**
  36877. * @brief Resizes a container to contain a given number of elements.
  36878. * @param sz The new size of the container.
  36879. * @return True in case of success, false otherwise.
  36880. */
  36881. inline bool meta_sequence_container::resize(const size_type sz) {
  36882. return resize_fn(storage, sz);
  36883. }
  36884. /**
  36885. * @brief Clears the content of a container.
  36886. * @return True in case of success, false otherwise.
  36887. */
  36888. inline bool meta_sequence_container::clear() {
  36889. return resize_fn(storage, 0u);
  36890. }
  36891. /**
  36892. * @brief Returns an iterator to the first element of a container.
  36893. * @return An iterator to the first element of the container.
  36894. */
  36895. [[nodiscard]] inline meta_sequence_container::iterator meta_sequence_container::begin() {
  36896. return iter_fn(storage, false);
  36897. }
  36898. /**
  36899. * @brief Returns an iterator that is past the last element of a container.
  36900. * @return An iterator that is past the last element of the container.
  36901. */
  36902. [[nodiscard]] inline meta_sequence_container::iterator meta_sequence_container::end() {
  36903. return iter_fn(storage, true);
  36904. }
  36905. /**
  36906. * @brief Inserts an element at a specified location of a container.
  36907. * @param it Iterator before which the element will be inserted.
  36908. * @param value Element value to insert.
  36909. * @return A possibly invalid iterator to the inserted element.
  36910. */
  36911. inline meta_sequence_container::iterator meta_sequence_container::insert(iterator it, meta_any value) {
  36912. return insert_fn(storage, it.offset, value);
  36913. }
  36914. /**
  36915. * @brief Removes a given element from a container.
  36916. * @param it Iterator to the element to remove.
  36917. * @return A possibly invalid iterator following the last removed element.
  36918. */
  36919. inline meta_sequence_container::iterator meta_sequence_container::erase(iterator it) {
  36920. return erase_fn(storage, it.offset);
  36921. }
  36922. /**
  36923. * @brief Returns a reference to the element at a given location of a container
  36924. * (no bounds checking is performed).
  36925. * @param pos The position of the element to return.
  36926. * @return A reference to the requested element properly wrapped.
  36927. */
  36928. [[nodiscard]] inline meta_any meta_sequence_container::operator[](const size_type pos) {
  36929. auto it = begin();
  36930. it.operator++(static_cast<int>(pos) - 1);
  36931. return *it;
  36932. }
  36933. /**
  36934. * @brief Returns false if a proxy is invalid, true otherwise.
  36935. * @return False if the proxy is invalid, true otherwise.
  36936. */
  36937. [[nodiscard]] inline meta_sequence_container::operator bool() const ENTT_NOEXCEPT {
  36938. return static_cast<bool>(storage);
  36939. }
  36940. /**
  36941. * @brief Returns true if a container is also key-only, false otherwise.
  36942. * @return True if the associative container is also key-only, false otherwise.
  36943. */
  36944. [[nodiscard]] inline bool meta_associative_container::key_only() const ENTT_NOEXCEPT {
  36945. return key_only_container;
  36946. }
  36947. /**
  36948. * @brief Returns the meta key type of a container.
  36949. * @return The meta key type of the a container.
  36950. */
  36951. [[nodiscard]] inline meta_type meta_associative_container::key_type() const ENTT_NOEXCEPT {
  36952. return key_type_node;
  36953. }
  36954. /**
  36955. * @brief Returns the meta mapped type of a container.
  36956. * @return The meta mapped type of the a container.
  36957. */
  36958. [[nodiscard]] inline meta_type meta_associative_container::mapped_type() const ENTT_NOEXCEPT {
  36959. return mapped_type_node;
  36960. }
  36961. /*! @copydoc meta_sequence_container::value_type */
  36962. [[nodiscard]] inline meta_type meta_associative_container::value_type() const ENTT_NOEXCEPT {
  36963. return value_type_node;
  36964. }
  36965. /*! @copydoc meta_sequence_container::size */
  36966. [[nodiscard]] inline meta_associative_container::size_type meta_associative_container::size() const ENTT_NOEXCEPT {
  36967. return size_fn(storage);
  36968. }
  36969. /*! @copydoc meta_sequence_container::clear */
  36970. inline bool meta_associative_container::clear() {
  36971. return clear_fn(storage);
  36972. }
  36973. /*! @copydoc meta_sequence_container::begin */
  36974. [[nodiscard]] inline meta_associative_container::iterator meta_associative_container::begin() {
  36975. return iter_fn(storage, false);
  36976. }
  36977. /*! @copydoc meta_sequence_container::end */
  36978. [[nodiscard]] inline meta_associative_container::iterator meta_associative_container::end() {
  36979. return iter_fn(storage, true);
  36980. }
  36981. /**
  36982. * @brief Inserts an element (a key/value pair) into a container.
  36983. * @param key The key of the element to insert.
  36984. * @param value The value of the element to insert.
  36985. * @return A bool denoting whether the insertion took place.
  36986. */
  36987. inline bool meta_associative_container::insert(meta_any key, meta_any value = {}) {
  36988. return insert_fn(storage, key, value);
  36989. }
  36990. /**
  36991. * @brief Removes the specified element from a container.
  36992. * @param key The key of the element to remove.
  36993. * @return A bool denoting whether the removal took place.
  36994. */
  36995. inline bool meta_associative_container::erase(meta_any key) {
  36996. return erase_fn(storage, key);
  36997. }
  36998. /**
  36999. * @brief Returns an iterator to the element with a given key, if any.
  37000. * @param key The key of the element to search.
  37001. * @return An iterator to the element with the given key, if any.
  37002. */
  37003. [[nodiscard]] inline meta_associative_container::iterator meta_associative_container::find(meta_any key) {
  37004. return find_fn(storage, key);
  37005. }
  37006. /**
  37007. * @brief Returns false if a proxy is invalid, true otherwise.
  37008. * @return False if the proxy is invalid, true otherwise.
  37009. */
  37010. [[nodiscard]] inline meta_associative_container::operator bool() const ENTT_NOEXCEPT {
  37011. return static_cast<bool>(storage);
  37012. }
  37013. } // namespace entt
  37014. #endif
  37015. // #include "type_traits.hpp"
  37016. namespace entt {
  37017. /**
  37018. * @cond TURN_OFF_DOXYGEN
  37019. * Internal details not to be documented.
  37020. */
  37021. namespace internal {
  37022. template<typename, typename = void>
  37023. struct is_dynamic_sequence_container: std::false_type {};
  37024. template<typename Type>
  37025. struct is_dynamic_sequence_container<Type, std::void_t<decltype(&Type::reserve)>>: std::true_type {};
  37026. template<typename, typename = void>
  37027. struct is_key_only_meta_associative_container: std::true_type {};
  37028. template<typename Type>
  37029. struct is_key_only_meta_associative_container<Type, std::void_t<typename Type::mapped_type>>: std::false_type {};
  37030. template<typename Type>
  37031. struct basic_meta_sequence_container_traits {
  37032. using iterator = meta_sequence_container::iterator;
  37033. using size_type = std::size_t;
  37034. [[nodiscard]] static size_type size(const any &container) ENTT_NOEXCEPT {
  37035. return any_cast<const Type &>(container).size();
  37036. }
  37037. [[nodiscard]] static bool resize([[maybe_unused]] any &container, [[maybe_unused]] size_type sz) {
  37038. if constexpr(is_dynamic_sequence_container<Type>::value) {
  37039. if(auto *const cont = any_cast<Type>(&container); cont) {
  37040. cont->resize(sz);
  37041. return true;
  37042. }
  37043. }
  37044. return false;
  37045. }
  37046. [[nodiscard]] static iterator iter(any &container, const bool as_end) {
  37047. if(auto *const cont = any_cast<Type>(&container); cont) {
  37048. return iterator{*cont, static_cast<typename iterator::difference_type>(as_end * cont->size())};
  37049. }
  37050. const Type &as_const = any_cast<const Type &>(container);
  37051. return iterator{as_const, static_cast<typename iterator::difference_type>(as_end * as_const.size())};
  37052. }
  37053. [[nodiscard]] static iterator insert([[maybe_unused]] any &container, [[maybe_unused]] const std::ptrdiff_t offset, [[maybe_unused]] meta_any &value) {
  37054. if constexpr(is_dynamic_sequence_container<Type>::value) {
  37055. if(auto *const cont = any_cast<Type>(&container); cont) {
  37056. // this abomination is necessary because only on macos value_type and const_reference are different types for std::vector<bool>
  37057. if(value.allow_cast<typename Type::const_reference>() || value.allow_cast<typename Type::value_type>()) {
  37058. const auto *element = value.try_cast<std::remove_reference_t<typename Type::const_reference>>();
  37059. const auto curr = cont->insert(cont->begin() + offset, element ? *element : value.cast<typename Type::value_type>());
  37060. return iterator{*cont, curr - cont->begin()};
  37061. }
  37062. }
  37063. }
  37064. return {};
  37065. }
  37066. [[nodiscard]] static iterator erase([[maybe_unused]] any &container, [[maybe_unused]] const std::ptrdiff_t offset) {
  37067. if constexpr(is_dynamic_sequence_container<Type>::value) {
  37068. if(auto *const cont = any_cast<Type>(&container); cont) {
  37069. const auto curr = cont->erase(cont->begin() + offset);
  37070. return iterator{*cont, curr - cont->begin()};
  37071. }
  37072. }
  37073. return {};
  37074. }
  37075. };
  37076. template<typename Type>
  37077. struct basic_meta_associative_container_traits {
  37078. using iterator = meta_associative_container::iterator;
  37079. using size_type = std::size_t;
  37080. static constexpr auto key_only = is_key_only_meta_associative_container<Type>::value;
  37081. [[nodiscard]] static size_type size(const any &container) ENTT_NOEXCEPT {
  37082. return any_cast<const Type &>(container).size();
  37083. }
  37084. [[nodiscard]] static bool clear(any &container) {
  37085. if(auto *const cont = any_cast<Type>(&container); cont) {
  37086. cont->clear();
  37087. return true;
  37088. }
  37089. return false;
  37090. }
  37091. [[nodiscard]] static iterator iter(any &container, const bool as_end) {
  37092. if(auto *const cont = any_cast<Type>(&container); cont) {
  37093. return iterator{std::integral_constant<bool, key_only>{}, as_end ? cont->end() : cont->begin()};
  37094. }
  37095. const auto &as_const = any_cast<const Type &>(container);
  37096. return iterator{std::integral_constant<bool, key_only>{}, as_end ? as_const.end() : as_const.begin()};
  37097. }
  37098. [[nodiscard]] static bool insert(any &container, meta_any &key, [[maybe_unused]] meta_any &value) {
  37099. auto *const cont = any_cast<Type>(&container);
  37100. if constexpr(is_key_only_meta_associative_container<Type>::value) {
  37101. return cont && key.allow_cast<const typename Type::key_type &>()
  37102. && cont->insert(key.cast<const typename Type::key_type &>()).second;
  37103. } else {
  37104. return cont && key.allow_cast<const typename Type::key_type &>() && value.allow_cast<const typename Type::mapped_type &>()
  37105. && cont->emplace(key.cast<const typename Type::key_type &>(), value.cast<const typename Type::mapped_type &>()).second;
  37106. }
  37107. }
  37108. [[nodiscard]] static bool erase(any &container, meta_any &key) {
  37109. auto *const cont = any_cast<Type>(&container);
  37110. return cont && key.allow_cast<const typename Type::key_type &>()
  37111. && (cont->erase(key.cast<const typename Type::key_type &>()) != cont->size());
  37112. }
  37113. [[nodiscard]] static iterator find(any &container, meta_any &key) {
  37114. if(key.allow_cast<const typename Type::key_type &>()) {
  37115. if(auto *const cont = any_cast<Type>(&container); cont) {
  37116. return iterator{std::integral_constant<bool, key_only>{}, cont->find(key.cast<const typename Type::key_type &>())};
  37117. }
  37118. return iterator{std::integral_constant<bool, key_only>{}, any_cast<const Type &>(container).find(key.cast<const typename Type::key_type &>())};
  37119. }
  37120. return {};
  37121. }
  37122. };
  37123. } // namespace internal
  37124. /**
  37125. * Internal details not to be documented.
  37126. * @endcond
  37127. */
  37128. /**
  37129. * @brief Meta sequence container traits for `std::vector`s of any type.
  37130. * @tparam Type The type of elements.
  37131. * @tparam Args Other arguments.
  37132. */
  37133. template<typename Type, typename... Args>
  37134. struct meta_sequence_container_traits<std::vector<Type, Args...>>
  37135. : internal::basic_meta_sequence_container_traits<std::vector<Type, Args...>> {};
  37136. /**
  37137. * @brief Meta sequence container traits for `std::array`s of any type.
  37138. * @tparam Type The type of elements.
  37139. * @tparam N The number of elements.
  37140. */
  37141. template<typename Type, auto N>
  37142. struct meta_sequence_container_traits<std::array<Type, N>>
  37143. : internal::basic_meta_sequence_container_traits<std::array<Type, N>> {};
  37144. /**
  37145. * @brief Meta associative container traits for `std::map`s of any type.
  37146. * @tparam Key The key type of elements.
  37147. * @tparam Value The value type of elements.
  37148. * @tparam Args Other arguments.
  37149. */
  37150. template<typename Key, typename Value, typename... Args>
  37151. struct meta_associative_container_traits<std::map<Key, Value, Args...>>
  37152. : internal::basic_meta_associative_container_traits<std::map<Key, Value, Args...>> {};
  37153. /**
  37154. * @brief Meta associative container traits for `std::unordered_map`s of any
  37155. * type.
  37156. * @tparam Key The key type of elements.
  37157. * @tparam Value The value type of elements.
  37158. * @tparam Args Other arguments.
  37159. */
  37160. template<typename Key, typename Value, typename... Args>
  37161. struct meta_associative_container_traits<std::unordered_map<Key, Value, Args...>>
  37162. : internal::basic_meta_associative_container_traits<std::unordered_map<Key, Value, Args...>> {};
  37163. /**
  37164. * @brief Meta associative container traits for `std::set`s of any type.
  37165. * @tparam Key The type of elements.
  37166. * @tparam Args Other arguments.
  37167. */
  37168. template<typename Key, typename... Args>
  37169. struct meta_associative_container_traits<std::set<Key, Args...>>
  37170. : internal::basic_meta_associative_container_traits<std::set<Key, Args...>> {};
  37171. /**
  37172. * @brief Meta associative container traits for `std::unordered_set`s of any
  37173. * type.
  37174. * @tparam Key The type of elements.
  37175. * @tparam Args Other arguments.
  37176. */
  37177. template<typename Key, typename... Args>
  37178. struct meta_associative_container_traits<std::unordered_set<Key, Args...>>
  37179. : internal::basic_meta_associative_container_traits<std::unordered_set<Key, Args...>> {};
  37180. /**
  37181. * @brief Meta associative container traits for `dense_map`s of any type.
  37182. * @tparam Key The key type of the elements.
  37183. * @tparam Type The value type of the elements.
  37184. * @tparam Args Other arguments.
  37185. */
  37186. template<typename Key, typename Type, typename... Args>
  37187. struct meta_associative_container_traits<dense_map<Key, Type, Args...>>
  37188. : internal::basic_meta_associative_container_traits<dense_map<Key, Type, Args...>> {};
  37189. /**
  37190. * @brief Meta associative container traits for `dense_set`s of any type.
  37191. * @tparam Type The value type of the elements.
  37192. * @tparam Args Other arguments.
  37193. */
  37194. template<typename Type, typename... Args>
  37195. struct meta_associative_container_traits<dense_set<Type, Args...>>
  37196. : internal::basic_meta_associative_container_traits<dense_set<Type, Args...>> {};
  37197. } // namespace entt
  37198. #endif
  37199. // #include "meta/ctx.hpp"
  37200. #ifndef ENTT_META_CTX_HPP
  37201. #define ENTT_META_CTX_HPP
  37202. // #include "../config/config.h"
  37203. // #include "../core/attribute.h"
  37204. namespace entt {
  37205. /**
  37206. * @cond TURN_OFF_DOXYGEN
  37207. * Internal details not to be documented.
  37208. */
  37209. namespace internal {
  37210. struct meta_type_node;
  37211. struct ENTT_API meta_context {
  37212. // we could use the lines below but VS2017 returns with an ICE if combined with ENTT_API despite the code being valid C++
  37213. // inline static meta_type_node *local = nullptr;
  37214. // inline static meta_type_node **global = &local;
  37215. [[nodiscard]] static meta_type_node *&local() ENTT_NOEXCEPT {
  37216. static meta_type_node *chain = nullptr;
  37217. return chain;
  37218. }
  37219. [[nodiscard]] static meta_type_node **&global() ENTT_NOEXCEPT {
  37220. static meta_type_node **chain = &local();
  37221. return chain;
  37222. }
  37223. };
  37224. } // namespace internal
  37225. /**
  37226. * Internal details not to be documented.
  37227. * @endcond
  37228. */
  37229. /*! @brief Opaque container for a meta context. */
  37230. struct meta_ctx {
  37231. /**
  37232. * @brief Binds the meta system to a given context.
  37233. * @param other A valid context to which to bind.
  37234. */
  37235. static void bind(meta_ctx other) ENTT_NOEXCEPT {
  37236. internal::meta_context::global() = other.ctx;
  37237. }
  37238. private:
  37239. internal::meta_type_node **ctx{&internal::meta_context::local()};
  37240. };
  37241. } // namespace entt
  37242. #endif
  37243. // #include "meta/factory.hpp"
  37244. #ifndef ENTT_META_FACTORY_HPP
  37245. #define ENTT_META_FACTORY_HPP
  37246. #include <algorithm>
  37247. #include <cstddef>
  37248. #include <functional>
  37249. #include <tuple>
  37250. #include <type_traits>
  37251. #include <utility>
  37252. // #include "../config/config.h"
  37253. // #include "../core/fwd.hpp"
  37254. // #include "../core/type_info.hpp"
  37255. // #include "../core/type_traits.hpp"
  37256. // #include "meta.hpp"
  37257. // #include "node.hpp"
  37258. // #include "policy.hpp"
  37259. #ifndef ENTT_META_POLICY_HPP
  37260. #define ENTT_META_POLICY_HPP
  37261. #include <type_traits>
  37262. namespace entt {
  37263. /*! @brief Empty class type used to request the _as ref_ policy. */
  37264. struct as_ref_t {
  37265. /**
  37266. * @cond TURN_OFF_DOXYGEN
  37267. * Internal details not to be documented.
  37268. */
  37269. template<typename Type>
  37270. static constexpr bool value = std::is_reference_v<Type> && !std::is_const_v<std::remove_reference_t<Type>>;
  37271. /**
  37272. * Internal details not to be documented.
  37273. * @endcond
  37274. */
  37275. };
  37276. /*! @brief Empty class type used to request the _as cref_ policy. */
  37277. struct as_cref_t {
  37278. /**
  37279. * @cond TURN_OFF_DOXYGEN
  37280. * Internal details not to be documented.
  37281. */
  37282. template<typename Type>
  37283. static constexpr bool value = std::is_reference_v<Type>;
  37284. /**
  37285. * Internal details not to be documented.
  37286. * @endcond
  37287. */
  37288. };
  37289. /*! @brief Empty class type used to request the _as-is_ policy. */
  37290. struct as_is_t {
  37291. /**
  37292. * @cond TURN_OFF_DOXYGEN
  37293. * Internal details not to be documented.
  37294. */
  37295. template<typename>
  37296. static constexpr bool value = true;
  37297. /**
  37298. * Internal details not to be documented.
  37299. * @endcond
  37300. */
  37301. };
  37302. /*! @brief Empty class type used to request the _as void_ policy. */
  37303. struct as_void_t {
  37304. /**
  37305. * @cond TURN_OFF_DOXYGEN
  37306. * Internal details not to be documented.
  37307. */
  37308. template<typename>
  37309. static constexpr bool value = true;
  37310. /**
  37311. * Internal details not to be documented.
  37312. * @endcond
  37313. */
  37314. };
  37315. } // namespace entt
  37316. #endif
  37317. // #include "range.hpp"
  37318. // #include "utility.hpp"
  37319. #ifndef ENTT_META_UTILITY_HPP
  37320. #define ENTT_META_UTILITY_HPP
  37321. #include <cstddef>
  37322. #include <functional>
  37323. #include <type_traits>
  37324. #include <utility>
  37325. // #include "../config/config.h"
  37326. // #include "../core/type_traits.hpp"
  37327. // #include "meta.hpp"
  37328. // #include "node.hpp"
  37329. // #include "policy.hpp"
  37330. namespace entt {
  37331. /*! @brief Primary template isn't defined on purpose. */
  37332. template<typename, typename>
  37333. struct meta_function_descriptor;
  37334. /**
  37335. * @brief Meta function descriptor.
  37336. * @tparam Type Reflected type to which the meta function is associated.
  37337. * @tparam Ret Function return type.
  37338. * @tparam Class Actual owner of the member function.
  37339. * @tparam Args Function arguments.
  37340. */
  37341. template<typename Type, typename Ret, typename Class, typename... Args>
  37342. struct meta_function_descriptor<Type, Ret (Class::*)(Args...) const> {
  37343. /*! @brief Meta function return type. */
  37344. using return_type = Ret;
  37345. /*! @brief Meta function arguments. */
  37346. using args_type = std::conditional_t<std::is_base_of_v<Class, Type>, type_list<Args...>, type_list<const Class &, Args...>>;
  37347. /*! @brief True if the meta function is const, false otherwise. */
  37348. static constexpr auto is_const = true;
  37349. /*! @brief True if the meta function is static, false otherwise. */
  37350. static constexpr auto is_static = !std::is_base_of_v<Class, Type>;
  37351. };
  37352. /**
  37353. * @brief Meta function descriptor.
  37354. * @tparam Type Reflected type to which the meta function is associated.
  37355. * @tparam Ret Function return type.
  37356. * @tparam Class Actual owner of the member function.
  37357. * @tparam Args Function arguments.
  37358. */
  37359. template<typename Type, typename Ret, typename Class, typename... Args>
  37360. struct meta_function_descriptor<Type, Ret (Class::*)(Args...)> {
  37361. /*! @brief Meta function return type. */
  37362. using return_type = Ret;
  37363. /*! @brief Meta function arguments. */
  37364. using args_type = std::conditional_t<std::is_base_of_v<Class, Type>, type_list<Args...>, type_list<Class &, Args...>>;
  37365. /*! @brief True if the meta function is const, false otherwise. */
  37366. static constexpr auto is_const = false;
  37367. /*! @brief True if the meta function is static, false otherwise. */
  37368. static constexpr auto is_static = !std::is_base_of_v<Class, Type>;
  37369. };
  37370. /**
  37371. * @brief Meta function descriptor.
  37372. * @tparam Type Reflected type to which the meta data is associated.
  37373. * @tparam Class Actual owner of the data member.
  37374. * @tparam Ret Data member type.
  37375. */
  37376. template<typename Type, typename Ret, typename Class>
  37377. struct meta_function_descriptor<Type, Ret Class::*> {
  37378. /*! @brief Meta data return type. */
  37379. using return_type = Ret &;
  37380. /*! @brief Meta data arguments. */
  37381. using args_type = std::conditional_t<std::is_base_of_v<Class, Type>, type_list<>, type_list<Class &>>;
  37382. /*! @brief True if the meta data is const, false otherwise. */
  37383. static constexpr auto is_const = false;
  37384. /*! @brief True if the meta data is static, false otherwise. */
  37385. static constexpr auto is_static = !std::is_base_of_v<Class, Type>;
  37386. };
  37387. /**
  37388. * @brief Meta function descriptor.
  37389. * @tparam Type Reflected type to which the meta function is associated.
  37390. * @tparam Ret Function return type.
  37391. * @tparam MaybeType First function argument.
  37392. * @tparam Args Other function arguments.
  37393. */
  37394. template<typename Type, typename Ret, typename MaybeType, typename... Args>
  37395. struct meta_function_descriptor<Type, Ret (*)(MaybeType, Args...)> {
  37396. /*! @brief Meta function return type. */
  37397. using return_type = Ret;
  37398. /*! @brief Meta function arguments. */
  37399. using args_type = std::conditional_t<std::is_base_of_v<std::remove_cv_t<std::remove_reference_t<MaybeType>>, Type>, type_list<Args...>, type_list<MaybeType, Args...>>;
  37400. /*! @brief True if the meta function is const, false otherwise. */
  37401. static constexpr auto is_const = std::is_base_of_v<std::remove_cv_t<std::remove_reference_t<MaybeType>>, Type> && std::is_const_v<std::remove_reference_t<MaybeType>>;
  37402. /*! @brief True if the meta function is static, false otherwise. */
  37403. static constexpr auto is_static = !std::is_base_of_v<std::remove_cv_t<std::remove_reference_t<MaybeType>>, Type>;
  37404. };
  37405. /**
  37406. * @brief Meta function descriptor.
  37407. * @tparam Type Reflected type to which the meta function is associated.
  37408. * @tparam Ret Function return type.
  37409. */
  37410. template<typename Type, typename Ret>
  37411. struct meta_function_descriptor<Type, Ret (*)()> {
  37412. /*! @brief Meta function return type. */
  37413. using return_type = Ret;
  37414. /*! @brief Meta function arguments. */
  37415. using args_type = type_list<>;
  37416. /*! @brief True if the meta function is const, false otherwise. */
  37417. static constexpr auto is_const = false;
  37418. /*! @brief True if the meta function is static, false otherwise. */
  37419. static constexpr auto is_static = true;
  37420. };
  37421. /**
  37422. * @brief Meta function helper.
  37423. *
  37424. * Converts a function type to be associated with a reflected type into its meta
  37425. * function descriptor.
  37426. *
  37427. * @tparam Type Reflected type to which the meta function is associated.
  37428. * @tparam Candidate The actual function to associate with the reflected type.
  37429. */
  37430. template<typename Type, typename Candidate>
  37431. class meta_function_helper {
  37432. template<typename Ret, typename... Args, typename Class>
  37433. static constexpr meta_function_descriptor<Type, Ret (Class::*)(Args...) const> get_rid_of_noexcept(Ret (Class::*)(Args...) const);
  37434. template<typename Ret, typename... Args, typename Class>
  37435. static constexpr meta_function_descriptor<Type, Ret (Class::*)(Args...)> get_rid_of_noexcept(Ret (Class::*)(Args...));
  37436. template<typename Ret, typename Class>
  37437. static constexpr meta_function_descriptor<Type, Ret Class::*> get_rid_of_noexcept(Ret Class::*);
  37438. template<typename Ret, typename... Args>
  37439. static constexpr meta_function_descriptor<Type, Ret (*)(Args...)> get_rid_of_noexcept(Ret (*)(Args...));
  37440. template<typename Class>
  37441. static constexpr meta_function_descriptor<Class, decltype(&Class::operator())> get_rid_of_noexcept(Class);
  37442. public:
  37443. /*! @brief The meta function descriptor of the given function. */
  37444. using type = decltype(get_rid_of_noexcept(std::declval<Candidate>()));
  37445. };
  37446. /**
  37447. * @brief Helper type.
  37448. * @tparam Type Reflected type to which the meta function is associated.
  37449. * @tparam Candidate The actual function to associate with the reflected type.
  37450. */
  37451. template<typename Type, typename Candidate>
  37452. using meta_function_helper_t = typename meta_function_helper<Type, Candidate>::type;
  37453. /**
  37454. * @brief Wraps a value depending on the given policy.
  37455. * @tparam Policy Optional policy (no policy set by default).
  37456. * @tparam Type Type of value to wrap.
  37457. * @param value Value to wrap.
  37458. * @return A meta any containing the returned value, if any.
  37459. */
  37460. template<typename Policy = as_is_t, typename Type>
  37461. meta_any meta_dispatch([[maybe_unused]] Type &&value) {
  37462. if constexpr(std::is_same_v<Policy, as_void_t>) {
  37463. return meta_any{std::in_place_type<void>};
  37464. } else if constexpr(std::is_same_v<Policy, as_ref_t>) {
  37465. return meta_any{std::in_place_type<Type>, std::forward<Type>(value)};
  37466. } else if constexpr(std::is_same_v<Policy, as_cref_t>) {
  37467. static_assert(std::is_lvalue_reference_v<Type>, "Invalid type");
  37468. return meta_any{std::in_place_type<const std::remove_reference_t<Type> &>, std::as_const(value)};
  37469. } else {
  37470. static_assert(std::is_same_v<Policy, as_is_t>, "Policy not supported");
  37471. return meta_any{std::forward<Type>(value)};
  37472. }
  37473. }
  37474. /**
  37475. * @brief Returns the meta type of the i-th element of a list of arguments.
  37476. * @tparam Type Type list of the actual types of arguments.
  37477. * @return The meta type of the i-th element of the list of arguments.
  37478. */
  37479. template<typename Type>
  37480. [[nodiscard]] static meta_type meta_arg(const std::size_t index) ENTT_NOEXCEPT {
  37481. return internal::meta_arg_node(Type{}, index);
  37482. }
  37483. /**
  37484. * @brief Sets the value of a given variable.
  37485. * @tparam Type Reflected type to which the variable is associated.
  37486. * @tparam Data The actual variable to set.
  37487. * @param instance An opaque instance of the underlying type, if required.
  37488. * @param value Parameter to use to set the variable.
  37489. * @return True in case of success, false otherwise.
  37490. */
  37491. template<typename Type, auto Data>
  37492. [[nodiscard]] bool meta_setter([[maybe_unused]] meta_handle instance, [[maybe_unused]] meta_any value) {
  37493. if constexpr(!std::is_same_v<decltype(Data), Type> && !std::is_same_v<decltype(Data), std::nullptr_t>) {
  37494. if constexpr(std::is_member_function_pointer_v<decltype(Data)> || std::is_function_v<std::remove_reference_t<std::remove_pointer_t<decltype(Data)>>>) {
  37495. using descriptor = meta_function_helper_t<Type, decltype(Data)>;
  37496. using data_type = type_list_element_t<descriptor::is_static, typename descriptor::args_type>;
  37497. if(auto *const clazz = instance->try_cast<Type>(); clazz && value.allow_cast<data_type>()) {
  37498. std::invoke(Data, *clazz, value.cast<data_type>());
  37499. return true;
  37500. }
  37501. } else if constexpr(std::is_member_object_pointer_v<decltype(Data)>) {
  37502. using data_type = std::remove_reference_t<typename meta_function_helper_t<Type, decltype(Data)>::return_type>;
  37503. if constexpr(!std::is_array_v<data_type> && !std::is_const_v<data_type>) {
  37504. if(auto *const clazz = instance->try_cast<Type>(); clazz && value.allow_cast<data_type>()) {
  37505. std::invoke(Data, *clazz) = value.cast<data_type>();
  37506. return true;
  37507. }
  37508. }
  37509. } else {
  37510. using data_type = std::remove_reference_t<decltype(*Data)>;
  37511. if constexpr(!std::is_array_v<data_type> && !std::is_const_v<data_type>) {
  37512. if(value.allow_cast<data_type>()) {
  37513. *Data = value.cast<data_type>();
  37514. return true;
  37515. }
  37516. }
  37517. }
  37518. }
  37519. return false;
  37520. }
  37521. /**
  37522. * @brief Gets the value of a given variable.
  37523. * @tparam Type Reflected type to which the variable is associated.
  37524. * @tparam Data The actual variable to get.
  37525. * @tparam Policy Optional policy (no policy set by default).
  37526. * @param instance An opaque instance of the underlying type, if required.
  37527. * @return A meta any containing the value of the underlying variable.
  37528. */
  37529. template<typename Type, auto Data, typename Policy = as_is_t>
  37530. [[nodiscard]] meta_any meta_getter([[maybe_unused]] meta_handle instance) {
  37531. if constexpr(std::is_member_pointer_v<decltype(Data)> || std::is_function_v<std::remove_reference_t<std::remove_pointer_t<decltype(Data)>>>) {
  37532. if constexpr(!std::is_array_v<std::remove_cv_t<std::remove_reference_t<std::invoke_result_t<decltype(Data), Type &>>>>) {
  37533. if constexpr(std::is_invocable_v<decltype(Data), Type &>) {
  37534. if(auto *clazz = instance->try_cast<Type>(); clazz) {
  37535. return meta_dispatch<Policy>(std::invoke(Data, *clazz));
  37536. }
  37537. }
  37538. if constexpr(std::is_invocable_v<decltype(Data), const Type &>) {
  37539. if(auto *fallback = instance->try_cast<const Type>(); fallback) {
  37540. return meta_dispatch<Policy>(std::invoke(Data, *fallback));
  37541. }
  37542. }
  37543. }
  37544. return meta_any{};
  37545. } else if constexpr(std::is_pointer_v<decltype(Data)>) {
  37546. if constexpr(std::is_array_v<std::remove_pointer_t<decltype(Data)>>) {
  37547. return meta_any{};
  37548. } else {
  37549. return meta_dispatch<Policy>(*Data);
  37550. }
  37551. } else {
  37552. return meta_dispatch<Policy>(Data);
  37553. }
  37554. }
  37555. /**
  37556. * @cond TURN_OFF_DOXYGEN
  37557. * Internal details not to be documented.
  37558. */
  37559. namespace internal {
  37560. template<typename Type, typename Policy, typename Candidate, typename... Args>
  37561. [[nodiscard]] meta_any meta_invoke_with_args(Candidate &&candidate, Args &&...args) {
  37562. if constexpr(std::is_same_v<std::invoke_result_t<decltype(candidate), Args...>, void>) {
  37563. std::invoke(candidate, args...);
  37564. return meta_any{std::in_place_type<void>};
  37565. } else {
  37566. return meta_dispatch<Policy>(std::invoke(candidate, args...));
  37567. }
  37568. }
  37569. template<typename Type, typename Policy, typename Candidate, std::size_t... Index>
  37570. [[nodiscard]] meta_any meta_invoke([[maybe_unused]] meta_handle instance, Candidate &&candidate, [[maybe_unused]] meta_any *args, std::index_sequence<Index...>) {
  37571. using descriptor = meta_function_helper_t<Type, std::remove_reference_t<Candidate>>;
  37572. if constexpr(std::is_invocable_v<std::remove_reference_t<Candidate>, const Type &, type_list_element_t<Index, typename descriptor::args_type>...>) {
  37573. if(const auto *const clazz = instance->try_cast<const Type>(); clazz && ((args + Index)->allow_cast<type_list_element_t<Index, typename descriptor::args_type>>() && ...)) {
  37574. return meta_invoke_with_args<Type, Policy>(std::forward<Candidate>(candidate), *clazz, (args + Index)->cast<type_list_element_t<Index, typename descriptor::args_type>>()...);
  37575. }
  37576. } else if constexpr(std::is_invocable_v<std::remove_reference_t<Candidate>, Type &, type_list_element_t<Index, typename descriptor::args_type>...>) {
  37577. if(auto *const clazz = instance->try_cast<Type>(); clazz && ((args + Index)->allow_cast<type_list_element_t<Index, typename descriptor::args_type>>() && ...)) {
  37578. return meta_invoke_with_args<Type, Policy>(std::forward<Candidate>(candidate), *clazz, (args + Index)->cast<type_list_element_t<Index, typename descriptor::args_type>>()...);
  37579. }
  37580. } else {
  37581. if(((args + Index)->allow_cast<type_list_element_t<Index, typename descriptor::args_type>>() && ...)) {
  37582. return meta_invoke_with_args<Type, Policy>(std::forward<Candidate>(candidate), (args + Index)->cast<type_list_element_t<Index, typename descriptor::args_type>>()...);
  37583. }
  37584. }
  37585. return meta_any{};
  37586. }
  37587. template<typename Type, typename... Args, std::size_t... Index>
  37588. [[nodiscard]] meta_any meta_construct(meta_any *const args, std::index_sequence<Index...>) {
  37589. if(((args + Index)->allow_cast<Args>() && ...)) {
  37590. return meta_any{std::in_place_type<Type>, (args + Index)->cast<Args>()...};
  37591. }
  37592. return meta_any{};
  37593. }
  37594. } // namespace internal
  37595. /**
  37596. * Internal details not to be documented.
  37597. * @endcond
  37598. */
  37599. /**
  37600. * @brief Tries to _invoke_ an object given a list of erased parameters.
  37601. * @tparam Type Reflected type to which the object to _invoke_ is associated.
  37602. * @tparam Policy Optional policy (no policy set by default).
  37603. * @tparam Candidate The type of the actual object to _invoke_.
  37604. * @param instance An opaque instance of the underlying type, if required.
  37605. * @param candidate The actual object to _invoke_.
  37606. * @param args Parameters to use to _invoke_ the object.
  37607. * @return A meta any containing the returned value, if any.
  37608. */
  37609. template<typename Type, typename Policy = as_is_t, typename Candidate>
  37610. [[nodiscard]] meta_any meta_invoke([[maybe_unused]] meta_handle instance, Candidate &&candidate, [[maybe_unused]] meta_any *const args) {
  37611. return internal::meta_invoke<Type, Policy>(std::move(instance), std::forward<Candidate>(candidate), args, std::make_index_sequence<meta_function_helper_t<Type, std::remove_reference_t<Candidate>>::args_type::size>{});
  37612. }
  37613. /**
  37614. * @brief Tries to invoke a function given a list of erased parameters.
  37615. * @tparam Type Reflected type to which the function is associated.
  37616. * @tparam Candidate The actual function to invoke.
  37617. * @tparam Policy Optional policy (no policy set by default).
  37618. * @param instance An opaque instance of the underlying type, if required.
  37619. * @param args Parameters to use to invoke the function.
  37620. * @return A meta any containing the returned value, if any.
  37621. */
  37622. template<typename Type, auto Candidate, typename Policy = as_is_t>
  37623. [[nodiscard]] meta_any meta_invoke(meta_handle instance, meta_any *const args) {
  37624. return internal::meta_invoke<Type, Policy>(std::move(instance), Candidate, args, std::make_index_sequence<meta_function_helper_t<Type, std::remove_reference_t<decltype(Candidate)>>::args_type::size>{});
  37625. }
  37626. /**
  37627. * @brief Tries to construct an instance given a list of erased parameters.
  37628. * @tparam Type Actual type of the instance to construct.
  37629. * @tparam Args Types of arguments expected.
  37630. * @param args Parameters to use to construct the instance.
  37631. * @return A meta any containing the new instance, if any.
  37632. */
  37633. template<typename Type, typename... Args>
  37634. [[nodiscard]] meta_any meta_construct(meta_any *const args) {
  37635. return internal::meta_construct<Type, Args...>(args, std::index_sequence_for<Args...>{});
  37636. }
  37637. /**
  37638. * @brief Tries to construct an instance given a list of erased parameters.
  37639. * @tparam Type Reflected type to which the object to _invoke_ is associated.
  37640. * @tparam Policy Optional policy (no policy set by default).
  37641. * @tparam Candidate The type of the actual object to _invoke_.
  37642. * @param args Parameters to use to _invoke_ the object.
  37643. * @param candidate The actual object to _invoke_.
  37644. * @return A meta any containing the returned value, if any.
  37645. */
  37646. template<typename Type, typename Policy = as_is_t, typename Candidate>
  37647. [[nodiscard]] meta_any meta_construct(Candidate &&candidate, meta_any *const args) {
  37648. if constexpr(meta_function_helper_t<Type, Candidate>::is_static) {
  37649. return internal::meta_invoke<Type, Policy>({}, std::forward<Candidate>(candidate), args, std::make_index_sequence<meta_function_helper_t<Type, std::remove_reference_t<Candidate>>::args_type::size>{});
  37650. } else {
  37651. 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>{});
  37652. }
  37653. }
  37654. /**
  37655. * @brief Tries to construct an instance given a list of erased parameters.
  37656. * @tparam Type Reflected type to which the function is associated.
  37657. * @tparam Candidate The actual function to invoke.
  37658. * @tparam Policy Optional policy (no policy set by default).
  37659. * @param args Parameters to use to invoke the function.
  37660. * @return A meta any containing the returned value, if any.
  37661. */
  37662. template<typename Type, auto Candidate, typename Policy = as_is_t>
  37663. [[nodiscard]] meta_any meta_construct(meta_any *const args) {
  37664. return meta_construct<Type, Policy>(Candidate, args);
  37665. }
  37666. } // namespace entt
  37667. #endif
  37668. namespace entt {
  37669. /**
  37670. * @brief Meta factory to be used for reflection purposes.
  37671. *
  37672. * The meta factory is an utility class used to reflect types, data members and
  37673. * functions of all sorts. This class ensures that the underlying web of types
  37674. * is built correctly and performs some checks in debug mode to ensure that
  37675. * there are no subtle errors at runtime.
  37676. */
  37677. template<typename...>
  37678. class meta_factory;
  37679. /**
  37680. * @brief Extended meta factory to be used for reflection purposes.
  37681. * @tparam Type Reflected type for which the factory was created.
  37682. * @tparam Spec Property specialization pack used to disambiguate overloads.
  37683. */
  37684. template<typename Type, typename... Spec>
  37685. class meta_factory<Type, Spec...>: public meta_factory<Type> {
  37686. void link_prop_if_required(internal::meta_prop_node &node) ENTT_NOEXCEPT {
  37687. if(meta_range<internal::meta_prop_node *, internal::meta_prop_node> range{*ref}; std::find(range.cbegin(), range.cend(), &node) == range.cend()) {
  37688. ENTT_ASSERT(std::find_if(range.cbegin(), range.cend(), [&node](const auto *curr) { return curr->id == node.id; }) == range.cend(), "Duplicate identifier");
  37689. node.next = *ref;
  37690. *ref = &node;
  37691. }
  37692. }
  37693. template<std::size_t Step = 0, typename... Property, typename... Other>
  37694. void unroll(choice_t<2>, std::tuple<Property...> property, Other &&...other) ENTT_NOEXCEPT {
  37695. std::apply([this](auto &&...curr) { (this->unroll<Step>(choice<2>, std::forward<Property>(curr)...)); }, property);
  37696. unroll<Step + sizeof...(Property)>(choice<2>, std::forward<Other>(other)...);
  37697. }
  37698. template<std::size_t Step = 0, typename... Property, typename... Other>
  37699. void unroll(choice_t<1>, std::pair<Property...> property, Other &&...other) ENTT_NOEXCEPT {
  37700. assign<Step>(std::move(property.first), std::move(property.second));
  37701. unroll<Step + 1>(choice<2>, std::forward<Other>(other)...);
  37702. }
  37703. template<std::size_t Step = 0, typename Property, typename... Other>
  37704. void unroll(choice_t<0>, Property &&property, Other &&...other) ENTT_NOEXCEPT {
  37705. assign<Step>(std::forward<Property>(property));
  37706. unroll<Step + 1>(choice<2>, std::forward<Other>(other)...);
  37707. }
  37708. template<std::size_t>
  37709. void unroll(choice_t<0>) ENTT_NOEXCEPT {}
  37710. template<std::size_t = 0>
  37711. void assign(meta_any key, meta_any value = {}) {
  37712. static meta_any property[2u]{};
  37713. static internal::meta_prop_node node{
  37714. nullptr,
  37715. property[0u],
  37716. property[1u]
  37717. // tricks clang-format
  37718. };
  37719. property[0u] = std::move(key);
  37720. property[1u] = std::move(value);
  37721. link_prop_if_required(node);
  37722. }
  37723. public:
  37724. /**
  37725. * @brief Constructs an extended factory from a given node.
  37726. * @param target The underlying node to which to assign the properties.
  37727. */
  37728. meta_factory(internal::meta_prop_node **target) ENTT_NOEXCEPT
  37729. : ref{target} {}
  37730. /**
  37731. * @brief Assigns a property to the last meta object created.
  37732. *
  37733. * Both the key and the value (if any) must be at least copy constructible.
  37734. *
  37735. * @tparam PropertyOrKey Type of the property or property key.
  37736. * @tparam Value Optional type of the property value.
  37737. * @param property_or_key Property or property key.
  37738. * @param value Optional property value.
  37739. * @return A meta factory for the parent type.
  37740. */
  37741. template<typename PropertyOrKey, typename... Value>
  37742. meta_factory<Type> prop(PropertyOrKey &&property_or_key, Value &&...value) {
  37743. if constexpr(sizeof...(Value) == 0) {
  37744. unroll(choice<2>, std::forward<PropertyOrKey>(property_or_key));
  37745. } else {
  37746. assign(std::forward<PropertyOrKey>(property_or_key), std::forward<Value>(value)...);
  37747. }
  37748. return {};
  37749. }
  37750. /**
  37751. * @brief Assigns properties to the last meta object created.
  37752. *
  37753. * Both key and value (if any) must be at least copy constructible.
  37754. *
  37755. * @tparam Property Types of the properties.
  37756. * @param property Properties to assign to the last meta object created.
  37757. * @return A meta factory for the parent type.
  37758. */
  37759. template<typename... Property>
  37760. meta_factory<Type> props(Property... property) {
  37761. unroll(choice<2>, std::forward<Property>(property)...);
  37762. return {};
  37763. }
  37764. private:
  37765. internal::meta_prop_node **ref;
  37766. };
  37767. /**
  37768. * @brief Basic meta factory to be used for reflection purposes.
  37769. * @tparam Type Reflected type for which the factory was created.
  37770. */
  37771. template<typename Type>
  37772. class meta_factory<Type> {
  37773. void link_base_if_required(internal::meta_base_node &node) ENTT_NOEXCEPT {
  37774. if(meta_range<internal::meta_base_node *, internal::meta_base_node> range{owner->base}; std::find(range.cbegin(), range.cend(), &node) == range.cend()) {
  37775. node.next = owner->base;
  37776. owner->base = &node;
  37777. }
  37778. }
  37779. void link_conv_if_required(internal::meta_conv_node &node) ENTT_NOEXCEPT {
  37780. if(meta_range<internal::meta_conv_node *, internal::meta_conv_node> range{owner->conv}; std::find(range.cbegin(), range.cend(), &node) == range.cend()) {
  37781. node.next = owner->conv;
  37782. owner->conv = &node;
  37783. }
  37784. }
  37785. void link_ctor_if_required(internal::meta_ctor_node &node) ENTT_NOEXCEPT {
  37786. if(meta_range<internal::meta_ctor_node *, internal::meta_ctor_node> range{owner->ctor}; std::find(range.cbegin(), range.cend(), &node) == range.cend()) {
  37787. node.next = owner->ctor;
  37788. owner->ctor = &node;
  37789. }
  37790. }
  37791. void link_data_if_required(const id_type id, internal::meta_data_node &node) ENTT_NOEXCEPT {
  37792. meta_range<internal::meta_data_node *, internal::meta_data_node> range{owner->data};
  37793. ENTT_ASSERT(std::find_if(range.cbegin(), range.cend(), [id, &node](const auto *curr) { return curr != &node && curr->id == id; }) == range.cend(), "Duplicate identifier");
  37794. node.id = id;
  37795. if(std::find(range.cbegin(), range.cend(), &node) == range.cend()) {
  37796. node.next = owner->data;
  37797. owner->data = &node;
  37798. }
  37799. }
  37800. void link_func_if_required(const id_type id, internal::meta_func_node &node) ENTT_NOEXCEPT {
  37801. node.id = id;
  37802. if(meta_range<internal::meta_func_node *, internal::meta_func_node> range{owner->func}; std::find(range.cbegin(), range.cend(), &node) == range.cend()) {
  37803. node.next = owner->func;
  37804. owner->func = &node;
  37805. }
  37806. }
  37807. template<typename Setter, auto Getter, typename Policy, std::size_t... Index>
  37808. auto data(const id_type id, std::index_sequence<Index...>) ENTT_NOEXCEPT {
  37809. using data_type = std::invoke_result_t<decltype(Getter), Type &>;
  37810. using args_type = type_list<typename meta_function_helper_t<Type, decltype(value_list_element_v<Index, Setter>)>::args_type...>;
  37811. static_assert(Policy::template value<data_type>, "Invalid return type for the given policy");
  37812. static internal::meta_data_node node{
  37813. {},
  37814. /* this is never static */
  37815. (std::is_member_object_pointer_v<decltype(value_list_element_v<Index, Setter>)> && ... && std::is_const_v<std::remove_reference_t<data_type>>) ? internal::meta_traits::is_const : internal::meta_traits::is_none,
  37816. nullptr,
  37817. nullptr,
  37818. Setter::size,
  37819. internal::meta_node<std::remove_cv_t<std::remove_reference_t<data_type>>>::resolve(),
  37820. &meta_arg<type_list<type_list_element_t<type_list_element_t<Index, args_type>::size != 1u, type_list_element_t<Index, args_type>>...>>,
  37821. [](meta_handle instance, meta_any value) -> bool { return (meta_setter<Type, value_list_element_v<Index, Setter>>(*instance.operator->(), value.as_ref()) || ...); },
  37822. &meta_getter<Type, Getter, Policy>
  37823. // tricks clang-format
  37824. };
  37825. link_data_if_required(id, node);
  37826. return meta_factory<Type, Setter, std::integral_constant<decltype(Getter), Getter>>{&node.prop};
  37827. }
  37828. public:
  37829. /*! @brief Default constructor. */
  37830. meta_factory() ENTT_NOEXCEPT
  37831. : owner{internal::meta_node<Type>::resolve()} {}
  37832. /**
  37833. * @brief Makes a meta type _searchable_.
  37834. * @param id Optional unique identifier.
  37835. * @return An extended meta factory for the given type.
  37836. */
  37837. auto type(const id_type id = type_hash<Type>::value()) ENTT_NOEXCEPT {
  37838. meta_range<internal::meta_type_node *, internal::meta_type_node> range{*internal::meta_context::global()};
  37839. ENTT_ASSERT(std::find_if(range.cbegin(), range.cend(), [id, this](const auto *curr) { return curr != owner && curr->id == id; }) == range.cend(), "Duplicate identifier");
  37840. owner->id = id;
  37841. if(std::find(range.cbegin(), range.cend(), owner) == range.cend()) {
  37842. owner->next = *internal::meta_context::global();
  37843. *internal::meta_context::global() = owner;
  37844. }
  37845. return meta_factory<Type, Type>{&owner->prop};
  37846. }
  37847. /**
  37848. * @brief Assigns a meta base to a meta type.
  37849. *
  37850. * A reflected base class must be a real base class of the reflected type.
  37851. *
  37852. * @tparam Base Type of the base class to assign to the meta type.
  37853. * @return A meta factory for the parent type.
  37854. */
  37855. template<typename Base>
  37856. auto base() ENTT_NOEXCEPT {
  37857. static_assert(!std::is_same_v<Type, Base> && std::is_base_of_v<Base, Type>, "Invalid base type");
  37858. static internal::meta_base_node node{
  37859. nullptr,
  37860. internal::meta_node<Base>::resolve(),
  37861. [](meta_any other) ENTT_NOEXCEPT -> meta_any {
  37862. if(auto *ptr = other.data(); ptr) {
  37863. return forward_as_meta(*static_cast<Base *>(static_cast<Type *>(ptr)));
  37864. }
  37865. return forward_as_meta(*static_cast<const Base *>(static_cast<const Type *>(std::as_const(other).data())));
  37866. }
  37867. // tricks clang-format
  37868. };
  37869. link_base_if_required(node);
  37870. return meta_factory<Type>{};
  37871. }
  37872. /**
  37873. * @brief Assigns a meta conversion function to a meta type.
  37874. *
  37875. * Conversion functions can be either free functions or member
  37876. * functions.<br/>
  37877. * In case of free functions, they must accept a const reference to an
  37878. * instance of the parent type as an argument. In case of member functions,
  37879. * they should have no arguments at all.
  37880. *
  37881. * @tparam Candidate The actual function to use for the conversion.
  37882. * @return A meta factory for the parent type.
  37883. */
  37884. template<auto Candidate>
  37885. auto conv() ENTT_NOEXCEPT {
  37886. static internal::meta_conv_node node{
  37887. nullptr,
  37888. internal::meta_node<std::remove_cv_t<std::remove_reference_t<std::invoke_result_t<decltype(Candidate), Type &>>>>::resolve(),
  37889. [](const meta_any &instance) -> meta_any {
  37890. return forward_as_meta(std::invoke(Candidate, *static_cast<const Type *>(instance.data())));
  37891. }
  37892. // tricks clang-format
  37893. };
  37894. link_conv_if_required(node);
  37895. return meta_factory<Type>{};
  37896. }
  37897. /**
  37898. * @brief Assigns a meta conversion function to a meta type.
  37899. *
  37900. * The given type must be such that an instance of the reflected type can be
  37901. * converted to it.
  37902. *
  37903. * @tparam To Type of the conversion function to assign to the meta type.
  37904. * @return A meta factory for the parent type.
  37905. */
  37906. template<typename To>
  37907. auto conv() ENTT_NOEXCEPT {
  37908. static internal::meta_conv_node node{
  37909. nullptr,
  37910. internal::meta_node<std::remove_cv_t<std::remove_reference_t<To>>>::resolve(),
  37911. [](const meta_any &instance) -> meta_any { return forward_as_meta(static_cast<To>(*static_cast<const Type *>(instance.data()))); }
  37912. // tricks clang-format
  37913. };
  37914. link_conv_if_required(node);
  37915. return meta_factory<Type>{};
  37916. }
  37917. /**
  37918. * @brief Assigns a meta constructor to a meta type.
  37919. *
  37920. * Both member functions and free function can be assigned to meta types in
  37921. * the role of constructors. All that is required is that they return an
  37922. * instance of the underlying type.<br/>
  37923. * From a client's point of view, nothing changes if a constructor of a meta
  37924. * type is a built-in one or not.
  37925. *
  37926. * @tparam Candidate The actual function to use as a constructor.
  37927. * @tparam Policy Optional policy (no policy set by default).
  37928. * @return An extended meta factory for the parent type.
  37929. */
  37930. template<auto Candidate, typename Policy = as_is_t>
  37931. auto ctor() ENTT_NOEXCEPT {
  37932. using descriptor = meta_function_helper_t<Type, decltype(Candidate)>;
  37933. static_assert(Policy::template value<typename descriptor::return_type>, "Invalid return type for the given policy");
  37934. static_assert(std::is_same_v<std::remove_cv_t<std::remove_reference_t<typename descriptor::return_type>>, Type>, "The function doesn't return an object of the required type");
  37935. static internal::meta_ctor_node node{
  37936. nullptr,
  37937. descriptor::args_type::size,
  37938. &meta_arg<typename descriptor::args_type>,
  37939. &meta_construct<Type, Candidate, Policy>
  37940. // tricks clang-format
  37941. };
  37942. link_ctor_if_required(node);
  37943. return meta_factory<Type>{};
  37944. }
  37945. /**
  37946. * @brief Assigns a meta constructor to a meta type.
  37947. *
  37948. * A meta constructor is uniquely identified by the types of its arguments
  37949. * and is such that there exists an actual constructor of the underlying
  37950. * type that can be invoked with parameters whose types are those given.
  37951. *
  37952. * @tparam Args Types of arguments to use to construct an instance.
  37953. * @return An extended meta factory for the parent type.
  37954. */
  37955. template<typename... Args>
  37956. auto ctor() ENTT_NOEXCEPT {
  37957. using descriptor = meta_function_helper_t<Type, Type (*)(Args...)>;
  37958. static internal::meta_ctor_node node{
  37959. nullptr,
  37960. descriptor::args_type::size,
  37961. &meta_arg<typename descriptor::args_type>,
  37962. &meta_construct<Type, Args...>
  37963. // tricks clang-format
  37964. };
  37965. link_ctor_if_required(node);
  37966. return meta_factory<Type>{};
  37967. }
  37968. /**
  37969. * @brief Assigns a meta destructor to a meta type.
  37970. *
  37971. * Both free functions and member functions can be assigned to meta types in
  37972. * the role of destructors.<br/>
  37973. * The signature of a free function should be identical to the following:
  37974. *
  37975. * @code{.cpp}
  37976. * void(Type &);
  37977. * @endcode
  37978. *
  37979. * Member functions should not take arguments instead.<br/>
  37980. * The purpose is to give users the ability to free up resources that
  37981. * require special treatment before an object is actually destroyed.
  37982. *
  37983. * @tparam Func The actual function to use as a destructor.
  37984. * @return A meta factory for the parent type.
  37985. */
  37986. template<auto Func>
  37987. auto dtor() ENTT_NOEXCEPT {
  37988. static_assert(std::is_invocable_v<decltype(Func), Type &>, "The function doesn't accept an object of the type provided");
  37989. owner->dtor = [](void *instance) { std::invoke(Func, *static_cast<Type *>(instance)); };
  37990. return meta_factory<Type>{};
  37991. }
  37992. /**
  37993. * @brief Assigns a meta data to a meta type.
  37994. *
  37995. * Both data members and static and global variables, as well as constants
  37996. * of any kind, can be assigned to a meta type.<br/>
  37997. * From a client's point of view, all the variables associated with the
  37998. * reflected object will appear as if they were part of the type itself.
  37999. *
  38000. * @tparam Data The actual variable to attach to the meta type.
  38001. * @tparam Policy Optional policy (no policy set by default).
  38002. * @param id Unique identifier.
  38003. * @return An extended meta factory for the parent type.
  38004. */
  38005. template<auto Data, typename Policy = as_is_t>
  38006. auto data(const id_type id) ENTT_NOEXCEPT {
  38007. if constexpr(std::is_member_object_pointer_v<decltype(Data)>) {
  38008. using data_type = std::remove_reference_t<std::invoke_result_t<decltype(Data), Type &>>;
  38009. static internal::meta_data_node node{
  38010. {},
  38011. /* this is never static */
  38012. std::is_const_v<data_type> ? internal::meta_traits::is_const : internal::meta_traits::is_none,
  38013. nullptr,
  38014. nullptr,
  38015. 1u,
  38016. internal::meta_node<std::remove_const_t<data_type>>::resolve(),
  38017. &meta_arg<type_list<std::remove_const_t<data_type>>>,
  38018. &meta_setter<Type, Data>,
  38019. &meta_getter<Type, Data, Policy>
  38020. // tricks clang-format
  38021. };
  38022. link_data_if_required(id, node);
  38023. return meta_factory<Type, std::integral_constant<decltype(Data), Data>, std::integral_constant<decltype(Data), Data>>{&node.prop};
  38024. } else {
  38025. using data_type = std::remove_reference_t<std::remove_pointer_t<decltype(Data)>>;
  38026. static internal::meta_data_node node{
  38027. {},
  38028. ((std::is_same_v<Type, std::remove_const_t<data_type>> || std::is_const_v<data_type>) ? internal::meta_traits::is_const : internal::meta_traits::is_none) | internal::meta_traits::is_static,
  38029. nullptr,
  38030. nullptr,
  38031. 1u,
  38032. internal::meta_node<std::remove_const_t<data_type>>::resolve(),
  38033. &meta_arg<type_list<std::remove_const_t<data_type>>>,
  38034. &meta_setter<Type, Data>,
  38035. &meta_getter<Type, Data, Policy>
  38036. // tricks clang-format
  38037. };
  38038. link_data_if_required(id, node);
  38039. return meta_factory<Type, std::integral_constant<decltype(Data), Data>>{&node.prop};
  38040. }
  38041. }
  38042. /**
  38043. * @brief Assigns a meta data to a meta type by means of its setter and
  38044. * getter.
  38045. *
  38046. * Setters and getters can be either free functions, member functions or a
  38047. * mix of them.<br/>
  38048. * In case of free functions, setters and getters must accept a reference to
  38049. * an instance of the parent type as their first argument. A setter has then
  38050. * an extra argument of a type convertible to that of the parameter to
  38051. * set.<br/>
  38052. * In case of member functions, getters have no arguments at all, while
  38053. * setters has an argument of a type convertible to that of the parameter to
  38054. * set.
  38055. *
  38056. * @tparam Setter The actual function to use as a setter.
  38057. * @tparam Getter The actual function to use as a getter.
  38058. * @tparam Policy Optional policy (no policy set by default).
  38059. * @param id Unique identifier.
  38060. * @return An extended meta factory for the parent type.
  38061. */
  38062. template<auto Setter, auto Getter, typename Policy = as_is_t>
  38063. auto data(const id_type id) ENTT_NOEXCEPT {
  38064. using data_type = std::invoke_result_t<decltype(Getter), Type &>;
  38065. static_assert(Policy::template value<data_type>, "Invalid return type for the given policy");
  38066. if constexpr(std::is_same_v<decltype(Setter), std::nullptr_t>) {
  38067. static internal::meta_data_node node{
  38068. {},
  38069. /* this is never static */
  38070. internal::meta_traits::is_const,
  38071. nullptr,
  38072. nullptr,
  38073. 0u,
  38074. internal::meta_node<std::remove_cv_t<std::remove_reference_t<data_type>>>::resolve(),
  38075. &meta_arg<type_list<>>,
  38076. &meta_setter<Type, Setter>,
  38077. &meta_getter<Type, Getter, Policy>
  38078. // tricks clang-format
  38079. };
  38080. link_data_if_required(id, node);
  38081. return meta_factory<Type, std::integral_constant<decltype(Setter), Setter>, std::integral_constant<decltype(Getter), Getter>>{&node.prop};
  38082. } else {
  38083. using args_type = typename meta_function_helper_t<Type, decltype(Setter)>::args_type;
  38084. static internal::meta_data_node node{
  38085. {},
  38086. /* this is never static nor const */
  38087. internal::meta_traits::is_none,
  38088. nullptr,
  38089. nullptr,
  38090. 1u,
  38091. internal::meta_node<std::remove_cv_t<std::remove_reference_t<data_type>>>::resolve(),
  38092. &meta_arg<type_list<type_list_element_t<args_type::size != 1u, args_type>>>,
  38093. &meta_setter<Type, Setter>,
  38094. &meta_getter<Type, Getter, Policy>
  38095. // tricks clang-format
  38096. };
  38097. link_data_if_required(id, node);
  38098. return meta_factory<Type, std::integral_constant<decltype(Setter), Setter>, std::integral_constant<decltype(Getter), Getter>>{&node.prop};
  38099. }
  38100. }
  38101. /**
  38102. * @brief Assigns a meta data to a meta type by means of its setters and
  38103. * getter.
  38104. *
  38105. * Multi-setter support for meta data members. All setters are tried in the
  38106. * order of definition before returning to the caller.<br/>
  38107. * Setters can be either free functions, member functions or a mix of them
  38108. * and are provided via a `value_list` type.
  38109. *
  38110. * @sa data
  38111. *
  38112. * @tparam Setter The actual functions to use as setters.
  38113. * @tparam Getter The actual getter function.
  38114. * @tparam Policy Optional policy (no policy set by default).
  38115. * @param id Unique identifier.
  38116. * @return An extended meta factory for the parent type.
  38117. */
  38118. template<typename Setter, auto Getter, typename Policy = as_is_t>
  38119. auto data(const id_type id) ENTT_NOEXCEPT {
  38120. return data<Setter, Getter, Policy>(id, std::make_index_sequence<Setter::size>{});
  38121. }
  38122. /**
  38123. * @brief Assigns a meta function to a meta type.
  38124. *
  38125. * Both member functions and free functions can be assigned to a meta
  38126. * type.<br/>
  38127. * From a client's point of view, all the functions associated with the
  38128. * reflected object will appear as if they were part of the type itself.
  38129. *
  38130. * @tparam Candidate The actual function to attach to the meta type.
  38131. * @tparam Policy Optional policy (no policy set by default).
  38132. * @param id Unique identifier.
  38133. * @return An extended meta factory for the parent type.
  38134. */
  38135. template<auto Candidate, typename Policy = as_is_t>
  38136. auto func(const id_type id) ENTT_NOEXCEPT {
  38137. using descriptor = meta_function_helper_t<Type, decltype(Candidate)>;
  38138. static_assert(Policy::template value<typename descriptor::return_type>, "Invalid return type for the given policy");
  38139. static internal::meta_func_node node{
  38140. {},
  38141. (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),
  38142. nullptr,
  38143. nullptr,
  38144. descriptor::args_type::size,
  38145. internal::meta_node<std::conditional_t<std::is_same_v<Policy, as_void_t>, void, std::remove_cv_t<std::remove_reference_t<typename descriptor::return_type>>>>::resolve(),
  38146. &meta_arg<typename descriptor::args_type>,
  38147. &meta_invoke<Type, Candidate, Policy>
  38148. // tricks clang-format
  38149. };
  38150. link_func_if_required(id, node);
  38151. return meta_factory<Type, std::integral_constant<decltype(Candidate), Candidate>>{&node.prop};
  38152. }
  38153. private:
  38154. internal::meta_type_node *owner;
  38155. };
  38156. /**
  38157. * @brief Utility function to use for reflection.
  38158. *
  38159. * This is the point from which everything starts.<br/>
  38160. * By invoking this function with a type that is not yet reflected, a meta type
  38161. * is created to which it will be possible to attach meta objects through a
  38162. * dedicated factory.
  38163. *
  38164. * @tparam Type Type to reflect.
  38165. * @return A meta factory for the given type.
  38166. */
  38167. template<typename Type>
  38168. [[nodiscard]] auto meta() ENTT_NOEXCEPT {
  38169. auto *const node = internal::meta_node<Type>::resolve();
  38170. // extended meta factory to allow assigning properties to opaque meta types
  38171. return meta_factory<Type, Type>{&node->prop};
  38172. }
  38173. /**
  38174. * @brief Resets a type and all its parts.
  38175. *
  38176. * Resets a type and all its data members, member functions and properties, as
  38177. * well as its constructors, destructors and conversion functions if any.<br/>
  38178. * Base classes aren't reset but the link between the two types is removed.
  38179. *
  38180. * The type is also removed from the list of searchable types.
  38181. *
  38182. * @param id Unique identifier.
  38183. */
  38184. inline void meta_reset(const id_type id) ENTT_NOEXCEPT {
  38185. auto clear_chain = [](auto **curr, auto... member) {
  38186. for(; *curr; *curr = std::exchange((*curr)->next, nullptr)) {
  38187. if constexpr(sizeof...(member) != 0u) {
  38188. static_assert(sizeof...(member) == 1u, "Assert in defense of the future me");
  38189. for(auto **sub = (&((*curr)->*member), ...); *sub; *sub = std::exchange((*sub)->next, nullptr)) {}
  38190. }
  38191. }
  38192. };
  38193. for(auto **it = internal::meta_context::global(); *it; it = &(*it)->next) {
  38194. if(auto *node = *it; node->id == id) {
  38195. clear_chain(&node->prop);
  38196. clear_chain(&node->base);
  38197. clear_chain(&node->conv);
  38198. clear_chain(&node->ctor);
  38199. clear_chain(&node->data, &internal::meta_data_node::prop);
  38200. clear_chain(&node->func, &internal::meta_func_node::prop);
  38201. node->id = {};
  38202. node->dtor = nullptr;
  38203. *it = std::exchange(node->next, nullptr);
  38204. break;
  38205. }
  38206. }
  38207. }
  38208. /**
  38209. * @brief Resets a type and all its parts.
  38210. *
  38211. * @sa meta_reset
  38212. *
  38213. * @tparam Type Type to reset.
  38214. */
  38215. template<typename Type>
  38216. void meta_reset() ENTT_NOEXCEPT {
  38217. meta_reset(internal::meta_node<Type>::resolve()->id);
  38218. }
  38219. /**
  38220. * @brief Resets all searchable types.
  38221. *
  38222. * @sa meta_reset
  38223. */
  38224. inline void meta_reset() ENTT_NOEXCEPT {
  38225. while(*internal::meta_context::global()) {
  38226. meta_reset((*internal::meta_context::global())->id);
  38227. }
  38228. }
  38229. } // namespace entt
  38230. #endif
  38231. // #include "meta/meta.hpp"
  38232. #ifndef ENTT_META_META_HPP
  38233. #define ENTT_META_META_HPP
  38234. #include <cstddef>
  38235. #include <iterator>
  38236. #include <memory>
  38237. #include <type_traits>
  38238. #include <utility>
  38239. // #include "../config/config.h"
  38240. // #include "../core/any.hpp"
  38241. // #include "../core/fwd.hpp"
  38242. // #include "../core/iterator.hpp"
  38243. // #include "../core/type_info.hpp"
  38244. // #include "../core/type_traits.hpp"
  38245. // #include "../core/utility.hpp"
  38246. // #include "adl_pointer.hpp"
  38247. // #include "ctx.hpp"
  38248. // #include "fwd.hpp"
  38249. // #include "node.hpp"
  38250. // #include "range.hpp"
  38251. // #include "type_traits.hpp"
  38252. namespace entt {
  38253. class meta_any;
  38254. class meta_type;
  38255. /*! @brief Proxy object for sequence containers. */
  38256. class meta_sequence_container {
  38257. class meta_iterator;
  38258. public:
  38259. /*! @brief Unsigned integer type. */
  38260. using size_type = std::size_t;
  38261. /*! @brief Meta iterator type. */
  38262. using iterator = meta_iterator;
  38263. /*! @brief Default constructor. */
  38264. meta_sequence_container() ENTT_NOEXCEPT = default;
  38265. /**
  38266. * @brief Construct a proxy object for sequence containers.
  38267. * @tparam Type Type of container to wrap.
  38268. * @param instance The container to wrap.
  38269. */
  38270. template<typename Type>
  38271. meta_sequence_container(std::in_place_type_t<Type>, any instance) ENTT_NOEXCEPT
  38272. : value_type_node{internal::meta_node<std::remove_cv_t<std::remove_reference_t<typename Type::value_type>>>::resolve()},
  38273. size_fn{&meta_sequence_container_traits<Type>::size},
  38274. resize_fn{&meta_sequence_container_traits<Type>::resize},
  38275. iter_fn{&meta_sequence_container_traits<Type>::iter},
  38276. insert_fn{&meta_sequence_container_traits<Type>::insert},
  38277. erase_fn{&meta_sequence_container_traits<Type>::erase},
  38278. storage{std::move(instance)} {}
  38279. [[nodiscard]] inline meta_type value_type() const ENTT_NOEXCEPT;
  38280. [[nodiscard]] inline size_type size() const ENTT_NOEXCEPT;
  38281. inline bool resize(const size_type);
  38282. inline bool clear();
  38283. [[nodiscard]] inline iterator begin();
  38284. [[nodiscard]] inline iterator end();
  38285. inline iterator insert(iterator, meta_any);
  38286. inline iterator erase(iterator);
  38287. [[nodiscard]] inline meta_any operator[](const size_type);
  38288. [[nodiscard]] inline explicit operator bool() const ENTT_NOEXCEPT;
  38289. private:
  38290. internal::meta_type_node *value_type_node = nullptr;
  38291. size_type (*size_fn)(const any &) ENTT_NOEXCEPT = nullptr;
  38292. bool (*resize_fn)(any &, size_type) = nullptr;
  38293. iterator (*iter_fn)(any &, const bool) = nullptr;
  38294. iterator (*insert_fn)(any &, const std::ptrdiff_t, meta_any &) = nullptr;
  38295. iterator (*erase_fn)(any &, const std::ptrdiff_t) = nullptr;
  38296. any storage{};
  38297. };
  38298. /*! @brief Proxy object for associative containers. */
  38299. class meta_associative_container {
  38300. class meta_iterator;
  38301. public:
  38302. /*! @brief Unsigned integer type. */
  38303. using size_type = std::size_t;
  38304. /*! @brief Meta iterator type. */
  38305. using iterator = meta_iterator;
  38306. /*! @brief Default constructor. */
  38307. meta_associative_container() ENTT_NOEXCEPT = default;
  38308. /**
  38309. * @brief Construct a proxy object for associative containers.
  38310. * @tparam Type Type of container to wrap.
  38311. * @param instance The container to wrap.
  38312. */
  38313. template<typename Type>
  38314. meta_associative_container(std::in_place_type_t<Type>, any instance) ENTT_NOEXCEPT
  38315. : key_only_container{meta_associative_container_traits<Type>::key_only},
  38316. key_type_node{internal::meta_node<std::remove_cv_t<std::remove_reference_t<typename Type::key_type>>>::resolve()},
  38317. mapped_type_node{nullptr},
  38318. value_type_node{internal::meta_node<std::remove_cv_t<std::remove_reference_t<typename Type::value_type>>>::resolve()},
  38319. size_fn{&meta_associative_container_traits<Type>::size},
  38320. clear_fn{&meta_associative_container_traits<Type>::clear},
  38321. iter_fn{&meta_associative_container_traits<Type>::iter},
  38322. insert_fn{&meta_associative_container_traits<Type>::insert},
  38323. erase_fn{&meta_associative_container_traits<Type>::erase},
  38324. find_fn{&meta_associative_container_traits<Type>::find},
  38325. storage{std::move(instance)} {
  38326. if constexpr(!meta_associative_container_traits<Type>::key_only) {
  38327. mapped_type_node = internal::meta_node<std::remove_cv_t<std::remove_reference_t<typename Type::mapped_type>>>::resolve();
  38328. }
  38329. }
  38330. [[nodiscard]] inline bool key_only() const ENTT_NOEXCEPT;
  38331. [[nodiscard]] inline meta_type key_type() const ENTT_NOEXCEPT;
  38332. [[nodiscard]] inline meta_type mapped_type() const ENTT_NOEXCEPT;
  38333. [[nodiscard]] inline meta_type value_type() const ENTT_NOEXCEPT;
  38334. [[nodiscard]] inline size_type size() const ENTT_NOEXCEPT;
  38335. inline bool clear();
  38336. [[nodiscard]] inline iterator begin();
  38337. [[nodiscard]] inline iterator end();
  38338. inline bool insert(meta_any, meta_any);
  38339. inline bool erase(meta_any);
  38340. [[nodiscard]] inline iterator find(meta_any);
  38341. [[nodiscard]] inline explicit operator bool() const ENTT_NOEXCEPT;
  38342. private:
  38343. bool key_only_container{};
  38344. internal::meta_type_node *key_type_node = nullptr;
  38345. internal::meta_type_node *mapped_type_node = nullptr;
  38346. internal::meta_type_node *value_type_node = nullptr;
  38347. size_type (*size_fn)(const any &) ENTT_NOEXCEPT = nullptr;
  38348. bool (*clear_fn)(any &) = nullptr;
  38349. iterator (*iter_fn)(any &, const bool) = nullptr;
  38350. bool (*insert_fn)(any &, meta_any &, meta_any &) = nullptr;
  38351. bool (*erase_fn)(any &, meta_any &) = nullptr;
  38352. iterator (*find_fn)(any &, meta_any &) = nullptr;
  38353. any storage{};
  38354. };
  38355. /*! @brief Opaque wrapper for values of any type. */
  38356. class meta_any {
  38357. enum class operation : std::uint8_t {
  38358. deref,
  38359. seq,
  38360. assoc
  38361. };
  38362. using vtable_type = void(const operation, const any &, void *);
  38363. template<typename Type>
  38364. static void basic_vtable([[maybe_unused]] const operation op, [[maybe_unused]] const any &value, [[maybe_unused]] void *other) {
  38365. static_assert(std::is_same_v<std::remove_cv_t<std::remove_reference_t<Type>>, Type>, "Invalid type");
  38366. if constexpr(!std::is_void_v<Type>) {
  38367. switch(op) {
  38368. case operation::deref:
  38369. if constexpr(is_meta_pointer_like_v<Type>) {
  38370. if constexpr(std::is_function_v<std::remove_const_t<typename std::pointer_traits<Type>::element_type>>) {
  38371. *static_cast<meta_any *>(other) = any_cast<Type>(value);
  38372. } else if constexpr(!std::is_same_v<std::remove_const_t<typename std::pointer_traits<Type>::element_type>, void>) {
  38373. using in_place_type = decltype(adl_meta_pointer_like<Type>::dereference(any_cast<const Type &>(value)));
  38374. if constexpr(std::is_constructible_v<bool, Type>) {
  38375. if(const auto &pointer_like = any_cast<const Type &>(value); pointer_like) {
  38376. static_cast<meta_any *>(other)->emplace<in_place_type>(adl_meta_pointer_like<Type>::dereference(pointer_like));
  38377. }
  38378. } else {
  38379. static_cast<meta_any *>(other)->emplace<in_place_type>(adl_meta_pointer_like<Type>::dereference(any_cast<const Type &>(value)));
  38380. }
  38381. }
  38382. }
  38383. break;
  38384. case operation::seq:
  38385. if constexpr(is_complete_v<meta_sequence_container_traits<Type>>) {
  38386. *static_cast<meta_sequence_container *>(other) = {std::in_place_type<Type>, std::move(const_cast<any &>(value))};
  38387. }
  38388. break;
  38389. case operation::assoc:
  38390. if constexpr(is_complete_v<meta_associative_container_traits<Type>>) {
  38391. *static_cast<meta_associative_container *>(other) = {std::in_place_type<Type>, std::move(const_cast<any &>(value))};
  38392. }
  38393. break;
  38394. }
  38395. }
  38396. }
  38397. void release() {
  38398. if(node && node->dtor && storage.owner()) {
  38399. node->dtor(storage.data());
  38400. }
  38401. }
  38402. meta_any(const meta_any &other, any ref) ENTT_NOEXCEPT
  38403. : storage{std::move(ref)},
  38404. node{storage ? other.node : nullptr},
  38405. vtable{storage ? other.vtable : &basic_vtable<void>} {}
  38406. public:
  38407. /*! @brief Default constructor. */
  38408. meta_any() ENTT_NOEXCEPT
  38409. : storage{},
  38410. node{},
  38411. vtable{&basic_vtable<void>} {}
  38412. /**
  38413. * @brief Constructs a wrapper by directly initializing the new object.
  38414. * @tparam Type Type of object to use to initialize the wrapper.
  38415. * @tparam Args Types of arguments to use to construct the new instance.
  38416. * @param args Parameters to use to construct the instance.
  38417. */
  38418. template<typename Type, typename... Args>
  38419. explicit meta_any(std::in_place_type_t<Type>, Args &&...args)
  38420. : storage{std::in_place_type<Type>, std::forward<Args>(args)...},
  38421. node{internal::meta_node<std::remove_cv_t<std::remove_reference_t<Type>>>::resolve()},
  38422. vtable{&basic_vtable<std::remove_cv_t<std::remove_reference_t<Type>>>} {}
  38423. /**
  38424. * @brief Constructs a wrapper from a given value.
  38425. * @tparam Type Type of object to use to initialize the wrapper.
  38426. * @param value An instance of an object to use to initialize the wrapper.
  38427. */
  38428. template<typename Type, typename = std::enable_if_t<!std::is_same_v<std::decay_t<Type>, meta_any>>>
  38429. meta_any(Type &&value)
  38430. : meta_any{std::in_place_type<std::remove_cv_t<std::remove_reference_t<Type>>>, std::forward<Type>(value)} {}
  38431. /**
  38432. * @brief Copy constructor.
  38433. * @param other The instance to copy from.
  38434. */
  38435. meta_any(const meta_any &other) = default;
  38436. /**
  38437. * @brief Move constructor.
  38438. * @param other The instance to move from.
  38439. */
  38440. meta_any(meta_any &&other) ENTT_NOEXCEPT
  38441. : storage{std::move(other.storage)},
  38442. node{std::exchange(other.node, nullptr)},
  38443. vtable{std::exchange(other.vtable, &basic_vtable<void>)} {}
  38444. /*! @brief Frees the internal storage, whatever it means. */
  38445. ~meta_any() {
  38446. release();
  38447. }
  38448. /**
  38449. * @brief Copy assignment operator.
  38450. * @param other The instance to copy from.
  38451. * @return This meta any object.
  38452. */
  38453. meta_any &operator=(const meta_any &other) {
  38454. release();
  38455. vtable = other.vtable;
  38456. storage = other.storage;
  38457. node = other.node;
  38458. return *this;
  38459. }
  38460. /**
  38461. * @brief Move assignment operator.
  38462. * @param other The instance to move from.
  38463. * @return This meta any object.
  38464. */
  38465. meta_any &operator=(meta_any &&other) ENTT_NOEXCEPT {
  38466. release();
  38467. vtable = std::exchange(other.vtable, &basic_vtable<void>);
  38468. storage = std::move(other.storage);
  38469. node = std::exchange(other.node, nullptr);
  38470. return *this;
  38471. }
  38472. /**
  38473. * @brief Value assignment operator.
  38474. * @tparam Type Type of object to use to initialize the wrapper.
  38475. * @param value An instance of an object to use to initialize the wrapper.
  38476. * @return This meta any object.
  38477. */
  38478. template<typename Type>
  38479. std::enable_if_t<!std::is_same_v<std::decay_t<Type>, meta_any>, meta_any &>
  38480. operator=(Type &&value) {
  38481. emplace<std::decay_t<Type>>(std::forward<Type>(value));
  38482. return *this;
  38483. }
  38484. /*! @copydoc any::type */
  38485. [[nodiscard]] inline meta_type type() const ENTT_NOEXCEPT;
  38486. /*! @copydoc any::data */
  38487. [[nodiscard]] const void *data() const ENTT_NOEXCEPT {
  38488. return storage.data();
  38489. }
  38490. /*! @copydoc any::data */
  38491. [[nodiscard]] void *data() ENTT_NOEXCEPT {
  38492. return storage.data();
  38493. }
  38494. /**
  38495. * @brief Invokes the underlying function, if possible.
  38496. *
  38497. * @sa meta_func::invoke
  38498. *
  38499. * @tparam Args Types of arguments to use to invoke the function.
  38500. * @param id Unique identifier.
  38501. * @param args Parameters to use to invoke the function.
  38502. * @return A wrapper containing the returned value, if any.
  38503. */
  38504. template<typename... Args>
  38505. meta_any invoke(const id_type id, Args &&...args) const;
  38506. /*! @copydoc invoke */
  38507. template<typename... Args>
  38508. meta_any invoke(const id_type id, Args &&...args);
  38509. /**
  38510. * @brief Sets the value of a given variable.
  38511. *
  38512. * The type of the value is such that a cast or conversion to the type of
  38513. * the variable is possible. Otherwise, invoking the setter does nothing.
  38514. *
  38515. * @tparam Type Type of value to assign.
  38516. * @param id Unique identifier.
  38517. * @param value Parameter to use to set the underlying variable.
  38518. * @return True in case of success, false otherwise.
  38519. */
  38520. template<typename Type>
  38521. bool set(const id_type id, Type &&value);
  38522. /**
  38523. * @brief Gets the value of a given variable.
  38524. * @param id Unique identifier.
  38525. * @return A wrapper containing the value of the underlying variable.
  38526. */
  38527. [[nodiscard]] meta_any get(const id_type id) const;
  38528. /*! @copydoc get */
  38529. [[nodiscard]] meta_any get(const id_type id);
  38530. /**
  38531. * @brief Tries to cast an instance to a given type.
  38532. * @tparam Type Type to which to cast the instance.
  38533. * @return A (possibly null) pointer to the contained instance.
  38534. */
  38535. template<typename Type>
  38536. [[nodiscard]] const Type *try_cast() const {
  38537. if(const auto &info = type_id<Type>(); node && *node->info == info) {
  38538. return any_cast<Type>(&storage);
  38539. } else if(node) {
  38540. for(auto *it = node->base; it; it = it->next) {
  38541. const auto as_const = it->cast(as_ref());
  38542. if(const Type *base = as_const.template try_cast<Type>(); base) {
  38543. return base;
  38544. }
  38545. }
  38546. }
  38547. return nullptr;
  38548. }
  38549. /*! @copydoc try_cast */
  38550. template<typename Type>
  38551. [[nodiscard]] Type *try_cast() {
  38552. if(const auto &info = type_id<Type>(); node && *node->info == info) {
  38553. return any_cast<Type>(&storage);
  38554. } else if(node) {
  38555. for(auto *it = node->base; it; it = it->next) {
  38556. if(Type *base = it->cast(as_ref()).template try_cast<Type>(); base) {
  38557. return base;
  38558. }
  38559. }
  38560. }
  38561. return nullptr;
  38562. }
  38563. /**
  38564. * @brief Tries to cast an instance to a given type.
  38565. *
  38566. * The type of the instance must be such that the cast is possible.
  38567. *
  38568. * @warning
  38569. * Attempting to perform an invalid cast results is undefined behavior.
  38570. *
  38571. * @tparam Type Type to which to cast the instance.
  38572. * @return A reference to the contained instance.
  38573. */
  38574. template<typename Type>
  38575. [[nodiscard]] Type cast() const {
  38576. auto *const instance = try_cast<std::remove_reference_t<Type>>();
  38577. ENTT_ASSERT(instance, "Invalid instance");
  38578. return static_cast<Type>(*instance);
  38579. }
  38580. /*! @copydoc cast */
  38581. template<typename Type>
  38582. [[nodiscard]] Type cast() {
  38583. // forces const on non-reference types to make them work also with wrappers for const references
  38584. auto *const instance = try_cast<std::remove_reference_t<const Type>>();
  38585. ENTT_ASSERT(instance, "Invalid instance");
  38586. return static_cast<Type>(*instance);
  38587. }
  38588. /**
  38589. * @brief Converts an object in such a way that a given cast becomes viable.
  38590. * @param type Meta type to which the cast is requested.
  38591. * @return A valid meta any object if there exists a viable conversion, an
  38592. * invalid one otherwise.
  38593. */
  38594. [[nodiscard]] meta_any allow_cast(const meta_type &type) const;
  38595. /**
  38596. * @brief Converts an object in such a way that a given cast becomes viable.
  38597. * @param type Meta type to which the cast is requested.
  38598. * @return True if there exists a viable conversion, false otherwise.
  38599. */
  38600. [[nodiscard]] bool allow_cast(const meta_type &type) {
  38601. if(auto other = std::as_const(*this).allow_cast(type); other) {
  38602. if(other.storage.owner()) {
  38603. std::swap(*this, other);
  38604. }
  38605. return true;
  38606. }
  38607. return false;
  38608. }
  38609. /**
  38610. * @brief Converts an object in such a way that a given cast becomes viable.
  38611. * @tparam Type Type to which the cast is requested.
  38612. * @return A valid meta any object if there exists a viable conversion, an
  38613. * invalid one otherwise.
  38614. */
  38615. template<typename Type>
  38616. [[nodiscard]] meta_any allow_cast() const {
  38617. const auto other = allow_cast(internal::meta_node<std::remove_cv_t<std::remove_reference_t<Type>>>::resolve());
  38618. if constexpr(std::is_reference_v<Type> && !std::is_const_v<std::remove_reference_t<Type>>) {
  38619. return other.storage.owner() ? other : meta_any{};
  38620. } else {
  38621. return other;
  38622. }
  38623. }
  38624. /**
  38625. * @brief Converts an object in such a way that a given cast becomes viable.
  38626. * @tparam Type Type to which the cast is requested.
  38627. * @return True if there exists a viable conversion, false otherwise.
  38628. */
  38629. template<typename Type>
  38630. bool allow_cast() {
  38631. if(auto other = std::as_const(*this).allow_cast(internal::meta_node<std::remove_cv_t<std::remove_reference_t<Type>>>::resolve()); other) {
  38632. if(other.storage.owner()) {
  38633. std::swap(*this, other);
  38634. return true;
  38635. }
  38636. return (static_cast<constness_as_t<any, std::remove_reference_t<const Type>> &>(storage).data() != nullptr);
  38637. }
  38638. return false;
  38639. }
  38640. /*! @copydoc any::emplace */
  38641. template<typename Type, typename... Args>
  38642. void emplace(Args &&...args) {
  38643. release();
  38644. vtable = &basic_vtable<std::remove_cv_t<std::remove_reference_t<Type>>>;
  38645. storage.emplace<Type>(std::forward<Args>(args)...);
  38646. node = internal::meta_node<std::remove_cv_t<std::remove_reference_t<Type>>>::resolve();
  38647. }
  38648. /*! @copydoc any::assign */
  38649. bool assign(const meta_any &other);
  38650. /*! @copydoc any::assign */
  38651. bool assign(meta_any &&other);
  38652. /*! @copydoc any::reset */
  38653. void reset() {
  38654. release();
  38655. vtable = &basic_vtable<void>;
  38656. storage.reset();
  38657. node = nullptr;
  38658. }
  38659. /**
  38660. * @brief Returns a sequence container proxy.
  38661. * @return A sequence container proxy for the underlying object.
  38662. */
  38663. [[nodiscard]] meta_sequence_container as_sequence_container() ENTT_NOEXCEPT {
  38664. any detached = storage.as_ref();
  38665. meta_sequence_container proxy;
  38666. vtable(operation::seq, detached, &proxy);
  38667. return proxy;
  38668. }
  38669. /*! @copydoc as_sequence_container */
  38670. [[nodiscard]] meta_sequence_container as_sequence_container() const ENTT_NOEXCEPT {
  38671. any detached = storage.as_ref();
  38672. meta_sequence_container proxy;
  38673. vtable(operation::seq, detached, &proxy);
  38674. return proxy;
  38675. }
  38676. /**
  38677. * @brief Returns an associative container proxy.
  38678. * @return An associative container proxy for the underlying object.
  38679. */
  38680. [[nodiscard]] meta_associative_container as_associative_container() ENTT_NOEXCEPT {
  38681. any detached = storage.as_ref();
  38682. meta_associative_container proxy;
  38683. vtable(operation::assoc, detached, &proxy);
  38684. return proxy;
  38685. }
  38686. /*! @copydoc as_associative_container */
  38687. [[nodiscard]] meta_associative_container as_associative_container() const ENTT_NOEXCEPT {
  38688. any detached = storage.as_ref();
  38689. meta_associative_container proxy;
  38690. vtable(operation::assoc, detached, &proxy);
  38691. return proxy;
  38692. }
  38693. /**
  38694. * @brief Indirection operator for dereferencing opaque objects.
  38695. * @return A wrapper that shares a reference to an unmanaged object if the
  38696. * wrapped element is dereferenceable, an invalid meta any otherwise.
  38697. */
  38698. [[nodiscard]] meta_any operator*() const ENTT_NOEXCEPT {
  38699. meta_any ret{};
  38700. vtable(operation::deref, storage, &ret);
  38701. return ret;
  38702. }
  38703. /**
  38704. * @brief Returns false if a wrapper is invalid, true otherwise.
  38705. * @return False if the wrapper is invalid, true otherwise.
  38706. */
  38707. [[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
  38708. return !(node == nullptr);
  38709. }
  38710. /*! @copydoc any::operator== */
  38711. [[nodiscard]] bool operator==(const meta_any &other) const {
  38712. return (!node && !other.node) || (node && other.node && *node->info == *other.node->info && storage == other.storage);
  38713. }
  38714. /*! @copydoc any::as_ref */
  38715. [[nodiscard]] meta_any as_ref() ENTT_NOEXCEPT {
  38716. return meta_any{*this, storage.as_ref()};
  38717. }
  38718. /*! @copydoc any::as_ref */
  38719. [[nodiscard]] meta_any as_ref() const ENTT_NOEXCEPT {
  38720. return meta_any{*this, storage.as_ref()};
  38721. }
  38722. /*! @copydoc any::owner */
  38723. [[nodiscard]] bool owner() const ENTT_NOEXCEPT {
  38724. return storage.owner();
  38725. }
  38726. private:
  38727. any storage;
  38728. internal::meta_type_node *node;
  38729. vtable_type *vtable;
  38730. };
  38731. /**
  38732. * @brief Checks if two wrappers differ in their content.
  38733. * @param lhs A wrapper, either empty or not.
  38734. * @param rhs A wrapper, either empty or not.
  38735. * @return True if the two wrappers differ in their content, false otherwise.
  38736. */
  38737. [[nodiscard]] inline bool operator!=(const meta_any &lhs, const meta_any &rhs) ENTT_NOEXCEPT {
  38738. return !(lhs == rhs);
  38739. }
  38740. /**
  38741. * @brief Constructs a wrapper from a given type, passing it all arguments.
  38742. * @tparam Type Type of object to use to initialize the wrapper.
  38743. * @tparam Args Types of arguments to use to construct the new instance.
  38744. * @param args Parameters to use to construct the instance.
  38745. * @return A properly initialized wrapper for an object of the given type.
  38746. */
  38747. template<typename Type, typename... Args>
  38748. meta_any make_meta(Args &&...args) {
  38749. return meta_any{std::in_place_type<Type>, std::forward<Args>(args)...};
  38750. }
  38751. /**
  38752. * @brief Forwards its argument and avoids copies for lvalue references.
  38753. * @tparam Type Type of argument to use to construct the new instance.
  38754. * @param value Parameter to use to construct the instance.
  38755. * @return A properly initialized and not necessarily owning wrapper.
  38756. */
  38757. template<typename Type>
  38758. meta_any forward_as_meta(Type &&value) {
  38759. return meta_any{std::in_place_type<std::conditional_t<std::is_rvalue_reference_v<Type>, std::decay_t<Type>, Type>>, std::forward<Type>(value)};
  38760. }
  38761. /**
  38762. * @brief Opaque pointers to instances of any type.
  38763. *
  38764. * A handle doesn't perform copies and isn't responsible for the contained
  38765. * object. It doesn't prolong the lifetime of the pointed instance.<br/>
  38766. * Handles are used to generate references to actual objects when needed.
  38767. */
  38768. struct meta_handle {
  38769. /*! @brief Default constructor. */
  38770. meta_handle() = default;
  38771. /*! @brief Default copy constructor, deleted on purpose. */
  38772. meta_handle(const meta_handle &) = delete;
  38773. /*! @brief Default move constructor. */
  38774. meta_handle(meta_handle &&) = default;
  38775. /**
  38776. * @brief Default copy assignment operator, deleted on purpose.
  38777. * @return This meta handle.
  38778. */
  38779. meta_handle &operator=(const meta_handle &) = delete;
  38780. /**
  38781. * @brief Default move assignment operator.
  38782. * @return This meta handle.
  38783. */
  38784. meta_handle &operator=(meta_handle &&) = default;
  38785. /**
  38786. * @brief Creates a handle that points to an unmanaged object.
  38787. * @tparam Type Type of object to use to initialize the handle.
  38788. * @param value An instance of an object to use to initialize the handle.
  38789. */
  38790. template<typename Type, typename = std::enable_if_t<!std::is_same_v<std::decay_t<Type>, meta_handle>>>
  38791. meta_handle(Type &value) ENTT_NOEXCEPT
  38792. : meta_handle{} {
  38793. if constexpr(std::is_same_v<std::decay_t<Type>, meta_any>) {
  38794. any = value.as_ref();
  38795. } else {
  38796. any.emplace<Type &>(value);
  38797. }
  38798. }
  38799. /**
  38800. * @brief Returns false if a handle is invalid, true otherwise.
  38801. * @return False if the handle is invalid, true otherwise.
  38802. */
  38803. [[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
  38804. return static_cast<bool>(any);
  38805. }
  38806. /**
  38807. * @brief Access operator for accessing the contained opaque object.
  38808. * @return A wrapper that shares a reference to an unmanaged object.
  38809. */
  38810. [[nodiscard]] meta_any *operator->() {
  38811. return &any;
  38812. }
  38813. /*! @copydoc operator-> */
  38814. [[nodiscard]] const meta_any *operator->() const {
  38815. return &any;
  38816. }
  38817. private:
  38818. meta_any any;
  38819. };
  38820. /*! @brief Opaque wrapper for properties of any type. */
  38821. struct meta_prop {
  38822. /*! @brief Node type. */
  38823. using node_type = internal::meta_prop_node;
  38824. /**
  38825. * @brief Constructs an instance from a given node.
  38826. * @param curr The underlying node with which to construct the instance.
  38827. */
  38828. meta_prop(const node_type *curr = nullptr) ENTT_NOEXCEPT
  38829. : node{curr} {}
  38830. /**
  38831. * @brief Returns the stored key as a const reference.
  38832. * @return A wrapper containing the key stored with the property.
  38833. */
  38834. [[nodiscard]] meta_any key() const {
  38835. return node->id.as_ref();
  38836. }
  38837. /**
  38838. * @brief Returns the stored value by copy.
  38839. * @return A wrapper containing the value stored with the property.
  38840. */
  38841. [[nodiscard]] meta_any value() const {
  38842. return node->value;
  38843. }
  38844. /**
  38845. * @brief Returns true if an object is valid, false otherwise.
  38846. * @return True if the object is valid, false otherwise.
  38847. */
  38848. [[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
  38849. return !(node == nullptr);
  38850. }
  38851. private:
  38852. const node_type *node;
  38853. };
  38854. /*! @brief Opaque wrapper for data members. */
  38855. struct meta_data {
  38856. /*! @brief Node type. */
  38857. using node_type = internal::meta_data_node;
  38858. /*! @brief Unsigned integer type. */
  38859. using size_type = typename node_type::size_type;
  38860. /*! @copydoc meta_prop::meta_prop */
  38861. meta_data(const node_type *curr = nullptr) ENTT_NOEXCEPT
  38862. : node{curr} {}
  38863. /*! @copydoc meta_type::id */
  38864. [[nodiscard]] id_type id() const ENTT_NOEXCEPT {
  38865. return node->id;
  38866. }
  38867. /**
  38868. * @brief Returns the number of setters available.
  38869. * @return The number of setters available.
  38870. */
  38871. [[nodiscard]] size_type arity() const ENTT_NOEXCEPT {
  38872. return node->arity;
  38873. }
  38874. /**
  38875. * @brief Indicates whether a data member is constant or not.
  38876. * @return True if the data member is constant, false otherwise.
  38877. */
  38878. [[nodiscard]] bool is_const() const ENTT_NOEXCEPT {
  38879. return !!(node->traits & internal::meta_traits::is_const);
  38880. }
  38881. /**
  38882. * @brief Indicates whether a data member is static or not.
  38883. * @return True if the data member is static, false otherwise.
  38884. */
  38885. [[nodiscard]] bool is_static() const ENTT_NOEXCEPT {
  38886. return !!(node->traits & internal::meta_traits::is_static);
  38887. }
  38888. /*! @copydoc meta_any::type */
  38889. [[nodiscard]] inline meta_type type() const ENTT_NOEXCEPT;
  38890. /**
  38891. * @brief Sets the value of a given variable.
  38892. *
  38893. * It must be possible to cast the instance to the parent type of the data
  38894. * member.<br/>
  38895. * The type of the value is such that a cast or conversion to the type of
  38896. * the variable is possible. Otherwise, invoking the setter does nothing.
  38897. *
  38898. * @tparam Type Type of value to assign.
  38899. * @param instance An opaque instance of the underlying type.
  38900. * @param value Parameter to use to set the underlying variable.
  38901. * @return True in case of success, false otherwise.
  38902. */
  38903. template<typename Type>
  38904. bool set(meta_handle instance, Type &&value) const {
  38905. return node->set && node->set(std::move(instance), std::forward<Type>(value));
  38906. }
  38907. /**
  38908. * @brief Gets the value of a given variable.
  38909. *
  38910. * It must be possible to cast the instance to the parent type of the data
  38911. * member.
  38912. *
  38913. * @param instance An opaque instance of the underlying type.
  38914. * @return A wrapper containing the value of the underlying variable.
  38915. */
  38916. [[nodiscard]] meta_any get(meta_handle instance) const {
  38917. return node->get(std::move(instance));
  38918. }
  38919. /**
  38920. * @brief Returns the type accepted by the i-th setter.
  38921. * @param index Index of the setter of which to return the accepted type.
  38922. * @return The type accepted by the i-th setter.
  38923. */
  38924. [[nodiscard]] inline meta_type arg(const size_type index) const ENTT_NOEXCEPT;
  38925. /**
  38926. * @brief Returns a range to visit registered meta properties.
  38927. * @return An iterable range to visit registered meta properties.
  38928. */
  38929. [[nodiscard]] meta_range<meta_prop> prop() const ENTT_NOEXCEPT {
  38930. return node->prop;
  38931. }
  38932. /**
  38933. * @brief Lookup function for registered meta properties.
  38934. * @param key The key to use to search for a property.
  38935. * @return The registered meta property for the given key, if any.
  38936. */
  38937. [[nodiscard]] meta_prop prop(meta_any key) const {
  38938. for(auto curr: prop()) {
  38939. if(curr.key() == key) {
  38940. return curr;
  38941. }
  38942. }
  38943. return nullptr;
  38944. }
  38945. /**
  38946. * @brief Returns true if an object is valid, false otherwise.
  38947. * @return True if the object is valid, false otherwise.
  38948. */
  38949. [[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
  38950. return !(node == nullptr);
  38951. }
  38952. private:
  38953. const node_type *node;
  38954. };
  38955. /*! @brief Opaque wrapper for member functions. */
  38956. struct meta_func {
  38957. /*! @brief Node type. */
  38958. using node_type = internal::meta_func_node;
  38959. /*! @brief Unsigned integer type. */
  38960. using size_type = typename node_type::size_type;
  38961. /*! @copydoc meta_prop::meta_prop */
  38962. meta_func(const node_type *curr = nullptr) ENTT_NOEXCEPT
  38963. : node{curr} {}
  38964. /*! @copydoc meta_type::id */
  38965. [[nodiscard]] id_type id() const ENTT_NOEXCEPT {
  38966. return node->id;
  38967. }
  38968. /**
  38969. * @brief Returns the number of arguments accepted by a member function.
  38970. * @return The number of arguments accepted by the member function.
  38971. */
  38972. [[nodiscard]] size_type arity() const ENTT_NOEXCEPT {
  38973. return node->arity;
  38974. }
  38975. /**
  38976. * @brief Indicates whether a member function is constant or not.
  38977. * @return True if the member function is constant, false otherwise.
  38978. */
  38979. [[nodiscard]] bool is_const() const ENTT_NOEXCEPT {
  38980. return !!(node->traits & internal::meta_traits::is_const);
  38981. }
  38982. /**
  38983. * @brief Indicates whether a member function is static or not.
  38984. * @return True if the member function is static, false otherwise.
  38985. */
  38986. [[nodiscard]] bool is_static() const ENTT_NOEXCEPT {
  38987. return !!(node->traits & internal::meta_traits::is_static);
  38988. }
  38989. /**
  38990. * @brief Returns the return type of a member function.
  38991. * @return The return type of the member function.
  38992. */
  38993. [[nodiscard]] inline meta_type ret() const ENTT_NOEXCEPT;
  38994. /**
  38995. * @brief Returns the type of the i-th argument of a member function.
  38996. * @param index Index of the argument of which to return the type.
  38997. * @return The type of the i-th argument of a member function.
  38998. */
  38999. [[nodiscard]] inline meta_type arg(const size_type index) const ENTT_NOEXCEPT;
  39000. /**
  39001. * @brief Invokes the underlying function, if possible.
  39002. *
  39003. * To invoke a member function, the parameters must be such that a cast or
  39004. * conversion to the required types is possible. Otherwise, an empty and
  39005. * thus invalid wrapper is returned.<br/>
  39006. * It must be possible to cast the instance to the parent type of the member
  39007. * function.
  39008. *
  39009. * @param instance An opaque instance of the underlying type.
  39010. * @param args Parameters to use to invoke the function.
  39011. * @param sz Number of parameters to use to invoke the function.
  39012. * @return A wrapper containing the returned value, if any.
  39013. */
  39014. meta_any invoke(meta_handle instance, meta_any *const args, const size_type sz) const {
  39015. return sz == arity() ? node->invoke(std::move(instance), args) : meta_any{};
  39016. }
  39017. /**
  39018. * @copybrief invoke
  39019. *
  39020. * @sa invoke
  39021. *
  39022. * @tparam Args Types of arguments to use to invoke the function.
  39023. * @param instance An opaque instance of the underlying type.
  39024. * @param args Parameters to use to invoke the function.
  39025. * @return A wrapper containing the new instance, if any.
  39026. */
  39027. template<typename... Args>
  39028. meta_any invoke(meta_handle instance, Args &&...args) const {
  39029. meta_any arguments[sizeof...(Args) + 1u]{std::forward<Args>(args)...};
  39030. return invoke(std::move(instance), arguments, sizeof...(Args));
  39031. }
  39032. /*! @copydoc meta_data::prop */
  39033. [[nodiscard]] meta_range<meta_prop> prop() const ENTT_NOEXCEPT {
  39034. return node->prop;
  39035. }
  39036. /**
  39037. * @brief Lookup function for registered meta properties.
  39038. * @param key The key to use to search for a property.
  39039. * @return The registered meta property for the given key, if any.
  39040. */
  39041. [[nodiscard]] meta_prop prop(meta_any key) const {
  39042. for(auto curr: prop()) {
  39043. if(curr.key() == key) {
  39044. return curr;
  39045. }
  39046. }
  39047. return nullptr;
  39048. }
  39049. /**
  39050. * @brief Returns true if an object is valid, false otherwise.
  39051. * @return True if the object is valid, false otherwise.
  39052. */
  39053. [[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
  39054. return !(node == nullptr);
  39055. }
  39056. private:
  39057. const node_type *node;
  39058. };
  39059. /*! @brief Opaque wrapper for types. */
  39060. class meta_type {
  39061. template<auto Member, typename Pred>
  39062. [[nodiscard]] std::decay_t<decltype(std::declval<internal::meta_type_node>().*Member)> lookup(meta_any *const args, const typename internal::meta_type_node::size_type sz, Pred pred) const {
  39063. std::decay_t<decltype(node->*Member)> candidate{};
  39064. size_type extent{sz + 1u};
  39065. bool ambiguous{};
  39066. for(auto *curr = (node->*Member); curr; curr = curr->next) {
  39067. if(pred(curr) && curr->arity == sz) {
  39068. size_type direct{};
  39069. size_type ext{};
  39070. for(size_type next{}; next < sz && next == (direct + ext) && args[next]; ++next) {
  39071. const auto type = args[next].type();
  39072. const auto other = curr->arg(next);
  39073. if(const auto &info = other.info(); info == type.info()) {
  39074. ++direct;
  39075. } else {
  39076. ext += internal::find_by<&node_type::base>(info, type.node)
  39077. || internal::find_by<&node_type::conv>(info, type.node)
  39078. || (type.node->conversion_helper && other.node->conversion_helper);
  39079. }
  39080. }
  39081. if((direct + ext) == sz) {
  39082. if(ext < extent) {
  39083. candidate = curr;
  39084. extent = ext;
  39085. ambiguous = false;
  39086. } else if(ext == extent) {
  39087. ambiguous = true;
  39088. }
  39089. }
  39090. }
  39091. }
  39092. return (candidate && !ambiguous) ? candidate : decltype(candidate){};
  39093. }
  39094. public:
  39095. /*! @brief Node type. */
  39096. using node_type = internal::meta_type_node;
  39097. /*! @brief Node type. */
  39098. using base_node_type = internal::meta_base_node;
  39099. /*! @brief Unsigned integer type. */
  39100. using size_type = typename node_type::size_type;
  39101. /*! @copydoc meta_prop::meta_prop */
  39102. meta_type(const node_type *curr = nullptr) ENTT_NOEXCEPT
  39103. : node{curr} {}
  39104. /**
  39105. * @brief Constructs an instance from a given base node.
  39106. * @param curr The base node with which to construct the instance.
  39107. */
  39108. meta_type(const base_node_type *curr) ENTT_NOEXCEPT
  39109. : node{curr ? curr->type : nullptr} {}
  39110. /**
  39111. * @brief Returns the type info object of the underlying type.
  39112. * @return The type info object of the underlying type.
  39113. */
  39114. [[nodiscard]] const type_info &info() const ENTT_NOEXCEPT {
  39115. return *node->info;
  39116. }
  39117. /**
  39118. * @brief Returns the identifier assigned to a type.
  39119. * @return The identifier assigned to the type.
  39120. */
  39121. [[nodiscard]] id_type id() const ENTT_NOEXCEPT {
  39122. return node->id;
  39123. }
  39124. /**
  39125. * @brief Returns the size of the underlying type if known.
  39126. * @return The size of the underlying type if known, 0 otherwise.
  39127. */
  39128. [[nodiscard]] size_type size_of() const ENTT_NOEXCEPT {
  39129. return node->size_of;
  39130. }
  39131. /**
  39132. * @brief Checks whether a type refers to an arithmetic type or not.
  39133. * @return True if the underlying type is an arithmetic type, false
  39134. * otherwise.
  39135. */
  39136. [[nodiscard]] bool is_arithmetic() const ENTT_NOEXCEPT {
  39137. return !!(node->traits & internal::meta_traits::is_arithmetic);
  39138. }
  39139. /**
  39140. * @brief Checks whether a type refers to an array type or not.
  39141. * @return True if the underlying type is an array type, false otherwise.
  39142. */
  39143. [[nodiscard]] bool is_array() const ENTT_NOEXCEPT {
  39144. return !!(node->traits & internal::meta_traits::is_array);
  39145. }
  39146. /**
  39147. * @brief Checks whether a type refers to an enum or not.
  39148. * @return True if the underlying type is an enum, false otherwise.
  39149. */
  39150. [[nodiscard]] bool is_enum() const ENTT_NOEXCEPT {
  39151. return !!(node->traits & internal::meta_traits::is_enum);
  39152. }
  39153. /**
  39154. * @brief Checks whether a type refers to a class or not.
  39155. * @return True if the underlying type is a class, false otherwise.
  39156. */
  39157. [[nodiscard]] bool is_class() const ENTT_NOEXCEPT {
  39158. return !!(node->traits & internal::meta_traits::is_class);
  39159. }
  39160. /**
  39161. * @brief Checks whether a type refers to a pointer or not.
  39162. * @return True if the underlying type is a pointer, false otherwise.
  39163. */
  39164. [[nodiscard]] bool is_pointer() const ENTT_NOEXCEPT {
  39165. return !!(node->traits & internal::meta_traits::is_pointer);
  39166. }
  39167. /**
  39168. * @brief Provides the type for which the pointer is defined.
  39169. * @return The type for which the pointer is defined or this type if it
  39170. * doesn't refer to a pointer type.
  39171. */
  39172. [[nodiscard]] meta_type remove_pointer() const ENTT_NOEXCEPT {
  39173. return node->remove_pointer();
  39174. }
  39175. /**
  39176. * @brief Checks whether a type is a pointer-like type or not.
  39177. * @return True if the underlying type is a pointer-like one, false
  39178. * otherwise.
  39179. */
  39180. [[nodiscard]] bool is_pointer_like() const ENTT_NOEXCEPT {
  39181. return !!(node->traits & internal::meta_traits::is_meta_pointer_like);
  39182. }
  39183. /**
  39184. * @brief Checks whether a type refers to a sequence container or not.
  39185. * @return True if the type is a sequence container, false otherwise.
  39186. */
  39187. [[nodiscard]] bool is_sequence_container() const ENTT_NOEXCEPT {
  39188. return !!(node->traits & internal::meta_traits::is_meta_sequence_container);
  39189. }
  39190. /**
  39191. * @brief Checks whether a type refers to an associative container or not.
  39192. * @return True if the type is an associative container, false otherwise.
  39193. */
  39194. [[nodiscard]] bool is_associative_container() const ENTT_NOEXCEPT {
  39195. return !!(node->traits & internal::meta_traits::is_meta_associative_container);
  39196. }
  39197. /**
  39198. * @brief Checks whether a type refers to a recognized class template
  39199. * specialization or not.
  39200. * @return True if the type is a recognized class template specialization,
  39201. * false otherwise.
  39202. */
  39203. [[nodiscard]] bool is_template_specialization() const ENTT_NOEXCEPT {
  39204. return (node->templ != nullptr);
  39205. }
  39206. /**
  39207. * @brief Returns the number of template arguments.
  39208. * @return The number of template arguments.
  39209. */
  39210. [[nodiscard]] size_type template_arity() const ENTT_NOEXCEPT {
  39211. return node->templ ? node->templ->arity : size_type{};
  39212. }
  39213. /**
  39214. * @brief Returns a tag for the class template of the underlying type.
  39215. *
  39216. * @sa meta_class_template_tag
  39217. *
  39218. * @return The tag for the class template of the underlying type.
  39219. */
  39220. [[nodiscard]] inline meta_type template_type() const ENTT_NOEXCEPT {
  39221. return node->templ ? node->templ->type : meta_type{};
  39222. }
  39223. /**
  39224. * @brief Returns the type of the i-th template argument of a type.
  39225. * @param index Index of the template argument of which to return the type.
  39226. * @return The type of the i-th template argument of a type.
  39227. */
  39228. [[nodiscard]] inline meta_type template_arg(const size_type index) const ENTT_NOEXCEPT {
  39229. return index < template_arity() ? node->templ->arg(index) : meta_type{};
  39230. }
  39231. /**
  39232. * @brief Returns a range to visit registered top-level base meta types.
  39233. * @return An iterable range to visit registered top-level base meta types.
  39234. */
  39235. [[nodiscard]] meta_range<meta_type, internal::meta_base_node> base() const ENTT_NOEXCEPT {
  39236. return node->base;
  39237. }
  39238. /**
  39239. * @brief Lookup function for registered base meta types.
  39240. * @param id Unique identifier.
  39241. * @return The registered base meta type for the given identifier, if any.
  39242. */
  39243. [[nodiscard]] meta_type base(const id_type id) const {
  39244. return internal::find_by<&node_type::base>(id, node);
  39245. }
  39246. /**
  39247. * @brief Returns a range to visit registered top-level meta data.
  39248. * @return An iterable range to visit registered top-level meta data.
  39249. */
  39250. [[nodiscard]] meta_range<meta_data> data() const ENTT_NOEXCEPT {
  39251. return node->data;
  39252. }
  39253. /**
  39254. * @brief Lookup function for registered meta data.
  39255. *
  39256. * Registered meta data of base classes will also be visited.
  39257. *
  39258. * @param id Unique identifier.
  39259. * @return The registered meta data for the given identifier, if any.
  39260. */
  39261. [[nodiscard]] meta_data data(const id_type id) const {
  39262. return internal::find_by<&node_type::data>(id, node);
  39263. }
  39264. /**
  39265. * @brief Returns a range to visit registered top-level functions.
  39266. * @return An iterable range to visit registered top-level functions.
  39267. */
  39268. [[nodiscard]] meta_range<meta_func> func() const ENTT_NOEXCEPT {
  39269. return node->func;
  39270. }
  39271. /**
  39272. * @brief Lookup function for registered meta functions.
  39273. *
  39274. * Registered meta functions of base classes will also be visited.<br/>
  39275. * In case of overloaded functions, the first one with the required
  39276. * identifier will be returned.
  39277. *
  39278. * @param id Unique identifier.
  39279. * @return The registered meta function for the given identifier, if any.
  39280. */
  39281. [[nodiscard]] meta_func func(const id_type id) const {
  39282. return internal::find_by<&node_type::func>(id, node);
  39283. }
  39284. /**
  39285. * @brief Creates an instance of the underlying type, if possible.
  39286. *
  39287. * Parameters are such that a cast or conversion to the required types is
  39288. * possible. Otherwise, an empty and thus invalid wrapper is returned.<br/>
  39289. * If suitable, the implicitly generated default constructor is used.
  39290. *
  39291. * @param args Parameters to use to construct the instance.
  39292. * @param sz Number of parameters to use to construct the instance.
  39293. * @return A wrapper containing the new instance, if any.
  39294. */
  39295. [[nodiscard]] meta_any construct(meta_any *const args, const size_type sz) const {
  39296. const auto *candidate = lookup<&node_type::ctor>(args, sz, [](const auto *) { return true; });
  39297. return candidate ? candidate->invoke(args) : ((!sz && node->default_constructor) ? node->default_constructor() : meta_any{});
  39298. }
  39299. /**
  39300. * @copybrief construct
  39301. *
  39302. * @sa construct
  39303. *
  39304. * @tparam Args Types of arguments to use to construct the instance.
  39305. * @param args Parameters to use to construct the instance.
  39306. * @return A wrapper containing the new instance, if any.
  39307. */
  39308. template<typename... Args>
  39309. [[nodiscard]] meta_any construct(Args &&...args) const {
  39310. meta_any arguments[sizeof...(Args) + 1u]{std::forward<Args>(args)...};
  39311. return construct(arguments, sizeof...(Args));
  39312. }
  39313. /**
  39314. * @brief Invokes a function given an identifier, if possible.
  39315. *
  39316. * It must be possible to cast the instance to the parent type of the member
  39317. * function.
  39318. *
  39319. * @sa meta_func::invoke
  39320. *
  39321. * @param id Unique identifier.
  39322. * @param instance An opaque instance of the underlying type.
  39323. * @param args Parameters to use to invoke the function.
  39324. * @param sz Number of parameters to use to invoke the function.
  39325. * @return A wrapper containing the returned value, if any.
  39326. */
  39327. meta_any invoke(const id_type id, meta_handle instance, meta_any *const args, const size_type sz) const {
  39328. const auto *candidate = lookup<&node_type::func>(args, sz, [id](const auto *curr) { return curr->id == id; });
  39329. for(auto it = base().begin(), last = base().end(); it != last && !candidate; ++it) {
  39330. candidate = it->lookup<&node_type::func>(args, sz, [id](const auto *curr) { return curr->id == id; });
  39331. }
  39332. return candidate ? candidate->invoke(std::move(instance), args) : meta_any{};
  39333. }
  39334. /**
  39335. * @copybrief invoke
  39336. *
  39337. * @sa invoke
  39338. *
  39339. * @param id Unique identifier.
  39340. * @tparam Args Types of arguments to use to invoke the function.
  39341. * @param instance An opaque instance of the underlying type.
  39342. * @param args Parameters to use to invoke the function.
  39343. * @return A wrapper containing the new instance, if any.
  39344. */
  39345. template<typename... Args>
  39346. meta_any invoke(const id_type id, meta_handle instance, Args &&...args) const {
  39347. meta_any arguments[sizeof...(Args) + 1u]{std::forward<Args>(args)...};
  39348. return invoke(id, std::move(instance), arguments, sizeof...(Args));
  39349. }
  39350. /**
  39351. * @brief Sets the value of a given variable.
  39352. *
  39353. * It must be possible to cast the instance to the parent type of the data
  39354. * member.<br/>
  39355. * The type of the value is such that a cast or conversion to the type of
  39356. * the variable is possible. Otherwise, invoking the setter does nothing.
  39357. *
  39358. * @tparam Type Type of value to assign.
  39359. * @param id Unique identifier.
  39360. * @param instance An opaque instance of the underlying type.
  39361. * @param value Parameter to use to set the underlying variable.
  39362. * @return True in case of success, false otherwise.
  39363. */
  39364. template<typename Type>
  39365. bool set(const id_type id, meta_handle instance, Type &&value) const {
  39366. const auto candidate = data(id);
  39367. return candidate && candidate.set(std::move(instance), std::forward<Type>(value));
  39368. }
  39369. /**
  39370. * @brief Gets the value of a given variable.
  39371. *
  39372. * It must be possible to cast the instance to the parent type of the data
  39373. * member.
  39374. *
  39375. * @param id Unique identifier.
  39376. * @param instance An opaque instance of the underlying type.
  39377. * @return A wrapper containing the value of the underlying variable.
  39378. */
  39379. [[nodiscard]] meta_any get(const id_type id, meta_handle instance) const {
  39380. const auto candidate = data(id);
  39381. return candidate ? candidate.get(std::move(instance)) : meta_any{};
  39382. }
  39383. /**
  39384. * @brief Returns a range to visit registered top-level meta properties.
  39385. * @return An iterable range to visit registered top-level meta properties.
  39386. */
  39387. [[nodiscard]] meta_range<meta_prop> prop() const ENTT_NOEXCEPT {
  39388. return node->prop;
  39389. }
  39390. /**
  39391. * @brief Lookup function for meta properties.
  39392. *
  39393. * Properties of base classes are also visited.
  39394. *
  39395. * @param key The key to use to search for a property.
  39396. * @return The registered meta property for the given key, if any.
  39397. */
  39398. [[nodiscard]] meta_prop prop(meta_any key) const {
  39399. return internal::find_by<&internal::meta_type_node::prop>(key, node);
  39400. }
  39401. /**
  39402. * @brief Returns true if an object is valid, false otherwise.
  39403. * @return True if the object is valid, false otherwise.
  39404. */
  39405. [[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
  39406. return !(node == nullptr);
  39407. }
  39408. /**
  39409. * @brief Checks if two objects refer to the same type.
  39410. * @param other The object with which to compare.
  39411. * @return True if the objects refer to the same type, false otherwise.
  39412. */
  39413. [[nodiscard]] bool operator==(const meta_type &other) const ENTT_NOEXCEPT {
  39414. return (!node && !other.node) || (node && other.node && *node->info == *other.node->info);
  39415. }
  39416. private:
  39417. const node_type *node;
  39418. };
  39419. /**
  39420. * @brief Checks if two objects refer to the same type.
  39421. * @param lhs An object, either valid or not.
  39422. * @param rhs An object, either valid or not.
  39423. * @return False if the objects refer to the same node, true otherwise.
  39424. */
  39425. [[nodiscard]] inline bool operator!=(const meta_type &lhs, const meta_type &rhs) ENTT_NOEXCEPT {
  39426. return !(lhs == rhs);
  39427. }
  39428. [[nodiscard]] inline meta_type meta_any::type() const ENTT_NOEXCEPT {
  39429. return node;
  39430. }
  39431. template<typename... Args>
  39432. meta_any meta_any::invoke(const id_type id, Args &&...args) const {
  39433. return type().invoke(id, *this, std::forward<Args>(args)...);
  39434. }
  39435. template<typename... Args>
  39436. meta_any meta_any::invoke(const id_type id, Args &&...args) {
  39437. return type().invoke(id, *this, std::forward<Args>(args)...);
  39438. }
  39439. template<typename Type>
  39440. bool meta_any::set(const id_type id, Type &&value) {
  39441. return type().set(id, *this, std::forward<Type>(value));
  39442. }
  39443. [[nodiscard]] inline meta_any meta_any::get(const id_type id) const {
  39444. return type().get(id, *this);
  39445. }
  39446. [[nodiscard]] inline meta_any meta_any::get(const id_type id) {
  39447. return type().get(id, *this);
  39448. }
  39449. [[nodiscard]] inline meta_any meta_any::allow_cast(const meta_type &type) const {
  39450. if(const auto &info = type.info(); node && *node->info == info) {
  39451. return as_ref();
  39452. } else if(node) {
  39453. for(auto *it = node->conv; it; it = it->next) {
  39454. if(*it->type->info == info) {
  39455. return it->conv(*this);
  39456. }
  39457. }
  39458. if(node->conversion_helper && (type.is_arithmetic() || type.is_enum())) {
  39459. // exploits the fact that arithmetic types and enums are also default constructible
  39460. auto other = type.construct();
  39461. ENTT_ASSERT(other.node->conversion_helper, "Conversion helper not found");
  39462. const auto value = node->conversion_helper(nullptr, storage.data());
  39463. other.node->conversion_helper(other.storage.data(), &value);
  39464. return other;
  39465. }
  39466. for(auto *it = node->base; it; it = it->next) {
  39467. const auto as_const = it->cast(as_ref());
  39468. if(auto other = as_const.allow_cast(type); other) {
  39469. return other;
  39470. }
  39471. }
  39472. }
  39473. return {};
  39474. }
  39475. inline bool meta_any::assign(const meta_any &other) {
  39476. auto value = other.allow_cast(node);
  39477. return value && storage.assign(std::move(value.storage));
  39478. }
  39479. inline bool meta_any::assign(meta_any &&other) {
  39480. if(*node->info == *other.node->info) {
  39481. return storage.assign(std::move(other.storage));
  39482. }
  39483. return assign(std::as_const(other));
  39484. }
  39485. [[nodiscard]] inline meta_type meta_data::type() const ENTT_NOEXCEPT {
  39486. return node->type;
  39487. }
  39488. [[nodiscard]] inline meta_type meta_func::ret() const ENTT_NOEXCEPT {
  39489. return node->ret;
  39490. }
  39491. [[nodiscard]] inline meta_type meta_data::arg(const size_type index) const ENTT_NOEXCEPT {
  39492. return index < arity() ? node->arg(index) : meta_type{};
  39493. }
  39494. [[nodiscard]] inline meta_type meta_func::arg(const size_type index) const ENTT_NOEXCEPT {
  39495. return index < arity() ? node->arg(index) : meta_type{};
  39496. }
  39497. /**
  39498. * @cond TURN_OFF_DOXYGEN
  39499. * Internal details not to be documented.
  39500. */
  39501. class meta_sequence_container::meta_iterator final {
  39502. friend class meta_sequence_container;
  39503. using deref_fn_type = meta_any(const any &, const std::ptrdiff_t);
  39504. template<typename It>
  39505. static meta_any deref_fn(const any &value, const std::ptrdiff_t pos) {
  39506. return meta_any{std::in_place_type<typename std::iterator_traits<It>::reference>, any_cast<const It &>(value)[pos]};
  39507. }
  39508. public:
  39509. using difference_type = std::ptrdiff_t;
  39510. using value_type = meta_any;
  39511. using pointer = input_iterator_pointer<value_type>;
  39512. using reference = value_type;
  39513. using iterator_category = std::input_iterator_tag;
  39514. meta_iterator() ENTT_NOEXCEPT
  39515. : deref{},
  39516. offset{},
  39517. handle{} {}
  39518. template<typename Type>
  39519. explicit meta_iterator(Type &cont, const difference_type init) ENTT_NOEXCEPT
  39520. : deref{&deref_fn<decltype(cont.begin())>},
  39521. offset{init},
  39522. handle{cont.begin()} {}
  39523. meta_iterator &operator++() ENTT_NOEXCEPT {
  39524. return ++offset, *this;
  39525. }
  39526. meta_iterator operator++(int value) ENTT_NOEXCEPT {
  39527. meta_iterator orig = *this;
  39528. offset += ++value;
  39529. return orig;
  39530. }
  39531. meta_iterator &operator--() ENTT_NOEXCEPT {
  39532. return --offset, *this;
  39533. }
  39534. meta_iterator operator--(int value) ENTT_NOEXCEPT {
  39535. meta_iterator orig = *this;
  39536. offset -= ++value;
  39537. return orig;
  39538. }
  39539. [[nodiscard]] reference operator*() const {
  39540. return deref(handle, offset);
  39541. }
  39542. [[nodiscard]] pointer operator->() const {
  39543. return operator*();
  39544. }
  39545. [[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
  39546. return static_cast<bool>(handle);
  39547. }
  39548. [[nodiscard]] bool operator==(const meta_iterator &other) const ENTT_NOEXCEPT {
  39549. return offset == other.offset;
  39550. }
  39551. [[nodiscard]] bool operator!=(const meta_iterator &other) const ENTT_NOEXCEPT {
  39552. return !(*this == other);
  39553. }
  39554. private:
  39555. deref_fn_type *deref;
  39556. difference_type offset;
  39557. any handle;
  39558. };
  39559. class meta_associative_container::meta_iterator final {
  39560. enum class operation : std::uint8_t {
  39561. incr,
  39562. deref
  39563. };
  39564. using vtable_type = void(const operation, const any &, std::pair<meta_any, meta_any> *);
  39565. template<bool KeyOnly, typename It>
  39566. static void basic_vtable(const operation op, const any &value, std::pair<meta_any, meta_any> *other) {
  39567. switch(op) {
  39568. case operation::incr:
  39569. ++any_cast<It &>(const_cast<any &>(value));
  39570. break;
  39571. case operation::deref:
  39572. const auto &it = any_cast<const It &>(value);
  39573. if constexpr(KeyOnly) {
  39574. other->first.emplace<decltype(*it)>(*it);
  39575. } else {
  39576. other->first.emplace<decltype((it->first))>(it->first);
  39577. other->second.emplace<decltype((it->second))>(it->second);
  39578. }
  39579. break;
  39580. }
  39581. }
  39582. public:
  39583. using difference_type = std::ptrdiff_t;
  39584. using value_type = std::pair<meta_any, meta_any>;
  39585. using pointer = input_iterator_pointer<value_type>;
  39586. using reference = value_type;
  39587. using iterator_category = std::input_iterator_tag;
  39588. meta_iterator() ENTT_NOEXCEPT
  39589. : vtable{},
  39590. handle{} {}
  39591. template<bool KeyOnly, typename It>
  39592. meta_iterator(std::integral_constant<bool, KeyOnly>, It iter) ENTT_NOEXCEPT
  39593. : vtable{&basic_vtable<KeyOnly, It>},
  39594. handle{std::move(iter)} {}
  39595. meta_iterator &operator++() ENTT_NOEXCEPT {
  39596. vtable(operation::incr, handle, nullptr);
  39597. return *this;
  39598. }
  39599. meta_iterator operator++(int) ENTT_NOEXCEPT {
  39600. meta_iterator orig = *this;
  39601. return ++(*this), orig;
  39602. }
  39603. [[nodiscard]] reference operator*() const {
  39604. reference other;
  39605. vtable(operation::deref, handle, &other);
  39606. return other;
  39607. }
  39608. [[nodiscard]] pointer operator->() const {
  39609. return operator*();
  39610. }
  39611. [[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
  39612. return static_cast<bool>(handle);
  39613. }
  39614. [[nodiscard]] bool operator==(const meta_iterator &other) const ENTT_NOEXCEPT {
  39615. return handle == other.handle;
  39616. }
  39617. [[nodiscard]] bool operator!=(const meta_iterator &other) const ENTT_NOEXCEPT {
  39618. return !(*this == other);
  39619. }
  39620. private:
  39621. vtable_type *vtable;
  39622. any handle;
  39623. };
  39624. /**
  39625. * Internal details not to be documented.
  39626. * @endcond
  39627. */
  39628. /**
  39629. * @brief Returns the meta value type of a container.
  39630. * @return The meta value type of the container.
  39631. */
  39632. [[nodiscard]] inline meta_type meta_sequence_container::value_type() const ENTT_NOEXCEPT {
  39633. return value_type_node;
  39634. }
  39635. /**
  39636. * @brief Returns the size of a container.
  39637. * @return The size of the container.
  39638. */
  39639. [[nodiscard]] inline meta_sequence_container::size_type meta_sequence_container::size() const ENTT_NOEXCEPT {
  39640. return size_fn(storage);
  39641. }
  39642. /**
  39643. * @brief Resizes a container to contain a given number of elements.
  39644. * @param sz The new size of the container.
  39645. * @return True in case of success, false otherwise.
  39646. */
  39647. inline bool meta_sequence_container::resize(const size_type sz) {
  39648. return resize_fn(storage, sz);
  39649. }
  39650. /**
  39651. * @brief Clears the content of a container.
  39652. * @return True in case of success, false otherwise.
  39653. */
  39654. inline bool meta_sequence_container::clear() {
  39655. return resize_fn(storage, 0u);
  39656. }
  39657. /**
  39658. * @brief Returns an iterator to the first element of a container.
  39659. * @return An iterator to the first element of the container.
  39660. */
  39661. [[nodiscard]] inline meta_sequence_container::iterator meta_sequence_container::begin() {
  39662. return iter_fn(storage, false);
  39663. }
  39664. /**
  39665. * @brief Returns an iterator that is past the last element of a container.
  39666. * @return An iterator that is past the last element of the container.
  39667. */
  39668. [[nodiscard]] inline meta_sequence_container::iterator meta_sequence_container::end() {
  39669. return iter_fn(storage, true);
  39670. }
  39671. /**
  39672. * @brief Inserts an element at a specified location of a container.
  39673. * @param it Iterator before which the element will be inserted.
  39674. * @param value Element value to insert.
  39675. * @return A possibly invalid iterator to the inserted element.
  39676. */
  39677. inline meta_sequence_container::iterator meta_sequence_container::insert(iterator it, meta_any value) {
  39678. return insert_fn(storage, it.offset, value);
  39679. }
  39680. /**
  39681. * @brief Removes a given element from a container.
  39682. * @param it Iterator to the element to remove.
  39683. * @return A possibly invalid iterator following the last removed element.
  39684. */
  39685. inline meta_sequence_container::iterator meta_sequence_container::erase(iterator it) {
  39686. return erase_fn(storage, it.offset);
  39687. }
  39688. /**
  39689. * @brief Returns a reference to the element at a given location of a container
  39690. * (no bounds checking is performed).
  39691. * @param pos The position of the element to return.
  39692. * @return A reference to the requested element properly wrapped.
  39693. */
  39694. [[nodiscard]] inline meta_any meta_sequence_container::operator[](const size_type pos) {
  39695. auto it = begin();
  39696. it.operator++(static_cast<int>(pos) - 1);
  39697. return *it;
  39698. }
  39699. /**
  39700. * @brief Returns false if a proxy is invalid, true otherwise.
  39701. * @return False if the proxy is invalid, true otherwise.
  39702. */
  39703. [[nodiscard]] inline meta_sequence_container::operator bool() const ENTT_NOEXCEPT {
  39704. return static_cast<bool>(storage);
  39705. }
  39706. /**
  39707. * @brief Returns true if a container is also key-only, false otherwise.
  39708. * @return True if the associative container is also key-only, false otherwise.
  39709. */
  39710. [[nodiscard]] inline bool meta_associative_container::key_only() const ENTT_NOEXCEPT {
  39711. return key_only_container;
  39712. }
  39713. /**
  39714. * @brief Returns the meta key type of a container.
  39715. * @return The meta key type of the a container.
  39716. */
  39717. [[nodiscard]] inline meta_type meta_associative_container::key_type() const ENTT_NOEXCEPT {
  39718. return key_type_node;
  39719. }
  39720. /**
  39721. * @brief Returns the meta mapped type of a container.
  39722. * @return The meta mapped type of the a container.
  39723. */
  39724. [[nodiscard]] inline meta_type meta_associative_container::mapped_type() const ENTT_NOEXCEPT {
  39725. return mapped_type_node;
  39726. }
  39727. /*! @copydoc meta_sequence_container::value_type */
  39728. [[nodiscard]] inline meta_type meta_associative_container::value_type() const ENTT_NOEXCEPT {
  39729. return value_type_node;
  39730. }
  39731. /*! @copydoc meta_sequence_container::size */
  39732. [[nodiscard]] inline meta_associative_container::size_type meta_associative_container::size() const ENTT_NOEXCEPT {
  39733. return size_fn(storage);
  39734. }
  39735. /*! @copydoc meta_sequence_container::clear */
  39736. inline bool meta_associative_container::clear() {
  39737. return clear_fn(storage);
  39738. }
  39739. /*! @copydoc meta_sequence_container::begin */
  39740. [[nodiscard]] inline meta_associative_container::iterator meta_associative_container::begin() {
  39741. return iter_fn(storage, false);
  39742. }
  39743. /*! @copydoc meta_sequence_container::end */
  39744. [[nodiscard]] inline meta_associative_container::iterator meta_associative_container::end() {
  39745. return iter_fn(storage, true);
  39746. }
  39747. /**
  39748. * @brief Inserts an element (a key/value pair) into a container.
  39749. * @param key The key of the element to insert.
  39750. * @param value The value of the element to insert.
  39751. * @return A bool denoting whether the insertion took place.
  39752. */
  39753. inline bool meta_associative_container::insert(meta_any key, meta_any value = {}) {
  39754. return insert_fn(storage, key, value);
  39755. }
  39756. /**
  39757. * @brief Removes the specified element from a container.
  39758. * @param key The key of the element to remove.
  39759. * @return A bool denoting whether the removal took place.
  39760. */
  39761. inline bool meta_associative_container::erase(meta_any key) {
  39762. return erase_fn(storage, key);
  39763. }
  39764. /**
  39765. * @brief Returns an iterator to the element with a given key, if any.
  39766. * @param key The key of the element to search.
  39767. * @return An iterator to the element with the given key, if any.
  39768. */
  39769. [[nodiscard]] inline meta_associative_container::iterator meta_associative_container::find(meta_any key) {
  39770. return find_fn(storage, key);
  39771. }
  39772. /**
  39773. * @brief Returns false if a proxy is invalid, true otherwise.
  39774. * @return False if the proxy is invalid, true otherwise.
  39775. */
  39776. [[nodiscard]] inline meta_associative_container::operator bool() const ENTT_NOEXCEPT {
  39777. return static_cast<bool>(storage);
  39778. }
  39779. } // namespace entt
  39780. #endif
  39781. // #include "meta/node.hpp"
  39782. #ifndef ENTT_META_NODE_HPP
  39783. #define ENTT_META_NODE_HPP
  39784. #include <cstddef>
  39785. #include <type_traits>
  39786. #include <utility>
  39787. // #include "../config/config.h"
  39788. // #include "../core/attribute.h"
  39789. // #include "../core/enum.hpp"
  39790. // #include "../core/fwd.hpp"
  39791. // #include "../core/type_info.hpp"
  39792. // #include "../core/type_traits.hpp"
  39793. // #include "type_traits.hpp"
  39794. namespace entt {
  39795. class meta_any;
  39796. class meta_type;
  39797. struct meta_handle;
  39798. /**
  39799. * @cond TURN_OFF_DOXYGEN
  39800. * Internal details not to be documented.
  39801. */
  39802. namespace internal {
  39803. enum class meta_traits : std::uint32_t {
  39804. is_none = 0x0000,
  39805. is_const = 0x0001,
  39806. is_static = 0x0002,
  39807. is_arithmetic = 0x0004,
  39808. is_array = 0x0008,
  39809. is_enum = 0x0010,
  39810. is_class = 0x0020,
  39811. is_pointer = 0x0040,
  39812. is_meta_pointer_like = 0x0080,
  39813. is_meta_sequence_container = 0x0100,
  39814. is_meta_associative_container = 0x0200,
  39815. _entt_enum_as_bitmask
  39816. };
  39817. struct meta_type_node;
  39818. struct meta_prop_node {
  39819. meta_prop_node *next;
  39820. const meta_any &id;
  39821. meta_any &value;
  39822. };
  39823. struct meta_base_node {
  39824. meta_base_node *next;
  39825. meta_type_node *const type;
  39826. meta_any (*const cast)(meta_any) ENTT_NOEXCEPT;
  39827. };
  39828. struct meta_conv_node {
  39829. meta_conv_node *next;
  39830. meta_type_node *const type;
  39831. meta_any (*const conv)(const meta_any &);
  39832. };
  39833. struct meta_ctor_node {
  39834. using size_type = std::size_t;
  39835. meta_ctor_node *next;
  39836. const size_type arity;
  39837. meta_type (*const arg)(const size_type) ENTT_NOEXCEPT;
  39838. meta_any (*const invoke)(meta_any *const);
  39839. };
  39840. struct meta_data_node {
  39841. using size_type = std::size_t;
  39842. id_type id;
  39843. const meta_traits traits;
  39844. meta_data_node *next;
  39845. meta_prop_node *prop;
  39846. const size_type arity;
  39847. meta_type_node *const type;
  39848. meta_type (*const arg)(const size_type) ENTT_NOEXCEPT;
  39849. bool (*const set)(meta_handle, meta_any);
  39850. meta_any (*const get)(meta_handle);
  39851. };
  39852. struct meta_func_node {
  39853. using size_type = std::size_t;
  39854. id_type id;
  39855. const meta_traits traits;
  39856. meta_func_node *next;
  39857. meta_prop_node *prop;
  39858. const size_type arity;
  39859. meta_type_node *const ret;
  39860. meta_type (*const arg)(const size_type) ENTT_NOEXCEPT;
  39861. meta_any (*const invoke)(meta_handle, meta_any *const);
  39862. };
  39863. struct meta_template_node {
  39864. using size_type = std::size_t;
  39865. const size_type arity;
  39866. meta_type_node *const type;
  39867. meta_type_node *(*const arg)(const size_type)ENTT_NOEXCEPT;
  39868. };
  39869. struct meta_type_node {
  39870. using size_type = std::size_t;
  39871. const type_info *info;
  39872. id_type id;
  39873. const meta_traits traits;
  39874. meta_type_node *next;
  39875. meta_prop_node *prop;
  39876. const size_type size_of;
  39877. meta_type_node *(*const remove_pointer)() ENTT_NOEXCEPT;
  39878. meta_any (*const default_constructor)();
  39879. double (*const conversion_helper)(void *, const void *);
  39880. const meta_template_node *const templ;
  39881. meta_ctor_node *ctor{nullptr};
  39882. meta_base_node *base{nullptr};
  39883. meta_conv_node *conv{nullptr};
  39884. meta_data_node *data{nullptr};
  39885. meta_func_node *func{nullptr};
  39886. void (*dtor)(void *){nullptr};
  39887. };
  39888. template<typename... Args>
  39889. meta_type_node *meta_arg_node(type_list<Args...>, const std::size_t index) ENTT_NOEXCEPT;
  39890. template<typename Type>
  39891. class ENTT_API meta_node {
  39892. static_assert(std::is_same_v<Type, std::remove_cv_t<std::remove_reference_t<Type>>>, "Invalid type");
  39893. [[nodiscard]] static auto *meta_default_constructor() ENTT_NOEXCEPT {
  39894. if constexpr(std::is_default_constructible_v<Type>) {
  39895. return +[]() { return meta_any{std::in_place_type<Type>}; };
  39896. } else {
  39897. return static_cast<std::decay_t<decltype(meta_type_node::default_constructor)>>(nullptr);
  39898. }
  39899. }
  39900. [[nodiscard]] static auto *meta_conversion_helper() ENTT_NOEXCEPT {
  39901. if constexpr(std::is_arithmetic_v<Type>) {
  39902. return +[](void *bin, const void *value) {
  39903. return bin ? static_cast<double>(*static_cast<Type *>(bin) = static_cast<Type>(*static_cast<const double *>(value))) : static_cast<double>(*static_cast<const Type *>(value));
  39904. };
  39905. } else if constexpr(std::is_enum_v<Type>) {
  39906. return +[](void *bin, const void *value) {
  39907. return bin ? static_cast<double>(*static_cast<Type *>(bin) = static_cast<Type>(static_cast<std::underlying_type_t<Type>>(*static_cast<const double *>(value)))) : static_cast<double>(*static_cast<const Type *>(value));
  39908. };
  39909. } else {
  39910. return static_cast<std::decay_t<decltype(meta_type_node::conversion_helper)>>(nullptr);
  39911. }
  39912. }
  39913. [[nodiscard]] static meta_template_node *meta_template_info() ENTT_NOEXCEPT {
  39914. if constexpr(is_complete_v<meta_template_traits<Type>>) {
  39915. static meta_template_node node{
  39916. meta_template_traits<Type>::args_type::size,
  39917. meta_node<typename meta_template_traits<Type>::class_type>::resolve(),
  39918. [](const std::size_t index) ENTT_NOEXCEPT { return meta_arg_node(typename meta_template_traits<Type>::args_type{}, index); }
  39919. // tricks clang-format
  39920. };
  39921. return &node;
  39922. } else {
  39923. return nullptr;
  39924. }
  39925. }
  39926. public:
  39927. [[nodiscard]] static meta_type_node *resolve() ENTT_NOEXCEPT {
  39928. static meta_type_node node{
  39929. &type_id<Type>(),
  39930. {},
  39931. internal::meta_traits::is_none
  39932. | (std::is_arithmetic_v<Type> ? internal::meta_traits::is_arithmetic : internal::meta_traits::is_none)
  39933. | (std::is_array_v<Type> ? internal::meta_traits::is_array : internal::meta_traits::is_none)
  39934. | (std::is_enum_v<Type> ? internal::meta_traits::is_enum : internal::meta_traits::is_none)
  39935. | (std::is_class_v<Type> ? internal::meta_traits::is_class : internal::meta_traits::is_none)
  39936. | (std::is_pointer_v<Type> ? internal::meta_traits::is_pointer : internal::meta_traits::is_none)
  39937. | (is_meta_pointer_like_v<Type> ? internal::meta_traits::is_meta_pointer_like : internal::meta_traits::is_none)
  39938. | (is_complete_v<meta_sequence_container_traits<Type>> ? internal::meta_traits::is_meta_sequence_container : internal::meta_traits::is_none)
  39939. | (is_complete_v<meta_associative_container_traits<Type>> ? internal::meta_traits::is_meta_associative_container : internal::meta_traits::is_none),
  39940. nullptr,
  39941. nullptr,
  39942. size_of_v<Type>,
  39943. &meta_node<std::remove_cv_t<std::remove_reference_t<std::remove_pointer_t<Type>>>>::resolve,
  39944. meta_default_constructor(),
  39945. meta_conversion_helper(),
  39946. meta_template_info()
  39947. // tricks clang-format
  39948. };
  39949. return &node;
  39950. }
  39951. };
  39952. template<typename... Args>
  39953. [[nodiscard]] meta_type_node *meta_arg_node(type_list<Args...>, const std::size_t index) ENTT_NOEXCEPT {
  39954. meta_type_node *args[sizeof...(Args) + 1u]{nullptr, internal::meta_node<std::remove_cv_t<std::remove_reference_t<Args>>>::resolve()...};
  39955. return args[index + 1u];
  39956. }
  39957. template<auto Member, typename Type>
  39958. [[nodiscard]] static std::decay_t<decltype(std::declval<internal::meta_type_node>().*Member)> find_by(const Type &info_or_id, const internal::meta_type_node *node) ENTT_NOEXCEPT {
  39959. for(auto *curr = node->*Member; curr; curr = curr->next) {
  39960. if constexpr(std::is_same_v<Type, type_info>) {
  39961. if(*curr->type->info == info_or_id) {
  39962. return curr;
  39963. }
  39964. } else if constexpr(std::is_same_v<decltype(curr), meta_base_node *>) {
  39965. if(curr->type->id == info_or_id) {
  39966. return curr;
  39967. }
  39968. } else {
  39969. if(curr->id == info_or_id) {
  39970. return curr;
  39971. }
  39972. }
  39973. }
  39974. for(auto *curr = node->base; curr; curr = curr->next) {
  39975. if(auto *ret = find_by<Member>(info_or_id, curr->type); ret) {
  39976. return ret;
  39977. }
  39978. }
  39979. return nullptr;
  39980. }
  39981. } // namespace internal
  39982. /**
  39983. * Internal details not to be documented.
  39984. * @endcond
  39985. */
  39986. } // namespace entt
  39987. #endif
  39988. // #include "meta/pointer.hpp"
  39989. #ifndef ENTT_META_POINTER_HPP
  39990. #define ENTT_META_POINTER_HPP
  39991. #include <memory>
  39992. #include <type_traits>
  39993. // #include "type_traits.hpp"
  39994. namespace entt {
  39995. /**
  39996. * @brief Makes plain pointers pointer-like types for the meta system.
  39997. * @tparam Type Element type.
  39998. */
  39999. template<typename Type>
  40000. struct is_meta_pointer_like<Type *>
  40001. : std::true_type {};
  40002. /**
  40003. * @brief Partial specialization used to reject pointers to arrays.
  40004. * @tparam Type Type of elements of the array.
  40005. * @tparam N Number of elements of the array.
  40006. */
  40007. template<typename Type, std::size_t N>
  40008. struct is_meta_pointer_like<Type (*)[N]>
  40009. : std::false_type {};
  40010. /**
  40011. * @brief Makes `std::shared_ptr`s of any type pointer-like types for the meta
  40012. * system.
  40013. * @tparam Type Element type.
  40014. */
  40015. template<typename Type>
  40016. struct is_meta_pointer_like<std::shared_ptr<Type>>
  40017. : std::true_type {};
  40018. /**
  40019. * @brief Makes `std::unique_ptr`s of any type pointer-like types for the meta
  40020. * system.
  40021. * @tparam Type Element type.
  40022. * @tparam Args Other arguments.
  40023. */
  40024. template<typename Type, typename... Args>
  40025. struct is_meta_pointer_like<std::unique_ptr<Type, Args...>>
  40026. : std::true_type {};
  40027. } // namespace entt
  40028. #endif
  40029. // #include "meta/policy.hpp"
  40030. #ifndef ENTT_META_POLICY_HPP
  40031. #define ENTT_META_POLICY_HPP
  40032. #include <type_traits>
  40033. namespace entt {
  40034. /*! @brief Empty class type used to request the _as ref_ policy. */
  40035. struct as_ref_t {
  40036. /**
  40037. * @cond TURN_OFF_DOXYGEN
  40038. * Internal details not to be documented.
  40039. */
  40040. template<typename Type>
  40041. static constexpr bool value = std::is_reference_v<Type> && !std::is_const_v<std::remove_reference_t<Type>>;
  40042. /**
  40043. * Internal details not to be documented.
  40044. * @endcond
  40045. */
  40046. };
  40047. /*! @brief Empty class type used to request the _as cref_ policy. */
  40048. struct as_cref_t {
  40049. /**
  40050. * @cond TURN_OFF_DOXYGEN
  40051. * Internal details not to be documented.
  40052. */
  40053. template<typename Type>
  40054. static constexpr bool value = std::is_reference_v<Type>;
  40055. /**
  40056. * Internal details not to be documented.
  40057. * @endcond
  40058. */
  40059. };
  40060. /*! @brief Empty class type used to request the _as-is_ policy. */
  40061. struct as_is_t {
  40062. /**
  40063. * @cond TURN_OFF_DOXYGEN
  40064. * Internal details not to be documented.
  40065. */
  40066. template<typename>
  40067. static constexpr bool value = true;
  40068. /**
  40069. * Internal details not to be documented.
  40070. * @endcond
  40071. */
  40072. };
  40073. /*! @brief Empty class type used to request the _as void_ policy. */
  40074. struct as_void_t {
  40075. /**
  40076. * @cond TURN_OFF_DOXYGEN
  40077. * Internal details not to be documented.
  40078. */
  40079. template<typename>
  40080. static constexpr bool value = true;
  40081. /**
  40082. * Internal details not to be documented.
  40083. * @endcond
  40084. */
  40085. };
  40086. } // namespace entt
  40087. #endif
  40088. // #include "meta/range.hpp"
  40089. #ifndef ENTT_META_RANGE_HPP
  40090. #define ENTT_META_RANGE_HPP
  40091. #include <cstddef>
  40092. #include <iterator>
  40093. // #include "../core/iterator.hpp"
  40094. namespace entt {
  40095. /**
  40096. * @cond TURN_OFF_DOXYGEN
  40097. * Internal details not to be documented.
  40098. */
  40099. namespace internal {
  40100. template<typename Type, typename Node>
  40101. struct meta_range_iterator final {
  40102. using difference_type = std::ptrdiff_t;
  40103. using value_type = Type;
  40104. using pointer = input_iterator_pointer<value_type>;
  40105. using reference = value_type;
  40106. using iterator_category = std::input_iterator_tag;
  40107. using node_type = Node;
  40108. meta_range_iterator() ENTT_NOEXCEPT
  40109. : it{} {}
  40110. meta_range_iterator(node_type *head) ENTT_NOEXCEPT
  40111. : it{head} {}
  40112. meta_range_iterator &operator++() ENTT_NOEXCEPT {
  40113. return (it = it->next), *this;
  40114. }
  40115. meta_range_iterator operator++(int) ENTT_NOEXCEPT {
  40116. meta_range_iterator orig = *this;
  40117. return ++(*this), orig;
  40118. }
  40119. [[nodiscard]] reference operator*() const ENTT_NOEXCEPT {
  40120. return it;
  40121. }
  40122. [[nodiscard]] pointer operator->() const ENTT_NOEXCEPT {
  40123. return operator*();
  40124. }
  40125. [[nodiscard]] bool operator==(const meta_range_iterator &other) const ENTT_NOEXCEPT {
  40126. return it == other.it;
  40127. }
  40128. [[nodiscard]] bool operator!=(const meta_range_iterator &other) const ENTT_NOEXCEPT {
  40129. return !(*this == other);
  40130. }
  40131. private:
  40132. node_type *it;
  40133. };
  40134. } // namespace internal
  40135. /**
  40136. * Internal details not to be documented.
  40137. * @endcond
  40138. */
  40139. /**
  40140. * @brief Iterable range to use to iterate all types of meta objects.
  40141. * @tparam Type Type of meta objects returned.
  40142. * @tparam Node Type of meta nodes iterated.
  40143. */
  40144. template<typename Type, typename Node = typename Type::node_type>
  40145. struct meta_range final {
  40146. /*! @brief Node type. */
  40147. using node_type = Node;
  40148. /*! @brief Input iterator type. */
  40149. using iterator = internal::meta_range_iterator<Type, Node>;
  40150. /*! @brief Constant input iterator type. */
  40151. using const_iterator = iterator;
  40152. /*! @brief Default constructor. */
  40153. meta_range() ENTT_NOEXCEPT = default;
  40154. /**
  40155. * @brief Constructs a meta range from a given node.
  40156. * @param head The underlying node with which to construct the range.
  40157. */
  40158. meta_range(node_type *head) ENTT_NOEXCEPT
  40159. : node{head} {}
  40160. /**
  40161. * @brief Returns an iterator to the beginning.
  40162. * @return An iterator to the first meta object of the range.
  40163. */
  40164. [[nodiscard]] const_iterator cbegin() const ENTT_NOEXCEPT {
  40165. return iterator{node};
  40166. }
  40167. /*! @copydoc cbegin */
  40168. [[nodiscard]] iterator begin() const ENTT_NOEXCEPT {
  40169. return cbegin();
  40170. }
  40171. /**
  40172. * @brief Returns an iterator to the end.
  40173. * @return An iterator to the element following the last meta object of the
  40174. * range.
  40175. */
  40176. [[nodiscard]] const_iterator cend() const ENTT_NOEXCEPT {
  40177. return iterator{};
  40178. }
  40179. /*! @copydoc cend */
  40180. [[nodiscard]] iterator end() const ENTT_NOEXCEPT {
  40181. return cend();
  40182. }
  40183. private:
  40184. node_type *node{nullptr};
  40185. };
  40186. } // namespace entt
  40187. #endif
  40188. // #include "meta/resolve.hpp"
  40189. #ifndef ENTT_META_RESOLVE_HPP
  40190. #define ENTT_META_RESOLVE_HPP
  40191. #include <algorithm>
  40192. // #include "../core/type_info.hpp"
  40193. // #include "ctx.hpp"
  40194. // #include "meta.hpp"
  40195. // #include "node.hpp"
  40196. // #include "range.hpp"
  40197. namespace entt {
  40198. /**
  40199. * @brief Returns the meta type associated with a given type.
  40200. * @tparam Type Type to use to search for a meta type.
  40201. * @return The meta type associated with the given type, if any.
  40202. */
  40203. template<typename Type>
  40204. [[nodiscard]] meta_type resolve() ENTT_NOEXCEPT {
  40205. return internal::meta_node<std::remove_cv_t<std::remove_reference_t<Type>>>::resolve();
  40206. }
  40207. /**
  40208. * @brief Returns a range to use to visit all meta types.
  40209. * @return An iterable range to use to visit all meta types.
  40210. */
  40211. [[nodiscard]] inline meta_range<meta_type> resolve() ENTT_NOEXCEPT {
  40212. return *internal::meta_context::global();
  40213. }
  40214. /**
  40215. * @brief Returns the meta type associated with a given identifier, if any.
  40216. * @param id Unique identifier.
  40217. * @return The meta type associated with the given identifier, if any.
  40218. */
  40219. [[nodiscard]] inline meta_type resolve(const id_type id) ENTT_NOEXCEPT {
  40220. for(auto &&curr: resolve()) {
  40221. if(curr.id() == id) {
  40222. return curr;
  40223. }
  40224. }
  40225. return {};
  40226. }
  40227. /**
  40228. * @brief Returns the meta type associated with a given type info object.
  40229. * @param info The type info object of the requested type.
  40230. * @return The meta type associated with the given type info object, if any.
  40231. */
  40232. [[nodiscard]] inline meta_type resolve(const type_info &info) ENTT_NOEXCEPT {
  40233. for(auto &&curr: resolve()) {
  40234. if(curr.info() == info) {
  40235. return curr;
  40236. }
  40237. }
  40238. return {};
  40239. }
  40240. } // namespace entt
  40241. #endif
  40242. // #include "meta/template.hpp"
  40243. #ifndef ENTT_META_TEMPLATE_HPP
  40244. #define ENTT_META_TEMPLATE_HPP
  40245. // #include "../core/type_traits.hpp"
  40246. namespace entt {
  40247. /*! @brief Utility class to disambiguate class templates. */
  40248. template<template<typename...> class>
  40249. struct meta_class_template_tag {};
  40250. /**
  40251. * @brief General purpose traits class for generating meta template information.
  40252. * @tparam Clazz Type of class template.
  40253. * @tparam Args Types of template arguments.
  40254. */
  40255. template<template<typename...> class Clazz, typename... Args>
  40256. struct meta_template_traits<Clazz<Args...>> {
  40257. /*! @brief Wrapped class template. */
  40258. using class_type = meta_class_template_tag<Clazz>;
  40259. /*! @brief List of template arguments. */
  40260. using args_type = type_list<Args...>;
  40261. };
  40262. } // namespace entt
  40263. #endif
  40264. // #include "meta/type_traits.hpp"
  40265. #ifndef ENTT_META_TYPE_TRAITS_HPP
  40266. #define ENTT_META_TYPE_TRAITS_HPP
  40267. #include <type_traits>
  40268. #include <utility>
  40269. namespace entt {
  40270. /**
  40271. * @brief Traits class template to be specialized to enable support for meta
  40272. * template information.
  40273. */
  40274. template<typename>
  40275. struct meta_template_traits;
  40276. /**
  40277. * @brief Traits class template to be specialized to enable support for meta
  40278. * sequence containers.
  40279. */
  40280. template<typename>
  40281. struct meta_sequence_container_traits;
  40282. /**
  40283. * @brief Traits class template to be specialized to enable support for meta
  40284. * associative containers.
  40285. */
  40286. template<typename>
  40287. struct meta_associative_container_traits;
  40288. /**
  40289. * @brief Provides the member constant `value` to true if a given type is a
  40290. * pointer-like type from the point of view of the meta system, false otherwise.
  40291. * @tparam Type Potentially pointer-like type.
  40292. */
  40293. template<typename>
  40294. struct is_meta_pointer_like: std::false_type {};
  40295. /**
  40296. * @brief Partial specialization to ensure that const pointer-like types are
  40297. * also accepted.
  40298. * @tparam Type Potentially pointer-like type.
  40299. */
  40300. template<typename Type>
  40301. struct is_meta_pointer_like<const Type>: is_meta_pointer_like<Type> {};
  40302. /**
  40303. * @brief Helper variable template.
  40304. * @tparam Type Potentially pointer-like type.
  40305. */
  40306. template<typename Type>
  40307. inline constexpr auto is_meta_pointer_like_v = is_meta_pointer_like<Type>::value;
  40308. } // namespace entt
  40309. #endif
  40310. // #include "meta/utility.hpp"
  40311. #ifndef ENTT_META_UTILITY_HPP
  40312. #define ENTT_META_UTILITY_HPP
  40313. #include <cstddef>
  40314. #include <functional>
  40315. #include <type_traits>
  40316. #include <utility>
  40317. // #include "../config/config.h"
  40318. // #include "../core/type_traits.hpp"
  40319. // #include "meta.hpp"
  40320. // #include "node.hpp"
  40321. // #include "policy.hpp"
  40322. namespace entt {
  40323. /*! @brief Primary template isn't defined on purpose. */
  40324. template<typename, typename>
  40325. struct meta_function_descriptor;
  40326. /**
  40327. * @brief Meta function descriptor.
  40328. * @tparam Type Reflected type to which the meta function is associated.
  40329. * @tparam Ret Function return type.
  40330. * @tparam Class Actual owner of the member function.
  40331. * @tparam Args Function arguments.
  40332. */
  40333. template<typename Type, typename Ret, typename Class, typename... Args>
  40334. struct meta_function_descriptor<Type, Ret (Class::*)(Args...) const> {
  40335. /*! @brief Meta function return type. */
  40336. using return_type = Ret;
  40337. /*! @brief Meta function arguments. */
  40338. using args_type = std::conditional_t<std::is_base_of_v<Class, Type>, type_list<Args...>, type_list<const Class &, Args...>>;
  40339. /*! @brief True if the meta function is const, false otherwise. */
  40340. static constexpr auto is_const = true;
  40341. /*! @brief True if the meta function is static, false otherwise. */
  40342. static constexpr auto is_static = !std::is_base_of_v<Class, Type>;
  40343. };
  40344. /**
  40345. * @brief Meta function descriptor.
  40346. * @tparam Type Reflected type to which the meta function is associated.
  40347. * @tparam Ret Function return type.
  40348. * @tparam Class Actual owner of the member function.
  40349. * @tparam Args Function arguments.
  40350. */
  40351. template<typename Type, typename Ret, typename Class, typename... Args>
  40352. struct meta_function_descriptor<Type, Ret (Class::*)(Args...)> {
  40353. /*! @brief Meta function return type. */
  40354. using return_type = Ret;
  40355. /*! @brief Meta function arguments. */
  40356. using args_type = std::conditional_t<std::is_base_of_v<Class, Type>, type_list<Args...>, type_list<Class &, Args...>>;
  40357. /*! @brief True if the meta function is const, false otherwise. */
  40358. static constexpr auto is_const = false;
  40359. /*! @brief True if the meta function is static, false otherwise. */
  40360. static constexpr auto is_static = !std::is_base_of_v<Class, Type>;
  40361. };
  40362. /**
  40363. * @brief Meta function descriptor.
  40364. * @tparam Type Reflected type to which the meta data is associated.
  40365. * @tparam Class Actual owner of the data member.
  40366. * @tparam Ret Data member type.
  40367. */
  40368. template<typename Type, typename Ret, typename Class>
  40369. struct meta_function_descriptor<Type, Ret Class::*> {
  40370. /*! @brief Meta data return type. */
  40371. using return_type = Ret &;
  40372. /*! @brief Meta data arguments. */
  40373. using args_type = std::conditional_t<std::is_base_of_v<Class, Type>, type_list<>, type_list<Class &>>;
  40374. /*! @brief True if the meta data is const, false otherwise. */
  40375. static constexpr auto is_const = false;
  40376. /*! @brief True if the meta data is static, false otherwise. */
  40377. static constexpr auto is_static = !std::is_base_of_v<Class, Type>;
  40378. };
  40379. /**
  40380. * @brief Meta function descriptor.
  40381. * @tparam Type Reflected type to which the meta function is associated.
  40382. * @tparam Ret Function return type.
  40383. * @tparam MaybeType First function argument.
  40384. * @tparam Args Other function arguments.
  40385. */
  40386. template<typename Type, typename Ret, typename MaybeType, typename... Args>
  40387. struct meta_function_descriptor<Type, Ret (*)(MaybeType, Args...)> {
  40388. /*! @brief Meta function return type. */
  40389. using return_type = Ret;
  40390. /*! @brief Meta function arguments. */
  40391. using args_type = std::conditional_t<std::is_base_of_v<std::remove_cv_t<std::remove_reference_t<MaybeType>>, Type>, type_list<Args...>, type_list<MaybeType, Args...>>;
  40392. /*! @brief True if the meta function is const, false otherwise. */
  40393. static constexpr auto is_const = std::is_base_of_v<std::remove_cv_t<std::remove_reference_t<MaybeType>>, Type> && std::is_const_v<std::remove_reference_t<MaybeType>>;
  40394. /*! @brief True if the meta function is static, false otherwise. */
  40395. static constexpr auto is_static = !std::is_base_of_v<std::remove_cv_t<std::remove_reference_t<MaybeType>>, Type>;
  40396. };
  40397. /**
  40398. * @brief Meta function descriptor.
  40399. * @tparam Type Reflected type to which the meta function is associated.
  40400. * @tparam Ret Function return type.
  40401. */
  40402. template<typename Type, typename Ret>
  40403. struct meta_function_descriptor<Type, Ret (*)()> {
  40404. /*! @brief Meta function return type. */
  40405. using return_type = Ret;
  40406. /*! @brief Meta function arguments. */
  40407. using args_type = type_list<>;
  40408. /*! @brief True if the meta function is const, false otherwise. */
  40409. static constexpr auto is_const = false;
  40410. /*! @brief True if the meta function is static, false otherwise. */
  40411. static constexpr auto is_static = true;
  40412. };
  40413. /**
  40414. * @brief Meta function helper.
  40415. *
  40416. * Converts a function type to be associated with a reflected type into its meta
  40417. * function descriptor.
  40418. *
  40419. * @tparam Type Reflected type to which the meta function is associated.
  40420. * @tparam Candidate The actual function to associate with the reflected type.
  40421. */
  40422. template<typename Type, typename Candidate>
  40423. class meta_function_helper {
  40424. template<typename Ret, typename... Args, typename Class>
  40425. static constexpr meta_function_descriptor<Type, Ret (Class::*)(Args...) const> get_rid_of_noexcept(Ret (Class::*)(Args...) const);
  40426. template<typename Ret, typename... Args, typename Class>
  40427. static constexpr meta_function_descriptor<Type, Ret (Class::*)(Args...)> get_rid_of_noexcept(Ret (Class::*)(Args...));
  40428. template<typename Ret, typename Class>
  40429. static constexpr meta_function_descriptor<Type, Ret Class::*> get_rid_of_noexcept(Ret Class::*);
  40430. template<typename Ret, typename... Args>
  40431. static constexpr meta_function_descriptor<Type, Ret (*)(Args...)> get_rid_of_noexcept(Ret (*)(Args...));
  40432. template<typename Class>
  40433. static constexpr meta_function_descriptor<Class, decltype(&Class::operator())> get_rid_of_noexcept(Class);
  40434. public:
  40435. /*! @brief The meta function descriptor of the given function. */
  40436. using type = decltype(get_rid_of_noexcept(std::declval<Candidate>()));
  40437. };
  40438. /**
  40439. * @brief Helper type.
  40440. * @tparam Type Reflected type to which the meta function is associated.
  40441. * @tparam Candidate The actual function to associate with the reflected type.
  40442. */
  40443. template<typename Type, typename Candidate>
  40444. using meta_function_helper_t = typename meta_function_helper<Type, Candidate>::type;
  40445. /**
  40446. * @brief Wraps a value depending on the given policy.
  40447. * @tparam Policy Optional policy (no policy set by default).
  40448. * @tparam Type Type of value to wrap.
  40449. * @param value Value to wrap.
  40450. * @return A meta any containing the returned value, if any.
  40451. */
  40452. template<typename Policy = as_is_t, typename Type>
  40453. meta_any meta_dispatch([[maybe_unused]] Type &&value) {
  40454. if constexpr(std::is_same_v<Policy, as_void_t>) {
  40455. return meta_any{std::in_place_type<void>};
  40456. } else if constexpr(std::is_same_v<Policy, as_ref_t>) {
  40457. return meta_any{std::in_place_type<Type>, std::forward<Type>(value)};
  40458. } else if constexpr(std::is_same_v<Policy, as_cref_t>) {
  40459. static_assert(std::is_lvalue_reference_v<Type>, "Invalid type");
  40460. return meta_any{std::in_place_type<const std::remove_reference_t<Type> &>, std::as_const(value)};
  40461. } else {
  40462. static_assert(std::is_same_v<Policy, as_is_t>, "Policy not supported");
  40463. return meta_any{std::forward<Type>(value)};
  40464. }
  40465. }
  40466. /**
  40467. * @brief Returns the meta type of the i-th element of a list of arguments.
  40468. * @tparam Type Type list of the actual types of arguments.
  40469. * @return The meta type of the i-th element of the list of arguments.
  40470. */
  40471. template<typename Type>
  40472. [[nodiscard]] static meta_type meta_arg(const std::size_t index) ENTT_NOEXCEPT {
  40473. return internal::meta_arg_node(Type{}, index);
  40474. }
  40475. /**
  40476. * @brief Sets the value of a given variable.
  40477. * @tparam Type Reflected type to which the variable is associated.
  40478. * @tparam Data The actual variable to set.
  40479. * @param instance An opaque instance of the underlying type, if required.
  40480. * @param value Parameter to use to set the variable.
  40481. * @return True in case of success, false otherwise.
  40482. */
  40483. template<typename Type, auto Data>
  40484. [[nodiscard]] bool meta_setter([[maybe_unused]] meta_handle instance, [[maybe_unused]] meta_any value) {
  40485. if constexpr(!std::is_same_v<decltype(Data), Type> && !std::is_same_v<decltype(Data), std::nullptr_t>) {
  40486. if constexpr(std::is_member_function_pointer_v<decltype(Data)> || std::is_function_v<std::remove_reference_t<std::remove_pointer_t<decltype(Data)>>>) {
  40487. using descriptor = meta_function_helper_t<Type, decltype(Data)>;
  40488. using data_type = type_list_element_t<descriptor::is_static, typename descriptor::args_type>;
  40489. if(auto *const clazz = instance->try_cast<Type>(); clazz && value.allow_cast<data_type>()) {
  40490. std::invoke(Data, *clazz, value.cast<data_type>());
  40491. return true;
  40492. }
  40493. } else if constexpr(std::is_member_object_pointer_v<decltype(Data)>) {
  40494. using data_type = std::remove_reference_t<typename meta_function_helper_t<Type, decltype(Data)>::return_type>;
  40495. if constexpr(!std::is_array_v<data_type> && !std::is_const_v<data_type>) {
  40496. if(auto *const clazz = instance->try_cast<Type>(); clazz && value.allow_cast<data_type>()) {
  40497. std::invoke(Data, *clazz) = value.cast<data_type>();
  40498. return true;
  40499. }
  40500. }
  40501. } else {
  40502. using data_type = std::remove_reference_t<decltype(*Data)>;
  40503. if constexpr(!std::is_array_v<data_type> && !std::is_const_v<data_type>) {
  40504. if(value.allow_cast<data_type>()) {
  40505. *Data = value.cast<data_type>();
  40506. return true;
  40507. }
  40508. }
  40509. }
  40510. }
  40511. return false;
  40512. }
  40513. /**
  40514. * @brief Gets the value of a given variable.
  40515. * @tparam Type Reflected type to which the variable is associated.
  40516. * @tparam Data The actual variable to get.
  40517. * @tparam Policy Optional policy (no policy set by default).
  40518. * @param instance An opaque instance of the underlying type, if required.
  40519. * @return A meta any containing the value of the underlying variable.
  40520. */
  40521. template<typename Type, auto Data, typename Policy = as_is_t>
  40522. [[nodiscard]] meta_any meta_getter([[maybe_unused]] meta_handle instance) {
  40523. if constexpr(std::is_member_pointer_v<decltype(Data)> || std::is_function_v<std::remove_reference_t<std::remove_pointer_t<decltype(Data)>>>) {
  40524. if constexpr(!std::is_array_v<std::remove_cv_t<std::remove_reference_t<std::invoke_result_t<decltype(Data), Type &>>>>) {
  40525. if constexpr(std::is_invocable_v<decltype(Data), Type &>) {
  40526. if(auto *clazz = instance->try_cast<Type>(); clazz) {
  40527. return meta_dispatch<Policy>(std::invoke(Data, *clazz));
  40528. }
  40529. }
  40530. if constexpr(std::is_invocable_v<decltype(Data), const Type &>) {
  40531. if(auto *fallback = instance->try_cast<const Type>(); fallback) {
  40532. return meta_dispatch<Policy>(std::invoke(Data, *fallback));
  40533. }
  40534. }
  40535. }
  40536. return meta_any{};
  40537. } else if constexpr(std::is_pointer_v<decltype(Data)>) {
  40538. if constexpr(std::is_array_v<std::remove_pointer_t<decltype(Data)>>) {
  40539. return meta_any{};
  40540. } else {
  40541. return meta_dispatch<Policy>(*Data);
  40542. }
  40543. } else {
  40544. return meta_dispatch<Policy>(Data);
  40545. }
  40546. }
  40547. /**
  40548. * @cond TURN_OFF_DOXYGEN
  40549. * Internal details not to be documented.
  40550. */
  40551. namespace internal {
  40552. template<typename Type, typename Policy, typename Candidate, typename... Args>
  40553. [[nodiscard]] meta_any meta_invoke_with_args(Candidate &&candidate, Args &&...args) {
  40554. if constexpr(std::is_same_v<std::invoke_result_t<decltype(candidate), Args...>, void>) {
  40555. std::invoke(candidate, args...);
  40556. return meta_any{std::in_place_type<void>};
  40557. } else {
  40558. return meta_dispatch<Policy>(std::invoke(candidate, args...));
  40559. }
  40560. }
  40561. template<typename Type, typename Policy, typename Candidate, std::size_t... Index>
  40562. [[nodiscard]] meta_any meta_invoke([[maybe_unused]] meta_handle instance, Candidate &&candidate, [[maybe_unused]] meta_any *args, std::index_sequence<Index...>) {
  40563. using descriptor = meta_function_helper_t<Type, std::remove_reference_t<Candidate>>;
  40564. if constexpr(std::is_invocable_v<std::remove_reference_t<Candidate>, const Type &, type_list_element_t<Index, typename descriptor::args_type>...>) {
  40565. if(const auto *const clazz = instance->try_cast<const Type>(); clazz && ((args + Index)->allow_cast<type_list_element_t<Index, typename descriptor::args_type>>() && ...)) {
  40566. return meta_invoke_with_args<Type, Policy>(std::forward<Candidate>(candidate), *clazz, (args + Index)->cast<type_list_element_t<Index, typename descriptor::args_type>>()...);
  40567. }
  40568. } else if constexpr(std::is_invocable_v<std::remove_reference_t<Candidate>, Type &, type_list_element_t<Index, typename descriptor::args_type>...>) {
  40569. if(auto *const clazz = instance->try_cast<Type>(); clazz && ((args + Index)->allow_cast<type_list_element_t<Index, typename descriptor::args_type>>() && ...)) {
  40570. return meta_invoke_with_args<Type, Policy>(std::forward<Candidate>(candidate), *clazz, (args + Index)->cast<type_list_element_t<Index, typename descriptor::args_type>>()...);
  40571. }
  40572. } else {
  40573. if(((args + Index)->allow_cast<type_list_element_t<Index, typename descriptor::args_type>>() && ...)) {
  40574. return meta_invoke_with_args<Type, Policy>(std::forward<Candidate>(candidate), (args + Index)->cast<type_list_element_t<Index, typename descriptor::args_type>>()...);
  40575. }
  40576. }
  40577. return meta_any{};
  40578. }
  40579. template<typename Type, typename... Args, std::size_t... Index>
  40580. [[nodiscard]] meta_any meta_construct(meta_any *const args, std::index_sequence<Index...>) {
  40581. if(((args + Index)->allow_cast<Args>() && ...)) {
  40582. return meta_any{std::in_place_type<Type>, (args + Index)->cast<Args>()...};
  40583. }
  40584. return meta_any{};
  40585. }
  40586. } // namespace internal
  40587. /**
  40588. * Internal details not to be documented.
  40589. * @endcond
  40590. */
  40591. /**
  40592. * @brief Tries to _invoke_ an object given a list of erased parameters.
  40593. * @tparam Type Reflected type to which the object to _invoke_ is associated.
  40594. * @tparam Policy Optional policy (no policy set by default).
  40595. * @tparam Candidate The type of the actual object to _invoke_.
  40596. * @param instance An opaque instance of the underlying type, if required.
  40597. * @param candidate The actual object to _invoke_.
  40598. * @param args Parameters to use to _invoke_ the object.
  40599. * @return A meta any containing the returned value, if any.
  40600. */
  40601. template<typename Type, typename Policy = as_is_t, typename Candidate>
  40602. [[nodiscard]] meta_any meta_invoke([[maybe_unused]] meta_handle instance, Candidate &&candidate, [[maybe_unused]] meta_any *const args) {
  40603. return internal::meta_invoke<Type, Policy>(std::move(instance), std::forward<Candidate>(candidate), args, std::make_index_sequence<meta_function_helper_t<Type, std::remove_reference_t<Candidate>>::args_type::size>{});
  40604. }
  40605. /**
  40606. * @brief Tries to invoke a function given a list of erased parameters.
  40607. * @tparam Type Reflected type to which the function is associated.
  40608. * @tparam Candidate The actual function to invoke.
  40609. * @tparam Policy Optional policy (no policy set by default).
  40610. * @param instance An opaque instance of the underlying type, if required.
  40611. * @param args Parameters to use to invoke the function.
  40612. * @return A meta any containing the returned value, if any.
  40613. */
  40614. template<typename Type, auto Candidate, typename Policy = as_is_t>
  40615. [[nodiscard]] meta_any meta_invoke(meta_handle instance, meta_any *const args) {
  40616. return internal::meta_invoke<Type, Policy>(std::move(instance), Candidate, args, std::make_index_sequence<meta_function_helper_t<Type, std::remove_reference_t<decltype(Candidate)>>::args_type::size>{});
  40617. }
  40618. /**
  40619. * @brief Tries to construct an instance given a list of erased parameters.
  40620. * @tparam Type Actual type of the instance to construct.
  40621. * @tparam Args Types of arguments expected.
  40622. * @param args Parameters to use to construct the instance.
  40623. * @return A meta any containing the new instance, if any.
  40624. */
  40625. template<typename Type, typename... Args>
  40626. [[nodiscard]] meta_any meta_construct(meta_any *const args) {
  40627. return internal::meta_construct<Type, Args...>(args, std::index_sequence_for<Args...>{});
  40628. }
  40629. /**
  40630. * @brief Tries to construct an instance given a list of erased parameters.
  40631. * @tparam Type Reflected type to which the object to _invoke_ is associated.
  40632. * @tparam Policy Optional policy (no policy set by default).
  40633. * @tparam Candidate The type of the actual object to _invoke_.
  40634. * @param args Parameters to use to _invoke_ the object.
  40635. * @param candidate The actual object to _invoke_.
  40636. * @return A meta any containing the returned value, if any.
  40637. */
  40638. template<typename Type, typename Policy = as_is_t, typename Candidate>
  40639. [[nodiscard]] meta_any meta_construct(Candidate &&candidate, meta_any *const args) {
  40640. if constexpr(meta_function_helper_t<Type, Candidate>::is_static) {
  40641. return internal::meta_invoke<Type, Policy>({}, std::forward<Candidate>(candidate), args, std::make_index_sequence<meta_function_helper_t<Type, std::remove_reference_t<Candidate>>::args_type::size>{});
  40642. } else {
  40643. 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>{});
  40644. }
  40645. }
  40646. /**
  40647. * @brief Tries to construct an instance given a list of erased parameters.
  40648. * @tparam Type Reflected type to which the function is associated.
  40649. * @tparam Candidate The actual function to invoke.
  40650. * @tparam Policy Optional policy (no policy set by default).
  40651. * @param args Parameters to use to invoke the function.
  40652. * @return A meta any containing the returned value, if any.
  40653. */
  40654. template<typename Type, auto Candidate, typename Policy = as_is_t>
  40655. [[nodiscard]] meta_any meta_construct(meta_any *const args) {
  40656. return meta_construct<Type, Policy>(Candidate, args);
  40657. }
  40658. } // namespace entt
  40659. #endif
  40660. // #include "platform/android-ndk-r17.hpp"
  40661. #ifndef ENTT_PLATFORM_ANDROID_NDK_R17_HPP
  40662. #define ENTT_PLATFORM_ANDROID_NDK_R17_HPP
  40663. /**
  40664. * @cond TURN_OFF_DOXYGEN
  40665. * Internal details not to be documented.
  40666. */
  40667. #ifdef __ANDROID__
  40668. # include <android/ndk-version.h>
  40669. # if __NDK_MAJOR__ == 17
  40670. # include <functional>
  40671. # include <type_traits>
  40672. # include <utility>
  40673. namespace std {
  40674. namespace internal {
  40675. template<typename Func, typename... Args>
  40676. constexpr auto is_invocable(int) -> decltype(std::invoke(std::declval<Func>(), std::declval<Args>()...), std::true_type{});
  40677. template<typename, typename...>
  40678. constexpr std::false_type is_invocable(...);
  40679. template<typename Ret, typename Func, typename... Args>
  40680. constexpr auto is_invocable_r(int)
  40681. -> std::enable_if_t<decltype(std::is_convertible_v<decltype(std::invoke(std::declval<Func>(), std::declval<Args>()...)), Ret>, std::true_type>;
  40682. template<typename, typename, typename...>
  40683. constexpr std::false_type is_invocable_r(...);
  40684. } // namespace internal
  40685. template<typename Func, typename... Args>
  40686. struct is_invocable: decltype(internal::is_invocable<Func, Args...>(0)) {};
  40687. template<typename Func, typename... Argsv>
  40688. inline constexpr bool is_invocable_v = std::is_invocable<Func, Args...>::value;
  40689. template<typename Ret, typename Func, typename... Args>
  40690. struct is_invocable_r: decltype(internal::is_invocable_r<Ret, Func, Args...>(0)) {};
  40691. template<typename Ret, typename Func, typename... Args>
  40692. inline constexpr bool is_invocable_r_v = std::is_invocable_r<Ret, Func, Args...>::value;
  40693. template<typename Func, typename... Args>
  40694. struct invoke_result {
  40695. using type = decltype(std::invoke(std::declval<Func>(), std::declval<Args>()...));
  40696. };
  40697. template<typename Func, typename... Args>
  40698. using invoke_result_t = typename std::invoke_result<Func, Args...>::type;
  40699. } // namespace std
  40700. # endif
  40701. #endif
  40702. /**
  40703. * Internal details not to be documented.
  40704. * @endcond
  40705. */
  40706. #endif
  40707. // #include "poly/poly.hpp"
  40708. #ifndef ENTT_POLY_POLY_HPP
  40709. #define ENTT_POLY_POLY_HPP
  40710. #include <cstddef>
  40711. #include <functional>
  40712. #include <tuple>
  40713. #include <type_traits>
  40714. #include <utility>
  40715. // #include "../config/config.h"
  40716. #ifndef ENTT_CONFIG_CONFIG_H
  40717. #define ENTT_CONFIG_CONFIG_H
  40718. // #include "version.h"
  40719. #ifndef ENTT_CONFIG_VERSION_H
  40720. #define ENTT_CONFIG_VERSION_H
  40721. // #include "macro.h"
  40722. #ifndef ENTT_CONFIG_MACRO_H
  40723. #define ENTT_CONFIG_MACRO_H
  40724. #define ENTT_STR(arg) #arg
  40725. #define ENTT_XSTR(arg) ENTT_STR(arg)
  40726. #endif
  40727. #define ENTT_VERSION_MAJOR 3
  40728. #define ENTT_VERSION_MINOR 10
  40729. #define ENTT_VERSION_PATCH 3
  40730. #define ENTT_VERSION \
  40731. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  40732. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  40733. #endif
  40734. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  40735. # define ENTT_THROW throw
  40736. # define ENTT_TRY try
  40737. # define ENTT_CATCH catch(...)
  40738. #else
  40739. # define ENTT_THROW
  40740. # define ENTT_TRY if(true)
  40741. # define ENTT_CATCH if(false)
  40742. #endif
  40743. #ifndef ENTT_NOEXCEPT
  40744. # define ENTT_NOEXCEPT noexcept
  40745. # define ENTT_NOEXCEPT_IF(expr) noexcept(expr)
  40746. # else
  40747. # define ENTT_NOEXCEPT_IF(...)
  40748. #endif
  40749. #ifdef ENTT_USE_ATOMIC
  40750. # include <atomic>
  40751. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  40752. #else
  40753. # define ENTT_MAYBE_ATOMIC(Type) Type
  40754. #endif
  40755. #ifndef ENTT_ID_TYPE
  40756. # include <cstdint>
  40757. # define ENTT_ID_TYPE std::uint32_t
  40758. #endif
  40759. #ifndef ENTT_SPARSE_PAGE
  40760. # define ENTT_SPARSE_PAGE 4096
  40761. #endif
  40762. #ifndef ENTT_PACKED_PAGE
  40763. # define ENTT_PACKED_PAGE 1024
  40764. #endif
  40765. #ifdef ENTT_DISABLE_ASSERT
  40766. # undef ENTT_ASSERT
  40767. # define ENTT_ASSERT(...) (void(0))
  40768. #elif !defined ENTT_ASSERT
  40769. # include <cassert>
  40770. # define ENTT_ASSERT(condition, ...) assert(condition)
  40771. #endif
  40772. #ifdef ENTT_NO_ETO
  40773. # define ENTT_IGNORE_IF_EMPTY false
  40774. #else
  40775. # define ENTT_IGNORE_IF_EMPTY true
  40776. #endif
  40777. #ifdef ENTT_STANDARD_CPP
  40778. # define ENTT_NONSTD false
  40779. #else
  40780. # define ENTT_NONSTD true
  40781. # if defined __clang__ || defined __GNUC__
  40782. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  40783. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  40784. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  40785. # elif defined _MSC_VER
  40786. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  40787. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  40788. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  40789. # endif
  40790. #endif
  40791. #if defined _MSC_VER
  40792. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  40793. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  40794. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  40795. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  40796. #endif
  40797. #endif
  40798. // #include "../core/any.hpp"
  40799. #ifndef ENTT_CORE_ANY_HPP
  40800. #define ENTT_CORE_ANY_HPP
  40801. #include <cstddef>
  40802. #include <memory>
  40803. #include <type_traits>
  40804. #include <utility>
  40805. // #include "../config/config.h"
  40806. #ifndef ENTT_CONFIG_CONFIG_H
  40807. #define ENTT_CONFIG_CONFIG_H
  40808. // #include "version.h"
  40809. #ifndef ENTT_CONFIG_VERSION_H
  40810. #define ENTT_CONFIG_VERSION_H
  40811. // #include "macro.h"
  40812. #ifndef ENTT_CONFIG_MACRO_H
  40813. #define ENTT_CONFIG_MACRO_H
  40814. #define ENTT_STR(arg) #arg
  40815. #define ENTT_XSTR(arg) ENTT_STR(arg)
  40816. #endif
  40817. #define ENTT_VERSION_MAJOR 3
  40818. #define ENTT_VERSION_MINOR 10
  40819. #define ENTT_VERSION_PATCH 3
  40820. #define ENTT_VERSION \
  40821. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  40822. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  40823. #endif
  40824. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  40825. # define ENTT_THROW throw
  40826. # define ENTT_TRY try
  40827. # define ENTT_CATCH catch(...)
  40828. #else
  40829. # define ENTT_THROW
  40830. # define ENTT_TRY if(true)
  40831. # define ENTT_CATCH if(false)
  40832. #endif
  40833. #ifndef ENTT_NOEXCEPT
  40834. # define ENTT_NOEXCEPT noexcept
  40835. # define ENTT_NOEXCEPT_IF(expr) noexcept(expr)
  40836. # else
  40837. # define ENTT_NOEXCEPT_IF(...)
  40838. #endif
  40839. #ifdef ENTT_USE_ATOMIC
  40840. # include <atomic>
  40841. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  40842. #else
  40843. # define ENTT_MAYBE_ATOMIC(Type) Type
  40844. #endif
  40845. #ifndef ENTT_ID_TYPE
  40846. # include <cstdint>
  40847. # define ENTT_ID_TYPE std::uint32_t
  40848. #endif
  40849. #ifndef ENTT_SPARSE_PAGE
  40850. # define ENTT_SPARSE_PAGE 4096
  40851. #endif
  40852. #ifndef ENTT_PACKED_PAGE
  40853. # define ENTT_PACKED_PAGE 1024
  40854. #endif
  40855. #ifdef ENTT_DISABLE_ASSERT
  40856. # undef ENTT_ASSERT
  40857. # define ENTT_ASSERT(...) (void(0))
  40858. #elif !defined ENTT_ASSERT
  40859. # include <cassert>
  40860. # define ENTT_ASSERT(condition, ...) assert(condition)
  40861. #endif
  40862. #ifdef ENTT_NO_ETO
  40863. # define ENTT_IGNORE_IF_EMPTY false
  40864. #else
  40865. # define ENTT_IGNORE_IF_EMPTY true
  40866. #endif
  40867. #ifdef ENTT_STANDARD_CPP
  40868. # define ENTT_NONSTD false
  40869. #else
  40870. # define ENTT_NONSTD true
  40871. # if defined __clang__ || defined __GNUC__
  40872. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  40873. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  40874. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  40875. # elif defined _MSC_VER
  40876. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  40877. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  40878. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  40879. # endif
  40880. #endif
  40881. #if defined _MSC_VER
  40882. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  40883. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  40884. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  40885. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  40886. #endif
  40887. #endif
  40888. // #include "../core/utility.hpp"
  40889. #ifndef ENTT_CORE_UTILITY_HPP
  40890. #define ENTT_CORE_UTILITY_HPP
  40891. #include <utility>
  40892. // #include "../config/config.h"
  40893. #ifndef ENTT_CONFIG_CONFIG_H
  40894. #define ENTT_CONFIG_CONFIG_H
  40895. // #include "version.h"
  40896. #ifndef ENTT_CONFIG_VERSION_H
  40897. #define ENTT_CONFIG_VERSION_H
  40898. // #include "macro.h"
  40899. #ifndef ENTT_CONFIG_MACRO_H
  40900. #define ENTT_CONFIG_MACRO_H
  40901. #define ENTT_STR(arg) #arg
  40902. #define ENTT_XSTR(arg) ENTT_STR(arg)
  40903. #endif
  40904. #define ENTT_VERSION_MAJOR 3
  40905. #define ENTT_VERSION_MINOR 10
  40906. #define ENTT_VERSION_PATCH 3
  40907. #define ENTT_VERSION \
  40908. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  40909. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  40910. #endif
  40911. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  40912. # define ENTT_THROW throw
  40913. # define ENTT_TRY try
  40914. # define ENTT_CATCH catch(...)
  40915. #else
  40916. # define ENTT_THROW
  40917. # define ENTT_TRY if(true)
  40918. # define ENTT_CATCH if(false)
  40919. #endif
  40920. #ifndef ENTT_NOEXCEPT
  40921. # define ENTT_NOEXCEPT noexcept
  40922. # define ENTT_NOEXCEPT_IF(expr) noexcept(expr)
  40923. # else
  40924. # define ENTT_NOEXCEPT_IF(...)
  40925. #endif
  40926. #ifdef ENTT_USE_ATOMIC
  40927. # include <atomic>
  40928. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  40929. #else
  40930. # define ENTT_MAYBE_ATOMIC(Type) Type
  40931. #endif
  40932. #ifndef ENTT_ID_TYPE
  40933. # include <cstdint>
  40934. # define ENTT_ID_TYPE std::uint32_t
  40935. #endif
  40936. #ifndef ENTT_SPARSE_PAGE
  40937. # define ENTT_SPARSE_PAGE 4096
  40938. #endif
  40939. #ifndef ENTT_PACKED_PAGE
  40940. # define ENTT_PACKED_PAGE 1024
  40941. #endif
  40942. #ifdef ENTT_DISABLE_ASSERT
  40943. # undef ENTT_ASSERT
  40944. # define ENTT_ASSERT(...) (void(0))
  40945. #elif !defined ENTT_ASSERT
  40946. # include <cassert>
  40947. # define ENTT_ASSERT(condition, ...) assert(condition)
  40948. #endif
  40949. #ifdef ENTT_NO_ETO
  40950. # define ENTT_IGNORE_IF_EMPTY false
  40951. #else
  40952. # define ENTT_IGNORE_IF_EMPTY true
  40953. #endif
  40954. #ifdef ENTT_STANDARD_CPP
  40955. # define ENTT_NONSTD false
  40956. #else
  40957. # define ENTT_NONSTD true
  40958. # if defined __clang__ || defined __GNUC__
  40959. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  40960. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  40961. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  40962. # elif defined _MSC_VER
  40963. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  40964. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  40965. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  40966. # endif
  40967. #endif
  40968. #if defined _MSC_VER
  40969. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  40970. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  40971. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  40972. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  40973. #endif
  40974. #endif
  40975. namespace entt {
  40976. /*! @brief Identity function object (waiting for C++20). */
  40977. struct identity {
  40978. /*! @brief Indicates that this is a transparent function object. */
  40979. using is_transparent = void;
  40980. /**
  40981. * @brief Returns its argument unchanged.
  40982. * @tparam Type Type of the argument.
  40983. * @param value The actual argument.
  40984. * @return The submitted value as-is.
  40985. */
  40986. template<class Type>
  40987. [[nodiscard]] constexpr Type &&operator()(Type &&value) const ENTT_NOEXCEPT {
  40988. return std::forward<Type>(value);
  40989. }
  40990. };
  40991. /**
  40992. * @brief Constant utility to disambiguate overloaded members of a class.
  40993. * @tparam Type Type of the desired overload.
  40994. * @tparam Class Type of class to which the member belongs.
  40995. * @param member A valid pointer to a member.
  40996. * @return Pointer to the member.
  40997. */
  40998. template<typename Type, typename Class>
  40999. [[nodiscard]] constexpr auto overload(Type Class::*member) ENTT_NOEXCEPT {
  41000. return member;
  41001. }
  41002. /**
  41003. * @brief Constant utility to disambiguate overloaded functions.
  41004. * @tparam Func Function type of the desired overload.
  41005. * @param func A valid pointer to a function.
  41006. * @return Pointer to the function.
  41007. */
  41008. template<typename Func>
  41009. [[nodiscard]] constexpr auto overload(Func *func) ENTT_NOEXCEPT {
  41010. return func;
  41011. }
  41012. /**
  41013. * @brief Helper type for visitors.
  41014. * @tparam Func Types of function objects.
  41015. */
  41016. template<class... Func>
  41017. struct overloaded: Func... {
  41018. using Func::operator()...;
  41019. };
  41020. /**
  41021. * @brief Deduction guide.
  41022. * @tparam Func Types of function objects.
  41023. */
  41024. template<class... Func>
  41025. overloaded(Func...) -> overloaded<Func...>;
  41026. /**
  41027. * @brief Basic implementation of a y-combinator.
  41028. * @tparam Func Type of a potentially recursive function.
  41029. */
  41030. template<class Func>
  41031. struct y_combinator {
  41032. /**
  41033. * @brief Constructs a y-combinator from a given function.
  41034. * @param recursive A potentially recursive function.
  41035. */
  41036. y_combinator(Func recursive)
  41037. : func{std::move(recursive)} {}
  41038. /**
  41039. * @brief Invokes a y-combinator and therefore its underlying function.
  41040. * @tparam Args Types of arguments to use to invoke the underlying function.
  41041. * @param args Parameters to use to invoke the underlying function.
  41042. * @return Return value of the underlying function, if any.
  41043. */
  41044. template<class... Args>
  41045. decltype(auto) operator()(Args &&...args) const {
  41046. return func(*this, std::forward<Args>(args)...);
  41047. }
  41048. /*! @copydoc operator()() */
  41049. template<class... Args>
  41050. decltype(auto) operator()(Args &&...args) {
  41051. return func(*this, std::forward<Args>(args)...);
  41052. }
  41053. private:
  41054. Func func;
  41055. };
  41056. } // namespace entt
  41057. #endif
  41058. // #include "fwd.hpp"
  41059. #ifndef ENTT_CORE_FWD_HPP
  41060. #define ENTT_CORE_FWD_HPP
  41061. #include <cstdint>
  41062. #include <type_traits>
  41063. // #include "../config/config.h"
  41064. namespace entt {
  41065. template<std::size_t Len = sizeof(double[2]), std::size_t = alignof(typename std::aligned_storage_t<Len + !Len>)>
  41066. class basic_any;
  41067. /*! @brief Alias declaration for type identifiers. */
  41068. using id_type = ENTT_ID_TYPE;
  41069. /*! @brief Alias declaration for the most common use case. */
  41070. using any = basic_any<>;
  41071. } // namespace entt
  41072. #endif
  41073. // #include "type_info.hpp"
  41074. #ifndef ENTT_CORE_TYPE_INFO_HPP
  41075. #define ENTT_CORE_TYPE_INFO_HPP
  41076. #include <string_view>
  41077. #include <type_traits>
  41078. #include <utility>
  41079. // #include "../config/config.h"
  41080. // #include "../core/attribute.h"
  41081. #ifndef ENTT_CORE_ATTRIBUTE_H
  41082. #define ENTT_CORE_ATTRIBUTE_H
  41083. #ifndef ENTT_EXPORT
  41084. # if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER
  41085. # define ENTT_EXPORT __declspec(dllexport)
  41086. # define ENTT_IMPORT __declspec(dllimport)
  41087. # define ENTT_HIDDEN
  41088. # elif defined __GNUC__ && __GNUC__ >= 4
  41089. # define ENTT_EXPORT __attribute__((visibility("default")))
  41090. # define ENTT_IMPORT __attribute__((visibility("default")))
  41091. # define ENTT_HIDDEN __attribute__((visibility("hidden")))
  41092. # else /* Unsupported compiler */
  41093. # define ENTT_EXPORT
  41094. # define ENTT_IMPORT
  41095. # define ENTT_HIDDEN
  41096. # endif
  41097. #endif
  41098. #ifndef ENTT_API
  41099. # if defined ENTT_API_EXPORT
  41100. # define ENTT_API ENTT_EXPORT
  41101. # elif defined ENTT_API_IMPORT
  41102. # define ENTT_API ENTT_IMPORT
  41103. # else /* No API */
  41104. # define ENTT_API
  41105. # endif
  41106. #endif
  41107. #endif
  41108. // #include "fwd.hpp"
  41109. // #include "hashed_string.hpp"
  41110. #ifndef ENTT_CORE_HASHED_STRING_HPP
  41111. #define ENTT_CORE_HASHED_STRING_HPP
  41112. #include <cstddef>
  41113. #include <cstdint>
  41114. // #include "../config/config.h"
  41115. // #include "fwd.hpp"
  41116. namespace entt {
  41117. /**
  41118. * @cond TURN_OFF_DOXYGEN
  41119. * Internal details not to be documented.
  41120. */
  41121. namespace internal {
  41122. template<typename>
  41123. struct fnv1a_traits;
  41124. template<>
  41125. struct fnv1a_traits<std::uint32_t> {
  41126. using type = std::uint32_t;
  41127. static constexpr std::uint32_t offset = 2166136261;
  41128. static constexpr std::uint32_t prime = 16777619;
  41129. };
  41130. template<>
  41131. struct fnv1a_traits<std::uint64_t> {
  41132. using type = std::uint64_t;
  41133. static constexpr std::uint64_t offset = 14695981039346656037ull;
  41134. static constexpr std::uint64_t prime = 1099511628211ull;
  41135. };
  41136. template<typename Char>
  41137. struct basic_hashed_string {
  41138. using value_type = Char;
  41139. using size_type = std::size_t;
  41140. using hash_type = id_type;
  41141. const value_type *repr;
  41142. size_type length;
  41143. hash_type hash;
  41144. };
  41145. } // namespace internal
  41146. /**
  41147. * Internal details not to be documented.
  41148. * @endcond
  41149. */
  41150. /**
  41151. * @brief Zero overhead unique identifier.
  41152. *
  41153. * A hashed string is a compile-time tool that allows users to use
  41154. * human-readable identifiers in the codebase while using their numeric
  41155. * counterparts at runtime.<br/>
  41156. * Because of that, a hashed string can also be used in constant expressions if
  41157. * required.
  41158. *
  41159. * @warning
  41160. * This class doesn't take ownership of user-supplied strings nor does it make a
  41161. * copy of them.
  41162. *
  41163. * @tparam Char Character type.
  41164. */
  41165. template<typename Char>
  41166. class basic_hashed_string: internal::basic_hashed_string<Char> {
  41167. using base_type = internal::basic_hashed_string<Char>;
  41168. using hs_traits = internal::fnv1a_traits<id_type>;
  41169. struct const_wrapper {
  41170. // non-explicit constructor on purpose
  41171. constexpr const_wrapper(const Char *str) ENTT_NOEXCEPT: repr{str} {}
  41172. const Char *repr;
  41173. };
  41174. // Fowler–Noll–Vo hash function v. 1a - the good
  41175. [[nodiscard]] static constexpr auto helper(const Char *str) ENTT_NOEXCEPT {
  41176. base_type base{str, 0u, hs_traits::offset};
  41177. for(; str[base.length]; ++base.length) {
  41178. base.hash = (base.hash ^ static_cast<hs_traits::type>(str[base.length])) * hs_traits::prime;
  41179. }
  41180. return base;
  41181. }
  41182. // Fowler–Noll–Vo hash function v. 1a - the good
  41183. [[nodiscard]] static constexpr auto helper(const Char *str, const std::size_t len) ENTT_NOEXCEPT {
  41184. base_type base{str, len, hs_traits::offset};
  41185. for(size_type pos{}; pos < len; ++pos) {
  41186. base.hash = (base.hash ^ static_cast<hs_traits::type>(str[pos])) * hs_traits::prime;
  41187. }
  41188. return base;
  41189. }
  41190. public:
  41191. /*! @brief Character type. */
  41192. using value_type = typename base_type::value_type;
  41193. /*! @brief Unsigned integer type. */
  41194. using size_type = typename base_type::size_type;
  41195. /*! @brief Unsigned integer type. */
  41196. using hash_type = typename base_type::hash_type;
  41197. /**
  41198. * @brief Returns directly the numeric representation of a string view.
  41199. * @param str Human-readable identifier.
  41200. * @param len Length of the string to hash.
  41201. * @return The numeric representation of the string.
  41202. */
  41203. [[nodiscard]] static constexpr hash_type value(const value_type *str, const size_type len) ENTT_NOEXCEPT {
  41204. return basic_hashed_string{str, len};
  41205. }
  41206. /**
  41207. * @brief Returns directly the numeric representation of a string.
  41208. * @tparam N Number of characters of the identifier.
  41209. * @param str Human-readable identifier.
  41210. * @return The numeric representation of the string.
  41211. */
  41212. template<std::size_t N>
  41213. [[nodiscard]] static constexpr hash_type value(const value_type (&str)[N]) ENTT_NOEXCEPT {
  41214. return basic_hashed_string{str};
  41215. }
  41216. /**
  41217. * @brief Returns directly the numeric representation of a string.
  41218. * @param wrapper Helps achieving the purpose by relying on overloading.
  41219. * @return The numeric representation of the string.
  41220. */
  41221. [[nodiscard]] static constexpr hash_type value(const_wrapper wrapper) ENTT_NOEXCEPT {
  41222. return basic_hashed_string{wrapper};
  41223. }
  41224. /*! @brief Constructs an empty hashed string. */
  41225. constexpr basic_hashed_string() ENTT_NOEXCEPT
  41226. : base_type{} {}
  41227. /**
  41228. * @brief Constructs a hashed string from a string view.
  41229. * @param str Human-readable identifier.
  41230. * @param len Length of the string to hash.
  41231. */
  41232. constexpr basic_hashed_string(const value_type *str, const size_type len) ENTT_NOEXCEPT
  41233. : base_type{helper(str, len)} {}
  41234. /**
  41235. * @brief Constructs a hashed string from an array of const characters.
  41236. * @tparam N Number of characters of the identifier.
  41237. * @param str Human-readable identifier.
  41238. */
  41239. template<std::size_t N>
  41240. constexpr basic_hashed_string(const value_type (&str)[N]) ENTT_NOEXCEPT
  41241. : base_type{helper(str)} {}
  41242. /**
  41243. * @brief Explicit constructor on purpose to avoid constructing a hashed
  41244. * string directly from a `const value_type *`.
  41245. *
  41246. * @warning
  41247. * The lifetime of the string is not extended nor is it copied.
  41248. *
  41249. * @param wrapper Helps achieving the purpose by relying on overloading.
  41250. */
  41251. explicit constexpr basic_hashed_string(const_wrapper wrapper) ENTT_NOEXCEPT
  41252. : base_type{helper(wrapper.repr)} {}
  41253. /**
  41254. * @brief Returns the size a hashed string.
  41255. * @return The size of the hashed string.
  41256. */
  41257. [[nodiscard]] constexpr size_type size() const ENTT_NOEXCEPT {
  41258. return base_type::length;
  41259. }
  41260. /**
  41261. * @brief Returns the human-readable representation of a hashed string.
  41262. * @return The string used to initialize the hashed string.
  41263. */
  41264. [[nodiscard]] constexpr const value_type *data() const ENTT_NOEXCEPT {
  41265. return base_type::repr;
  41266. }
  41267. /**
  41268. * @brief Returns the numeric representation of a hashed string.
  41269. * @return The numeric representation of the hashed string.
  41270. */
  41271. [[nodiscard]] constexpr hash_type value() const ENTT_NOEXCEPT {
  41272. return base_type::hash;
  41273. }
  41274. /*! @copydoc data */
  41275. [[nodiscard]] constexpr operator const value_type *() const ENTT_NOEXCEPT {
  41276. return data();
  41277. }
  41278. /**
  41279. * @brief Returns the numeric representation of a hashed string.
  41280. * @return The numeric representation of the hashed string.
  41281. */
  41282. [[nodiscard]] constexpr operator hash_type() const ENTT_NOEXCEPT {
  41283. return value();
  41284. }
  41285. };
  41286. /**
  41287. * @brief Deduction guide.
  41288. * @tparam Char Character type.
  41289. * @param str Human-readable identifier.
  41290. * @param len Length of the string to hash.
  41291. */
  41292. template<typename Char>
  41293. basic_hashed_string(const Char *str, const std::size_t len) -> basic_hashed_string<Char>;
  41294. /**
  41295. * @brief Deduction guide.
  41296. * @tparam Char Character type.
  41297. * @tparam N Number of characters of the identifier.
  41298. * @param str Human-readable identifier.
  41299. */
  41300. template<typename Char, std::size_t N>
  41301. basic_hashed_string(const Char (&str)[N]) -> basic_hashed_string<Char>;
  41302. /**
  41303. * @brief Compares two hashed strings.
  41304. * @tparam Char Character type.
  41305. * @param lhs A valid hashed string.
  41306. * @param rhs A valid hashed string.
  41307. * @return True if the two hashed strings are identical, false otherwise.
  41308. */
  41309. template<typename Char>
  41310. [[nodiscard]] constexpr bool operator==(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) ENTT_NOEXCEPT {
  41311. return lhs.value() == rhs.value();
  41312. }
  41313. /**
  41314. * @brief Compares two hashed strings.
  41315. * @tparam Char Character type.
  41316. * @param lhs A valid hashed string.
  41317. * @param rhs A valid hashed string.
  41318. * @return True if the two hashed strings differ, false otherwise.
  41319. */
  41320. template<typename Char>
  41321. [[nodiscard]] constexpr bool operator!=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) ENTT_NOEXCEPT {
  41322. return !(lhs == rhs);
  41323. }
  41324. /**
  41325. * @brief Compares two hashed strings.
  41326. * @tparam Char Character type.
  41327. * @param lhs A valid hashed string.
  41328. * @param rhs A valid hashed string.
  41329. * @return True if the first element is less than the second, false otherwise.
  41330. */
  41331. template<typename Char>
  41332. [[nodiscard]] constexpr bool operator<(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) ENTT_NOEXCEPT {
  41333. return lhs.value() < rhs.value();
  41334. }
  41335. /**
  41336. * @brief Compares two hashed strings.
  41337. * @tparam Char Character type.
  41338. * @param lhs A valid hashed string.
  41339. * @param rhs A valid hashed string.
  41340. * @return True if the first element is less than or equal to the second, false
  41341. * otherwise.
  41342. */
  41343. template<typename Char>
  41344. [[nodiscard]] constexpr bool operator<=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) ENTT_NOEXCEPT {
  41345. return !(rhs < lhs);
  41346. }
  41347. /**
  41348. * @brief Compares two hashed strings.
  41349. * @tparam Char Character type.
  41350. * @param lhs A valid hashed string.
  41351. * @param rhs A valid hashed string.
  41352. * @return True if the first element is greater than the second, false
  41353. * otherwise.
  41354. */
  41355. template<typename Char>
  41356. [[nodiscard]] constexpr bool operator>(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) ENTT_NOEXCEPT {
  41357. return rhs < lhs;
  41358. }
  41359. /**
  41360. * @brief Compares two hashed strings.
  41361. * @tparam Char Character type.
  41362. * @param lhs A valid hashed string.
  41363. * @param rhs A valid hashed string.
  41364. * @return True if the first element is greater than or equal to the second,
  41365. * false otherwise.
  41366. */
  41367. template<typename Char>
  41368. [[nodiscard]] constexpr bool operator>=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) ENTT_NOEXCEPT {
  41369. return !(lhs < rhs);
  41370. }
  41371. /*! @brief Aliases for common character types. */
  41372. using hashed_string = basic_hashed_string<char>;
  41373. /*! @brief Aliases for common character types. */
  41374. using hashed_wstring = basic_hashed_string<wchar_t>;
  41375. inline namespace literals {
  41376. /**
  41377. * @brief User defined literal for hashed strings.
  41378. * @param str The literal without its suffix.
  41379. * @return A properly initialized hashed string.
  41380. */
  41381. [[nodiscard]] constexpr hashed_string operator"" _hs(const char *str, std::size_t) ENTT_NOEXCEPT {
  41382. return hashed_string{str};
  41383. }
  41384. /**
  41385. * @brief User defined literal for hashed wstrings.
  41386. * @param str The literal without its suffix.
  41387. * @return A properly initialized hashed wstring.
  41388. */
  41389. [[nodiscard]] constexpr hashed_wstring operator"" _hws(const wchar_t *str, std::size_t) ENTT_NOEXCEPT {
  41390. return hashed_wstring{str};
  41391. }
  41392. } // namespace literals
  41393. } // namespace entt
  41394. #endif
  41395. namespace entt {
  41396. /**
  41397. * @cond TURN_OFF_DOXYGEN
  41398. * Internal details not to be documented.
  41399. */
  41400. namespace internal {
  41401. struct ENTT_API type_index final {
  41402. [[nodiscard]] static id_type next() ENTT_NOEXCEPT {
  41403. static ENTT_MAYBE_ATOMIC(id_type) value{};
  41404. return value++;
  41405. }
  41406. };
  41407. template<typename Type>
  41408. [[nodiscard]] constexpr auto stripped_type_name() ENTT_NOEXCEPT {
  41409. #if defined ENTT_PRETTY_FUNCTION
  41410. std::string_view pretty_function{ENTT_PRETTY_FUNCTION};
  41411. auto first = pretty_function.find_first_not_of(' ', pretty_function.find_first_of(ENTT_PRETTY_FUNCTION_PREFIX) + 1);
  41412. auto value = pretty_function.substr(first, pretty_function.find_last_of(ENTT_PRETTY_FUNCTION_SUFFIX) - first);
  41413. return value;
  41414. #else
  41415. return std::string_view{""};
  41416. #endif
  41417. }
  41418. template<typename Type, auto = stripped_type_name<Type>().find_first_of('.')>
  41419. [[nodiscard]] static constexpr std::string_view type_name(int) ENTT_NOEXCEPT {
  41420. constexpr auto value = stripped_type_name<Type>();
  41421. return value;
  41422. }
  41423. template<typename Type>
  41424. [[nodiscard]] static std::string_view type_name(char) ENTT_NOEXCEPT {
  41425. static const auto value = stripped_type_name<Type>();
  41426. return value;
  41427. }
  41428. template<typename Type, auto = stripped_type_name<Type>().find_first_of('.')>
  41429. [[nodiscard]] static constexpr id_type type_hash(int) ENTT_NOEXCEPT {
  41430. constexpr auto stripped = stripped_type_name<Type>();
  41431. constexpr auto value = hashed_string::value(stripped.data(), stripped.size());
  41432. return value;
  41433. }
  41434. template<typename Type>
  41435. [[nodiscard]] static id_type type_hash(char) ENTT_NOEXCEPT {
  41436. static const auto value = [](const auto stripped) {
  41437. return hashed_string::value(stripped.data(), stripped.size());
  41438. }(stripped_type_name<Type>());
  41439. return value;
  41440. }
  41441. } // namespace internal
  41442. /**
  41443. * Internal details not to be documented.
  41444. * @endcond
  41445. */
  41446. /**
  41447. * @brief Type sequential identifier.
  41448. * @tparam Type Type for which to generate a sequential identifier.
  41449. */
  41450. template<typename Type, typename = void>
  41451. struct ENTT_API type_index final {
  41452. /**
  41453. * @brief Returns the sequential identifier of a given type.
  41454. * @return The sequential identifier of a given type.
  41455. */
  41456. [[nodiscard]] static id_type value() ENTT_NOEXCEPT {
  41457. static const id_type value = internal::type_index::next();
  41458. return value;
  41459. }
  41460. /*! @copydoc value */
  41461. [[nodiscard]] constexpr operator id_type() const ENTT_NOEXCEPT {
  41462. return value();
  41463. }
  41464. };
  41465. /**
  41466. * @brief Type hash.
  41467. * @tparam Type Type for which to generate a hash value.
  41468. */
  41469. template<typename Type, typename = void>
  41470. struct type_hash final {
  41471. /**
  41472. * @brief Returns the numeric representation of a given type.
  41473. * @return The numeric representation of the given type.
  41474. */
  41475. #if defined ENTT_PRETTY_FUNCTION
  41476. [[nodiscard]] static constexpr id_type value() ENTT_NOEXCEPT {
  41477. return internal::type_hash<Type>(0);
  41478. #else
  41479. [[nodiscard]] static constexpr id_type value() ENTT_NOEXCEPT {
  41480. return type_index<Type>::value();
  41481. #endif
  41482. }
  41483. /*! @copydoc value */
  41484. [[nodiscard]] constexpr operator id_type() const ENTT_NOEXCEPT {
  41485. return value();
  41486. }
  41487. };
  41488. /**
  41489. * @brief Type name.
  41490. * @tparam Type Type for which to generate a name.
  41491. */
  41492. template<typename Type, typename = void>
  41493. struct type_name final {
  41494. /**
  41495. * @brief Returns the name of a given type.
  41496. * @return The name of the given type.
  41497. */
  41498. [[nodiscard]] static constexpr std::string_view value() ENTT_NOEXCEPT {
  41499. return internal::type_name<Type>(0);
  41500. }
  41501. /*! @copydoc value */
  41502. [[nodiscard]] constexpr operator std::string_view() const ENTT_NOEXCEPT {
  41503. return value();
  41504. }
  41505. };
  41506. /*! @brief Implementation specific information about a type. */
  41507. struct type_info final {
  41508. /**
  41509. * @brief Constructs a type info object for a given type.
  41510. * @tparam Type Type for which to construct a type info object.
  41511. */
  41512. template<typename Type>
  41513. constexpr type_info(std::in_place_type_t<Type>) ENTT_NOEXCEPT
  41514. : seq{type_index<std::remove_cv_t<std::remove_reference_t<Type>>>::value()},
  41515. identifier{type_hash<std::remove_cv_t<std::remove_reference_t<Type>>>::value()},
  41516. alias{type_name<std::remove_cv_t<std::remove_reference_t<Type>>>::value()} {}
  41517. /**
  41518. * @brief Type index.
  41519. * @return Type index.
  41520. */
  41521. [[nodiscard]] constexpr id_type index() const ENTT_NOEXCEPT {
  41522. return seq;
  41523. }
  41524. /**
  41525. * @brief Type hash.
  41526. * @return Type hash.
  41527. */
  41528. [[nodiscard]] constexpr id_type hash() const ENTT_NOEXCEPT {
  41529. return identifier;
  41530. }
  41531. /**
  41532. * @brief Type name.
  41533. * @return Type name.
  41534. */
  41535. [[nodiscard]] constexpr std::string_view name() const ENTT_NOEXCEPT {
  41536. return alias;
  41537. }
  41538. private:
  41539. id_type seq;
  41540. id_type identifier;
  41541. std::string_view alias;
  41542. };
  41543. /**
  41544. * @brief Compares the contents of two type info objects.
  41545. * @param lhs A type info object.
  41546. * @param rhs A type info object.
  41547. * @return True if the two type info objects are identical, false otherwise.
  41548. */
  41549. [[nodiscard]] inline constexpr bool operator==(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT {
  41550. return lhs.hash() == rhs.hash();
  41551. }
  41552. /**
  41553. * @brief Compares the contents of two type info objects.
  41554. * @param lhs A type info object.
  41555. * @param rhs A type info object.
  41556. * @return True if the two type info objects differ, false otherwise.
  41557. */
  41558. [[nodiscard]] inline constexpr bool operator!=(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT {
  41559. return !(lhs == rhs);
  41560. }
  41561. /**
  41562. * @brief Compares two type info objects.
  41563. * @param lhs A valid type info object.
  41564. * @param rhs A valid type info object.
  41565. * @return True if the first element is less than the second, false otherwise.
  41566. */
  41567. [[nodiscard]] constexpr bool operator<(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT {
  41568. return lhs.index() < rhs.index();
  41569. }
  41570. /**
  41571. * @brief Compares two type info objects.
  41572. * @param lhs A valid type info object.
  41573. * @param rhs A valid type info object.
  41574. * @return True if the first element is less than or equal to the second, false
  41575. * otherwise.
  41576. */
  41577. [[nodiscard]] constexpr bool operator<=(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT {
  41578. return !(rhs < lhs);
  41579. }
  41580. /**
  41581. * @brief Compares two type info objects.
  41582. * @param lhs A valid type info object.
  41583. * @param rhs A valid type info object.
  41584. * @return True if the first element is greater than the second, false
  41585. * otherwise.
  41586. */
  41587. [[nodiscard]] constexpr bool operator>(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT {
  41588. return rhs < lhs;
  41589. }
  41590. /**
  41591. * @brief Compares two type info objects.
  41592. * @param lhs A valid type info object.
  41593. * @param rhs A valid type info object.
  41594. * @return True if the first element is greater than or equal to the second,
  41595. * false otherwise.
  41596. */
  41597. [[nodiscard]] constexpr bool operator>=(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT {
  41598. return !(lhs < rhs);
  41599. }
  41600. /**
  41601. * @brief Returns the type info object associated to a given type.
  41602. *
  41603. * The returned element refers to an object with static storage duration.<br/>
  41604. * The type doesn't need to be a complete type. If the type is a reference, the
  41605. * result refers to the referenced type. In all cases, top-level cv-qualifiers
  41606. * are ignored.
  41607. *
  41608. * @tparam Type Type for which to generate a type info object.
  41609. * @return A reference to a properly initialized type info object.
  41610. */
  41611. template<typename Type>
  41612. [[nodiscard]] const type_info &type_id() ENTT_NOEXCEPT {
  41613. if constexpr(std::is_same_v<Type, std::remove_cv_t<std::remove_reference_t<Type>>>) {
  41614. static type_info instance{std::in_place_type<Type>};
  41615. return instance;
  41616. } else {
  41617. return type_id<std::remove_cv_t<std::remove_reference_t<Type>>>();
  41618. }
  41619. }
  41620. /*! @copydoc type_id */
  41621. template<typename Type>
  41622. [[nodiscard]] const type_info &type_id(Type &&) ENTT_NOEXCEPT {
  41623. return type_id<std::remove_cv_t<std::remove_reference_t<Type>>>();
  41624. }
  41625. } // namespace entt
  41626. #endif
  41627. // #include "type_traits.hpp"
  41628. #ifndef ENTT_CORE_TYPE_TRAITS_HPP
  41629. #define ENTT_CORE_TYPE_TRAITS_HPP
  41630. #include <cstddef>
  41631. #include <iterator>
  41632. #include <type_traits>
  41633. #include <utility>
  41634. // #include "../config/config.h"
  41635. // #include "fwd.hpp"
  41636. namespace entt {
  41637. /**
  41638. * @brief Utility class to disambiguate overloaded functions.
  41639. * @tparam N Number of choices available.
  41640. */
  41641. template<std::size_t N>
  41642. struct choice_t
  41643. // Unfortunately, doxygen cannot parse such a construct.
  41644. : /*! @cond TURN_OFF_DOXYGEN */ choice_t<N - 1> /*! @endcond */
  41645. {};
  41646. /*! @copybrief choice_t */
  41647. template<>
  41648. struct choice_t<0> {};
  41649. /**
  41650. * @brief Variable template for the choice trick.
  41651. * @tparam N Number of choices available.
  41652. */
  41653. template<std::size_t N>
  41654. inline constexpr choice_t<N> choice{};
  41655. /**
  41656. * @brief Identity type trait.
  41657. *
  41658. * Useful to establish non-deduced contexts in template argument deduction
  41659. * (waiting for C++20) or to provide types through function arguments.
  41660. *
  41661. * @tparam Type A type.
  41662. */
  41663. template<typename Type>
  41664. struct type_identity {
  41665. /*! @brief Identity type. */
  41666. using type = Type;
  41667. };
  41668. /**
  41669. * @brief Helper type.
  41670. * @tparam Type A type.
  41671. */
  41672. template<typename Type>
  41673. using type_identity_t = typename type_identity<Type>::type;
  41674. /**
  41675. * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains.
  41676. * @tparam Type The type of which to return the size.
  41677. * @tparam The size of the type if `sizeof` accepts it, 0 otherwise.
  41678. */
  41679. template<typename Type, typename = void>
  41680. struct size_of: std::integral_constant<std::size_t, 0u> {};
  41681. /*! @copydoc size_of */
  41682. template<typename Type>
  41683. struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
  41684. : std::integral_constant<std::size_t, sizeof(Type)> {};
  41685. /**
  41686. * @brief Helper variable template.
  41687. * @tparam Type The type of which to return the size.
  41688. */
  41689. template<typename Type>
  41690. inline constexpr std::size_t size_of_v = size_of<Type>::value;
  41691. /**
  41692. * @brief Using declaration to be used to _repeat_ the same type a number of
  41693. * times equal to the size of a given parameter pack.
  41694. * @tparam Type A type to repeat.
  41695. */
  41696. template<typename Type, typename>
  41697. using unpack_as_type = Type;
  41698. /**
  41699. * @brief Helper variable template to be used to _repeat_ the same value a
  41700. * number of times equal to the size of a given parameter pack.
  41701. * @tparam Value A value to repeat.
  41702. */
  41703. template<auto Value, typename>
  41704. inline constexpr auto unpack_as_value = Value;
  41705. /**
  41706. * @brief Wraps a static constant.
  41707. * @tparam Value A static constant.
  41708. */
  41709. template<auto Value>
  41710. using integral_constant = std::integral_constant<decltype(Value), Value>;
  41711. /**
  41712. * @brief Alias template to facilitate the creation of named values.
  41713. * @tparam Value A constant value at least convertible to `id_type`.
  41714. */
  41715. template<id_type Value>
  41716. using tag = integral_constant<Value>;
  41717. /**
  41718. * @brief A class to use to push around lists of types, nothing more.
  41719. * @tparam Type Types provided by the type list.
  41720. */
  41721. template<typename... Type>
  41722. struct type_list {
  41723. /*! @brief Type list type. */
  41724. using type = type_list;
  41725. /*! @brief Compile-time number of elements in the type list. */
  41726. static constexpr auto size = sizeof...(Type);
  41727. };
  41728. /*! @brief Primary template isn't defined on purpose. */
  41729. template<std::size_t, typename>
  41730. struct type_list_element;
  41731. /**
  41732. * @brief Provides compile-time indexed access to the types of a type list.
  41733. * @tparam Index Index of the type to return.
  41734. * @tparam Type First type provided by the type list.
  41735. * @tparam Other Other types provided by the type list.
  41736. */
  41737. template<std::size_t Index, typename Type, typename... Other>
  41738. struct type_list_element<Index, type_list<Type, Other...>>
  41739. : type_list_element<Index - 1u, type_list<Other...>> {};
  41740. /**
  41741. * @brief Provides compile-time indexed access to the types of a type list.
  41742. * @tparam Type First type provided by the type list.
  41743. * @tparam Other Other types provided by the type list.
  41744. */
  41745. template<typename Type, typename... Other>
  41746. struct type_list_element<0u, type_list<Type, Other...>> {
  41747. /*! @brief Searched type. */
  41748. using type = Type;
  41749. };
  41750. /**
  41751. * @brief Helper type.
  41752. * @tparam Index Index of the type to return.
  41753. * @tparam List Type list to search into.
  41754. */
  41755. template<std::size_t Index, typename List>
  41756. using type_list_element_t = typename type_list_element<Index, List>::type;
  41757. /**
  41758. * @brief Concatenates multiple type lists.
  41759. * @tparam Type Types provided by the first type list.
  41760. * @tparam Other Types provided by the second type list.
  41761. * @return A type list composed by the types of both the type lists.
  41762. */
  41763. template<typename... Type, typename... Other>
  41764. constexpr type_list<Type..., Other...> operator+(type_list<Type...>, type_list<Other...>) {
  41765. return {};
  41766. }
  41767. /*! @brief Primary template isn't defined on purpose. */
  41768. template<typename...>
  41769. struct type_list_cat;
  41770. /*! @brief Concatenates multiple type lists. */
  41771. template<>
  41772. struct type_list_cat<> {
  41773. /*! @brief A type list composed by the types of all the type lists. */
  41774. using type = type_list<>;
  41775. };
  41776. /**
  41777. * @brief Concatenates multiple type lists.
  41778. * @tparam Type Types provided by the first type list.
  41779. * @tparam Other Types provided by the second type list.
  41780. * @tparam List Other type lists, if any.
  41781. */
  41782. template<typename... Type, typename... Other, typename... List>
  41783. struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
  41784. /*! @brief A type list composed by the types of all the type lists. */
  41785. using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
  41786. };
  41787. /**
  41788. * @brief Concatenates multiple type lists.
  41789. * @tparam Type Types provided by the type list.
  41790. */
  41791. template<typename... Type>
  41792. struct type_list_cat<type_list<Type...>> {
  41793. /*! @brief A type list composed by the types of all the type lists. */
  41794. using type = type_list<Type...>;
  41795. };
  41796. /**
  41797. * @brief Helper type.
  41798. * @tparam List Type lists to concatenate.
  41799. */
  41800. template<typename... List>
  41801. using type_list_cat_t = typename type_list_cat<List...>::type;
  41802. /*! @brief Primary template isn't defined on purpose. */
  41803. template<typename>
  41804. struct type_list_unique;
  41805. /**
  41806. * @brief Removes duplicates types from a type list.
  41807. * @tparam Type One of the types provided by the given type list.
  41808. * @tparam Other The other types provided by the given type list.
  41809. */
  41810. template<typename Type, typename... Other>
  41811. struct type_list_unique<type_list<Type, Other...>> {
  41812. /*! @brief A type list without duplicate types. */
  41813. using type = std::conditional_t<
  41814. (std::is_same_v<Type, Other> || ...),
  41815. typename type_list_unique<type_list<Other...>>::type,
  41816. type_list_cat_t<type_list<Type>, typename type_list_unique<type_list<Other...>>::type>>;
  41817. };
  41818. /*! @brief Removes duplicates types from a type list. */
  41819. template<>
  41820. struct type_list_unique<type_list<>> {
  41821. /*! @brief A type list without duplicate types. */
  41822. using type = type_list<>;
  41823. };
  41824. /**
  41825. * @brief Helper type.
  41826. * @tparam Type A type list.
  41827. */
  41828. template<typename Type>
  41829. using type_list_unique_t = typename type_list_unique<Type>::type;
  41830. /**
  41831. * @brief Provides the member constant `value` to true if a type list contains a
  41832. * given type, false otherwise.
  41833. * @tparam List Type list.
  41834. * @tparam Type Type to look for.
  41835. */
  41836. template<typename List, typename Type>
  41837. struct type_list_contains;
  41838. /**
  41839. * @copybrief type_list_contains
  41840. * @tparam Type Types provided by the type list.
  41841. * @tparam Other Type to look for.
  41842. */
  41843. template<typename... Type, typename Other>
  41844. struct type_list_contains<type_list<Type...>, Other>: std::disjunction<std::is_same<Type, Other>...> {};
  41845. /**
  41846. * @brief Helper variable template.
  41847. * @tparam List Type list.
  41848. * @tparam Type Type to look for.
  41849. */
  41850. template<typename List, typename Type>
  41851. inline constexpr bool type_list_contains_v = type_list_contains<List, Type>::value;
  41852. /*! @brief Primary template isn't defined on purpose. */
  41853. template<typename...>
  41854. struct type_list_diff;
  41855. /**
  41856. * @brief Computes the difference between two type lists.
  41857. * @tparam Type Types provided by the first type list.
  41858. * @tparam Other Types provided by the second type list.
  41859. */
  41860. template<typename... Type, typename... Other>
  41861. struct type_list_diff<type_list<Type...>, type_list<Other...>> {
  41862. /*! @brief A type list that is the difference between the two type lists. */
  41863. using type = type_list_cat_t<std::conditional_t<type_list_contains_v<type_list<Other...>, Type>, type_list<>, type_list<Type>>...>;
  41864. };
  41865. /**
  41866. * @brief Helper type.
  41867. * @tparam List Type lists between which to compute the difference.
  41868. */
  41869. template<typename... List>
  41870. using type_list_diff_t = typename type_list_diff<List...>::type;
  41871. /**
  41872. * @brief A class to use to push around lists of constant values, nothing more.
  41873. * @tparam Value Values provided by the value list.
  41874. */
  41875. template<auto... Value>
  41876. struct value_list {
  41877. /*! @brief Value list type. */
  41878. using type = value_list;
  41879. /*! @brief Compile-time number of elements in the value list. */
  41880. static constexpr auto size = sizeof...(Value);
  41881. };
  41882. /*! @brief Primary template isn't defined on purpose. */
  41883. template<std::size_t, typename>
  41884. struct value_list_element;
  41885. /**
  41886. * @brief Provides compile-time indexed access to the values of a value list.
  41887. * @tparam Index Index of the value to return.
  41888. * @tparam Value First value provided by the value list.
  41889. * @tparam Other Other values provided by the value list.
  41890. */
  41891. template<std::size_t Index, auto Value, auto... Other>
  41892. struct value_list_element<Index, value_list<Value, Other...>>
  41893. : value_list_element<Index - 1u, value_list<Other...>> {};
  41894. /**
  41895. * @brief Provides compile-time indexed access to the types of a type list.
  41896. * @tparam Value First value provided by the value list.
  41897. * @tparam Other Other values provided by the value list.
  41898. */
  41899. template<auto Value, auto... Other>
  41900. struct value_list_element<0u, value_list<Value, Other...>> {
  41901. /*! @brief Searched value. */
  41902. static constexpr auto value = Value;
  41903. };
  41904. /**
  41905. * @brief Helper type.
  41906. * @tparam Index Index of the value to return.
  41907. * @tparam List Value list to search into.
  41908. */
  41909. template<std::size_t Index, typename List>
  41910. inline constexpr auto value_list_element_v = value_list_element<Index, List>::value;
  41911. /**
  41912. * @brief Concatenates multiple value lists.
  41913. * @tparam Value Values provided by the first value list.
  41914. * @tparam Other Values provided by the second value list.
  41915. * @return A value list composed by the values of both the value lists.
  41916. */
  41917. template<auto... Value, auto... Other>
  41918. constexpr value_list<Value..., Other...> operator+(value_list<Value...>, value_list<Other...>) {
  41919. return {};
  41920. }
  41921. /*! @brief Primary template isn't defined on purpose. */
  41922. template<typename...>
  41923. struct value_list_cat;
  41924. /*! @brief Concatenates multiple value lists. */
  41925. template<>
  41926. struct value_list_cat<> {
  41927. /*! @brief A value list composed by the values of all the value lists. */
  41928. using type = value_list<>;
  41929. };
  41930. /**
  41931. * @brief Concatenates multiple value lists.
  41932. * @tparam Value Values provided by the first value list.
  41933. * @tparam Other Values provided by the second value list.
  41934. * @tparam List Other value lists, if any.
  41935. */
  41936. template<auto... Value, auto... Other, typename... List>
  41937. struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
  41938. /*! @brief A value list composed by the values of all the value lists. */
  41939. using type = typename value_list_cat<value_list<Value..., Other...>, List...>::type;
  41940. };
  41941. /**
  41942. * @brief Concatenates multiple value lists.
  41943. * @tparam Value Values provided by the value list.
  41944. */
  41945. template<auto... Value>
  41946. struct value_list_cat<value_list<Value...>> {
  41947. /*! @brief A value list composed by the values of all the value lists. */
  41948. using type = value_list<Value...>;
  41949. };
  41950. /**
  41951. * @brief Helper type.
  41952. * @tparam List Value lists to concatenate.
  41953. */
  41954. template<typename... List>
  41955. using value_list_cat_t = typename value_list_cat<List...>::type;
  41956. /*! @brief Same as std::is_invocable, but with tuples. */
  41957. template<typename, typename>
  41958. struct is_applicable: std::false_type {};
  41959. /**
  41960. * @copybrief is_applicable
  41961. * @tparam Func A valid function type.
  41962. * @tparam Tuple Tuple-like type.
  41963. * @tparam Args The list of arguments to use to probe the function type.
  41964. */
  41965. template<typename Func, template<typename...> class Tuple, typename... Args>
  41966. struct is_applicable<Func, Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  41967. /**
  41968. * @copybrief is_applicable
  41969. * @tparam Func A valid function type.
  41970. * @tparam Tuple Tuple-like type.
  41971. * @tparam Args The list of arguments to use to probe the function type.
  41972. */
  41973. template<typename Func, template<typename...> class Tuple, typename... Args>
  41974. struct is_applicable<Func, const Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  41975. /**
  41976. * @brief Helper variable template.
  41977. * @tparam Func A valid function type.
  41978. * @tparam Args The list of arguments to use to probe the function type.
  41979. */
  41980. template<typename Func, typename Args>
  41981. inline constexpr bool is_applicable_v = is_applicable<Func, Args>::value;
  41982. /*! @brief Same as std::is_invocable_r, but with tuples for arguments. */
  41983. template<typename, typename, typename>
  41984. struct is_applicable_r: std::false_type {};
  41985. /**
  41986. * @copybrief is_applicable_r
  41987. * @tparam Ret The type to which the return type of the function should be
  41988. * convertible.
  41989. * @tparam Func A valid function type.
  41990. * @tparam Args The list of arguments to use to probe the function type.
  41991. */
  41992. template<typename Ret, typename Func, typename... Args>
  41993. struct is_applicable_r<Ret, Func, std::tuple<Args...>>: std::is_invocable_r<Ret, Func, Args...> {};
  41994. /**
  41995. * @brief Helper variable template.
  41996. * @tparam Ret The type to which the return type of the function should be
  41997. * convertible.
  41998. * @tparam Func A valid function type.
  41999. * @tparam Args The list of arguments to use to probe the function type.
  42000. */
  42001. template<typename Ret, typename Func, typename Args>
  42002. inline constexpr bool is_applicable_r_v = is_applicable_r<Ret, Func, Args>::value;
  42003. /**
  42004. * @brief Provides the member constant `value` to true if a given type is
  42005. * complete, false otherwise.
  42006. * @tparam Type The type to test.
  42007. */
  42008. template<typename Type, typename = void>
  42009. struct is_complete: std::false_type {};
  42010. /*! @copydoc is_complete */
  42011. template<typename Type>
  42012. struct is_complete<Type, std::void_t<decltype(sizeof(Type))>>: std::true_type {};
  42013. /**
  42014. * @brief Helper variable template.
  42015. * @tparam Type The type to test.
  42016. */
  42017. template<typename Type>
  42018. inline constexpr bool is_complete_v = is_complete<Type>::value;
  42019. /**
  42020. * @brief Provides the member constant `value` to true if a given type is an
  42021. * iterator, false otherwise.
  42022. * @tparam Type The type to test.
  42023. */
  42024. template<typename Type, typename = void>
  42025. struct is_iterator: std::false_type {};
  42026. /**
  42027. * @cond TURN_OFF_DOXYGEN
  42028. * Internal details not to be documented.
  42029. */
  42030. namespace internal {
  42031. template<typename, typename = void>
  42032. struct has_iterator_category: std::false_type {};
  42033. template<typename Type>
  42034. struct has_iterator_category<Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>: std::true_type {};
  42035. } // namespace internal
  42036. /**
  42037. * Internal details not to be documented.
  42038. * @endcond
  42039. */
  42040. /*! @copydoc is_iterator */
  42041. template<typename Type>
  42042. struct is_iterator<Type, std::enable_if_t<!std::is_same_v<std::remove_const_t<std::remove_pointer_t<Type>>, void>>>
  42043. : internal::has_iterator_category<Type> {};
  42044. /**
  42045. * @brief Helper variable template.
  42046. * @tparam Type The type to test.
  42047. */
  42048. template<typename Type>
  42049. inline constexpr bool is_iterator_v = is_iterator<Type>::value;
  42050. /**
  42051. * @brief Provides the member constant `value` to true if a given type is both
  42052. * an empty and non-final class, false otherwise.
  42053. * @tparam Type The type to test
  42054. */
  42055. template<typename Type>
  42056. struct is_ebco_eligible
  42057. : std::conjunction<std::is_empty<Type>, std::negation<std::is_final<Type>>> {};
  42058. /**
  42059. * @brief Helper variable template.
  42060. * @tparam Type The type to test.
  42061. */
  42062. template<typename Type>
  42063. inline constexpr bool is_ebco_eligible_v = is_ebco_eligible<Type>::value;
  42064. /**
  42065. * @brief Provides the member constant `value` to true if `Type::is_transparent`
  42066. * is valid and denotes a type, false otherwise.
  42067. * @tparam Type The type to test.
  42068. */
  42069. template<typename Type, typename = void>
  42070. struct is_transparent: std::false_type {};
  42071. /*! @copydoc is_transparent */
  42072. template<typename Type>
  42073. struct is_transparent<Type, std::void_t<typename Type::is_transparent>>: std::true_type {};
  42074. /**
  42075. * @brief Helper variable template.
  42076. * @tparam Type The type to test.
  42077. */
  42078. template<typename Type>
  42079. inline constexpr bool is_transparent_v = is_transparent<Type>::value;
  42080. /**
  42081. * @brief Provides the member constant `value` to true if a given type is
  42082. * equality comparable, false otherwise.
  42083. * @tparam Type The type to test.
  42084. */
  42085. template<typename Type, typename = void>
  42086. struct is_equality_comparable: std::false_type {};
  42087. /**
  42088. * @cond TURN_OFF_DOXYGEN
  42089. * Internal details not to be documented.
  42090. */
  42091. namespace internal {
  42092. template<typename, typename = void>
  42093. struct has_tuple_size_value: std::false_type {};
  42094. template<typename Type>
  42095. struct has_tuple_size_value<Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>: std::true_type {};
  42096. template<typename Type, std::size_t... Index>
  42097. [[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
  42098. return (is_equality_comparable<std::tuple_element_t<Index, Type>>::value && ...);
  42099. }
  42100. template<typename>
  42101. [[nodiscard]] constexpr bool maybe_equality_comparable(choice_t<0>) {
  42102. return true;
  42103. }
  42104. template<typename Type>
  42105. [[nodiscard]] constexpr auto maybe_equality_comparable(choice_t<1>) -> decltype(std::declval<typename Type::value_type>(), bool{}) {
  42106. if constexpr(is_iterator_v<Type>) {
  42107. return true;
  42108. } else if constexpr(std::is_same_v<typename Type::value_type, Type>) {
  42109. return maybe_equality_comparable<Type>(choice<0>);
  42110. } else {
  42111. return is_equality_comparable<typename Type::value_type>::value;
  42112. }
  42113. }
  42114. template<typename Type>
  42115. [[nodiscard]] constexpr std::enable_if_t<is_complete_v<std::tuple_size<std::remove_const_t<Type>>>, bool> maybe_equality_comparable(choice_t<2>) {
  42116. if constexpr(has_tuple_size_value<Type>::value) {
  42117. return unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
  42118. } else {
  42119. return maybe_equality_comparable<Type>(choice<1>);
  42120. }
  42121. }
  42122. } // namespace internal
  42123. /**
  42124. * Internal details not to be documented.
  42125. * @endcond
  42126. */
  42127. /*! @copydoc is_equality_comparable */
  42128. template<typename Type>
  42129. struct is_equality_comparable<Type, std::void_t<decltype(std::declval<Type>() == std::declval<Type>())>>
  42130. : std::bool_constant<internal::maybe_equality_comparable<Type>(choice<2>)> {};
  42131. /**
  42132. * @brief Helper variable template.
  42133. * @tparam Type The type to test.
  42134. */
  42135. template<typename Type>
  42136. inline constexpr bool is_equality_comparable_v = is_equality_comparable<Type>::value;
  42137. /**
  42138. * @brief Transcribes the constness of a type to another type.
  42139. * @tparam To The type to which to transcribe the constness.
  42140. * @tparam From The type from which to transcribe the constness.
  42141. */
  42142. template<typename To, typename From>
  42143. struct constness_as {
  42144. /*! @brief The type resulting from the transcription of the constness. */
  42145. using type = std::remove_const_t<To>;
  42146. };
  42147. /*! @copydoc constness_as */
  42148. template<typename To, typename From>
  42149. struct constness_as<To, const From> {
  42150. /*! @brief The type resulting from the transcription of the constness. */
  42151. using type = std::add_const_t<To>;
  42152. };
  42153. /**
  42154. * @brief Alias template to facilitate the transcription of the constness.
  42155. * @tparam To The type to which to transcribe the constness.
  42156. * @tparam From The type from which to transcribe the constness.
  42157. */
  42158. template<typename To, typename From>
  42159. using constness_as_t = typename constness_as<To, From>::type;
  42160. /**
  42161. * @brief Extracts the class of a non-static member object or function.
  42162. * @tparam Member A pointer to a non-static member object or function.
  42163. */
  42164. template<typename Member>
  42165. class member_class {
  42166. static_assert(std::is_member_pointer_v<Member>, "Invalid pointer type to non-static member object or function");
  42167. template<typename Class, typename Ret, typename... Args>
  42168. static Class *clazz(Ret (Class::*)(Args...));
  42169. template<typename Class, typename Ret, typename... Args>
  42170. static Class *clazz(Ret (Class::*)(Args...) const);
  42171. template<typename Class, typename Type>
  42172. static Class *clazz(Type Class::*);
  42173. public:
  42174. /*! @brief The class of the given non-static member object or function. */
  42175. using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
  42176. };
  42177. /**
  42178. * @brief Helper type.
  42179. * @tparam Member A pointer to a non-static member object or function.
  42180. */
  42181. template<typename Member>
  42182. using member_class_t = typename member_class<Member>::type;
  42183. } // namespace entt
  42184. #endif
  42185. namespace entt {
  42186. /**
  42187. * @brief A SBO friendly, type-safe container for single values of any type.
  42188. * @tparam Len Size of the storage reserved for the small buffer optimization.
  42189. * @tparam Align Optional alignment requirement.
  42190. */
  42191. template<std::size_t Len, std::size_t Align>
  42192. class basic_any {
  42193. enum class operation : std::uint8_t {
  42194. copy,
  42195. move,
  42196. transfer,
  42197. assign,
  42198. destroy,
  42199. compare,
  42200. get
  42201. };
  42202. enum class policy : std::uint8_t {
  42203. owner,
  42204. ref,
  42205. cref
  42206. };
  42207. using storage_type = std::aligned_storage_t<Len + !Len, Align>;
  42208. using vtable_type = const void *(const operation, const basic_any &, const void *);
  42209. template<typename Type>
  42210. static constexpr bool in_situ = Len && alignof(Type) <= alignof(storage_type) && sizeof(Type) <= sizeof(storage_type) && std::is_nothrow_move_constructible_v<Type>;
  42211. template<typename Type>
  42212. static const void *basic_vtable([[maybe_unused]] const operation op, [[maybe_unused]] const basic_any &value, [[maybe_unused]] const void *other) {
  42213. static_assert(!std::is_same_v<Type, void> && std::is_same_v<std::remove_cv_t<std::remove_reference_t<Type>>, Type>, "Invalid type");
  42214. const Type *element = nullptr;
  42215. if constexpr(in_situ<Type>) {
  42216. element = value.owner() ? reinterpret_cast<const Type *>(&value.storage) : static_cast<const Type *>(value.instance);
  42217. } else {
  42218. element = static_cast<const Type *>(value.instance);
  42219. }
  42220. switch(op) {
  42221. case operation::copy:
  42222. if constexpr(std::is_copy_constructible_v<Type>) {
  42223. static_cast<basic_any *>(const_cast<void *>(other))->initialize<Type>(*element);
  42224. }
  42225. break;
  42226. case operation::move:
  42227. if constexpr(in_situ<Type>) {
  42228. if(value.owner()) {
  42229. return new(&static_cast<basic_any *>(const_cast<void *>(other))->storage) Type{std::move(*const_cast<Type *>(element))};
  42230. }
  42231. }
  42232. return (static_cast<basic_any *>(const_cast<void *>(other))->instance = std::exchange(const_cast<basic_any &>(value).instance, nullptr));
  42233. case operation::transfer:
  42234. if constexpr(std::is_move_assignable_v<Type>) {
  42235. *const_cast<Type *>(element) = std::move(*static_cast<Type *>(const_cast<void *>(other)));
  42236. return other;
  42237. }
  42238. [[fallthrough]];
  42239. case operation::assign:
  42240. if constexpr(std::is_copy_assignable_v<Type>) {
  42241. *const_cast<Type *>(element) = *static_cast<const Type *>(other);
  42242. return other;
  42243. }
  42244. break;
  42245. case operation::destroy:
  42246. if constexpr(in_situ<Type>) {
  42247. element->~Type();
  42248. } else if constexpr(std::is_array_v<Type>) {
  42249. delete[] element;
  42250. } else {
  42251. delete element;
  42252. }
  42253. break;
  42254. case operation::compare:
  42255. if constexpr(!std::is_function_v<Type> && !std::is_array_v<Type> && is_equality_comparable_v<Type>) {
  42256. return *static_cast<const Type *>(element) == *static_cast<const Type *>(other) ? other : nullptr;
  42257. } else {
  42258. return (element == other) ? other : nullptr;
  42259. }
  42260. case operation::get:
  42261. return element;
  42262. }
  42263. return nullptr;
  42264. }
  42265. template<typename Type, typename... Args>
  42266. void initialize([[maybe_unused]] Args &&...args) {
  42267. if constexpr(!std::is_void_v<Type>) {
  42268. info = &type_id<std::remove_cv_t<std::remove_reference_t<Type>>>();
  42269. vtable = basic_vtable<std::remove_cv_t<std::remove_reference_t<Type>>>;
  42270. if constexpr(std::is_lvalue_reference_v<Type>) {
  42271. static_assert(sizeof...(Args) == 1u && (std::is_lvalue_reference_v<Args> && ...), "Invalid arguments");
  42272. mode = std::is_const_v<std::remove_reference_t<Type>> ? policy::cref : policy::ref;
  42273. instance = (std::addressof(args), ...);
  42274. } else if constexpr(in_situ<Type>) {
  42275. if constexpr(sizeof...(Args) != 0u && std::is_aggregate_v<Type>) {
  42276. new(&storage) Type{std::forward<Args>(args)...};
  42277. } else {
  42278. new(&storage) Type(std::forward<Args>(args)...);
  42279. }
  42280. } else {
  42281. if constexpr(sizeof...(Args) != 0u && std::is_aggregate_v<Type>) {
  42282. instance = new Type{std::forward<Args>(args)...};
  42283. } else {
  42284. instance = new Type(std::forward<Args>(args)...);
  42285. }
  42286. }
  42287. }
  42288. }
  42289. basic_any(const basic_any &other, const policy pol) ENTT_NOEXCEPT
  42290. : instance{other.data()},
  42291. info{other.info},
  42292. vtable{other.vtable},
  42293. mode{pol} {}
  42294. public:
  42295. /*! @brief Size of the internal storage. */
  42296. static constexpr auto length = Len;
  42297. /*! @brief Alignment requirement. */
  42298. static constexpr auto alignment = Align;
  42299. /*! @brief Default constructor. */
  42300. constexpr basic_any() ENTT_NOEXCEPT
  42301. : instance{},
  42302. info{&type_id<void>()},
  42303. vtable{},
  42304. mode{policy::owner} {}
  42305. /**
  42306. * @brief Constructs a wrapper by directly initializing the new object.
  42307. * @tparam Type Type of object to use to initialize the wrapper.
  42308. * @tparam Args Types of arguments to use to construct the new instance.
  42309. * @param args Parameters to use to construct the instance.
  42310. */
  42311. template<typename Type, typename... Args>
  42312. explicit basic_any(std::in_place_type_t<Type>, Args &&...args)
  42313. : basic_any{} {
  42314. initialize<Type>(std::forward<Args>(args)...);
  42315. }
  42316. /**
  42317. * @brief Constructs a wrapper from a given value.
  42318. * @tparam Type Type of object to use to initialize the wrapper.
  42319. * @param value An instance of an object to use to initialize the wrapper.
  42320. */
  42321. template<typename Type, typename = std::enable_if_t<!std::is_same_v<std::decay_t<Type>, basic_any>>>
  42322. basic_any(Type &&value)
  42323. : basic_any{} {
  42324. initialize<std::decay_t<Type>>(std::forward<Type>(value));
  42325. }
  42326. /**
  42327. * @brief Copy constructor.
  42328. * @param other The instance to copy from.
  42329. */
  42330. basic_any(const basic_any &other)
  42331. : basic_any{} {
  42332. if(other.vtable) {
  42333. other.vtable(operation::copy, other, this);
  42334. }
  42335. }
  42336. /**
  42337. * @brief Move constructor.
  42338. * @param other The instance to move from.
  42339. */
  42340. basic_any(basic_any &&other) ENTT_NOEXCEPT
  42341. : instance{},
  42342. info{other.info},
  42343. vtable{other.vtable},
  42344. mode{other.mode} {
  42345. if(other.vtable) {
  42346. other.vtable(operation::move, other, this);
  42347. }
  42348. }
  42349. /*! @brief Frees the internal storage, whatever it means. */
  42350. ~basic_any() {
  42351. if(vtable && owner()) {
  42352. vtable(operation::destroy, *this, nullptr);
  42353. }
  42354. }
  42355. /**
  42356. * @brief Copy assignment operator.
  42357. * @param other The instance to copy from.
  42358. * @return This any object.
  42359. */
  42360. basic_any &operator=(const basic_any &other) {
  42361. reset();
  42362. if(other.vtable) {
  42363. other.vtable(operation::copy, other, this);
  42364. }
  42365. return *this;
  42366. }
  42367. /**
  42368. * @brief Move assignment operator.
  42369. * @param other The instance to move from.
  42370. * @return This any object.
  42371. */
  42372. basic_any &operator=(basic_any &&other) ENTT_NOEXCEPT {
  42373. reset();
  42374. if(other.vtable) {
  42375. other.vtable(operation::move, other, this);
  42376. info = other.info;
  42377. vtable = other.vtable;
  42378. mode = other.mode;
  42379. }
  42380. return *this;
  42381. }
  42382. /**
  42383. * @brief Value assignment operator.
  42384. * @tparam Type Type of object to use to initialize the wrapper.
  42385. * @param value An instance of an object to use to initialize the wrapper.
  42386. * @return This any object.
  42387. */
  42388. template<typename Type>
  42389. std::enable_if_t<!std::is_same_v<std::decay_t<Type>, basic_any>, basic_any &>
  42390. operator=(Type &&value) {
  42391. emplace<std::decay_t<Type>>(std::forward<Type>(value));
  42392. return *this;
  42393. }
  42394. /**
  42395. * @brief Returns the object type if any, `type_id<void>()` otherwise.
  42396. * @return The object type if any, `type_id<void>()` otherwise.
  42397. */
  42398. [[nodiscard]] const type_info &type() const ENTT_NOEXCEPT {
  42399. return *info;
  42400. }
  42401. /**
  42402. * @brief Returns an opaque pointer to the contained instance.
  42403. * @return An opaque pointer the contained instance, if any.
  42404. */
  42405. [[nodiscard]] const void *data() const ENTT_NOEXCEPT {
  42406. return vtable ? vtable(operation::get, *this, nullptr) : nullptr;
  42407. }
  42408. /**
  42409. * @brief Returns an opaque pointer to the contained instance.
  42410. * @param req Expected type.
  42411. * @return An opaque pointer the contained instance, if any.
  42412. */
  42413. [[nodiscard]] const void *data(const type_info &req) const ENTT_NOEXCEPT {
  42414. return *info == req ? data() : nullptr;
  42415. }
  42416. /**
  42417. * @brief Returns an opaque pointer to the contained instance.
  42418. * @return An opaque pointer the contained instance, if any.
  42419. */
  42420. [[nodiscard]] void *data() ENTT_NOEXCEPT {
  42421. return (!vtable || mode == policy::cref) ? nullptr : const_cast<void *>(vtable(operation::get, *this, nullptr));
  42422. }
  42423. /**
  42424. * @brief Returns an opaque pointer to the contained instance.
  42425. * @param req Expected type.
  42426. * @return An opaque pointer the contained instance, if any.
  42427. */
  42428. [[nodiscard]] void *data(const type_info &req) ENTT_NOEXCEPT {
  42429. return *info == req ? data() : nullptr;
  42430. }
  42431. /**
  42432. * @brief Replaces the contained object by creating a new instance directly.
  42433. * @tparam Type Type of object to use to initialize the wrapper.
  42434. * @tparam Args Types of arguments to use to construct the new instance.
  42435. * @param args Parameters to use to construct the instance.
  42436. */
  42437. template<typename Type, typename... Args>
  42438. void emplace(Args &&...args) {
  42439. reset();
  42440. initialize<Type>(std::forward<Args>(args)...);
  42441. }
  42442. /**
  42443. * @brief Assigns a value to the contained object without replacing it.
  42444. * @param other The value to assign to the contained object.
  42445. * @return True in case of success, false otherwise.
  42446. */
  42447. bool assign(const any &other) {
  42448. if(vtable && mode != policy::cref && *info == *other.info) {
  42449. return (vtable(operation::assign, *this, other.data()) != nullptr);
  42450. }
  42451. return false;
  42452. }
  42453. /*! @copydoc assign */
  42454. bool assign(any &&other) {
  42455. if(vtable && mode != policy::cref && *info == *other.info) {
  42456. if(auto *val = other.data(); val) {
  42457. return (vtable(operation::transfer, *this, val) != nullptr);
  42458. } else {
  42459. return (vtable(operation::assign, *this, std::as_const(other).data()) != nullptr);
  42460. }
  42461. }
  42462. return false;
  42463. }
  42464. /*! @brief Destroys contained object */
  42465. void reset() {
  42466. if(vtable && owner()) {
  42467. vtable(operation::destroy, *this, nullptr);
  42468. }
  42469. info = &type_id<void>();
  42470. vtable = nullptr;
  42471. mode = policy::owner;
  42472. }
  42473. /**
  42474. * @brief Returns false if a wrapper is empty, true otherwise.
  42475. * @return False if the wrapper is empty, true otherwise.
  42476. */
  42477. [[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
  42478. return vtable != nullptr;
  42479. }
  42480. /**
  42481. * @brief Checks if two wrappers differ in their content.
  42482. * @param other Wrapper with which to compare.
  42483. * @return False if the two objects differ in their content, true otherwise.
  42484. */
  42485. bool operator==(const basic_any &other) const ENTT_NOEXCEPT {
  42486. if(vtable && *info == *other.info) {
  42487. return (vtable(operation::compare, *this, other.data()) != nullptr);
  42488. }
  42489. return (!vtable && !other.vtable);
  42490. }
  42491. /**
  42492. * @brief Aliasing constructor.
  42493. * @return A wrapper that shares a reference to an unmanaged object.
  42494. */
  42495. [[nodiscard]] basic_any as_ref() ENTT_NOEXCEPT {
  42496. return basic_any{*this, (mode == policy::cref ? policy::cref : policy::ref)};
  42497. }
  42498. /*! @copydoc as_ref */
  42499. [[nodiscard]] basic_any as_ref() const ENTT_NOEXCEPT {
  42500. return basic_any{*this, policy::cref};
  42501. }
  42502. /**
  42503. * @brief Returns true if a wrapper owns its object, false otherwise.
  42504. * @return True if the wrapper owns its object, false otherwise.
  42505. */
  42506. [[nodiscard]] bool owner() const ENTT_NOEXCEPT {
  42507. return (mode == policy::owner);
  42508. }
  42509. private:
  42510. union {
  42511. const void *instance;
  42512. storage_type storage;
  42513. };
  42514. const type_info *info;
  42515. vtable_type *vtable;
  42516. policy mode;
  42517. };
  42518. /**
  42519. * @brief Checks if two wrappers differ in their content.
  42520. * @tparam Len Size of the storage reserved for the small buffer optimization.
  42521. * @tparam Align Alignment requirement.
  42522. * @param lhs A wrapper, either empty or not.
  42523. * @param rhs A wrapper, either empty or not.
  42524. * @return True if the two wrappers differ in their content, false otherwise.
  42525. */
  42526. template<std::size_t Len, std::size_t Align>
  42527. [[nodiscard]] inline bool operator!=(const basic_any<Len, Align> &lhs, const basic_any<Len, Align> &rhs) ENTT_NOEXCEPT {
  42528. return !(lhs == rhs);
  42529. }
  42530. /**
  42531. * @brief Performs type-safe access to the contained object.
  42532. * @tparam Type Type to which conversion is required.
  42533. * @tparam Len Size of the storage reserved for the small buffer optimization.
  42534. * @tparam Align Alignment requirement.
  42535. * @param data Target any object.
  42536. * @return The element converted to the requested type.
  42537. */
  42538. template<typename Type, std::size_t Len, std::size_t Align>
  42539. Type any_cast(const basic_any<Len, Align> &data) ENTT_NOEXCEPT {
  42540. const auto *const instance = any_cast<std::remove_reference_t<Type>>(&data);
  42541. ENTT_ASSERT(instance, "Invalid instance");
  42542. return static_cast<Type>(*instance);
  42543. }
  42544. /*! @copydoc any_cast */
  42545. template<typename Type, std::size_t Len, std::size_t Align>
  42546. Type any_cast(basic_any<Len, Align> &data) ENTT_NOEXCEPT {
  42547. // forces const on non-reference types to make them work also with wrappers for const references
  42548. auto *const instance = any_cast<std::remove_reference_t<const Type>>(&data);
  42549. ENTT_ASSERT(instance, "Invalid instance");
  42550. return static_cast<Type>(*instance);
  42551. }
  42552. /*! @copydoc any_cast */
  42553. template<typename Type, std::size_t Len, std::size_t Align>
  42554. Type any_cast(basic_any<Len, Align> &&data) ENTT_NOEXCEPT {
  42555. if constexpr(std::is_copy_constructible_v<std::remove_cv_t<std::remove_reference_t<Type>>>) {
  42556. if(auto *const instance = any_cast<std::remove_reference_t<Type>>(&data); instance) {
  42557. return static_cast<Type>(std::move(*instance));
  42558. } else {
  42559. return any_cast<Type>(data);
  42560. }
  42561. } else {
  42562. auto *const instance = any_cast<std::remove_reference_t<Type>>(&data);
  42563. ENTT_ASSERT(instance, "Invalid instance");
  42564. return static_cast<Type>(std::move(*instance));
  42565. }
  42566. }
  42567. /*! @copydoc any_cast */
  42568. template<typename Type, std::size_t Len, std::size_t Align>
  42569. const Type *any_cast(const basic_any<Len, Align> *data) ENTT_NOEXCEPT {
  42570. const auto &info = type_id<std::remove_cv_t<std::remove_reference_t<Type>>>();
  42571. return static_cast<const Type *>(data->data(info));
  42572. }
  42573. /*! @copydoc any_cast */
  42574. template<typename Type, std::size_t Len, std::size_t Align>
  42575. Type *any_cast(basic_any<Len, Align> *data) ENTT_NOEXCEPT {
  42576. const auto &info = type_id<std::remove_cv_t<std::remove_reference_t<Type>>>();
  42577. // last attempt to make wrappers for const references return their values
  42578. return static_cast<Type *>(static_cast<constness_as_t<basic_any<Len, Align>, Type> *>(data)->data(info));
  42579. }
  42580. /**
  42581. * @brief Constructs a wrapper from a given type, passing it all arguments.
  42582. * @tparam Type Type of object to use to initialize the wrapper.
  42583. * @tparam Len Size of the storage reserved for the small buffer optimization.
  42584. * @tparam Align Optional alignment requirement.
  42585. * @tparam Args Types of arguments to use to construct the new instance.
  42586. * @param args Parameters to use to construct the instance.
  42587. * @return A properly initialized wrapper for an object of the given type.
  42588. */
  42589. template<typename Type, std::size_t Len = basic_any<>::length, std::size_t Align = basic_any<Len>::alignment, typename... Args>
  42590. basic_any<Len, Align> make_any(Args &&...args) {
  42591. return basic_any<Len, Align>{std::in_place_type<Type>, std::forward<Args>(args)...};
  42592. }
  42593. /**
  42594. * @brief Forwards its argument and avoids copies for lvalue references.
  42595. * @tparam Len Size of the storage reserved for the small buffer optimization.
  42596. * @tparam Align Optional alignment requirement.
  42597. * @tparam Type Type of argument to use to construct the new instance.
  42598. * @param value Parameter to use to construct the instance.
  42599. * @return A properly initialized and not necessarily owning wrapper.
  42600. */
  42601. template<std::size_t Len = basic_any<>::length, std::size_t Align = basic_any<Len>::alignment, typename Type>
  42602. basic_any<Len, Align> forward_as_any(Type &&value) {
  42603. return basic_any<Len, Align>{std::in_place_type<std::conditional_t<std::is_rvalue_reference_v<Type>, std::decay_t<Type>, Type>>, std::forward<Type>(value)};
  42604. }
  42605. } // namespace entt
  42606. #endif
  42607. // #include "../core/type_info.hpp"
  42608. #ifndef ENTT_CORE_TYPE_INFO_HPP
  42609. #define ENTT_CORE_TYPE_INFO_HPP
  42610. #include <string_view>
  42611. #include <type_traits>
  42612. #include <utility>
  42613. // #include "../config/config.h"
  42614. // #include "../core/attribute.h"
  42615. // #include "fwd.hpp"
  42616. // #include "hashed_string.hpp"
  42617. namespace entt {
  42618. /**
  42619. * @cond TURN_OFF_DOXYGEN
  42620. * Internal details not to be documented.
  42621. */
  42622. namespace internal {
  42623. struct ENTT_API type_index final {
  42624. [[nodiscard]] static id_type next() ENTT_NOEXCEPT {
  42625. static ENTT_MAYBE_ATOMIC(id_type) value{};
  42626. return value++;
  42627. }
  42628. };
  42629. template<typename Type>
  42630. [[nodiscard]] constexpr auto stripped_type_name() ENTT_NOEXCEPT {
  42631. #if defined ENTT_PRETTY_FUNCTION
  42632. std::string_view pretty_function{ENTT_PRETTY_FUNCTION};
  42633. auto first = pretty_function.find_first_not_of(' ', pretty_function.find_first_of(ENTT_PRETTY_FUNCTION_PREFIX) + 1);
  42634. auto value = pretty_function.substr(first, pretty_function.find_last_of(ENTT_PRETTY_FUNCTION_SUFFIX) - first);
  42635. return value;
  42636. #else
  42637. return std::string_view{""};
  42638. #endif
  42639. }
  42640. template<typename Type, auto = stripped_type_name<Type>().find_first_of('.')>
  42641. [[nodiscard]] static constexpr std::string_view type_name(int) ENTT_NOEXCEPT {
  42642. constexpr auto value = stripped_type_name<Type>();
  42643. return value;
  42644. }
  42645. template<typename Type>
  42646. [[nodiscard]] static std::string_view type_name(char) ENTT_NOEXCEPT {
  42647. static const auto value = stripped_type_name<Type>();
  42648. return value;
  42649. }
  42650. template<typename Type, auto = stripped_type_name<Type>().find_first_of('.')>
  42651. [[nodiscard]] static constexpr id_type type_hash(int) ENTT_NOEXCEPT {
  42652. constexpr auto stripped = stripped_type_name<Type>();
  42653. constexpr auto value = hashed_string::value(stripped.data(), stripped.size());
  42654. return value;
  42655. }
  42656. template<typename Type>
  42657. [[nodiscard]] static id_type type_hash(char) ENTT_NOEXCEPT {
  42658. static const auto value = [](const auto stripped) {
  42659. return hashed_string::value(stripped.data(), stripped.size());
  42660. }(stripped_type_name<Type>());
  42661. return value;
  42662. }
  42663. } // namespace internal
  42664. /**
  42665. * Internal details not to be documented.
  42666. * @endcond
  42667. */
  42668. /**
  42669. * @brief Type sequential identifier.
  42670. * @tparam Type Type for which to generate a sequential identifier.
  42671. */
  42672. template<typename Type, typename = void>
  42673. struct ENTT_API type_index final {
  42674. /**
  42675. * @brief Returns the sequential identifier of a given type.
  42676. * @return The sequential identifier of a given type.
  42677. */
  42678. [[nodiscard]] static id_type value() ENTT_NOEXCEPT {
  42679. static const id_type value = internal::type_index::next();
  42680. return value;
  42681. }
  42682. /*! @copydoc value */
  42683. [[nodiscard]] constexpr operator id_type() const ENTT_NOEXCEPT {
  42684. return value();
  42685. }
  42686. };
  42687. /**
  42688. * @brief Type hash.
  42689. * @tparam Type Type for which to generate a hash value.
  42690. */
  42691. template<typename Type, typename = void>
  42692. struct type_hash final {
  42693. /**
  42694. * @brief Returns the numeric representation of a given type.
  42695. * @return The numeric representation of the given type.
  42696. */
  42697. #if defined ENTT_PRETTY_FUNCTION
  42698. [[nodiscard]] static constexpr id_type value() ENTT_NOEXCEPT {
  42699. return internal::type_hash<Type>(0);
  42700. #else
  42701. [[nodiscard]] static constexpr id_type value() ENTT_NOEXCEPT {
  42702. return type_index<Type>::value();
  42703. #endif
  42704. }
  42705. /*! @copydoc value */
  42706. [[nodiscard]] constexpr operator id_type() const ENTT_NOEXCEPT {
  42707. return value();
  42708. }
  42709. };
  42710. /**
  42711. * @brief Type name.
  42712. * @tparam Type Type for which to generate a name.
  42713. */
  42714. template<typename Type, typename = void>
  42715. struct type_name final {
  42716. /**
  42717. * @brief Returns the name of a given type.
  42718. * @return The name of the given type.
  42719. */
  42720. [[nodiscard]] static constexpr std::string_view value() ENTT_NOEXCEPT {
  42721. return internal::type_name<Type>(0);
  42722. }
  42723. /*! @copydoc value */
  42724. [[nodiscard]] constexpr operator std::string_view() const ENTT_NOEXCEPT {
  42725. return value();
  42726. }
  42727. };
  42728. /*! @brief Implementation specific information about a type. */
  42729. struct type_info final {
  42730. /**
  42731. * @brief Constructs a type info object for a given type.
  42732. * @tparam Type Type for which to construct a type info object.
  42733. */
  42734. template<typename Type>
  42735. constexpr type_info(std::in_place_type_t<Type>) ENTT_NOEXCEPT
  42736. : seq{type_index<std::remove_cv_t<std::remove_reference_t<Type>>>::value()},
  42737. identifier{type_hash<std::remove_cv_t<std::remove_reference_t<Type>>>::value()},
  42738. alias{type_name<std::remove_cv_t<std::remove_reference_t<Type>>>::value()} {}
  42739. /**
  42740. * @brief Type index.
  42741. * @return Type index.
  42742. */
  42743. [[nodiscard]] constexpr id_type index() const ENTT_NOEXCEPT {
  42744. return seq;
  42745. }
  42746. /**
  42747. * @brief Type hash.
  42748. * @return Type hash.
  42749. */
  42750. [[nodiscard]] constexpr id_type hash() const ENTT_NOEXCEPT {
  42751. return identifier;
  42752. }
  42753. /**
  42754. * @brief Type name.
  42755. * @return Type name.
  42756. */
  42757. [[nodiscard]] constexpr std::string_view name() const ENTT_NOEXCEPT {
  42758. return alias;
  42759. }
  42760. private:
  42761. id_type seq;
  42762. id_type identifier;
  42763. std::string_view alias;
  42764. };
  42765. /**
  42766. * @brief Compares the contents of two type info objects.
  42767. * @param lhs A type info object.
  42768. * @param rhs A type info object.
  42769. * @return True if the two type info objects are identical, false otherwise.
  42770. */
  42771. [[nodiscard]] inline constexpr bool operator==(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT {
  42772. return lhs.hash() == rhs.hash();
  42773. }
  42774. /**
  42775. * @brief Compares the contents of two type info objects.
  42776. * @param lhs A type info object.
  42777. * @param rhs A type info object.
  42778. * @return True if the two type info objects differ, false otherwise.
  42779. */
  42780. [[nodiscard]] inline constexpr bool operator!=(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT {
  42781. return !(lhs == rhs);
  42782. }
  42783. /**
  42784. * @brief Compares two type info objects.
  42785. * @param lhs A valid type info object.
  42786. * @param rhs A valid type info object.
  42787. * @return True if the first element is less than the second, false otherwise.
  42788. */
  42789. [[nodiscard]] constexpr bool operator<(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT {
  42790. return lhs.index() < rhs.index();
  42791. }
  42792. /**
  42793. * @brief Compares two type info objects.
  42794. * @param lhs A valid type info object.
  42795. * @param rhs A valid type info object.
  42796. * @return True if the first element is less than or equal to the second, false
  42797. * otherwise.
  42798. */
  42799. [[nodiscard]] constexpr bool operator<=(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT {
  42800. return !(rhs < lhs);
  42801. }
  42802. /**
  42803. * @brief Compares two type info objects.
  42804. * @param lhs A valid type info object.
  42805. * @param rhs A valid type info object.
  42806. * @return True if the first element is greater than the second, false
  42807. * otherwise.
  42808. */
  42809. [[nodiscard]] constexpr bool operator>(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT {
  42810. return rhs < lhs;
  42811. }
  42812. /**
  42813. * @brief Compares two type info objects.
  42814. * @param lhs A valid type info object.
  42815. * @param rhs A valid type info object.
  42816. * @return True if the first element is greater than or equal to the second,
  42817. * false otherwise.
  42818. */
  42819. [[nodiscard]] constexpr bool operator>=(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT {
  42820. return !(lhs < rhs);
  42821. }
  42822. /**
  42823. * @brief Returns the type info object associated to a given type.
  42824. *
  42825. * The returned element refers to an object with static storage duration.<br/>
  42826. * The type doesn't need to be a complete type. If the type is a reference, the
  42827. * result refers to the referenced type. In all cases, top-level cv-qualifiers
  42828. * are ignored.
  42829. *
  42830. * @tparam Type Type for which to generate a type info object.
  42831. * @return A reference to a properly initialized type info object.
  42832. */
  42833. template<typename Type>
  42834. [[nodiscard]] const type_info &type_id() ENTT_NOEXCEPT {
  42835. if constexpr(std::is_same_v<Type, std::remove_cv_t<std::remove_reference_t<Type>>>) {
  42836. static type_info instance{std::in_place_type<Type>};
  42837. return instance;
  42838. } else {
  42839. return type_id<std::remove_cv_t<std::remove_reference_t<Type>>>();
  42840. }
  42841. }
  42842. /*! @copydoc type_id */
  42843. template<typename Type>
  42844. [[nodiscard]] const type_info &type_id(Type &&) ENTT_NOEXCEPT {
  42845. return type_id<std::remove_cv_t<std::remove_reference_t<Type>>>();
  42846. }
  42847. } // namespace entt
  42848. #endif
  42849. // #include "../core/type_traits.hpp"
  42850. #ifndef ENTT_CORE_TYPE_TRAITS_HPP
  42851. #define ENTT_CORE_TYPE_TRAITS_HPP
  42852. #include <cstddef>
  42853. #include <iterator>
  42854. #include <type_traits>
  42855. #include <utility>
  42856. // #include "../config/config.h"
  42857. // #include "fwd.hpp"
  42858. namespace entt {
  42859. /**
  42860. * @brief Utility class to disambiguate overloaded functions.
  42861. * @tparam N Number of choices available.
  42862. */
  42863. template<std::size_t N>
  42864. struct choice_t
  42865. // Unfortunately, doxygen cannot parse such a construct.
  42866. : /*! @cond TURN_OFF_DOXYGEN */ choice_t<N - 1> /*! @endcond */
  42867. {};
  42868. /*! @copybrief choice_t */
  42869. template<>
  42870. struct choice_t<0> {};
  42871. /**
  42872. * @brief Variable template for the choice trick.
  42873. * @tparam N Number of choices available.
  42874. */
  42875. template<std::size_t N>
  42876. inline constexpr choice_t<N> choice{};
  42877. /**
  42878. * @brief Identity type trait.
  42879. *
  42880. * Useful to establish non-deduced contexts in template argument deduction
  42881. * (waiting for C++20) or to provide types through function arguments.
  42882. *
  42883. * @tparam Type A type.
  42884. */
  42885. template<typename Type>
  42886. struct type_identity {
  42887. /*! @brief Identity type. */
  42888. using type = Type;
  42889. };
  42890. /**
  42891. * @brief Helper type.
  42892. * @tparam Type A type.
  42893. */
  42894. template<typename Type>
  42895. using type_identity_t = typename type_identity<Type>::type;
  42896. /**
  42897. * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains.
  42898. * @tparam Type The type of which to return the size.
  42899. * @tparam The size of the type if `sizeof` accepts it, 0 otherwise.
  42900. */
  42901. template<typename Type, typename = void>
  42902. struct size_of: std::integral_constant<std::size_t, 0u> {};
  42903. /*! @copydoc size_of */
  42904. template<typename Type>
  42905. struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
  42906. : std::integral_constant<std::size_t, sizeof(Type)> {};
  42907. /**
  42908. * @brief Helper variable template.
  42909. * @tparam Type The type of which to return the size.
  42910. */
  42911. template<typename Type>
  42912. inline constexpr std::size_t size_of_v = size_of<Type>::value;
  42913. /**
  42914. * @brief Using declaration to be used to _repeat_ the same type a number of
  42915. * times equal to the size of a given parameter pack.
  42916. * @tparam Type A type to repeat.
  42917. */
  42918. template<typename Type, typename>
  42919. using unpack_as_type = Type;
  42920. /**
  42921. * @brief Helper variable template to be used to _repeat_ the same value a
  42922. * number of times equal to the size of a given parameter pack.
  42923. * @tparam Value A value to repeat.
  42924. */
  42925. template<auto Value, typename>
  42926. inline constexpr auto unpack_as_value = Value;
  42927. /**
  42928. * @brief Wraps a static constant.
  42929. * @tparam Value A static constant.
  42930. */
  42931. template<auto Value>
  42932. using integral_constant = std::integral_constant<decltype(Value), Value>;
  42933. /**
  42934. * @brief Alias template to facilitate the creation of named values.
  42935. * @tparam Value A constant value at least convertible to `id_type`.
  42936. */
  42937. template<id_type Value>
  42938. using tag = integral_constant<Value>;
  42939. /**
  42940. * @brief A class to use to push around lists of types, nothing more.
  42941. * @tparam Type Types provided by the type list.
  42942. */
  42943. template<typename... Type>
  42944. struct type_list {
  42945. /*! @brief Type list type. */
  42946. using type = type_list;
  42947. /*! @brief Compile-time number of elements in the type list. */
  42948. static constexpr auto size = sizeof...(Type);
  42949. };
  42950. /*! @brief Primary template isn't defined on purpose. */
  42951. template<std::size_t, typename>
  42952. struct type_list_element;
  42953. /**
  42954. * @brief Provides compile-time indexed access to the types of a type list.
  42955. * @tparam Index Index of the type to return.
  42956. * @tparam Type First type provided by the type list.
  42957. * @tparam Other Other types provided by the type list.
  42958. */
  42959. template<std::size_t Index, typename Type, typename... Other>
  42960. struct type_list_element<Index, type_list<Type, Other...>>
  42961. : type_list_element<Index - 1u, type_list<Other...>> {};
  42962. /**
  42963. * @brief Provides compile-time indexed access to the types of a type list.
  42964. * @tparam Type First type provided by the type list.
  42965. * @tparam Other Other types provided by the type list.
  42966. */
  42967. template<typename Type, typename... Other>
  42968. struct type_list_element<0u, type_list<Type, Other...>> {
  42969. /*! @brief Searched type. */
  42970. using type = Type;
  42971. };
  42972. /**
  42973. * @brief Helper type.
  42974. * @tparam Index Index of the type to return.
  42975. * @tparam List Type list to search into.
  42976. */
  42977. template<std::size_t Index, typename List>
  42978. using type_list_element_t = typename type_list_element<Index, List>::type;
  42979. /**
  42980. * @brief Concatenates multiple type lists.
  42981. * @tparam Type Types provided by the first type list.
  42982. * @tparam Other Types provided by the second type list.
  42983. * @return A type list composed by the types of both the type lists.
  42984. */
  42985. template<typename... Type, typename... Other>
  42986. constexpr type_list<Type..., Other...> operator+(type_list<Type...>, type_list<Other...>) {
  42987. return {};
  42988. }
  42989. /*! @brief Primary template isn't defined on purpose. */
  42990. template<typename...>
  42991. struct type_list_cat;
  42992. /*! @brief Concatenates multiple type lists. */
  42993. template<>
  42994. struct type_list_cat<> {
  42995. /*! @brief A type list composed by the types of all the type lists. */
  42996. using type = type_list<>;
  42997. };
  42998. /**
  42999. * @brief Concatenates multiple type lists.
  43000. * @tparam Type Types provided by the first type list.
  43001. * @tparam Other Types provided by the second type list.
  43002. * @tparam List Other type lists, if any.
  43003. */
  43004. template<typename... Type, typename... Other, typename... List>
  43005. struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
  43006. /*! @brief A type list composed by the types of all the type lists. */
  43007. using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
  43008. };
  43009. /**
  43010. * @brief Concatenates multiple type lists.
  43011. * @tparam Type Types provided by the type list.
  43012. */
  43013. template<typename... Type>
  43014. struct type_list_cat<type_list<Type...>> {
  43015. /*! @brief A type list composed by the types of all the type lists. */
  43016. using type = type_list<Type...>;
  43017. };
  43018. /**
  43019. * @brief Helper type.
  43020. * @tparam List Type lists to concatenate.
  43021. */
  43022. template<typename... List>
  43023. using type_list_cat_t = typename type_list_cat<List...>::type;
  43024. /*! @brief Primary template isn't defined on purpose. */
  43025. template<typename>
  43026. struct type_list_unique;
  43027. /**
  43028. * @brief Removes duplicates types from a type list.
  43029. * @tparam Type One of the types provided by the given type list.
  43030. * @tparam Other The other types provided by the given type list.
  43031. */
  43032. template<typename Type, typename... Other>
  43033. struct type_list_unique<type_list<Type, Other...>> {
  43034. /*! @brief A type list without duplicate types. */
  43035. using type = std::conditional_t<
  43036. (std::is_same_v<Type, Other> || ...),
  43037. typename type_list_unique<type_list<Other...>>::type,
  43038. type_list_cat_t<type_list<Type>, typename type_list_unique<type_list<Other...>>::type>>;
  43039. };
  43040. /*! @brief Removes duplicates types from a type list. */
  43041. template<>
  43042. struct type_list_unique<type_list<>> {
  43043. /*! @brief A type list without duplicate types. */
  43044. using type = type_list<>;
  43045. };
  43046. /**
  43047. * @brief Helper type.
  43048. * @tparam Type A type list.
  43049. */
  43050. template<typename Type>
  43051. using type_list_unique_t = typename type_list_unique<Type>::type;
  43052. /**
  43053. * @brief Provides the member constant `value` to true if a type list contains a
  43054. * given type, false otherwise.
  43055. * @tparam List Type list.
  43056. * @tparam Type Type to look for.
  43057. */
  43058. template<typename List, typename Type>
  43059. struct type_list_contains;
  43060. /**
  43061. * @copybrief type_list_contains
  43062. * @tparam Type Types provided by the type list.
  43063. * @tparam Other Type to look for.
  43064. */
  43065. template<typename... Type, typename Other>
  43066. struct type_list_contains<type_list<Type...>, Other>: std::disjunction<std::is_same<Type, Other>...> {};
  43067. /**
  43068. * @brief Helper variable template.
  43069. * @tparam List Type list.
  43070. * @tparam Type Type to look for.
  43071. */
  43072. template<typename List, typename Type>
  43073. inline constexpr bool type_list_contains_v = type_list_contains<List, Type>::value;
  43074. /*! @brief Primary template isn't defined on purpose. */
  43075. template<typename...>
  43076. struct type_list_diff;
  43077. /**
  43078. * @brief Computes the difference between two type lists.
  43079. * @tparam Type Types provided by the first type list.
  43080. * @tparam Other Types provided by the second type list.
  43081. */
  43082. template<typename... Type, typename... Other>
  43083. struct type_list_diff<type_list<Type...>, type_list<Other...>> {
  43084. /*! @brief A type list that is the difference between the two type lists. */
  43085. using type = type_list_cat_t<std::conditional_t<type_list_contains_v<type_list<Other...>, Type>, type_list<>, type_list<Type>>...>;
  43086. };
  43087. /**
  43088. * @brief Helper type.
  43089. * @tparam List Type lists between which to compute the difference.
  43090. */
  43091. template<typename... List>
  43092. using type_list_diff_t = typename type_list_diff<List...>::type;
  43093. /**
  43094. * @brief A class to use to push around lists of constant values, nothing more.
  43095. * @tparam Value Values provided by the value list.
  43096. */
  43097. template<auto... Value>
  43098. struct value_list {
  43099. /*! @brief Value list type. */
  43100. using type = value_list;
  43101. /*! @brief Compile-time number of elements in the value list. */
  43102. static constexpr auto size = sizeof...(Value);
  43103. };
  43104. /*! @brief Primary template isn't defined on purpose. */
  43105. template<std::size_t, typename>
  43106. struct value_list_element;
  43107. /**
  43108. * @brief Provides compile-time indexed access to the values of a value list.
  43109. * @tparam Index Index of the value to return.
  43110. * @tparam Value First value provided by the value list.
  43111. * @tparam Other Other values provided by the value list.
  43112. */
  43113. template<std::size_t Index, auto Value, auto... Other>
  43114. struct value_list_element<Index, value_list<Value, Other...>>
  43115. : value_list_element<Index - 1u, value_list<Other...>> {};
  43116. /**
  43117. * @brief Provides compile-time indexed access to the types of a type list.
  43118. * @tparam Value First value provided by the value list.
  43119. * @tparam Other Other values provided by the value list.
  43120. */
  43121. template<auto Value, auto... Other>
  43122. struct value_list_element<0u, value_list<Value, Other...>> {
  43123. /*! @brief Searched value. */
  43124. static constexpr auto value = Value;
  43125. };
  43126. /**
  43127. * @brief Helper type.
  43128. * @tparam Index Index of the value to return.
  43129. * @tparam List Value list to search into.
  43130. */
  43131. template<std::size_t Index, typename List>
  43132. inline constexpr auto value_list_element_v = value_list_element<Index, List>::value;
  43133. /**
  43134. * @brief Concatenates multiple value lists.
  43135. * @tparam Value Values provided by the first value list.
  43136. * @tparam Other Values provided by the second value list.
  43137. * @return A value list composed by the values of both the value lists.
  43138. */
  43139. template<auto... Value, auto... Other>
  43140. constexpr value_list<Value..., Other...> operator+(value_list<Value...>, value_list<Other...>) {
  43141. return {};
  43142. }
  43143. /*! @brief Primary template isn't defined on purpose. */
  43144. template<typename...>
  43145. struct value_list_cat;
  43146. /*! @brief Concatenates multiple value lists. */
  43147. template<>
  43148. struct value_list_cat<> {
  43149. /*! @brief A value list composed by the values of all the value lists. */
  43150. using type = value_list<>;
  43151. };
  43152. /**
  43153. * @brief Concatenates multiple value lists.
  43154. * @tparam Value Values provided by the first value list.
  43155. * @tparam Other Values provided by the second value list.
  43156. * @tparam List Other value lists, if any.
  43157. */
  43158. template<auto... Value, auto... Other, typename... List>
  43159. struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
  43160. /*! @brief A value list composed by the values of all the value lists. */
  43161. using type = typename value_list_cat<value_list<Value..., Other...>, List...>::type;
  43162. };
  43163. /**
  43164. * @brief Concatenates multiple value lists.
  43165. * @tparam Value Values provided by the value list.
  43166. */
  43167. template<auto... Value>
  43168. struct value_list_cat<value_list<Value...>> {
  43169. /*! @brief A value list composed by the values of all the value lists. */
  43170. using type = value_list<Value...>;
  43171. };
  43172. /**
  43173. * @brief Helper type.
  43174. * @tparam List Value lists to concatenate.
  43175. */
  43176. template<typename... List>
  43177. using value_list_cat_t = typename value_list_cat<List...>::type;
  43178. /*! @brief Same as std::is_invocable, but with tuples. */
  43179. template<typename, typename>
  43180. struct is_applicable: std::false_type {};
  43181. /**
  43182. * @copybrief is_applicable
  43183. * @tparam Func A valid function type.
  43184. * @tparam Tuple Tuple-like type.
  43185. * @tparam Args The list of arguments to use to probe the function type.
  43186. */
  43187. template<typename Func, template<typename...> class Tuple, typename... Args>
  43188. struct is_applicable<Func, Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  43189. /**
  43190. * @copybrief is_applicable
  43191. * @tparam Func A valid function type.
  43192. * @tparam Tuple Tuple-like type.
  43193. * @tparam Args The list of arguments to use to probe the function type.
  43194. */
  43195. template<typename Func, template<typename...> class Tuple, typename... Args>
  43196. struct is_applicable<Func, const Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  43197. /**
  43198. * @brief Helper variable template.
  43199. * @tparam Func A valid function type.
  43200. * @tparam Args The list of arguments to use to probe the function type.
  43201. */
  43202. template<typename Func, typename Args>
  43203. inline constexpr bool is_applicable_v = is_applicable<Func, Args>::value;
  43204. /*! @brief Same as std::is_invocable_r, but with tuples for arguments. */
  43205. template<typename, typename, typename>
  43206. struct is_applicable_r: std::false_type {};
  43207. /**
  43208. * @copybrief is_applicable_r
  43209. * @tparam Ret The type to which the return type of the function should be
  43210. * convertible.
  43211. * @tparam Func A valid function type.
  43212. * @tparam Args The list of arguments to use to probe the function type.
  43213. */
  43214. template<typename Ret, typename Func, typename... Args>
  43215. struct is_applicable_r<Ret, Func, std::tuple<Args...>>: std::is_invocable_r<Ret, Func, Args...> {};
  43216. /**
  43217. * @brief Helper variable template.
  43218. * @tparam Ret The type to which the return type of the function should be
  43219. * convertible.
  43220. * @tparam Func A valid function type.
  43221. * @tparam Args The list of arguments to use to probe the function type.
  43222. */
  43223. template<typename Ret, typename Func, typename Args>
  43224. inline constexpr bool is_applicable_r_v = is_applicable_r<Ret, Func, Args>::value;
  43225. /**
  43226. * @brief Provides the member constant `value` to true if a given type is
  43227. * complete, false otherwise.
  43228. * @tparam Type The type to test.
  43229. */
  43230. template<typename Type, typename = void>
  43231. struct is_complete: std::false_type {};
  43232. /*! @copydoc is_complete */
  43233. template<typename Type>
  43234. struct is_complete<Type, std::void_t<decltype(sizeof(Type))>>: std::true_type {};
  43235. /**
  43236. * @brief Helper variable template.
  43237. * @tparam Type The type to test.
  43238. */
  43239. template<typename Type>
  43240. inline constexpr bool is_complete_v = is_complete<Type>::value;
  43241. /**
  43242. * @brief Provides the member constant `value` to true if a given type is an
  43243. * iterator, false otherwise.
  43244. * @tparam Type The type to test.
  43245. */
  43246. template<typename Type, typename = void>
  43247. struct is_iterator: std::false_type {};
  43248. /**
  43249. * @cond TURN_OFF_DOXYGEN
  43250. * Internal details not to be documented.
  43251. */
  43252. namespace internal {
  43253. template<typename, typename = void>
  43254. struct has_iterator_category: std::false_type {};
  43255. template<typename Type>
  43256. struct has_iterator_category<Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>: std::true_type {};
  43257. } // namespace internal
  43258. /**
  43259. * Internal details not to be documented.
  43260. * @endcond
  43261. */
  43262. /*! @copydoc is_iterator */
  43263. template<typename Type>
  43264. struct is_iterator<Type, std::enable_if_t<!std::is_same_v<std::remove_const_t<std::remove_pointer_t<Type>>, void>>>
  43265. : internal::has_iterator_category<Type> {};
  43266. /**
  43267. * @brief Helper variable template.
  43268. * @tparam Type The type to test.
  43269. */
  43270. template<typename Type>
  43271. inline constexpr bool is_iterator_v = is_iterator<Type>::value;
  43272. /**
  43273. * @brief Provides the member constant `value` to true if a given type is both
  43274. * an empty and non-final class, false otherwise.
  43275. * @tparam Type The type to test
  43276. */
  43277. template<typename Type>
  43278. struct is_ebco_eligible
  43279. : std::conjunction<std::is_empty<Type>, std::negation<std::is_final<Type>>> {};
  43280. /**
  43281. * @brief Helper variable template.
  43282. * @tparam Type The type to test.
  43283. */
  43284. template<typename Type>
  43285. inline constexpr bool is_ebco_eligible_v = is_ebco_eligible<Type>::value;
  43286. /**
  43287. * @brief Provides the member constant `value` to true if `Type::is_transparent`
  43288. * is valid and denotes a type, false otherwise.
  43289. * @tparam Type The type to test.
  43290. */
  43291. template<typename Type, typename = void>
  43292. struct is_transparent: std::false_type {};
  43293. /*! @copydoc is_transparent */
  43294. template<typename Type>
  43295. struct is_transparent<Type, std::void_t<typename Type::is_transparent>>: std::true_type {};
  43296. /**
  43297. * @brief Helper variable template.
  43298. * @tparam Type The type to test.
  43299. */
  43300. template<typename Type>
  43301. inline constexpr bool is_transparent_v = is_transparent<Type>::value;
  43302. /**
  43303. * @brief Provides the member constant `value` to true if a given type is
  43304. * equality comparable, false otherwise.
  43305. * @tparam Type The type to test.
  43306. */
  43307. template<typename Type, typename = void>
  43308. struct is_equality_comparable: std::false_type {};
  43309. /**
  43310. * @cond TURN_OFF_DOXYGEN
  43311. * Internal details not to be documented.
  43312. */
  43313. namespace internal {
  43314. template<typename, typename = void>
  43315. struct has_tuple_size_value: std::false_type {};
  43316. template<typename Type>
  43317. struct has_tuple_size_value<Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>: std::true_type {};
  43318. template<typename Type, std::size_t... Index>
  43319. [[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
  43320. return (is_equality_comparable<std::tuple_element_t<Index, Type>>::value && ...);
  43321. }
  43322. template<typename>
  43323. [[nodiscard]] constexpr bool maybe_equality_comparable(choice_t<0>) {
  43324. return true;
  43325. }
  43326. template<typename Type>
  43327. [[nodiscard]] constexpr auto maybe_equality_comparable(choice_t<1>) -> decltype(std::declval<typename Type::value_type>(), bool{}) {
  43328. if constexpr(is_iterator_v<Type>) {
  43329. return true;
  43330. } else if constexpr(std::is_same_v<typename Type::value_type, Type>) {
  43331. return maybe_equality_comparable<Type>(choice<0>);
  43332. } else {
  43333. return is_equality_comparable<typename Type::value_type>::value;
  43334. }
  43335. }
  43336. template<typename Type>
  43337. [[nodiscard]] constexpr std::enable_if_t<is_complete_v<std::tuple_size<std::remove_const_t<Type>>>, bool> maybe_equality_comparable(choice_t<2>) {
  43338. if constexpr(has_tuple_size_value<Type>::value) {
  43339. return unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
  43340. } else {
  43341. return maybe_equality_comparable<Type>(choice<1>);
  43342. }
  43343. }
  43344. } // namespace internal
  43345. /**
  43346. * Internal details not to be documented.
  43347. * @endcond
  43348. */
  43349. /*! @copydoc is_equality_comparable */
  43350. template<typename Type>
  43351. struct is_equality_comparable<Type, std::void_t<decltype(std::declval<Type>() == std::declval<Type>())>>
  43352. : std::bool_constant<internal::maybe_equality_comparable<Type>(choice<2>)> {};
  43353. /**
  43354. * @brief Helper variable template.
  43355. * @tparam Type The type to test.
  43356. */
  43357. template<typename Type>
  43358. inline constexpr bool is_equality_comparable_v = is_equality_comparable<Type>::value;
  43359. /**
  43360. * @brief Transcribes the constness of a type to another type.
  43361. * @tparam To The type to which to transcribe the constness.
  43362. * @tparam From The type from which to transcribe the constness.
  43363. */
  43364. template<typename To, typename From>
  43365. struct constness_as {
  43366. /*! @brief The type resulting from the transcription of the constness. */
  43367. using type = std::remove_const_t<To>;
  43368. };
  43369. /*! @copydoc constness_as */
  43370. template<typename To, typename From>
  43371. struct constness_as<To, const From> {
  43372. /*! @brief The type resulting from the transcription of the constness. */
  43373. using type = std::add_const_t<To>;
  43374. };
  43375. /**
  43376. * @brief Alias template to facilitate the transcription of the constness.
  43377. * @tparam To The type to which to transcribe the constness.
  43378. * @tparam From The type from which to transcribe the constness.
  43379. */
  43380. template<typename To, typename From>
  43381. using constness_as_t = typename constness_as<To, From>::type;
  43382. /**
  43383. * @brief Extracts the class of a non-static member object or function.
  43384. * @tparam Member A pointer to a non-static member object or function.
  43385. */
  43386. template<typename Member>
  43387. class member_class {
  43388. static_assert(std::is_member_pointer_v<Member>, "Invalid pointer type to non-static member object or function");
  43389. template<typename Class, typename Ret, typename... Args>
  43390. static Class *clazz(Ret (Class::*)(Args...));
  43391. template<typename Class, typename Ret, typename... Args>
  43392. static Class *clazz(Ret (Class::*)(Args...) const);
  43393. template<typename Class, typename Type>
  43394. static Class *clazz(Type Class::*);
  43395. public:
  43396. /*! @brief The class of the given non-static member object or function. */
  43397. using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
  43398. };
  43399. /**
  43400. * @brief Helper type.
  43401. * @tparam Member A pointer to a non-static member object or function.
  43402. */
  43403. template<typename Member>
  43404. using member_class_t = typename member_class<Member>::type;
  43405. } // namespace entt
  43406. #endif
  43407. // #include "fwd.hpp"
  43408. #ifndef ENTT_POLY_FWD_HPP
  43409. #define ENTT_POLY_FWD_HPP
  43410. #include <cstdint>
  43411. #include <type_traits>
  43412. namespace entt {
  43413. template<typename, std::size_t Len = sizeof(double[2]), std::size_t = alignof(typename std::aligned_storage_t<Len + !Len>)>
  43414. class basic_poly;
  43415. /**
  43416. * @brief Alias declaration for the most common use case.
  43417. * @tparam Concept Concept descriptor.
  43418. */
  43419. template<typename Concept>
  43420. using poly = basic_poly<Concept>;
  43421. } // namespace entt
  43422. #endif
  43423. namespace entt {
  43424. /*! @brief Inspector class used to infer the type of the virtual table. */
  43425. struct poly_inspector {
  43426. /**
  43427. * @brief Generic conversion operator (definition only).
  43428. * @tparam Type Type to which conversion is requested.
  43429. */
  43430. template<class Type>
  43431. operator Type &&() const;
  43432. /**
  43433. * @brief Dummy invocation function (definition only).
  43434. * @tparam Member Index of the function to invoke.
  43435. * @tparam Args Types of arguments to pass to the function.
  43436. * @param args The arguments to pass to the function.
  43437. * @return A poly inspector convertible to any type.
  43438. */
  43439. template<std::size_t Member, typename... Args>
  43440. poly_inspector invoke(Args &&...args) const;
  43441. /*! @copydoc invoke */
  43442. template<std::size_t Member, typename... Args>
  43443. poly_inspector invoke(Args &&...args);
  43444. };
  43445. /**
  43446. * @brief Static virtual table factory.
  43447. * @tparam Concept Concept descriptor.
  43448. * @tparam Len Size of the storage reserved for the small buffer optimization.
  43449. * @tparam Align Alignment requirement.
  43450. */
  43451. template<typename Concept, std::size_t Len, std::size_t Align>
  43452. class poly_vtable {
  43453. using inspector = typename Concept::template type<poly_inspector>;
  43454. template<typename Ret, typename... Args>
  43455. static auto vtable_entry(Ret (*)(inspector &, Args...)) -> Ret (*)(basic_any<Len, Align> &, Args...);
  43456. template<typename Ret, typename... Args>
  43457. static auto vtable_entry(Ret (*)(const inspector &, Args...)) -> Ret (*)(const basic_any<Len, Align> &, Args...);
  43458. template<typename Ret, typename... Args>
  43459. static auto vtable_entry(Ret (*)(Args...)) -> Ret (*)(const basic_any<Len, Align> &, Args...);
  43460. template<typename Ret, typename... Args>
  43461. static auto vtable_entry(Ret (inspector::*)(Args...)) -> Ret (*)(basic_any<Len, Align> &, Args...);
  43462. template<typename Ret, typename... Args>
  43463. static auto vtable_entry(Ret (inspector::*)(Args...) const) -> Ret (*)(const basic_any<Len, Align> &, Args...);
  43464. template<auto... Candidate>
  43465. static auto make_vtable(value_list<Candidate...>) ENTT_NOEXCEPT
  43466. -> decltype(std::make_tuple(vtable_entry(Candidate)...));
  43467. template<typename... Func>
  43468. [[nodiscard]] static constexpr auto make_vtable(type_list<Func...>) ENTT_NOEXCEPT {
  43469. if constexpr(sizeof...(Func) == 0u) {
  43470. return decltype(make_vtable(typename Concept::template impl<inspector>{})){};
  43471. } else if constexpr((std::is_function_v<Func> && ...)) {
  43472. return decltype(std::make_tuple(vtable_entry(std::declval<Func inspector::*>())...)){};
  43473. }
  43474. }
  43475. template<typename Type, auto Candidate, typename Ret, typename Any, typename... Args>
  43476. static void fill_vtable_entry(Ret (*&entry)(Any &, Args...)) ENTT_NOEXCEPT {
  43477. if constexpr(std::is_invocable_r_v<Ret, decltype(Candidate), Args...>) {
  43478. entry = +[](Any &, Args... args) -> Ret {
  43479. return std::invoke(Candidate, std::forward<Args>(args)...);
  43480. };
  43481. } else {
  43482. entry = +[](Any &instance, Args... args) -> Ret {
  43483. return static_cast<Ret>(std::invoke(Candidate, any_cast<constness_as_t<Type, Any> &>(instance), std::forward<Args>(args)...));
  43484. };
  43485. }
  43486. }
  43487. template<typename Type, auto... Index>
  43488. [[nodiscard]] static auto fill_vtable(std::index_sequence<Index...>) ENTT_NOEXCEPT {
  43489. vtable_type impl{};
  43490. (fill_vtable_entry<Type, value_list_element_v<Index, typename Concept::template impl<Type>>>(std::get<Index>(impl)), ...);
  43491. return impl;
  43492. }
  43493. using vtable_type = decltype(make_vtable(Concept{}));
  43494. static constexpr bool is_mono_v = std::tuple_size_v<vtable_type> == 1u;
  43495. public:
  43496. /*! @brief Virtual table type. */
  43497. using type = std::conditional_t<is_mono_v, std::tuple_element_t<0u, vtable_type>, const vtable_type *>;
  43498. /**
  43499. * @brief Returns a static virtual table for a specific concept and type.
  43500. * @tparam Type The type for which to generate the virtual table.
  43501. * @return A static virtual table for the given concept and type.
  43502. */
  43503. template<typename Type>
  43504. [[nodiscard]] static type instance() ENTT_NOEXCEPT {
  43505. static_assert(std::is_same_v<Type, std::decay_t<Type>>, "Type differs from its decayed form");
  43506. static const vtable_type vtable = fill_vtable<Type>(std::make_index_sequence<Concept::template impl<Type>::size>{});
  43507. if constexpr(is_mono_v) {
  43508. return std::get<0>(vtable);
  43509. } else {
  43510. return &vtable;
  43511. }
  43512. }
  43513. };
  43514. /**
  43515. * @brief Poly base class used to inject functionalities into concepts.
  43516. * @tparam Poly The outermost poly class.
  43517. */
  43518. template<typename Poly>
  43519. struct poly_base {
  43520. /**
  43521. * @brief Invokes a function from the static virtual table.
  43522. * @tparam Member Index of the function to invoke.
  43523. * @tparam Args Types of arguments to pass to the function.
  43524. * @param self A reference to the poly object that made the call.
  43525. * @param args The arguments to pass to the function.
  43526. * @return The return value of the invoked function, if any.
  43527. */
  43528. template<std::size_t Member, typename... Args>
  43529. [[nodiscard]] decltype(auto) invoke(const poly_base &self, Args &&...args) const {
  43530. const auto &poly = static_cast<const Poly &>(self);
  43531. if constexpr(std::is_function_v<std::remove_pointer_t<decltype(poly.vtable)>>) {
  43532. return poly.vtable(poly.storage, std::forward<Args>(args)...);
  43533. } else {
  43534. return std::get<Member>(*poly.vtable)(poly.storage, std::forward<Args>(args)...);
  43535. }
  43536. }
  43537. /*! @copydoc invoke */
  43538. template<std::size_t Member, typename... Args>
  43539. [[nodiscard]] decltype(auto) invoke(poly_base &self, Args &&...args) {
  43540. auto &poly = static_cast<Poly &>(self);
  43541. if constexpr(std::is_function_v<std::remove_pointer_t<decltype(poly.vtable)>>) {
  43542. static_assert(Member == 0u, "Unknown member");
  43543. return poly.vtable(poly.storage, std::forward<Args>(args)...);
  43544. } else {
  43545. return std::get<Member>(*poly.vtable)(poly.storage, std::forward<Args>(args)...);
  43546. }
  43547. }
  43548. };
  43549. /**
  43550. * @brief Shortcut for calling `poly_base<Type>::invoke`.
  43551. * @tparam Member Index of the function to invoke.
  43552. * @tparam Poly A fully defined poly object.
  43553. * @tparam Args Types of arguments to pass to the function.
  43554. * @param self A reference to the poly object that made the call.
  43555. * @param args The arguments to pass to the function.
  43556. * @return The return value of the invoked function, if any.
  43557. */
  43558. template<std::size_t Member, typename Poly, typename... Args>
  43559. decltype(auto) poly_call(Poly &&self, Args &&...args) {
  43560. return std::forward<Poly>(self).template invoke<Member>(self, std::forward<Args>(args)...);
  43561. }
  43562. /**
  43563. * @brief Static polymorphism made simple and within everyone's reach.
  43564. *
  43565. * Static polymorphism is a very powerful tool in C++, albeit sometimes
  43566. * cumbersome to obtain.<br/>
  43567. * This class aims to make it simple and easy to use.
  43568. *
  43569. * @note
  43570. * Both deduced and defined static virtual tables are supported.<br/>
  43571. * Moreover, the `poly` class template also works with unmanaged objects.
  43572. *
  43573. * @tparam Concept Concept descriptor.
  43574. * @tparam Len Size of the storage reserved for the small buffer optimization.
  43575. * @tparam Align Optional alignment requirement.
  43576. */
  43577. template<typename Concept, std::size_t Len, std::size_t Align>
  43578. class basic_poly: private Concept::template type<poly_base<basic_poly<Concept, Len, Align>>> {
  43579. /*! @brief A poly base is allowed to snoop into a poly object. */
  43580. friend struct poly_base<basic_poly>;
  43581. public:
  43582. /*! @brief Concept type. */
  43583. using concept_type = typename Concept::template type<poly_base<basic_poly>>;
  43584. /*! @brief Virtual table type. */
  43585. using vtable_type = typename poly_vtable<Concept, Len, Align>::type;
  43586. /*! @brief Default constructor. */
  43587. basic_poly() ENTT_NOEXCEPT
  43588. : storage{},
  43589. vtable{} {}
  43590. /**
  43591. * @brief Constructs a poly by directly initializing the new object.
  43592. * @tparam Type Type of object to use to initialize the poly.
  43593. * @tparam Args Types of arguments to use to construct the new instance.
  43594. * @param args Parameters to use to construct the instance.
  43595. */
  43596. template<typename Type, typename... Args>
  43597. explicit basic_poly(std::in_place_type_t<Type>, Args &&...args)
  43598. : storage{std::in_place_type<Type>, std::forward<Args>(args)...},
  43599. vtable{poly_vtable<Concept, Len, Align>::template instance<std::remove_cv_t<std::remove_reference_t<Type>>>()} {}
  43600. /**
  43601. * @brief Constructs a poly from a given value.
  43602. * @tparam Type Type of object to use to initialize the poly.
  43603. * @param value An instance of an object to use to initialize the poly.
  43604. */
  43605. template<typename Type, typename = std::enable_if_t<!std::is_same_v<std::remove_cv_t<std::remove_reference_t<Type>>, basic_poly>>>
  43606. basic_poly(Type &&value) ENTT_NOEXCEPT
  43607. : basic_poly{std::in_place_type<std::remove_cv_t<std::remove_reference_t<Type>>>, std::forward<Type>(value)} {}
  43608. /**
  43609. * @brief Returns the object type if any, `type_id<void>()` otherwise.
  43610. * @return The object type if any, `type_id<void>()` otherwise.
  43611. */
  43612. [[nodiscard]] const type_info &type() const ENTT_NOEXCEPT {
  43613. return storage.type();
  43614. }
  43615. /**
  43616. * @brief Returns an opaque pointer to the contained instance.
  43617. * @return An opaque pointer the contained instance, if any.
  43618. */
  43619. [[nodiscard]] const void *data() const ENTT_NOEXCEPT {
  43620. return storage.data();
  43621. }
  43622. /*! @copydoc data */
  43623. [[nodiscard]] void *data() ENTT_NOEXCEPT {
  43624. return storage.data();
  43625. }
  43626. /**
  43627. * @brief Replaces the contained object by creating a new instance directly.
  43628. * @tparam Type Type of object to use to initialize the poly.
  43629. * @tparam Args Types of arguments to use to construct the new instance.
  43630. * @param args Parameters to use to construct the instance.
  43631. */
  43632. template<typename Type, typename... Args>
  43633. void emplace(Args &&...args) {
  43634. storage.template emplace<Type>(std::forward<Args>(args)...);
  43635. vtable = poly_vtable<Concept, Len, Align>::template instance<std::remove_cv_t<std::remove_reference_t<Type>>>();
  43636. }
  43637. /*! @brief Destroys contained object */
  43638. void reset() {
  43639. storage.reset();
  43640. vtable = {};
  43641. }
  43642. /**
  43643. * @brief Returns false if a poly is empty, true otherwise.
  43644. * @return False if the poly is empty, true otherwise.
  43645. */
  43646. [[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
  43647. return static_cast<bool>(storage);
  43648. }
  43649. /**
  43650. * @brief Returns a pointer to the underlying concept.
  43651. * @return A pointer to the underlying concept.
  43652. */
  43653. [[nodiscard]] concept_type *operator->() ENTT_NOEXCEPT {
  43654. return this;
  43655. }
  43656. /*! @copydoc operator-> */
  43657. [[nodiscard]] const concept_type *operator->() const ENTT_NOEXCEPT {
  43658. return this;
  43659. }
  43660. /**
  43661. * @brief Aliasing constructor.
  43662. * @return A poly that shares a reference to an unmanaged object.
  43663. */
  43664. [[nodiscard]] basic_poly as_ref() ENTT_NOEXCEPT {
  43665. basic_poly ref{};
  43666. ref.storage = storage.as_ref();
  43667. ref.vtable = vtable;
  43668. return ref;
  43669. }
  43670. /*! @copydoc as_ref */
  43671. [[nodiscard]] basic_poly as_ref() const ENTT_NOEXCEPT {
  43672. basic_poly ref{};
  43673. ref.storage = storage.as_ref();
  43674. ref.vtable = vtable;
  43675. return ref;
  43676. }
  43677. private:
  43678. basic_any<Len, Align> storage;
  43679. vtable_type vtable;
  43680. };
  43681. } // namespace entt
  43682. #endif
  43683. // #include "process/process.hpp"
  43684. #ifndef ENTT_PROCESS_PROCESS_HPP
  43685. #define ENTT_PROCESS_PROCESS_HPP
  43686. #include <cstdint>
  43687. #include <type_traits>
  43688. #include <utility>
  43689. // #include "../config/config.h"
  43690. #ifndef ENTT_CONFIG_CONFIG_H
  43691. #define ENTT_CONFIG_CONFIG_H
  43692. // #include "version.h"
  43693. #ifndef ENTT_CONFIG_VERSION_H
  43694. #define ENTT_CONFIG_VERSION_H
  43695. // #include "macro.h"
  43696. #ifndef ENTT_CONFIG_MACRO_H
  43697. #define ENTT_CONFIG_MACRO_H
  43698. #define ENTT_STR(arg) #arg
  43699. #define ENTT_XSTR(arg) ENTT_STR(arg)
  43700. #endif
  43701. #define ENTT_VERSION_MAJOR 3
  43702. #define ENTT_VERSION_MINOR 10
  43703. #define ENTT_VERSION_PATCH 3
  43704. #define ENTT_VERSION \
  43705. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  43706. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  43707. #endif
  43708. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  43709. # define ENTT_THROW throw
  43710. # define ENTT_TRY try
  43711. # define ENTT_CATCH catch(...)
  43712. #else
  43713. # define ENTT_THROW
  43714. # define ENTT_TRY if(true)
  43715. # define ENTT_CATCH if(false)
  43716. #endif
  43717. #ifndef ENTT_NOEXCEPT
  43718. # define ENTT_NOEXCEPT noexcept
  43719. # define ENTT_NOEXCEPT_IF(expr) noexcept(expr)
  43720. # else
  43721. # define ENTT_NOEXCEPT_IF(...)
  43722. #endif
  43723. #ifdef ENTT_USE_ATOMIC
  43724. # include <atomic>
  43725. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  43726. #else
  43727. # define ENTT_MAYBE_ATOMIC(Type) Type
  43728. #endif
  43729. #ifndef ENTT_ID_TYPE
  43730. # include <cstdint>
  43731. # define ENTT_ID_TYPE std::uint32_t
  43732. #endif
  43733. #ifndef ENTT_SPARSE_PAGE
  43734. # define ENTT_SPARSE_PAGE 4096
  43735. #endif
  43736. #ifndef ENTT_PACKED_PAGE
  43737. # define ENTT_PACKED_PAGE 1024
  43738. #endif
  43739. #ifdef ENTT_DISABLE_ASSERT
  43740. # undef ENTT_ASSERT
  43741. # define ENTT_ASSERT(...) (void(0))
  43742. #elif !defined ENTT_ASSERT
  43743. # include <cassert>
  43744. # define ENTT_ASSERT(condition, ...) assert(condition)
  43745. #endif
  43746. #ifdef ENTT_NO_ETO
  43747. # define ENTT_IGNORE_IF_EMPTY false
  43748. #else
  43749. # define ENTT_IGNORE_IF_EMPTY true
  43750. #endif
  43751. #ifdef ENTT_STANDARD_CPP
  43752. # define ENTT_NONSTD false
  43753. #else
  43754. # define ENTT_NONSTD true
  43755. # if defined __clang__ || defined __GNUC__
  43756. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  43757. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  43758. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  43759. # elif defined _MSC_VER
  43760. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  43761. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  43762. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  43763. # endif
  43764. #endif
  43765. #if defined _MSC_VER
  43766. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  43767. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  43768. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  43769. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  43770. #endif
  43771. #endif
  43772. namespace entt {
  43773. /**
  43774. * @brief Base class for processes.
  43775. *
  43776. * This class stays true to the CRTP idiom. Derived classes must specify what's
  43777. * the intended type for elapsed times.<br/>
  43778. * A process should expose publicly the following member functions whether
  43779. * required:
  43780. *
  43781. * * @code{.cpp}
  43782. * void update(Delta, void *);
  43783. * @endcode
  43784. *
  43785. * It's invoked once per tick until a process is explicitly aborted or it
  43786. * terminates either with or without errors. Even though it's not mandatory to
  43787. * declare this member function, as a rule of thumb each process should at
  43788. * least define it to work properly. The `void *` parameter is an opaque
  43789. * pointer to user data (if any) forwarded directly to the process during an
  43790. * update.
  43791. *
  43792. * * @code{.cpp}
  43793. * void init();
  43794. * @endcode
  43795. *
  43796. * It's invoked when the process joins the running queue of a scheduler. This
  43797. * happens as soon as it's attached to the scheduler if the process is a top
  43798. * level one, otherwise when it replaces its parent if the process is a
  43799. * continuation.
  43800. *
  43801. * * @code{.cpp}
  43802. * void succeeded();
  43803. * @endcode
  43804. *
  43805. * It's invoked in case of success, immediately after an update and during the
  43806. * same tick.
  43807. *
  43808. * * @code{.cpp}
  43809. * void failed();
  43810. * @endcode
  43811. *
  43812. * It's invoked in case of errors, immediately after an update and during the
  43813. * same tick.
  43814. *
  43815. * * @code{.cpp}
  43816. * void aborted();
  43817. * @endcode
  43818. *
  43819. * It's invoked only if a process is explicitly aborted. There is no guarantee
  43820. * that it executes in the same tick, this depends solely on whether the
  43821. * process is aborted immediately or not.
  43822. *
  43823. * Derived classes can change the internal state of a process by invoking the
  43824. * `succeed` and `fail` protected member functions and even pause or unpause the
  43825. * process itself.
  43826. *
  43827. * @sa scheduler
  43828. *
  43829. * @tparam Derived Actual type of process that extends the class template.
  43830. * @tparam Delta Type to use to provide elapsed time.
  43831. */
  43832. template<typename Derived, typename Delta>
  43833. class process {
  43834. enum class state : std::uint8_t {
  43835. uninitialized = 0,
  43836. running,
  43837. paused,
  43838. succeeded,
  43839. failed,
  43840. aborted,
  43841. finished,
  43842. rejected
  43843. };
  43844. template<typename Target = Derived>
  43845. auto next(std::integral_constant<state, state::uninitialized>)
  43846. -> decltype(std::declval<Target>().init(), void()) {
  43847. static_cast<Target *>(this)->init();
  43848. }
  43849. template<typename Target = Derived>
  43850. auto next(std::integral_constant<state, state::running>, Delta delta, void *data)
  43851. -> decltype(std::declval<Target>().update(delta, data), void()) {
  43852. static_cast<Target *>(this)->update(delta, data);
  43853. }
  43854. template<typename Target = Derived>
  43855. auto next(std::integral_constant<state, state::succeeded>)
  43856. -> decltype(std::declval<Target>().succeeded(), void()) {
  43857. static_cast<Target *>(this)->succeeded();
  43858. }
  43859. template<typename Target = Derived>
  43860. auto next(std::integral_constant<state, state::failed>)
  43861. -> decltype(std::declval<Target>().failed(), void()) {
  43862. static_cast<Target *>(this)->failed();
  43863. }
  43864. template<typename Target = Derived>
  43865. auto next(std::integral_constant<state, state::aborted>)
  43866. -> decltype(std::declval<Target>().aborted(), void()) {
  43867. static_cast<Target *>(this)->aborted();
  43868. }
  43869. void next(...) const ENTT_NOEXCEPT {}
  43870. protected:
  43871. /**
  43872. * @brief Terminates a process with success if it's still alive.
  43873. *
  43874. * The function is idempotent and it does nothing if the process isn't
  43875. * alive.
  43876. */
  43877. void succeed() ENTT_NOEXCEPT {
  43878. if(alive()) {
  43879. current = state::succeeded;
  43880. }
  43881. }
  43882. /**
  43883. * @brief Terminates a process with errors if it's still alive.
  43884. *
  43885. * The function is idempotent and it does nothing if the process isn't
  43886. * alive.
  43887. */
  43888. void fail() ENTT_NOEXCEPT {
  43889. if(alive()) {
  43890. current = state::failed;
  43891. }
  43892. }
  43893. /**
  43894. * @brief Stops a process if it's in a running state.
  43895. *
  43896. * The function is idempotent and it does nothing if the process isn't
  43897. * running.
  43898. */
  43899. void pause() ENTT_NOEXCEPT {
  43900. if(current == state::running) {
  43901. current = state::paused;
  43902. }
  43903. }
  43904. /**
  43905. * @brief Restarts a process if it's paused.
  43906. *
  43907. * The function is idempotent and it does nothing if the process isn't
  43908. * paused.
  43909. */
  43910. void unpause() ENTT_NOEXCEPT {
  43911. if(current == state::paused) {
  43912. current = state::running;
  43913. }
  43914. }
  43915. public:
  43916. /*! @brief Type used to provide elapsed time. */
  43917. using delta_type = Delta;
  43918. /*! @brief Default destructor. */
  43919. virtual ~process() ENTT_NOEXCEPT {
  43920. static_assert(std::is_base_of_v<process, Derived>, "Incorrect use of the class template");
  43921. }
  43922. /**
  43923. * @brief Aborts a process if it's still alive.
  43924. *
  43925. * The function is idempotent and it does nothing if the process isn't
  43926. * alive.
  43927. *
  43928. * @param immediately Requests an immediate operation.
  43929. */
  43930. void abort(const bool immediately = false) {
  43931. if(alive()) {
  43932. current = state::aborted;
  43933. if(immediately) {
  43934. tick({});
  43935. }
  43936. }
  43937. }
  43938. /**
  43939. * @brief Returns true if a process is either running or paused.
  43940. * @return True if the process is still alive, false otherwise.
  43941. */
  43942. [[nodiscard]] bool alive() const ENTT_NOEXCEPT {
  43943. return current == state::running || current == state::paused;
  43944. }
  43945. /**
  43946. * @brief Returns true if a process is already terminated.
  43947. * @return True if the process is terminated, false otherwise.
  43948. */
  43949. [[nodiscard]] bool finished() const ENTT_NOEXCEPT {
  43950. return current == state::finished;
  43951. }
  43952. /**
  43953. * @brief Returns true if a process is currently paused.
  43954. * @return True if the process is paused, false otherwise.
  43955. */
  43956. [[nodiscard]] bool paused() const ENTT_NOEXCEPT {
  43957. return current == state::paused;
  43958. }
  43959. /**
  43960. * @brief Returns true if a process terminated with errors.
  43961. * @return True if the process terminated with errors, false otherwise.
  43962. */
  43963. [[nodiscard]] bool rejected() const ENTT_NOEXCEPT {
  43964. return current == state::rejected;
  43965. }
  43966. /**
  43967. * @brief Updates a process and its internal state if required.
  43968. * @param delta Elapsed time.
  43969. * @param data Optional data.
  43970. */
  43971. void tick(const Delta delta, void *data = nullptr) {
  43972. switch(current) {
  43973. case state::uninitialized:
  43974. next(std::integral_constant<state, state::uninitialized>{});
  43975. current = state::running;
  43976. break;
  43977. case state::running:
  43978. next(std::integral_constant<state, state::running>{}, delta, data);
  43979. break;
  43980. default:
  43981. // suppress warnings
  43982. break;
  43983. }
  43984. // if it's dead, it must be notified and removed immediately
  43985. switch(current) {
  43986. case state::succeeded:
  43987. next(std::integral_constant<state, state::succeeded>{});
  43988. current = state::finished;
  43989. break;
  43990. case state::failed:
  43991. next(std::integral_constant<state, state::failed>{});
  43992. current = state::rejected;
  43993. break;
  43994. case state::aborted:
  43995. next(std::integral_constant<state, state::aborted>{});
  43996. current = state::rejected;
  43997. break;
  43998. default:
  43999. // suppress warnings
  44000. break;
  44001. }
  44002. }
  44003. private:
  44004. state current{state::uninitialized};
  44005. };
  44006. /**
  44007. * @brief Adaptor for lambdas and functors to turn them into processes.
  44008. *
  44009. * Lambdas and functors can't be used directly with a scheduler for they are not
  44010. * properly defined processes with managed life cycles.<br/>
  44011. * This class helps in filling the gap and turning lambdas and functors into
  44012. * full featured processes usable by a scheduler.
  44013. *
  44014. * The signature of the function call operator should be equivalent to the
  44015. * following:
  44016. *
  44017. * @code{.cpp}
  44018. * void(Delta delta, void *data, auto succeed, auto fail);
  44019. * @endcode
  44020. *
  44021. * Where:
  44022. *
  44023. * * `delta` is the elapsed time.
  44024. * * `data` is an opaque pointer to user data if any, `nullptr` otherwise.
  44025. * * `succeed` is a function to call when a process terminates with success.
  44026. * * `fail` is a function to call when a process terminates with errors.
  44027. *
  44028. * The signature of the function call operator of both `succeed` and `fail`
  44029. * is equivalent to the following:
  44030. *
  44031. * @code{.cpp}
  44032. * void();
  44033. * @endcode
  44034. *
  44035. * Usually users shouldn't worry about creating adaptors. A scheduler will
  44036. * create them internally each and avery time a lambda or a functor is used as
  44037. * a process.
  44038. *
  44039. * @sa process
  44040. * @sa scheduler
  44041. *
  44042. * @tparam Func Actual type of process.
  44043. * @tparam Delta Type to use to provide elapsed time.
  44044. */
  44045. template<typename Func, typename Delta>
  44046. struct process_adaptor: process<process_adaptor<Func, Delta>, Delta>, private Func {
  44047. /**
  44048. * @brief Constructs a process adaptor from a lambda or a functor.
  44049. * @tparam Args Types of arguments to use to initialize the actual process.
  44050. * @param args Parameters to use to initialize the actual process.
  44051. */
  44052. template<typename... Args>
  44053. process_adaptor(Args &&...args)
  44054. : Func{std::forward<Args>(args)...} {}
  44055. /**
  44056. * @brief Updates a process and its internal state if required.
  44057. * @param delta Elapsed time.
  44058. * @param data Optional data.
  44059. */
  44060. void update(const Delta delta, void *data) {
  44061. Func::operator()(
  44062. delta,
  44063. data,
  44064. [this]() { this->succeed(); },
  44065. [this]() { this->fail(); });
  44066. }
  44067. };
  44068. } // namespace entt
  44069. #endif
  44070. // #include "process/scheduler.hpp"
  44071. #ifndef ENTT_PROCESS_SCHEDULER_HPP
  44072. #define ENTT_PROCESS_SCHEDULER_HPP
  44073. #include <algorithm>
  44074. #include <iterator>
  44075. #include <memory>
  44076. #include <type_traits>
  44077. #include <utility>
  44078. #include <vector>
  44079. // #include "../config/config.h"
  44080. // #include "process.hpp"
  44081. #ifndef ENTT_PROCESS_PROCESS_HPP
  44082. #define ENTT_PROCESS_PROCESS_HPP
  44083. #include <cstdint>
  44084. #include <type_traits>
  44085. #include <utility>
  44086. // #include "../config/config.h"
  44087. namespace entt {
  44088. /**
  44089. * @brief Base class for processes.
  44090. *
  44091. * This class stays true to the CRTP idiom. Derived classes must specify what's
  44092. * the intended type for elapsed times.<br/>
  44093. * A process should expose publicly the following member functions whether
  44094. * required:
  44095. *
  44096. * * @code{.cpp}
  44097. * void update(Delta, void *);
  44098. * @endcode
  44099. *
  44100. * It's invoked once per tick until a process is explicitly aborted or it
  44101. * terminates either with or without errors. Even though it's not mandatory to
  44102. * declare this member function, as a rule of thumb each process should at
  44103. * least define it to work properly. The `void *` parameter is an opaque
  44104. * pointer to user data (if any) forwarded directly to the process during an
  44105. * update.
  44106. *
  44107. * * @code{.cpp}
  44108. * void init();
  44109. * @endcode
  44110. *
  44111. * It's invoked when the process joins the running queue of a scheduler. This
  44112. * happens as soon as it's attached to the scheduler if the process is a top
  44113. * level one, otherwise when it replaces its parent if the process is a
  44114. * continuation.
  44115. *
  44116. * * @code{.cpp}
  44117. * void succeeded();
  44118. * @endcode
  44119. *
  44120. * It's invoked in case of success, immediately after an update and during the
  44121. * same tick.
  44122. *
  44123. * * @code{.cpp}
  44124. * void failed();
  44125. * @endcode
  44126. *
  44127. * It's invoked in case of errors, immediately after an update and during the
  44128. * same tick.
  44129. *
  44130. * * @code{.cpp}
  44131. * void aborted();
  44132. * @endcode
  44133. *
  44134. * It's invoked only if a process is explicitly aborted. There is no guarantee
  44135. * that it executes in the same tick, this depends solely on whether the
  44136. * process is aborted immediately or not.
  44137. *
  44138. * Derived classes can change the internal state of a process by invoking the
  44139. * `succeed` and `fail` protected member functions and even pause or unpause the
  44140. * process itself.
  44141. *
  44142. * @sa scheduler
  44143. *
  44144. * @tparam Derived Actual type of process that extends the class template.
  44145. * @tparam Delta Type to use to provide elapsed time.
  44146. */
  44147. template<typename Derived, typename Delta>
  44148. class process {
  44149. enum class state : std::uint8_t {
  44150. uninitialized = 0,
  44151. running,
  44152. paused,
  44153. succeeded,
  44154. failed,
  44155. aborted,
  44156. finished,
  44157. rejected
  44158. };
  44159. template<typename Target = Derived>
  44160. auto next(std::integral_constant<state, state::uninitialized>)
  44161. -> decltype(std::declval<Target>().init(), void()) {
  44162. static_cast<Target *>(this)->init();
  44163. }
  44164. template<typename Target = Derived>
  44165. auto next(std::integral_constant<state, state::running>, Delta delta, void *data)
  44166. -> decltype(std::declval<Target>().update(delta, data), void()) {
  44167. static_cast<Target *>(this)->update(delta, data);
  44168. }
  44169. template<typename Target = Derived>
  44170. auto next(std::integral_constant<state, state::succeeded>)
  44171. -> decltype(std::declval<Target>().succeeded(), void()) {
  44172. static_cast<Target *>(this)->succeeded();
  44173. }
  44174. template<typename Target = Derived>
  44175. auto next(std::integral_constant<state, state::failed>)
  44176. -> decltype(std::declval<Target>().failed(), void()) {
  44177. static_cast<Target *>(this)->failed();
  44178. }
  44179. template<typename Target = Derived>
  44180. auto next(std::integral_constant<state, state::aborted>)
  44181. -> decltype(std::declval<Target>().aborted(), void()) {
  44182. static_cast<Target *>(this)->aborted();
  44183. }
  44184. void next(...) const ENTT_NOEXCEPT {}
  44185. protected:
  44186. /**
  44187. * @brief Terminates a process with success if it's still alive.
  44188. *
  44189. * The function is idempotent and it does nothing if the process isn't
  44190. * alive.
  44191. */
  44192. void succeed() ENTT_NOEXCEPT {
  44193. if(alive()) {
  44194. current = state::succeeded;
  44195. }
  44196. }
  44197. /**
  44198. * @brief Terminates a process with errors if it's still alive.
  44199. *
  44200. * The function is idempotent and it does nothing if the process isn't
  44201. * alive.
  44202. */
  44203. void fail() ENTT_NOEXCEPT {
  44204. if(alive()) {
  44205. current = state::failed;
  44206. }
  44207. }
  44208. /**
  44209. * @brief Stops a process if it's in a running state.
  44210. *
  44211. * The function is idempotent and it does nothing if the process isn't
  44212. * running.
  44213. */
  44214. void pause() ENTT_NOEXCEPT {
  44215. if(current == state::running) {
  44216. current = state::paused;
  44217. }
  44218. }
  44219. /**
  44220. * @brief Restarts a process if it's paused.
  44221. *
  44222. * The function is idempotent and it does nothing if the process isn't
  44223. * paused.
  44224. */
  44225. void unpause() ENTT_NOEXCEPT {
  44226. if(current == state::paused) {
  44227. current = state::running;
  44228. }
  44229. }
  44230. public:
  44231. /*! @brief Type used to provide elapsed time. */
  44232. using delta_type = Delta;
  44233. /*! @brief Default destructor. */
  44234. virtual ~process() ENTT_NOEXCEPT {
  44235. static_assert(std::is_base_of_v<process, Derived>, "Incorrect use of the class template");
  44236. }
  44237. /**
  44238. * @brief Aborts a process if it's still alive.
  44239. *
  44240. * The function is idempotent and it does nothing if the process isn't
  44241. * alive.
  44242. *
  44243. * @param immediately Requests an immediate operation.
  44244. */
  44245. void abort(const bool immediately = false) {
  44246. if(alive()) {
  44247. current = state::aborted;
  44248. if(immediately) {
  44249. tick({});
  44250. }
  44251. }
  44252. }
  44253. /**
  44254. * @brief Returns true if a process is either running or paused.
  44255. * @return True if the process is still alive, false otherwise.
  44256. */
  44257. [[nodiscard]] bool alive() const ENTT_NOEXCEPT {
  44258. return current == state::running || current == state::paused;
  44259. }
  44260. /**
  44261. * @brief Returns true if a process is already terminated.
  44262. * @return True if the process is terminated, false otherwise.
  44263. */
  44264. [[nodiscard]] bool finished() const ENTT_NOEXCEPT {
  44265. return current == state::finished;
  44266. }
  44267. /**
  44268. * @brief Returns true if a process is currently paused.
  44269. * @return True if the process is paused, false otherwise.
  44270. */
  44271. [[nodiscard]] bool paused() const ENTT_NOEXCEPT {
  44272. return current == state::paused;
  44273. }
  44274. /**
  44275. * @brief Returns true if a process terminated with errors.
  44276. * @return True if the process terminated with errors, false otherwise.
  44277. */
  44278. [[nodiscard]] bool rejected() const ENTT_NOEXCEPT {
  44279. return current == state::rejected;
  44280. }
  44281. /**
  44282. * @brief Updates a process and its internal state if required.
  44283. * @param delta Elapsed time.
  44284. * @param data Optional data.
  44285. */
  44286. void tick(const Delta delta, void *data = nullptr) {
  44287. switch(current) {
  44288. case state::uninitialized:
  44289. next(std::integral_constant<state, state::uninitialized>{});
  44290. current = state::running;
  44291. break;
  44292. case state::running:
  44293. next(std::integral_constant<state, state::running>{}, delta, data);
  44294. break;
  44295. default:
  44296. // suppress warnings
  44297. break;
  44298. }
  44299. // if it's dead, it must be notified and removed immediately
  44300. switch(current) {
  44301. case state::succeeded:
  44302. next(std::integral_constant<state, state::succeeded>{});
  44303. current = state::finished;
  44304. break;
  44305. case state::failed:
  44306. next(std::integral_constant<state, state::failed>{});
  44307. current = state::rejected;
  44308. break;
  44309. case state::aborted:
  44310. next(std::integral_constant<state, state::aborted>{});
  44311. current = state::rejected;
  44312. break;
  44313. default:
  44314. // suppress warnings
  44315. break;
  44316. }
  44317. }
  44318. private:
  44319. state current{state::uninitialized};
  44320. };
  44321. /**
  44322. * @brief Adaptor for lambdas and functors to turn them into processes.
  44323. *
  44324. * Lambdas and functors can't be used directly with a scheduler for they are not
  44325. * properly defined processes with managed life cycles.<br/>
  44326. * This class helps in filling the gap and turning lambdas and functors into
  44327. * full featured processes usable by a scheduler.
  44328. *
  44329. * The signature of the function call operator should be equivalent to the
  44330. * following:
  44331. *
  44332. * @code{.cpp}
  44333. * void(Delta delta, void *data, auto succeed, auto fail);
  44334. * @endcode
  44335. *
  44336. * Where:
  44337. *
  44338. * * `delta` is the elapsed time.
  44339. * * `data` is an opaque pointer to user data if any, `nullptr` otherwise.
  44340. * * `succeed` is a function to call when a process terminates with success.
  44341. * * `fail` is a function to call when a process terminates with errors.
  44342. *
  44343. * The signature of the function call operator of both `succeed` and `fail`
  44344. * is equivalent to the following:
  44345. *
  44346. * @code{.cpp}
  44347. * void();
  44348. * @endcode
  44349. *
  44350. * Usually users shouldn't worry about creating adaptors. A scheduler will
  44351. * create them internally each and avery time a lambda or a functor is used as
  44352. * a process.
  44353. *
  44354. * @sa process
  44355. * @sa scheduler
  44356. *
  44357. * @tparam Func Actual type of process.
  44358. * @tparam Delta Type to use to provide elapsed time.
  44359. */
  44360. template<typename Func, typename Delta>
  44361. struct process_adaptor: process<process_adaptor<Func, Delta>, Delta>, private Func {
  44362. /**
  44363. * @brief Constructs a process adaptor from a lambda or a functor.
  44364. * @tparam Args Types of arguments to use to initialize the actual process.
  44365. * @param args Parameters to use to initialize the actual process.
  44366. */
  44367. template<typename... Args>
  44368. process_adaptor(Args &&...args)
  44369. : Func{std::forward<Args>(args)...} {}
  44370. /**
  44371. * @brief Updates a process and its internal state if required.
  44372. * @param delta Elapsed time.
  44373. * @param data Optional data.
  44374. */
  44375. void update(const Delta delta, void *data) {
  44376. Func::operator()(
  44377. delta,
  44378. data,
  44379. [this]() { this->succeed(); },
  44380. [this]() { this->fail(); });
  44381. }
  44382. };
  44383. } // namespace entt
  44384. #endif
  44385. namespace entt {
  44386. /**
  44387. * @brief Cooperative scheduler for processes.
  44388. *
  44389. * A cooperative scheduler runs processes and helps managing their life cycles.
  44390. *
  44391. * Each process is invoked once per tick. If a process terminates, it's
  44392. * removed automatically from the scheduler and it's never invoked again.<br/>
  44393. * A process can also have a child. In this case, the process is replaced with
  44394. * its child when it terminates if it returns with success. In case of errors,
  44395. * both the process and its child are discarded.
  44396. *
  44397. * Example of use (pseudocode):
  44398. *
  44399. * @code{.cpp}
  44400. * scheduler.attach([](auto delta, void *, auto succeed, auto fail) {
  44401. * // code
  44402. * }).then<my_process>(arguments...);
  44403. * @endcode
  44404. *
  44405. * In order to invoke all scheduled processes, call the `update` member function
  44406. * passing it the elapsed time to forward to the tasks.
  44407. *
  44408. * @sa process
  44409. *
  44410. * @tparam Delta Type to use to provide elapsed time.
  44411. */
  44412. template<typename Delta>
  44413. class scheduler {
  44414. struct process_handler {
  44415. using instance_type = std::unique_ptr<void, void (*)(void *)>;
  44416. using update_fn_type = bool(scheduler &, std::size_t, Delta, void *);
  44417. using abort_fn_type = void(scheduler &, std::size_t, bool);
  44418. using next_type = std::unique_ptr<process_handler>;
  44419. instance_type instance;
  44420. update_fn_type *update;
  44421. abort_fn_type *abort;
  44422. next_type next;
  44423. };
  44424. struct continuation {
  44425. continuation(process_handler *ref) ENTT_NOEXCEPT
  44426. : handler{ref} {}
  44427. template<typename Proc, typename... Args>
  44428. continuation then(Args &&...args) {
  44429. static_assert(std::is_base_of_v<process<Proc, Delta>, Proc>, "Invalid process type");
  44430. auto proc = typename process_handler::instance_type{new Proc{std::forward<Args>(args)...}, &scheduler::deleter<Proc>};
  44431. handler->next.reset(new process_handler{std::move(proc), &scheduler::update<Proc>, &scheduler::abort<Proc>, nullptr});
  44432. handler = handler->next.get();
  44433. return *this;
  44434. }
  44435. template<typename Func>
  44436. continuation then(Func &&func) {
  44437. return then<process_adaptor<std::decay_t<Func>, Delta>>(std::forward<Func>(func));
  44438. }
  44439. private:
  44440. process_handler *handler;
  44441. };
  44442. template<typename Proc>
  44443. [[nodiscard]] static bool update(scheduler &owner, std::size_t pos, const Delta delta, void *data) {
  44444. auto *process = static_cast<Proc *>(owner.handlers[pos].instance.get());
  44445. process->tick(delta, data);
  44446. if(process->rejected()) {
  44447. return true;
  44448. } else if(process->finished()) {
  44449. if(auto &&handler = owner.handlers[pos]; handler.next) {
  44450. handler = std::move(*handler.next);
  44451. // forces the process to exit the uninitialized state
  44452. return handler.update(owner, pos, {}, nullptr);
  44453. }
  44454. return true;
  44455. }
  44456. return false;
  44457. }
  44458. template<typename Proc>
  44459. static void abort(scheduler &owner, std::size_t pos, const bool immediately) {
  44460. static_cast<Proc *>(owner.handlers[pos].instance.get())->abort(immediately);
  44461. }
  44462. template<typename Proc>
  44463. static void deleter(void *proc) {
  44464. delete static_cast<Proc *>(proc);
  44465. }
  44466. public:
  44467. /*! @brief Unsigned integer type. */
  44468. using size_type = std::size_t;
  44469. /*! @brief Default constructor. */
  44470. scheduler() = default;
  44471. /*! @brief Default move constructor. */
  44472. scheduler(scheduler &&) = default;
  44473. /*! @brief Default move assignment operator. @return This scheduler. */
  44474. scheduler &operator=(scheduler &&) = default;
  44475. /**
  44476. * @brief Number of processes currently scheduled.
  44477. * @return Number of processes currently scheduled.
  44478. */
  44479. [[nodiscard]] size_type size() const ENTT_NOEXCEPT {
  44480. return handlers.size();
  44481. }
  44482. /**
  44483. * @brief Returns true if at least a process is currently scheduled.
  44484. * @return True if there are scheduled processes, false otherwise.
  44485. */
  44486. [[nodiscard]] bool empty() const ENTT_NOEXCEPT {
  44487. return handlers.empty();
  44488. }
  44489. /**
  44490. * @brief Discards all scheduled processes.
  44491. *
  44492. * Processes aren't aborted. They are discarded along with their children
  44493. * and never executed again.
  44494. */
  44495. void clear() {
  44496. handlers.clear();
  44497. }
  44498. /**
  44499. * @brief Schedules a process for the next tick.
  44500. *
  44501. * Returned value is an opaque object that can be used to attach a child to
  44502. * the given process. The child is automatically scheduled when the process
  44503. * terminates and only if the process returns with success.
  44504. *
  44505. * Example of use (pseudocode):
  44506. *
  44507. * @code{.cpp}
  44508. * // schedules a task in the form of a process class
  44509. * scheduler.attach<my_process>(arguments...)
  44510. * // appends a child in the form of a lambda function
  44511. * .then([](auto delta, void *, auto succeed, auto fail) {
  44512. * // code
  44513. * })
  44514. * // appends a child in the form of another process class
  44515. * .then<my_other_process>();
  44516. * @endcode
  44517. *
  44518. * @tparam Proc Type of process to schedule.
  44519. * @tparam Args Types of arguments to use to initialize the process.
  44520. * @param args Parameters to use to initialize the process.
  44521. * @return An opaque object to use to concatenate processes.
  44522. */
  44523. template<typename Proc, typename... Args>
  44524. auto attach(Args &&...args) {
  44525. static_assert(std::is_base_of_v<process<Proc, Delta>, Proc>, "Invalid process type");
  44526. auto proc = typename process_handler::instance_type{new Proc{std::forward<Args>(args)...}, &scheduler::deleter<Proc>};
  44527. auto &&ref = handlers.emplace_back(process_handler{std::move(proc), &scheduler::update<Proc>, &scheduler::abort<Proc>, nullptr});
  44528. // forces the process to exit the uninitialized state
  44529. ref.update(*this, handlers.size() - 1u, {}, nullptr);
  44530. return continuation{&handlers.back()};
  44531. }
  44532. /**
  44533. * @brief Schedules a process for the next tick.
  44534. *
  44535. * A process can be either a lambda or a functor. The scheduler wraps both
  44536. * of them in a process adaptor internally.<br/>
  44537. * The signature of the function call operator should be equivalent to the
  44538. * following:
  44539. *
  44540. * @code{.cpp}
  44541. * void(Delta delta, void *data, auto succeed, auto fail);
  44542. * @endcode
  44543. *
  44544. * Where:
  44545. *
  44546. * * `delta` is the elapsed time.
  44547. * * `data` is an opaque pointer to user data if any, `nullptr` otherwise.
  44548. * * `succeed` is a function to call when a process terminates with success.
  44549. * * `fail` is a function to call when a process terminates with errors.
  44550. *
  44551. * The signature of the function call operator of both `succeed` and `fail`
  44552. * is equivalent to the following:
  44553. *
  44554. * @code{.cpp}
  44555. * void();
  44556. * @endcode
  44557. *
  44558. * Returned value is an opaque object that can be used to attach a child to
  44559. * the given process. The child is automatically scheduled when the process
  44560. * terminates and only if the process returns with success.
  44561. *
  44562. * Example of use (pseudocode):
  44563. *
  44564. * @code{.cpp}
  44565. * // schedules a task in the form of a lambda function
  44566. * scheduler.attach([](auto delta, void *, auto succeed, auto fail) {
  44567. * // code
  44568. * })
  44569. * // appends a child in the form of another lambda function
  44570. * .then([](auto delta, void *, auto succeed, auto fail) {
  44571. * // code
  44572. * })
  44573. * // appends a child in the form of a process class
  44574. * .then<my_process>(arguments...);
  44575. * @endcode
  44576. *
  44577. * @sa process_adaptor
  44578. *
  44579. * @tparam Func Type of process to schedule.
  44580. * @param func Either a lambda or a functor to use as a process.
  44581. * @return An opaque object to use to concatenate processes.
  44582. */
  44583. template<typename Func>
  44584. auto attach(Func &&func) {
  44585. using Proc = process_adaptor<std::decay_t<Func>, Delta>;
  44586. return attach<Proc>(std::forward<Func>(func));
  44587. }
  44588. /**
  44589. * @brief Updates all scheduled processes.
  44590. *
  44591. * All scheduled processes are executed in no specific order.<br/>
  44592. * If a process terminates with success, it's replaced with its child, if
  44593. * any. Otherwise, if a process terminates with an error, it's removed along
  44594. * with its child.
  44595. *
  44596. * @param delta Elapsed time.
  44597. * @param data Optional data.
  44598. */
  44599. void update(const Delta delta, void *data = nullptr) {
  44600. for(auto pos = handlers.size(); pos; --pos) {
  44601. const auto curr = pos - 1u;
  44602. if(const auto dead = handlers[curr].update(*this, curr, delta, data); dead) {
  44603. std::swap(handlers[curr], handlers.back());
  44604. handlers.pop_back();
  44605. }
  44606. }
  44607. }
  44608. /**
  44609. * @brief Aborts all scheduled processes.
  44610. *
  44611. * Unless an immediate operation is requested, the abort is scheduled for
  44612. * the next tick. Processes won't be executed anymore in any case.<br/>
  44613. * Once a process is fully aborted and thus finished, it's discarded along
  44614. * with its child, if any.
  44615. *
  44616. * @param immediately Requests an immediate operation.
  44617. */
  44618. void abort(const bool immediately = false) {
  44619. for(auto pos = handlers.size(); pos; --pos) {
  44620. const auto curr = pos - 1u;
  44621. handlers[curr].abort(*this, curr, immediately);
  44622. }
  44623. }
  44624. private:
  44625. std::vector<process_handler> handlers{};
  44626. };
  44627. } // namespace entt
  44628. #endif
  44629. // #include "resource/cache.hpp"
  44630. #ifndef ENTT_RESOURCE_RESOURCE_CACHE_HPP
  44631. #define ENTT_RESOURCE_RESOURCE_CACHE_HPP
  44632. #include <cstddef>
  44633. #include <functional>
  44634. #include <iterator>
  44635. #include <memory>
  44636. #include <tuple>
  44637. #include <type_traits>
  44638. #include <utility>
  44639. // #include "../config/config.h"
  44640. #ifndef ENTT_CONFIG_CONFIG_H
  44641. #define ENTT_CONFIG_CONFIG_H
  44642. // #include "version.h"
  44643. #ifndef ENTT_CONFIG_VERSION_H
  44644. #define ENTT_CONFIG_VERSION_H
  44645. // #include "macro.h"
  44646. #ifndef ENTT_CONFIG_MACRO_H
  44647. #define ENTT_CONFIG_MACRO_H
  44648. #define ENTT_STR(arg) #arg
  44649. #define ENTT_XSTR(arg) ENTT_STR(arg)
  44650. #endif
  44651. #define ENTT_VERSION_MAJOR 3
  44652. #define ENTT_VERSION_MINOR 10
  44653. #define ENTT_VERSION_PATCH 3
  44654. #define ENTT_VERSION \
  44655. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  44656. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  44657. #endif
  44658. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  44659. # define ENTT_THROW throw
  44660. # define ENTT_TRY try
  44661. # define ENTT_CATCH catch(...)
  44662. #else
  44663. # define ENTT_THROW
  44664. # define ENTT_TRY if(true)
  44665. # define ENTT_CATCH if(false)
  44666. #endif
  44667. #ifndef ENTT_NOEXCEPT
  44668. # define ENTT_NOEXCEPT noexcept
  44669. # define ENTT_NOEXCEPT_IF(expr) noexcept(expr)
  44670. # else
  44671. # define ENTT_NOEXCEPT_IF(...)
  44672. #endif
  44673. #ifdef ENTT_USE_ATOMIC
  44674. # include <atomic>
  44675. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  44676. #else
  44677. # define ENTT_MAYBE_ATOMIC(Type) Type
  44678. #endif
  44679. #ifndef ENTT_ID_TYPE
  44680. # include <cstdint>
  44681. # define ENTT_ID_TYPE std::uint32_t
  44682. #endif
  44683. #ifndef ENTT_SPARSE_PAGE
  44684. # define ENTT_SPARSE_PAGE 4096
  44685. #endif
  44686. #ifndef ENTT_PACKED_PAGE
  44687. # define ENTT_PACKED_PAGE 1024
  44688. #endif
  44689. #ifdef ENTT_DISABLE_ASSERT
  44690. # undef ENTT_ASSERT
  44691. # define ENTT_ASSERT(...) (void(0))
  44692. #elif !defined ENTT_ASSERT
  44693. # include <cassert>
  44694. # define ENTT_ASSERT(condition, ...) assert(condition)
  44695. #endif
  44696. #ifdef ENTT_NO_ETO
  44697. # define ENTT_IGNORE_IF_EMPTY false
  44698. #else
  44699. # define ENTT_IGNORE_IF_EMPTY true
  44700. #endif
  44701. #ifdef ENTT_STANDARD_CPP
  44702. # define ENTT_NONSTD false
  44703. #else
  44704. # define ENTT_NONSTD true
  44705. # if defined __clang__ || defined __GNUC__
  44706. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  44707. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  44708. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  44709. # elif defined _MSC_VER
  44710. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  44711. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  44712. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  44713. # endif
  44714. #endif
  44715. #if defined _MSC_VER
  44716. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  44717. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  44718. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  44719. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  44720. #endif
  44721. #endif
  44722. // #include "../container/dense_map.hpp"
  44723. #ifndef ENTT_CONTAINER_DENSE_MAP_HPP
  44724. #define ENTT_CONTAINER_DENSE_MAP_HPP
  44725. #include <algorithm>
  44726. #include <cmath>
  44727. #include <cstddef>
  44728. #include <functional>
  44729. #include <iterator>
  44730. #include <limits>
  44731. #include <memory>
  44732. #include <tuple>
  44733. #include <type_traits>
  44734. #include <utility>
  44735. #include <vector>
  44736. // #include "../config/config.h"
  44737. #ifndef ENTT_CONFIG_CONFIG_H
  44738. #define ENTT_CONFIG_CONFIG_H
  44739. // #include "version.h"
  44740. #ifndef ENTT_CONFIG_VERSION_H
  44741. #define ENTT_CONFIG_VERSION_H
  44742. // #include "macro.h"
  44743. #ifndef ENTT_CONFIG_MACRO_H
  44744. #define ENTT_CONFIG_MACRO_H
  44745. #define ENTT_STR(arg) #arg
  44746. #define ENTT_XSTR(arg) ENTT_STR(arg)
  44747. #endif
  44748. #define ENTT_VERSION_MAJOR 3
  44749. #define ENTT_VERSION_MINOR 10
  44750. #define ENTT_VERSION_PATCH 3
  44751. #define ENTT_VERSION \
  44752. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  44753. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  44754. #endif
  44755. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  44756. # define ENTT_THROW throw
  44757. # define ENTT_TRY try
  44758. # define ENTT_CATCH catch(...)
  44759. #else
  44760. # define ENTT_THROW
  44761. # define ENTT_TRY if(true)
  44762. # define ENTT_CATCH if(false)
  44763. #endif
  44764. #ifndef ENTT_NOEXCEPT
  44765. # define ENTT_NOEXCEPT noexcept
  44766. # define ENTT_NOEXCEPT_IF(expr) noexcept(expr)
  44767. # else
  44768. # define ENTT_NOEXCEPT_IF(...)
  44769. #endif
  44770. #ifdef ENTT_USE_ATOMIC
  44771. # include <atomic>
  44772. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  44773. #else
  44774. # define ENTT_MAYBE_ATOMIC(Type) Type
  44775. #endif
  44776. #ifndef ENTT_ID_TYPE
  44777. # include <cstdint>
  44778. # define ENTT_ID_TYPE std::uint32_t
  44779. #endif
  44780. #ifndef ENTT_SPARSE_PAGE
  44781. # define ENTT_SPARSE_PAGE 4096
  44782. #endif
  44783. #ifndef ENTT_PACKED_PAGE
  44784. # define ENTT_PACKED_PAGE 1024
  44785. #endif
  44786. #ifdef ENTT_DISABLE_ASSERT
  44787. # undef ENTT_ASSERT
  44788. # define ENTT_ASSERT(...) (void(0))
  44789. #elif !defined ENTT_ASSERT
  44790. # include <cassert>
  44791. # define ENTT_ASSERT(condition, ...) assert(condition)
  44792. #endif
  44793. #ifdef ENTT_NO_ETO
  44794. # define ENTT_IGNORE_IF_EMPTY false
  44795. #else
  44796. # define ENTT_IGNORE_IF_EMPTY true
  44797. #endif
  44798. #ifdef ENTT_STANDARD_CPP
  44799. # define ENTT_NONSTD false
  44800. #else
  44801. # define ENTT_NONSTD true
  44802. # if defined __clang__ || defined __GNUC__
  44803. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  44804. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  44805. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  44806. # elif defined _MSC_VER
  44807. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  44808. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  44809. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  44810. # endif
  44811. #endif
  44812. #if defined _MSC_VER
  44813. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  44814. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  44815. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  44816. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  44817. #endif
  44818. #endif
  44819. // #include "../core/compressed_pair.hpp"
  44820. #ifndef ENTT_CORE_COMPRESSED_PAIR_HPP
  44821. #define ENTT_CORE_COMPRESSED_PAIR_HPP
  44822. #include <cstddef>
  44823. #include <tuple>
  44824. #include <type_traits>
  44825. #include <utility>
  44826. // #include "../config/config.h"
  44827. #ifndef ENTT_CONFIG_CONFIG_H
  44828. #define ENTT_CONFIG_CONFIG_H
  44829. // #include "version.h"
  44830. #ifndef ENTT_CONFIG_VERSION_H
  44831. #define ENTT_CONFIG_VERSION_H
  44832. // #include "macro.h"
  44833. #ifndef ENTT_CONFIG_MACRO_H
  44834. #define ENTT_CONFIG_MACRO_H
  44835. #define ENTT_STR(arg) #arg
  44836. #define ENTT_XSTR(arg) ENTT_STR(arg)
  44837. #endif
  44838. #define ENTT_VERSION_MAJOR 3
  44839. #define ENTT_VERSION_MINOR 10
  44840. #define ENTT_VERSION_PATCH 3
  44841. #define ENTT_VERSION \
  44842. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  44843. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  44844. #endif
  44845. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  44846. # define ENTT_THROW throw
  44847. # define ENTT_TRY try
  44848. # define ENTT_CATCH catch(...)
  44849. #else
  44850. # define ENTT_THROW
  44851. # define ENTT_TRY if(true)
  44852. # define ENTT_CATCH if(false)
  44853. #endif
  44854. #ifndef ENTT_NOEXCEPT
  44855. # define ENTT_NOEXCEPT noexcept
  44856. # define ENTT_NOEXCEPT_IF(expr) noexcept(expr)
  44857. # else
  44858. # define ENTT_NOEXCEPT_IF(...)
  44859. #endif
  44860. #ifdef ENTT_USE_ATOMIC
  44861. # include <atomic>
  44862. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  44863. #else
  44864. # define ENTT_MAYBE_ATOMIC(Type) Type
  44865. #endif
  44866. #ifndef ENTT_ID_TYPE
  44867. # include <cstdint>
  44868. # define ENTT_ID_TYPE std::uint32_t
  44869. #endif
  44870. #ifndef ENTT_SPARSE_PAGE
  44871. # define ENTT_SPARSE_PAGE 4096
  44872. #endif
  44873. #ifndef ENTT_PACKED_PAGE
  44874. # define ENTT_PACKED_PAGE 1024
  44875. #endif
  44876. #ifdef ENTT_DISABLE_ASSERT
  44877. # undef ENTT_ASSERT
  44878. # define ENTT_ASSERT(...) (void(0))
  44879. #elif !defined ENTT_ASSERT
  44880. # include <cassert>
  44881. # define ENTT_ASSERT(condition, ...) assert(condition)
  44882. #endif
  44883. #ifdef ENTT_NO_ETO
  44884. # define ENTT_IGNORE_IF_EMPTY false
  44885. #else
  44886. # define ENTT_IGNORE_IF_EMPTY true
  44887. #endif
  44888. #ifdef ENTT_STANDARD_CPP
  44889. # define ENTT_NONSTD false
  44890. #else
  44891. # define ENTT_NONSTD true
  44892. # if defined __clang__ || defined __GNUC__
  44893. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  44894. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  44895. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  44896. # elif defined _MSC_VER
  44897. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  44898. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  44899. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  44900. # endif
  44901. #endif
  44902. #if defined _MSC_VER
  44903. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  44904. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  44905. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  44906. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  44907. #endif
  44908. #endif
  44909. // #include "type_traits.hpp"
  44910. #ifndef ENTT_CORE_TYPE_TRAITS_HPP
  44911. #define ENTT_CORE_TYPE_TRAITS_HPP
  44912. #include <cstddef>
  44913. #include <iterator>
  44914. #include <type_traits>
  44915. #include <utility>
  44916. // #include "../config/config.h"
  44917. // #include "fwd.hpp"
  44918. #ifndef ENTT_CORE_FWD_HPP
  44919. #define ENTT_CORE_FWD_HPP
  44920. #include <cstdint>
  44921. #include <type_traits>
  44922. // #include "../config/config.h"
  44923. namespace entt {
  44924. template<std::size_t Len = sizeof(double[2]), std::size_t = alignof(typename std::aligned_storage_t<Len + !Len>)>
  44925. class basic_any;
  44926. /*! @brief Alias declaration for type identifiers. */
  44927. using id_type = ENTT_ID_TYPE;
  44928. /*! @brief Alias declaration for the most common use case. */
  44929. using any = basic_any<>;
  44930. } // namespace entt
  44931. #endif
  44932. namespace entt {
  44933. /**
  44934. * @brief Utility class to disambiguate overloaded functions.
  44935. * @tparam N Number of choices available.
  44936. */
  44937. template<std::size_t N>
  44938. struct choice_t
  44939. // Unfortunately, doxygen cannot parse such a construct.
  44940. : /*! @cond TURN_OFF_DOXYGEN */ choice_t<N - 1> /*! @endcond */
  44941. {};
  44942. /*! @copybrief choice_t */
  44943. template<>
  44944. struct choice_t<0> {};
  44945. /**
  44946. * @brief Variable template for the choice trick.
  44947. * @tparam N Number of choices available.
  44948. */
  44949. template<std::size_t N>
  44950. inline constexpr choice_t<N> choice{};
  44951. /**
  44952. * @brief Identity type trait.
  44953. *
  44954. * Useful to establish non-deduced contexts in template argument deduction
  44955. * (waiting for C++20) or to provide types through function arguments.
  44956. *
  44957. * @tparam Type A type.
  44958. */
  44959. template<typename Type>
  44960. struct type_identity {
  44961. /*! @brief Identity type. */
  44962. using type = Type;
  44963. };
  44964. /**
  44965. * @brief Helper type.
  44966. * @tparam Type A type.
  44967. */
  44968. template<typename Type>
  44969. using type_identity_t = typename type_identity<Type>::type;
  44970. /**
  44971. * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains.
  44972. * @tparam Type The type of which to return the size.
  44973. * @tparam The size of the type if `sizeof` accepts it, 0 otherwise.
  44974. */
  44975. template<typename Type, typename = void>
  44976. struct size_of: std::integral_constant<std::size_t, 0u> {};
  44977. /*! @copydoc size_of */
  44978. template<typename Type>
  44979. struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
  44980. : std::integral_constant<std::size_t, sizeof(Type)> {};
  44981. /**
  44982. * @brief Helper variable template.
  44983. * @tparam Type The type of which to return the size.
  44984. */
  44985. template<typename Type>
  44986. inline constexpr std::size_t size_of_v = size_of<Type>::value;
  44987. /**
  44988. * @brief Using declaration to be used to _repeat_ the same type a number of
  44989. * times equal to the size of a given parameter pack.
  44990. * @tparam Type A type to repeat.
  44991. */
  44992. template<typename Type, typename>
  44993. using unpack_as_type = Type;
  44994. /**
  44995. * @brief Helper variable template to be used to _repeat_ the same value a
  44996. * number of times equal to the size of a given parameter pack.
  44997. * @tparam Value A value to repeat.
  44998. */
  44999. template<auto Value, typename>
  45000. inline constexpr auto unpack_as_value = Value;
  45001. /**
  45002. * @brief Wraps a static constant.
  45003. * @tparam Value A static constant.
  45004. */
  45005. template<auto Value>
  45006. using integral_constant = std::integral_constant<decltype(Value), Value>;
  45007. /**
  45008. * @brief Alias template to facilitate the creation of named values.
  45009. * @tparam Value A constant value at least convertible to `id_type`.
  45010. */
  45011. template<id_type Value>
  45012. using tag = integral_constant<Value>;
  45013. /**
  45014. * @brief A class to use to push around lists of types, nothing more.
  45015. * @tparam Type Types provided by the type list.
  45016. */
  45017. template<typename... Type>
  45018. struct type_list {
  45019. /*! @brief Type list type. */
  45020. using type = type_list;
  45021. /*! @brief Compile-time number of elements in the type list. */
  45022. static constexpr auto size = sizeof...(Type);
  45023. };
  45024. /*! @brief Primary template isn't defined on purpose. */
  45025. template<std::size_t, typename>
  45026. struct type_list_element;
  45027. /**
  45028. * @brief Provides compile-time indexed access to the types of a type list.
  45029. * @tparam Index Index of the type to return.
  45030. * @tparam Type First type provided by the type list.
  45031. * @tparam Other Other types provided by the type list.
  45032. */
  45033. template<std::size_t Index, typename Type, typename... Other>
  45034. struct type_list_element<Index, type_list<Type, Other...>>
  45035. : type_list_element<Index - 1u, type_list<Other...>> {};
  45036. /**
  45037. * @brief Provides compile-time indexed access to the types of a type list.
  45038. * @tparam Type First type provided by the type list.
  45039. * @tparam Other Other types provided by the type list.
  45040. */
  45041. template<typename Type, typename... Other>
  45042. struct type_list_element<0u, type_list<Type, Other...>> {
  45043. /*! @brief Searched type. */
  45044. using type = Type;
  45045. };
  45046. /**
  45047. * @brief Helper type.
  45048. * @tparam Index Index of the type to return.
  45049. * @tparam List Type list to search into.
  45050. */
  45051. template<std::size_t Index, typename List>
  45052. using type_list_element_t = typename type_list_element<Index, List>::type;
  45053. /**
  45054. * @brief Concatenates multiple type lists.
  45055. * @tparam Type Types provided by the first type list.
  45056. * @tparam Other Types provided by the second type list.
  45057. * @return A type list composed by the types of both the type lists.
  45058. */
  45059. template<typename... Type, typename... Other>
  45060. constexpr type_list<Type..., Other...> operator+(type_list<Type...>, type_list<Other...>) {
  45061. return {};
  45062. }
  45063. /*! @brief Primary template isn't defined on purpose. */
  45064. template<typename...>
  45065. struct type_list_cat;
  45066. /*! @brief Concatenates multiple type lists. */
  45067. template<>
  45068. struct type_list_cat<> {
  45069. /*! @brief A type list composed by the types of all the type lists. */
  45070. using type = type_list<>;
  45071. };
  45072. /**
  45073. * @brief Concatenates multiple type lists.
  45074. * @tparam Type Types provided by the first type list.
  45075. * @tparam Other Types provided by the second type list.
  45076. * @tparam List Other type lists, if any.
  45077. */
  45078. template<typename... Type, typename... Other, typename... List>
  45079. struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
  45080. /*! @brief A type list composed by the types of all the type lists. */
  45081. using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
  45082. };
  45083. /**
  45084. * @brief Concatenates multiple type lists.
  45085. * @tparam Type Types provided by the type list.
  45086. */
  45087. template<typename... Type>
  45088. struct type_list_cat<type_list<Type...>> {
  45089. /*! @brief A type list composed by the types of all the type lists. */
  45090. using type = type_list<Type...>;
  45091. };
  45092. /**
  45093. * @brief Helper type.
  45094. * @tparam List Type lists to concatenate.
  45095. */
  45096. template<typename... List>
  45097. using type_list_cat_t = typename type_list_cat<List...>::type;
  45098. /*! @brief Primary template isn't defined on purpose. */
  45099. template<typename>
  45100. struct type_list_unique;
  45101. /**
  45102. * @brief Removes duplicates types from a type list.
  45103. * @tparam Type One of the types provided by the given type list.
  45104. * @tparam Other The other types provided by the given type list.
  45105. */
  45106. template<typename Type, typename... Other>
  45107. struct type_list_unique<type_list<Type, Other...>> {
  45108. /*! @brief A type list without duplicate types. */
  45109. using type = std::conditional_t<
  45110. (std::is_same_v<Type, Other> || ...),
  45111. typename type_list_unique<type_list<Other...>>::type,
  45112. type_list_cat_t<type_list<Type>, typename type_list_unique<type_list<Other...>>::type>>;
  45113. };
  45114. /*! @brief Removes duplicates types from a type list. */
  45115. template<>
  45116. struct type_list_unique<type_list<>> {
  45117. /*! @brief A type list without duplicate types. */
  45118. using type = type_list<>;
  45119. };
  45120. /**
  45121. * @brief Helper type.
  45122. * @tparam Type A type list.
  45123. */
  45124. template<typename Type>
  45125. using type_list_unique_t = typename type_list_unique<Type>::type;
  45126. /**
  45127. * @brief Provides the member constant `value` to true if a type list contains a
  45128. * given type, false otherwise.
  45129. * @tparam List Type list.
  45130. * @tparam Type Type to look for.
  45131. */
  45132. template<typename List, typename Type>
  45133. struct type_list_contains;
  45134. /**
  45135. * @copybrief type_list_contains
  45136. * @tparam Type Types provided by the type list.
  45137. * @tparam Other Type to look for.
  45138. */
  45139. template<typename... Type, typename Other>
  45140. struct type_list_contains<type_list<Type...>, Other>: std::disjunction<std::is_same<Type, Other>...> {};
  45141. /**
  45142. * @brief Helper variable template.
  45143. * @tparam List Type list.
  45144. * @tparam Type Type to look for.
  45145. */
  45146. template<typename List, typename Type>
  45147. inline constexpr bool type_list_contains_v = type_list_contains<List, Type>::value;
  45148. /*! @brief Primary template isn't defined on purpose. */
  45149. template<typename...>
  45150. struct type_list_diff;
  45151. /**
  45152. * @brief Computes the difference between two type lists.
  45153. * @tparam Type Types provided by the first type list.
  45154. * @tparam Other Types provided by the second type list.
  45155. */
  45156. template<typename... Type, typename... Other>
  45157. struct type_list_diff<type_list<Type...>, type_list<Other...>> {
  45158. /*! @brief A type list that is the difference between the two type lists. */
  45159. using type = type_list_cat_t<std::conditional_t<type_list_contains_v<type_list<Other...>, Type>, type_list<>, type_list<Type>>...>;
  45160. };
  45161. /**
  45162. * @brief Helper type.
  45163. * @tparam List Type lists between which to compute the difference.
  45164. */
  45165. template<typename... List>
  45166. using type_list_diff_t = typename type_list_diff<List...>::type;
  45167. /**
  45168. * @brief A class to use to push around lists of constant values, nothing more.
  45169. * @tparam Value Values provided by the value list.
  45170. */
  45171. template<auto... Value>
  45172. struct value_list {
  45173. /*! @brief Value list type. */
  45174. using type = value_list;
  45175. /*! @brief Compile-time number of elements in the value list. */
  45176. static constexpr auto size = sizeof...(Value);
  45177. };
  45178. /*! @brief Primary template isn't defined on purpose. */
  45179. template<std::size_t, typename>
  45180. struct value_list_element;
  45181. /**
  45182. * @brief Provides compile-time indexed access to the values of a value list.
  45183. * @tparam Index Index of the value to return.
  45184. * @tparam Value First value provided by the value list.
  45185. * @tparam Other Other values provided by the value list.
  45186. */
  45187. template<std::size_t Index, auto Value, auto... Other>
  45188. struct value_list_element<Index, value_list<Value, Other...>>
  45189. : value_list_element<Index - 1u, value_list<Other...>> {};
  45190. /**
  45191. * @brief Provides compile-time indexed access to the types of a type list.
  45192. * @tparam Value First value provided by the value list.
  45193. * @tparam Other Other values provided by the value list.
  45194. */
  45195. template<auto Value, auto... Other>
  45196. struct value_list_element<0u, value_list<Value, Other...>> {
  45197. /*! @brief Searched value. */
  45198. static constexpr auto value = Value;
  45199. };
  45200. /**
  45201. * @brief Helper type.
  45202. * @tparam Index Index of the value to return.
  45203. * @tparam List Value list to search into.
  45204. */
  45205. template<std::size_t Index, typename List>
  45206. inline constexpr auto value_list_element_v = value_list_element<Index, List>::value;
  45207. /**
  45208. * @brief Concatenates multiple value lists.
  45209. * @tparam Value Values provided by the first value list.
  45210. * @tparam Other Values provided by the second value list.
  45211. * @return A value list composed by the values of both the value lists.
  45212. */
  45213. template<auto... Value, auto... Other>
  45214. constexpr value_list<Value..., Other...> operator+(value_list<Value...>, value_list<Other...>) {
  45215. return {};
  45216. }
  45217. /*! @brief Primary template isn't defined on purpose. */
  45218. template<typename...>
  45219. struct value_list_cat;
  45220. /*! @brief Concatenates multiple value lists. */
  45221. template<>
  45222. struct value_list_cat<> {
  45223. /*! @brief A value list composed by the values of all the value lists. */
  45224. using type = value_list<>;
  45225. };
  45226. /**
  45227. * @brief Concatenates multiple value lists.
  45228. * @tparam Value Values provided by the first value list.
  45229. * @tparam Other Values provided by the second value list.
  45230. * @tparam List Other value lists, if any.
  45231. */
  45232. template<auto... Value, auto... Other, typename... List>
  45233. struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
  45234. /*! @brief A value list composed by the values of all the value lists. */
  45235. using type = typename value_list_cat<value_list<Value..., Other...>, List...>::type;
  45236. };
  45237. /**
  45238. * @brief Concatenates multiple value lists.
  45239. * @tparam Value Values provided by the value list.
  45240. */
  45241. template<auto... Value>
  45242. struct value_list_cat<value_list<Value...>> {
  45243. /*! @brief A value list composed by the values of all the value lists. */
  45244. using type = value_list<Value...>;
  45245. };
  45246. /**
  45247. * @brief Helper type.
  45248. * @tparam List Value lists to concatenate.
  45249. */
  45250. template<typename... List>
  45251. using value_list_cat_t = typename value_list_cat<List...>::type;
  45252. /*! @brief Same as std::is_invocable, but with tuples. */
  45253. template<typename, typename>
  45254. struct is_applicable: std::false_type {};
  45255. /**
  45256. * @copybrief is_applicable
  45257. * @tparam Func A valid function type.
  45258. * @tparam Tuple Tuple-like type.
  45259. * @tparam Args The list of arguments to use to probe the function type.
  45260. */
  45261. template<typename Func, template<typename...> class Tuple, typename... Args>
  45262. struct is_applicable<Func, Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  45263. /**
  45264. * @copybrief is_applicable
  45265. * @tparam Func A valid function type.
  45266. * @tparam Tuple Tuple-like type.
  45267. * @tparam Args The list of arguments to use to probe the function type.
  45268. */
  45269. template<typename Func, template<typename...> class Tuple, typename... Args>
  45270. struct is_applicable<Func, const Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  45271. /**
  45272. * @brief Helper variable template.
  45273. * @tparam Func A valid function type.
  45274. * @tparam Args The list of arguments to use to probe the function type.
  45275. */
  45276. template<typename Func, typename Args>
  45277. inline constexpr bool is_applicable_v = is_applicable<Func, Args>::value;
  45278. /*! @brief Same as std::is_invocable_r, but with tuples for arguments. */
  45279. template<typename, typename, typename>
  45280. struct is_applicable_r: std::false_type {};
  45281. /**
  45282. * @copybrief is_applicable_r
  45283. * @tparam Ret The type to which the return type of the function should be
  45284. * convertible.
  45285. * @tparam Func A valid function type.
  45286. * @tparam Args The list of arguments to use to probe the function type.
  45287. */
  45288. template<typename Ret, typename Func, typename... Args>
  45289. struct is_applicable_r<Ret, Func, std::tuple<Args...>>: std::is_invocable_r<Ret, Func, Args...> {};
  45290. /**
  45291. * @brief Helper variable template.
  45292. * @tparam Ret The type to which the return type of the function should be
  45293. * convertible.
  45294. * @tparam Func A valid function type.
  45295. * @tparam Args The list of arguments to use to probe the function type.
  45296. */
  45297. template<typename Ret, typename Func, typename Args>
  45298. inline constexpr bool is_applicable_r_v = is_applicable_r<Ret, Func, Args>::value;
  45299. /**
  45300. * @brief Provides the member constant `value` to true if a given type is
  45301. * complete, false otherwise.
  45302. * @tparam Type The type to test.
  45303. */
  45304. template<typename Type, typename = void>
  45305. struct is_complete: std::false_type {};
  45306. /*! @copydoc is_complete */
  45307. template<typename Type>
  45308. struct is_complete<Type, std::void_t<decltype(sizeof(Type))>>: std::true_type {};
  45309. /**
  45310. * @brief Helper variable template.
  45311. * @tparam Type The type to test.
  45312. */
  45313. template<typename Type>
  45314. inline constexpr bool is_complete_v = is_complete<Type>::value;
  45315. /**
  45316. * @brief Provides the member constant `value` to true if a given type is an
  45317. * iterator, false otherwise.
  45318. * @tparam Type The type to test.
  45319. */
  45320. template<typename Type, typename = void>
  45321. struct is_iterator: std::false_type {};
  45322. /**
  45323. * @cond TURN_OFF_DOXYGEN
  45324. * Internal details not to be documented.
  45325. */
  45326. namespace internal {
  45327. template<typename, typename = void>
  45328. struct has_iterator_category: std::false_type {};
  45329. template<typename Type>
  45330. struct has_iterator_category<Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>: std::true_type {};
  45331. } // namespace internal
  45332. /**
  45333. * Internal details not to be documented.
  45334. * @endcond
  45335. */
  45336. /*! @copydoc is_iterator */
  45337. template<typename Type>
  45338. struct is_iterator<Type, std::enable_if_t<!std::is_same_v<std::remove_const_t<std::remove_pointer_t<Type>>, void>>>
  45339. : internal::has_iterator_category<Type> {};
  45340. /**
  45341. * @brief Helper variable template.
  45342. * @tparam Type The type to test.
  45343. */
  45344. template<typename Type>
  45345. inline constexpr bool is_iterator_v = is_iterator<Type>::value;
  45346. /**
  45347. * @brief Provides the member constant `value` to true if a given type is both
  45348. * an empty and non-final class, false otherwise.
  45349. * @tparam Type The type to test
  45350. */
  45351. template<typename Type>
  45352. struct is_ebco_eligible
  45353. : std::conjunction<std::is_empty<Type>, std::negation<std::is_final<Type>>> {};
  45354. /**
  45355. * @brief Helper variable template.
  45356. * @tparam Type The type to test.
  45357. */
  45358. template<typename Type>
  45359. inline constexpr bool is_ebco_eligible_v = is_ebco_eligible<Type>::value;
  45360. /**
  45361. * @brief Provides the member constant `value` to true if `Type::is_transparent`
  45362. * is valid and denotes a type, false otherwise.
  45363. * @tparam Type The type to test.
  45364. */
  45365. template<typename Type, typename = void>
  45366. struct is_transparent: std::false_type {};
  45367. /*! @copydoc is_transparent */
  45368. template<typename Type>
  45369. struct is_transparent<Type, std::void_t<typename Type::is_transparent>>: std::true_type {};
  45370. /**
  45371. * @brief Helper variable template.
  45372. * @tparam Type The type to test.
  45373. */
  45374. template<typename Type>
  45375. inline constexpr bool is_transparent_v = is_transparent<Type>::value;
  45376. /**
  45377. * @brief Provides the member constant `value` to true if a given type is
  45378. * equality comparable, false otherwise.
  45379. * @tparam Type The type to test.
  45380. */
  45381. template<typename Type, typename = void>
  45382. struct is_equality_comparable: std::false_type {};
  45383. /**
  45384. * @cond TURN_OFF_DOXYGEN
  45385. * Internal details not to be documented.
  45386. */
  45387. namespace internal {
  45388. template<typename, typename = void>
  45389. struct has_tuple_size_value: std::false_type {};
  45390. template<typename Type>
  45391. struct has_tuple_size_value<Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>: std::true_type {};
  45392. template<typename Type, std::size_t... Index>
  45393. [[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
  45394. return (is_equality_comparable<std::tuple_element_t<Index, Type>>::value && ...);
  45395. }
  45396. template<typename>
  45397. [[nodiscard]] constexpr bool maybe_equality_comparable(choice_t<0>) {
  45398. return true;
  45399. }
  45400. template<typename Type>
  45401. [[nodiscard]] constexpr auto maybe_equality_comparable(choice_t<1>) -> decltype(std::declval<typename Type::value_type>(), bool{}) {
  45402. if constexpr(is_iterator_v<Type>) {
  45403. return true;
  45404. } else if constexpr(std::is_same_v<typename Type::value_type, Type>) {
  45405. return maybe_equality_comparable<Type>(choice<0>);
  45406. } else {
  45407. return is_equality_comparable<typename Type::value_type>::value;
  45408. }
  45409. }
  45410. template<typename Type>
  45411. [[nodiscard]] constexpr std::enable_if_t<is_complete_v<std::tuple_size<std::remove_const_t<Type>>>, bool> maybe_equality_comparable(choice_t<2>) {
  45412. if constexpr(has_tuple_size_value<Type>::value) {
  45413. return unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
  45414. } else {
  45415. return maybe_equality_comparable<Type>(choice<1>);
  45416. }
  45417. }
  45418. } // namespace internal
  45419. /**
  45420. * Internal details not to be documented.
  45421. * @endcond
  45422. */
  45423. /*! @copydoc is_equality_comparable */
  45424. template<typename Type>
  45425. struct is_equality_comparable<Type, std::void_t<decltype(std::declval<Type>() == std::declval<Type>())>>
  45426. : std::bool_constant<internal::maybe_equality_comparable<Type>(choice<2>)> {};
  45427. /**
  45428. * @brief Helper variable template.
  45429. * @tparam Type The type to test.
  45430. */
  45431. template<typename Type>
  45432. inline constexpr bool is_equality_comparable_v = is_equality_comparable<Type>::value;
  45433. /**
  45434. * @brief Transcribes the constness of a type to another type.
  45435. * @tparam To The type to which to transcribe the constness.
  45436. * @tparam From The type from which to transcribe the constness.
  45437. */
  45438. template<typename To, typename From>
  45439. struct constness_as {
  45440. /*! @brief The type resulting from the transcription of the constness. */
  45441. using type = std::remove_const_t<To>;
  45442. };
  45443. /*! @copydoc constness_as */
  45444. template<typename To, typename From>
  45445. struct constness_as<To, const From> {
  45446. /*! @brief The type resulting from the transcription of the constness. */
  45447. using type = std::add_const_t<To>;
  45448. };
  45449. /**
  45450. * @brief Alias template to facilitate the transcription of the constness.
  45451. * @tparam To The type to which to transcribe the constness.
  45452. * @tparam From The type from which to transcribe the constness.
  45453. */
  45454. template<typename To, typename From>
  45455. using constness_as_t = typename constness_as<To, From>::type;
  45456. /**
  45457. * @brief Extracts the class of a non-static member object or function.
  45458. * @tparam Member A pointer to a non-static member object or function.
  45459. */
  45460. template<typename Member>
  45461. class member_class {
  45462. static_assert(std::is_member_pointer_v<Member>, "Invalid pointer type to non-static member object or function");
  45463. template<typename Class, typename Ret, typename... Args>
  45464. static Class *clazz(Ret (Class::*)(Args...));
  45465. template<typename Class, typename Ret, typename... Args>
  45466. static Class *clazz(Ret (Class::*)(Args...) const);
  45467. template<typename Class, typename Type>
  45468. static Class *clazz(Type Class::*);
  45469. public:
  45470. /*! @brief The class of the given non-static member object or function. */
  45471. using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
  45472. };
  45473. /**
  45474. * @brief Helper type.
  45475. * @tparam Member A pointer to a non-static member object or function.
  45476. */
  45477. template<typename Member>
  45478. using member_class_t = typename member_class<Member>::type;
  45479. } // namespace entt
  45480. #endif
  45481. namespace entt {
  45482. /**
  45483. * @cond TURN_OFF_DOXYGEN
  45484. * Internal details not to be documented.
  45485. */
  45486. namespace internal {
  45487. template<typename Type, std::size_t, typename = void>
  45488. struct compressed_pair_element {
  45489. using reference = Type &;
  45490. using const_reference = const Type &;
  45491. template<bool Dummy = true, typename = std::enable_if_t<Dummy && std::is_default_constructible_v<Type>>>
  45492. compressed_pair_element()
  45493. : value{} {}
  45494. template<typename Args, typename = std::enable_if_t<!std::is_same_v<std::remove_cv_t<std::remove_reference_t<Args>>, compressed_pair_element>>>
  45495. compressed_pair_element(Args &&args)
  45496. : value{std::forward<Args>(args)} {}
  45497. template<typename... Args, std::size_t... Index>
  45498. compressed_pair_element(std::tuple<Args...> args, std::index_sequence<Index...>)
  45499. : value{std::forward<Args>(std::get<Index>(args))...} {}
  45500. [[nodiscard]] reference get() ENTT_NOEXCEPT {
  45501. return value;
  45502. }
  45503. [[nodiscard]] const_reference get() const ENTT_NOEXCEPT {
  45504. return value;
  45505. }
  45506. private:
  45507. Type value;
  45508. };
  45509. template<typename Type, std::size_t Tag>
  45510. struct compressed_pair_element<Type, Tag, std::enable_if_t<is_ebco_eligible_v<Type>>>: Type {
  45511. using reference = Type &;
  45512. using const_reference = const Type &;
  45513. using base_type = Type;
  45514. template<bool Dummy = true, typename = std::enable_if_t<Dummy && std::is_default_constructible_v<base_type>>>
  45515. compressed_pair_element()
  45516. : base_type{} {}
  45517. template<typename Args, typename = std::enable_if_t<!std::is_same_v<std::remove_cv_t<std::remove_reference_t<Args>>, compressed_pair_element>>>
  45518. compressed_pair_element(Args &&args)
  45519. : base_type{std::forward<Args>(args)} {}
  45520. template<typename... Args, std::size_t... Index>
  45521. compressed_pair_element(std::tuple<Args...> args, std::index_sequence<Index...>)
  45522. : base_type{std::forward<Args>(std::get<Index>(args))...} {}
  45523. [[nodiscard]] reference get() ENTT_NOEXCEPT {
  45524. return *this;
  45525. }
  45526. [[nodiscard]] const_reference get() const ENTT_NOEXCEPT {
  45527. return *this;
  45528. }
  45529. };
  45530. } // namespace internal
  45531. /**
  45532. * Internal details not to be documented.
  45533. * @endcond
  45534. */
  45535. /**
  45536. * @brief A compressed pair.
  45537. *
  45538. * A pair that exploits the _Empty Base Class Optimization_ (or _EBCO_) to
  45539. * reduce its final size to a minimum.
  45540. *
  45541. * @tparam First The type of the first element that the pair stores.
  45542. * @tparam Second The type of the second element that the pair stores.
  45543. */
  45544. template<typename First, typename Second>
  45545. class compressed_pair final
  45546. : internal::compressed_pair_element<First, 0u>,
  45547. internal::compressed_pair_element<Second, 1u> {
  45548. using first_base = internal::compressed_pair_element<First, 0u>;
  45549. using second_base = internal::compressed_pair_element<Second, 1u>;
  45550. public:
  45551. /*! @brief The type of the first element that the pair stores. */
  45552. using first_type = First;
  45553. /*! @brief The type of the second element that the pair stores. */
  45554. using second_type = Second;
  45555. /**
  45556. * @brief Default constructor, conditionally enabled.
  45557. *
  45558. * This constructor is only available when the types that the pair stores
  45559. * are both at least default constructible.
  45560. *
  45561. * @tparam Dummy Dummy template parameter used for internal purposes.
  45562. */
  45563. template<bool Dummy = true, typename = std::enable_if_t<Dummy && std::is_default_constructible_v<first_type> && std::is_default_constructible_v<second_type>>>
  45564. constexpr compressed_pair()
  45565. : first_base{},
  45566. second_base{} {}
  45567. /**
  45568. * @brief Copy constructor.
  45569. * @param other The instance to copy from.
  45570. */
  45571. constexpr compressed_pair(const compressed_pair &other) = default;
  45572. /**
  45573. * @brief Move constructor.
  45574. * @param other The instance to move from.
  45575. */
  45576. constexpr compressed_pair(compressed_pair &&other) = default;
  45577. /**
  45578. * @brief Constructs a pair from its values.
  45579. * @tparam Arg Type of value to use to initialize the first element.
  45580. * @tparam Other Type of value to use to initialize the second element.
  45581. * @param arg Value to use to initialize the first element.
  45582. * @param other Value to use to initialize the second element.
  45583. */
  45584. template<typename Arg, typename Other>
  45585. constexpr compressed_pair(Arg &&arg, Other &&other)
  45586. : first_base{std::forward<Arg>(arg)},
  45587. second_base{std::forward<Other>(other)} {}
  45588. /**
  45589. * @brief Constructs a pair by forwarding the arguments to its parts.
  45590. * @tparam Args Types of arguments to use to initialize the first element.
  45591. * @tparam Other Types of arguments to use to initialize the second element.
  45592. * @param args Arguments to use to initialize the first element.
  45593. * @param other Arguments to use to initialize the second element.
  45594. */
  45595. template<typename... Args, typename... Other>
  45596. constexpr compressed_pair(std::piecewise_construct_t, std::tuple<Args...> args, std::tuple<Other...> other)
  45597. : first_base{std::move(args), std::index_sequence_for<Args...>{}},
  45598. second_base{std::move(other), std::index_sequence_for<Other...>{}} {}
  45599. /**
  45600. * @brief Copy assignment operator.
  45601. * @param other The instance to copy from.
  45602. * @return This compressed pair object.
  45603. */
  45604. constexpr compressed_pair &operator=(const compressed_pair &other) = default;
  45605. /**
  45606. * @brief Move assignment operator.
  45607. * @param other The instance to move from.
  45608. * @return This compressed pair object.
  45609. */
  45610. constexpr compressed_pair &operator=(compressed_pair &&other) = default;
  45611. /**
  45612. * @brief Returns the first element that a pair stores.
  45613. * @return The first element that a pair stores.
  45614. */
  45615. [[nodiscard]] first_type &first() ENTT_NOEXCEPT {
  45616. return static_cast<first_base &>(*this).get();
  45617. }
  45618. /*! @copydoc first */
  45619. [[nodiscard]] const first_type &first() const ENTT_NOEXCEPT {
  45620. return static_cast<const first_base &>(*this).get();
  45621. }
  45622. /**
  45623. * @brief Returns the second element that a pair stores.
  45624. * @return The second element that a pair stores.
  45625. */
  45626. [[nodiscard]] second_type &second() ENTT_NOEXCEPT {
  45627. return static_cast<second_base &>(*this).get();
  45628. }
  45629. /*! @copydoc second */
  45630. [[nodiscard]] const second_type &second() const ENTT_NOEXCEPT {
  45631. return static_cast<const second_base &>(*this).get();
  45632. }
  45633. /**
  45634. * @brief Swaps two compressed pair objects.
  45635. * @param other The compressed pair to swap with.
  45636. */
  45637. void swap(compressed_pair &other) {
  45638. using std::swap;
  45639. swap(first(), other.first());
  45640. swap(second(), other.second());
  45641. }
  45642. /**
  45643. * @brief Extracts an element from the compressed pair.
  45644. * @tparam Index An integer value that is either 0 or 1.
  45645. * @return Returns a reference to the first element if `Index` is 0 and a
  45646. * reference to the second element if `Index` is 1.
  45647. */
  45648. template<std::size_t Index>
  45649. decltype(auto) get() ENTT_NOEXCEPT {
  45650. if constexpr(Index == 0u) {
  45651. return first();
  45652. } else {
  45653. static_assert(Index == 1u, "Index out of bounds");
  45654. return second();
  45655. }
  45656. }
  45657. /*! @copydoc get */
  45658. template<std::size_t Index>
  45659. decltype(auto) get() const ENTT_NOEXCEPT {
  45660. if constexpr(Index == 0u) {
  45661. return first();
  45662. } else {
  45663. static_assert(Index == 1u, "Index out of bounds");
  45664. return second();
  45665. }
  45666. }
  45667. };
  45668. /**
  45669. * @brief Deduction guide.
  45670. * @tparam Type Type of value to use to initialize the first element.
  45671. * @tparam Other Type of value to use to initialize the second element.
  45672. */
  45673. template<typename Type, typename Other>
  45674. compressed_pair(Type &&, Other &&) -> compressed_pair<std::decay_t<Type>, std::decay_t<Other>>;
  45675. /**
  45676. * @brief Swaps two compressed pair objects.
  45677. * @tparam First The type of the first element that the pairs store.
  45678. * @tparam Second The type of the second element that the pairs store.
  45679. * @param lhs A valid compressed pair object.
  45680. * @param rhs A valid compressed pair object.
  45681. */
  45682. template<typename First, typename Second>
  45683. inline void swap(compressed_pair<First, Second> &lhs, compressed_pair<First, Second> &rhs) {
  45684. lhs.swap(rhs);
  45685. }
  45686. } // namespace entt
  45687. // disable structured binding support for clang 6, it messes when specializing tuple_size
  45688. #if !defined __clang_major__ || __clang_major__ > 6
  45689. namespace std {
  45690. /**
  45691. * @brief `std::tuple_size` specialization for `compressed_pair`s.
  45692. * @tparam First The type of the first element that the pair stores.
  45693. * @tparam Second The type of the second element that the pair stores.
  45694. */
  45695. template<typename First, typename Second>
  45696. struct tuple_size<entt::compressed_pair<First, Second>>: integral_constant<size_t, 2u> {};
  45697. /**
  45698. * @brief `std::tuple_element` specialization for `compressed_pair`s.
  45699. * @tparam Index The index of the type to return.
  45700. * @tparam First The type of the first element that the pair stores.
  45701. * @tparam Second The type of the second element that the pair stores.
  45702. */
  45703. template<size_t Index, typename First, typename Second>
  45704. struct tuple_element<Index, entt::compressed_pair<First, Second>>: conditional<Index == 0u, First, Second> {
  45705. static_assert(Index < 2u, "Index out of bounds");
  45706. };
  45707. } // namespace std
  45708. #endif
  45709. #endif
  45710. // #include "../core/iterator.hpp"
  45711. #ifndef ENTT_CORE_ITERATOR_HPP
  45712. #define ENTT_CORE_ITERATOR_HPP
  45713. #include <iterator>
  45714. #include <memory>
  45715. #include <utility>
  45716. // #include "../config/config.h"
  45717. namespace entt {
  45718. /**
  45719. * @brief Helper type to use as pointer with input iterators.
  45720. * @tparam Type of wrapped value.
  45721. */
  45722. template<typename Type>
  45723. struct input_iterator_pointer final {
  45724. /*! @brief Pointer type. */
  45725. using pointer = Type *;
  45726. /*! @brief Default copy constructor, deleted on purpose. */
  45727. input_iterator_pointer(const input_iterator_pointer &) = delete;
  45728. /*! @brief Default move constructor. */
  45729. input_iterator_pointer(input_iterator_pointer &&) = default;
  45730. /**
  45731. * @brief Constructs a proxy object by move.
  45732. * @param val Value to use to initialize the proxy object.
  45733. */
  45734. input_iterator_pointer(Type &&val)
  45735. : value{std::move(val)} {}
  45736. /**
  45737. * @brief Default copy assignment operator, deleted on purpose.
  45738. * @return This proxy object.
  45739. */
  45740. input_iterator_pointer &operator=(const input_iterator_pointer &) = delete;
  45741. /**
  45742. * @brief Default move assignment operator.
  45743. * @return This proxy object.
  45744. */
  45745. input_iterator_pointer &operator=(input_iterator_pointer &&) = default;
  45746. /**
  45747. * @brief Access operator for accessing wrapped values.
  45748. * @return A pointer to the wrapped value.
  45749. */
  45750. [[nodiscard]] pointer operator->() ENTT_NOEXCEPT {
  45751. return std::addressof(value);
  45752. }
  45753. private:
  45754. Type value;
  45755. };
  45756. /**
  45757. * @brief Utility class to create an iterable object from a pair of iterators.
  45758. * @tparam It Type of iterator.
  45759. * @tparam Sentinel Type of sentinel.
  45760. */
  45761. template<typename It, typename Sentinel = It>
  45762. struct iterable_adaptor final {
  45763. /*! @brief Value type. */
  45764. using value_type = typename std::iterator_traits<It>::value_type;
  45765. /*! @brief Iterator type. */
  45766. using iterator = It;
  45767. /*! @brief Sentinel type. */
  45768. using sentinel = Sentinel;
  45769. /*! @brief Default constructor. */
  45770. iterable_adaptor() = default;
  45771. /**
  45772. * @brief Creates an iterable object from a pair of iterators.
  45773. * @param from Begin iterator.
  45774. * @param to End iterator.
  45775. */
  45776. iterable_adaptor(iterator from, sentinel to)
  45777. : first{from},
  45778. last{to} {}
  45779. /**
  45780. * @brief Returns an iterator to the beginning.
  45781. * @return An iterator to the first element of the range.
  45782. */
  45783. [[nodiscard]] iterator begin() const ENTT_NOEXCEPT {
  45784. return first;
  45785. }
  45786. /**
  45787. * @brief Returns an iterator to the end.
  45788. * @return An iterator to the element following the last element of the
  45789. * range.
  45790. */
  45791. [[nodiscard]] sentinel end() const ENTT_NOEXCEPT {
  45792. return last;
  45793. }
  45794. /*! @copydoc begin */
  45795. [[nodiscard]] iterator cbegin() const ENTT_NOEXCEPT {
  45796. return begin();
  45797. }
  45798. /*! @copydoc end */
  45799. [[nodiscard]] sentinel cend() const ENTT_NOEXCEPT {
  45800. return end();
  45801. }
  45802. private:
  45803. It first;
  45804. Sentinel last;
  45805. };
  45806. } // namespace entt
  45807. #endif
  45808. // #include "../core/memory.hpp"
  45809. #ifndef ENTT_CORE_MEMORY_HPP
  45810. #define ENTT_CORE_MEMORY_HPP
  45811. #include <cstddef>
  45812. #include <limits>
  45813. #include <memory>
  45814. #include <tuple>
  45815. #include <type_traits>
  45816. #include <utility>
  45817. // #include "../config/config.h"
  45818. namespace entt {
  45819. /**
  45820. * @brief Unwraps fancy pointers, does nothing otherwise (waiting for C++20).
  45821. * @tparam Type Pointer type.
  45822. * @param ptr Fancy or raw pointer.
  45823. * @return A raw pointer that represents the address of the original pointer.
  45824. */
  45825. template<typename Type>
  45826. [[nodiscard]] constexpr auto to_address(Type &&ptr) ENTT_NOEXCEPT {
  45827. if constexpr(std::is_pointer_v<std::remove_cv_t<std::remove_reference_t<Type>>>) {
  45828. return ptr;
  45829. } else {
  45830. return to_address(std::forward<Type>(ptr).operator->());
  45831. }
  45832. }
  45833. /**
  45834. * @brief Utility function to design allocation-aware containers.
  45835. * @tparam Allocator Type of allocator.
  45836. * @param lhs A valid allocator.
  45837. * @param rhs Another valid allocator.
  45838. */
  45839. template<typename Allocator>
  45840. constexpr void propagate_on_container_copy_assignment([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) ENTT_NOEXCEPT {
  45841. if constexpr(std::allocator_traits<Allocator>::propagate_on_container_copy_assignment::value) {
  45842. lhs = rhs;
  45843. }
  45844. }
  45845. /**
  45846. * @brief Utility function to design allocation-aware containers.
  45847. * @tparam Allocator Type of allocator.
  45848. * @param lhs A valid allocator.
  45849. * @param rhs Another valid allocator.
  45850. */
  45851. template<typename Allocator>
  45852. constexpr void propagate_on_container_move_assignment([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) ENTT_NOEXCEPT {
  45853. if constexpr(std::allocator_traits<Allocator>::propagate_on_container_move_assignment::value) {
  45854. lhs = std::move(rhs);
  45855. }
  45856. }
  45857. /**
  45858. * @brief Utility function to design allocation-aware containers.
  45859. * @tparam Allocator Type of allocator.
  45860. * @param lhs A valid allocator.
  45861. * @param rhs Another valid allocator.
  45862. */
  45863. template<typename Allocator>
  45864. constexpr void propagate_on_container_swap([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) ENTT_NOEXCEPT {
  45865. ENTT_ASSERT(std::allocator_traits<Allocator>::propagate_on_container_swap::value || lhs == rhs, "Cannot swap the containers");
  45866. if constexpr(std::allocator_traits<Allocator>::propagate_on_container_swap::value) {
  45867. using std::swap;
  45868. swap(lhs, rhs);
  45869. }
  45870. }
  45871. /**
  45872. * @brief Checks whether a value is a power of two or not.
  45873. * @param value A value that may or may not be a power of two.
  45874. * @return True if the value is a power of two, false otherwise.
  45875. */
  45876. [[nodiscard]] inline constexpr bool is_power_of_two(const std::size_t value) ENTT_NOEXCEPT {
  45877. return value && ((value & (value - 1)) == 0);
  45878. }
  45879. /**
  45880. * @brief Computes the smallest power of two greater than or equal to a value.
  45881. * @param value The value to use.
  45882. * @return The smallest power of two greater than or equal to the given value.
  45883. */
  45884. [[nodiscard]] inline constexpr std::size_t next_power_of_two(const std::size_t value) ENTT_NOEXCEPT {
  45885. ENTT_ASSERT(value < (std::size_t{1u} << (std::numeric_limits<std::size_t>::digits - 1)), "Numeric limits exceeded");
  45886. std::size_t curr = value - (value != 0u);
  45887. for(int next = 1; next < std::numeric_limits<std::size_t>::digits; next = next * 2) {
  45888. curr |= curr >> next;
  45889. }
  45890. return ++curr;
  45891. }
  45892. /**
  45893. * @brief Fast module utility function (powers of two only).
  45894. * @param value A value for which to calculate the modulus.
  45895. * @param mod _Modulus_, it must be a power of two.
  45896. * @return The common remainder.
  45897. */
  45898. [[nodiscard]] inline constexpr std::size_t fast_mod(const std::size_t value, const std::size_t mod) ENTT_NOEXCEPT {
  45899. ENTT_ASSERT(is_power_of_two(mod), "Value must be a power of two");
  45900. return value & (mod - 1u);
  45901. }
  45902. /**
  45903. * @brief Deleter for allocator-aware unique pointers (waiting for C++20).
  45904. * @tparam Args Types of arguments to use to construct the object.
  45905. */
  45906. template<typename Allocator>
  45907. struct allocation_deleter: private Allocator {
  45908. /*! @brief Allocator type. */
  45909. using allocator_type = Allocator;
  45910. /*! @brief Pointer type. */
  45911. using pointer = typename std::allocator_traits<Allocator>::pointer;
  45912. /**
  45913. * @brief Inherited constructors.
  45914. * @param alloc The allocator to use.
  45915. */
  45916. allocation_deleter(const allocator_type &alloc)
  45917. : Allocator{alloc} {}
  45918. /**
  45919. * @brief Destroys the pointed object and deallocates its memory.
  45920. * @param ptr A valid pointer to an object of the given type.
  45921. */
  45922. void operator()(pointer ptr) {
  45923. using alloc_traits = typename std::allocator_traits<Allocator>;
  45924. alloc_traits::destroy(*this, to_address(ptr));
  45925. alloc_traits::deallocate(*this, ptr, 1u);
  45926. }
  45927. };
  45928. /**
  45929. * @brief Allows `std::unique_ptr` to use allocators (waiting for C++20).
  45930. * @tparam Type Type of object to allocate for and to construct.
  45931. * @tparam Allocator Type of allocator used to manage memory and elements.
  45932. * @tparam Args Types of arguments to use to construct the object.
  45933. * @param allocator The allocator to use.
  45934. * @param args Parameters to use to construct the object.
  45935. * @return A properly initialized unique pointer with a custom deleter.
  45936. */
  45937. template<typename Type, typename Allocator, typename... Args>
  45938. auto allocate_unique(Allocator &allocator, Args &&...args) {
  45939. static_assert(!std::is_array_v<Type>, "Array types are not supported");
  45940. using alloc_traits = typename std::allocator_traits<Allocator>::template rebind_traits<Type>;
  45941. using allocator_type = typename alloc_traits::allocator_type;
  45942. allocator_type alloc{allocator};
  45943. auto ptr = alloc_traits::allocate(alloc, 1u);
  45944. ENTT_TRY {
  45945. alloc_traits::construct(alloc, to_address(ptr), std::forward<Args>(args)...);
  45946. }
  45947. ENTT_CATCH {
  45948. alloc_traits::deallocate(alloc, ptr, 1u);
  45949. ENTT_THROW;
  45950. }
  45951. return std::unique_ptr<Type, allocation_deleter<allocator_type>>{ptr, alloc};
  45952. }
  45953. /**
  45954. * @cond TURN_OFF_DOXYGEN
  45955. * Internal details not to be documented.
  45956. */
  45957. namespace internal {
  45958. template<typename Type>
  45959. struct uses_allocator_construction {
  45960. template<typename Allocator, typename... Params>
  45961. static constexpr auto args([[maybe_unused]] const Allocator &allocator, Params &&...params) ENTT_NOEXCEPT {
  45962. if constexpr(!std::uses_allocator_v<Type, Allocator> && std::is_constructible_v<Type, Params...>) {
  45963. return std::forward_as_tuple(std::forward<Params>(params)...);
  45964. } else {
  45965. static_assert(std::uses_allocator_v<Type, Allocator>, "Ill-formed request");
  45966. if constexpr(std::is_constructible_v<Type, std::allocator_arg_t, const Allocator &, Params...>) {
  45967. return std::tuple<std::allocator_arg_t, const Allocator &, Params &&...>(std::allocator_arg, allocator, std::forward<Params>(params)...);
  45968. } else {
  45969. static_assert(std::is_constructible_v<Type, Params..., const Allocator &>, "Ill-formed request");
  45970. return std::forward_as_tuple(std::forward<Params>(params)..., allocator);
  45971. }
  45972. }
  45973. }
  45974. };
  45975. template<typename Type, typename Other>
  45976. struct uses_allocator_construction<std::pair<Type, Other>> {
  45977. using type = std::pair<Type, Other>;
  45978. template<typename Allocator, typename First, typename Second>
  45979. static constexpr auto args(const Allocator &allocator, std::piecewise_construct_t, First &&first, Second &&second) ENTT_NOEXCEPT {
  45980. return std::make_tuple(
  45981. std::piecewise_construct,
  45982. std::apply([&allocator](auto &&...curr) { return uses_allocator_construction<Type>::args(allocator, std::forward<decltype(curr)>(curr)...); }, std::forward<First>(first)),
  45983. std::apply([&allocator](auto &&...curr) { return uses_allocator_construction<Other>::args(allocator, std::forward<decltype(curr)>(curr)...); }, std::forward<Second>(second)));
  45984. }
  45985. template<typename Allocator>
  45986. static constexpr auto args(const Allocator &allocator) ENTT_NOEXCEPT {
  45987. return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::tuple<>{}, std::tuple<>{});
  45988. }
  45989. template<typename Allocator, typename First, typename Second>
  45990. static constexpr auto args(const Allocator &allocator, First &&first, Second &&second) ENTT_NOEXCEPT {
  45991. 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)));
  45992. }
  45993. template<typename Allocator, typename First, typename Second>
  45994. static constexpr auto args(const Allocator &allocator, const std::pair<First, Second> &value) ENTT_NOEXCEPT {
  45995. return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::forward_as_tuple(value.first), std::forward_as_tuple(value.second));
  45996. }
  45997. template<typename Allocator, typename First, typename Second>
  45998. static constexpr auto args(const Allocator &allocator, std::pair<First, Second> &&value) ENTT_NOEXCEPT {
  45999. 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)));
  46000. }
  46001. };
  46002. } // namespace internal
  46003. /**
  46004. * Internal details not to be documented.
  46005. * @endcond
  46006. */
  46007. /**
  46008. * @brief Uses-allocator construction utility (waiting for C++20).
  46009. *
  46010. * Primarily intended for internal use. Prepares the argument list needed to
  46011. * create an object of a given type by means of uses-allocator construction.
  46012. *
  46013. * @tparam Type Type to return arguments for.
  46014. * @tparam Allocator Type of allocator used to manage memory and elements.
  46015. * @tparam Args Types of arguments to use to construct the object.
  46016. * @param allocator The allocator to use.
  46017. * @param args Parameters to use to construct the object.
  46018. * @return The arguments needed to create an object of the given type.
  46019. */
  46020. template<typename Type, typename Allocator, typename... Args>
  46021. constexpr auto uses_allocator_construction_args(const Allocator &allocator, Args &&...args) ENTT_NOEXCEPT {
  46022. return internal::uses_allocator_construction<Type>::args(allocator, std::forward<Args>(args)...);
  46023. }
  46024. /**
  46025. * @brief Uses-allocator construction utility (waiting for C++20).
  46026. *
  46027. * Primarily intended for internal use. Creates an object of a given type by
  46028. * means of uses-allocator construction.
  46029. *
  46030. * @tparam Type Type of object to create.
  46031. * @tparam Allocator Type of allocator used to manage memory and elements.
  46032. * @tparam Args Types of arguments to use to construct the object.
  46033. * @param allocator The allocator to use.
  46034. * @param args Parameters to use to construct the object.
  46035. * @return A newly created object of the given type.
  46036. */
  46037. template<typename Type, typename Allocator, typename... Args>
  46038. constexpr Type make_obj_using_allocator(const Allocator &allocator, Args &&...args) {
  46039. return std::make_from_tuple<Type>(internal::uses_allocator_construction<Type>::args(allocator, std::forward<Args>(args)...));
  46040. }
  46041. /**
  46042. * @brief Uses-allocator construction utility (waiting for C++20).
  46043. *
  46044. * Primarily intended for internal use. Creates an object of a given type by
  46045. * means of uses-allocator construction at an uninitialized memory location.
  46046. *
  46047. * @tparam Type Type of object to create.
  46048. * @tparam Allocator Type of allocator used to manage memory and elements.
  46049. * @tparam Args Types of arguments to use to construct the object.
  46050. * @param value Memory location in which to place the object.
  46051. * @param allocator The allocator to use.
  46052. * @param args Parameters to use to construct the object.
  46053. * @return A pointer to the newly created object of the given type.
  46054. */
  46055. template<typename Type, typename Allocator, typename... Args>
  46056. constexpr Type *uninitialized_construct_using_allocator(Type *value, const Allocator &allocator, Args &&...args) {
  46057. return std::apply([&](auto &&...curr) { return new(value) Type(std::forward<decltype(curr)>(curr)...); }, internal::uses_allocator_construction<Type>::args(allocator, std::forward<Args>(args)...));
  46058. }
  46059. } // namespace entt
  46060. #endif
  46061. // #include "../core/type_traits.hpp"
  46062. #ifndef ENTT_CORE_TYPE_TRAITS_HPP
  46063. #define ENTT_CORE_TYPE_TRAITS_HPP
  46064. #include <cstddef>
  46065. #include <iterator>
  46066. #include <type_traits>
  46067. #include <utility>
  46068. // #include "../config/config.h"
  46069. // #include "fwd.hpp"
  46070. namespace entt {
  46071. /**
  46072. * @brief Utility class to disambiguate overloaded functions.
  46073. * @tparam N Number of choices available.
  46074. */
  46075. template<std::size_t N>
  46076. struct choice_t
  46077. // Unfortunately, doxygen cannot parse such a construct.
  46078. : /*! @cond TURN_OFF_DOXYGEN */ choice_t<N - 1> /*! @endcond */
  46079. {};
  46080. /*! @copybrief choice_t */
  46081. template<>
  46082. struct choice_t<0> {};
  46083. /**
  46084. * @brief Variable template for the choice trick.
  46085. * @tparam N Number of choices available.
  46086. */
  46087. template<std::size_t N>
  46088. inline constexpr choice_t<N> choice{};
  46089. /**
  46090. * @brief Identity type trait.
  46091. *
  46092. * Useful to establish non-deduced contexts in template argument deduction
  46093. * (waiting for C++20) or to provide types through function arguments.
  46094. *
  46095. * @tparam Type A type.
  46096. */
  46097. template<typename Type>
  46098. struct type_identity {
  46099. /*! @brief Identity type. */
  46100. using type = Type;
  46101. };
  46102. /**
  46103. * @brief Helper type.
  46104. * @tparam Type A type.
  46105. */
  46106. template<typename Type>
  46107. using type_identity_t = typename type_identity<Type>::type;
  46108. /**
  46109. * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains.
  46110. * @tparam Type The type of which to return the size.
  46111. * @tparam The size of the type if `sizeof` accepts it, 0 otherwise.
  46112. */
  46113. template<typename Type, typename = void>
  46114. struct size_of: std::integral_constant<std::size_t, 0u> {};
  46115. /*! @copydoc size_of */
  46116. template<typename Type>
  46117. struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
  46118. : std::integral_constant<std::size_t, sizeof(Type)> {};
  46119. /**
  46120. * @brief Helper variable template.
  46121. * @tparam Type The type of which to return the size.
  46122. */
  46123. template<typename Type>
  46124. inline constexpr std::size_t size_of_v = size_of<Type>::value;
  46125. /**
  46126. * @brief Using declaration to be used to _repeat_ the same type a number of
  46127. * times equal to the size of a given parameter pack.
  46128. * @tparam Type A type to repeat.
  46129. */
  46130. template<typename Type, typename>
  46131. using unpack_as_type = Type;
  46132. /**
  46133. * @brief Helper variable template to be used to _repeat_ the same value a
  46134. * number of times equal to the size of a given parameter pack.
  46135. * @tparam Value A value to repeat.
  46136. */
  46137. template<auto Value, typename>
  46138. inline constexpr auto unpack_as_value = Value;
  46139. /**
  46140. * @brief Wraps a static constant.
  46141. * @tparam Value A static constant.
  46142. */
  46143. template<auto Value>
  46144. using integral_constant = std::integral_constant<decltype(Value), Value>;
  46145. /**
  46146. * @brief Alias template to facilitate the creation of named values.
  46147. * @tparam Value A constant value at least convertible to `id_type`.
  46148. */
  46149. template<id_type Value>
  46150. using tag = integral_constant<Value>;
  46151. /**
  46152. * @brief A class to use to push around lists of types, nothing more.
  46153. * @tparam Type Types provided by the type list.
  46154. */
  46155. template<typename... Type>
  46156. struct type_list {
  46157. /*! @brief Type list type. */
  46158. using type = type_list;
  46159. /*! @brief Compile-time number of elements in the type list. */
  46160. static constexpr auto size = sizeof...(Type);
  46161. };
  46162. /*! @brief Primary template isn't defined on purpose. */
  46163. template<std::size_t, typename>
  46164. struct type_list_element;
  46165. /**
  46166. * @brief Provides compile-time indexed access to the types of a type list.
  46167. * @tparam Index Index of the type to return.
  46168. * @tparam Type First type provided by the type list.
  46169. * @tparam Other Other types provided by the type list.
  46170. */
  46171. template<std::size_t Index, typename Type, typename... Other>
  46172. struct type_list_element<Index, type_list<Type, Other...>>
  46173. : type_list_element<Index - 1u, type_list<Other...>> {};
  46174. /**
  46175. * @brief Provides compile-time indexed access to the types of a type list.
  46176. * @tparam Type First type provided by the type list.
  46177. * @tparam Other Other types provided by the type list.
  46178. */
  46179. template<typename Type, typename... Other>
  46180. struct type_list_element<0u, type_list<Type, Other...>> {
  46181. /*! @brief Searched type. */
  46182. using type = Type;
  46183. };
  46184. /**
  46185. * @brief Helper type.
  46186. * @tparam Index Index of the type to return.
  46187. * @tparam List Type list to search into.
  46188. */
  46189. template<std::size_t Index, typename List>
  46190. using type_list_element_t = typename type_list_element<Index, List>::type;
  46191. /**
  46192. * @brief Concatenates multiple type lists.
  46193. * @tparam Type Types provided by the first type list.
  46194. * @tparam Other Types provided by the second type list.
  46195. * @return A type list composed by the types of both the type lists.
  46196. */
  46197. template<typename... Type, typename... Other>
  46198. constexpr type_list<Type..., Other...> operator+(type_list<Type...>, type_list<Other...>) {
  46199. return {};
  46200. }
  46201. /*! @brief Primary template isn't defined on purpose. */
  46202. template<typename...>
  46203. struct type_list_cat;
  46204. /*! @brief Concatenates multiple type lists. */
  46205. template<>
  46206. struct type_list_cat<> {
  46207. /*! @brief A type list composed by the types of all the type lists. */
  46208. using type = type_list<>;
  46209. };
  46210. /**
  46211. * @brief Concatenates multiple type lists.
  46212. * @tparam Type Types provided by the first type list.
  46213. * @tparam Other Types provided by the second type list.
  46214. * @tparam List Other type lists, if any.
  46215. */
  46216. template<typename... Type, typename... Other, typename... List>
  46217. struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
  46218. /*! @brief A type list composed by the types of all the type lists. */
  46219. using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
  46220. };
  46221. /**
  46222. * @brief Concatenates multiple type lists.
  46223. * @tparam Type Types provided by the type list.
  46224. */
  46225. template<typename... Type>
  46226. struct type_list_cat<type_list<Type...>> {
  46227. /*! @brief A type list composed by the types of all the type lists. */
  46228. using type = type_list<Type...>;
  46229. };
  46230. /**
  46231. * @brief Helper type.
  46232. * @tparam List Type lists to concatenate.
  46233. */
  46234. template<typename... List>
  46235. using type_list_cat_t = typename type_list_cat<List...>::type;
  46236. /*! @brief Primary template isn't defined on purpose. */
  46237. template<typename>
  46238. struct type_list_unique;
  46239. /**
  46240. * @brief Removes duplicates types from a type list.
  46241. * @tparam Type One of the types provided by the given type list.
  46242. * @tparam Other The other types provided by the given type list.
  46243. */
  46244. template<typename Type, typename... Other>
  46245. struct type_list_unique<type_list<Type, Other...>> {
  46246. /*! @brief A type list without duplicate types. */
  46247. using type = std::conditional_t<
  46248. (std::is_same_v<Type, Other> || ...),
  46249. typename type_list_unique<type_list<Other...>>::type,
  46250. type_list_cat_t<type_list<Type>, typename type_list_unique<type_list<Other...>>::type>>;
  46251. };
  46252. /*! @brief Removes duplicates types from a type list. */
  46253. template<>
  46254. struct type_list_unique<type_list<>> {
  46255. /*! @brief A type list without duplicate types. */
  46256. using type = type_list<>;
  46257. };
  46258. /**
  46259. * @brief Helper type.
  46260. * @tparam Type A type list.
  46261. */
  46262. template<typename Type>
  46263. using type_list_unique_t = typename type_list_unique<Type>::type;
  46264. /**
  46265. * @brief Provides the member constant `value` to true if a type list contains a
  46266. * given type, false otherwise.
  46267. * @tparam List Type list.
  46268. * @tparam Type Type to look for.
  46269. */
  46270. template<typename List, typename Type>
  46271. struct type_list_contains;
  46272. /**
  46273. * @copybrief type_list_contains
  46274. * @tparam Type Types provided by the type list.
  46275. * @tparam Other Type to look for.
  46276. */
  46277. template<typename... Type, typename Other>
  46278. struct type_list_contains<type_list<Type...>, Other>: std::disjunction<std::is_same<Type, Other>...> {};
  46279. /**
  46280. * @brief Helper variable template.
  46281. * @tparam List Type list.
  46282. * @tparam Type Type to look for.
  46283. */
  46284. template<typename List, typename Type>
  46285. inline constexpr bool type_list_contains_v = type_list_contains<List, Type>::value;
  46286. /*! @brief Primary template isn't defined on purpose. */
  46287. template<typename...>
  46288. struct type_list_diff;
  46289. /**
  46290. * @brief Computes the difference between two type lists.
  46291. * @tparam Type Types provided by the first type list.
  46292. * @tparam Other Types provided by the second type list.
  46293. */
  46294. template<typename... Type, typename... Other>
  46295. struct type_list_diff<type_list<Type...>, type_list<Other...>> {
  46296. /*! @brief A type list that is the difference between the two type lists. */
  46297. using type = type_list_cat_t<std::conditional_t<type_list_contains_v<type_list<Other...>, Type>, type_list<>, type_list<Type>>...>;
  46298. };
  46299. /**
  46300. * @brief Helper type.
  46301. * @tparam List Type lists between which to compute the difference.
  46302. */
  46303. template<typename... List>
  46304. using type_list_diff_t = typename type_list_diff<List...>::type;
  46305. /**
  46306. * @brief A class to use to push around lists of constant values, nothing more.
  46307. * @tparam Value Values provided by the value list.
  46308. */
  46309. template<auto... Value>
  46310. struct value_list {
  46311. /*! @brief Value list type. */
  46312. using type = value_list;
  46313. /*! @brief Compile-time number of elements in the value list. */
  46314. static constexpr auto size = sizeof...(Value);
  46315. };
  46316. /*! @brief Primary template isn't defined on purpose. */
  46317. template<std::size_t, typename>
  46318. struct value_list_element;
  46319. /**
  46320. * @brief Provides compile-time indexed access to the values of a value list.
  46321. * @tparam Index Index of the value to return.
  46322. * @tparam Value First value provided by the value list.
  46323. * @tparam Other Other values provided by the value list.
  46324. */
  46325. template<std::size_t Index, auto Value, auto... Other>
  46326. struct value_list_element<Index, value_list<Value, Other...>>
  46327. : value_list_element<Index - 1u, value_list<Other...>> {};
  46328. /**
  46329. * @brief Provides compile-time indexed access to the types of a type list.
  46330. * @tparam Value First value provided by the value list.
  46331. * @tparam Other Other values provided by the value list.
  46332. */
  46333. template<auto Value, auto... Other>
  46334. struct value_list_element<0u, value_list<Value, Other...>> {
  46335. /*! @brief Searched value. */
  46336. static constexpr auto value = Value;
  46337. };
  46338. /**
  46339. * @brief Helper type.
  46340. * @tparam Index Index of the value to return.
  46341. * @tparam List Value list to search into.
  46342. */
  46343. template<std::size_t Index, typename List>
  46344. inline constexpr auto value_list_element_v = value_list_element<Index, List>::value;
  46345. /**
  46346. * @brief Concatenates multiple value lists.
  46347. * @tparam Value Values provided by the first value list.
  46348. * @tparam Other Values provided by the second value list.
  46349. * @return A value list composed by the values of both the value lists.
  46350. */
  46351. template<auto... Value, auto... Other>
  46352. constexpr value_list<Value..., Other...> operator+(value_list<Value...>, value_list<Other...>) {
  46353. return {};
  46354. }
  46355. /*! @brief Primary template isn't defined on purpose. */
  46356. template<typename...>
  46357. struct value_list_cat;
  46358. /*! @brief Concatenates multiple value lists. */
  46359. template<>
  46360. struct value_list_cat<> {
  46361. /*! @brief A value list composed by the values of all the value lists. */
  46362. using type = value_list<>;
  46363. };
  46364. /**
  46365. * @brief Concatenates multiple value lists.
  46366. * @tparam Value Values provided by the first value list.
  46367. * @tparam Other Values provided by the second value list.
  46368. * @tparam List Other value lists, if any.
  46369. */
  46370. template<auto... Value, auto... Other, typename... List>
  46371. struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
  46372. /*! @brief A value list composed by the values of all the value lists. */
  46373. using type = typename value_list_cat<value_list<Value..., Other...>, List...>::type;
  46374. };
  46375. /**
  46376. * @brief Concatenates multiple value lists.
  46377. * @tparam Value Values provided by the value list.
  46378. */
  46379. template<auto... Value>
  46380. struct value_list_cat<value_list<Value...>> {
  46381. /*! @brief A value list composed by the values of all the value lists. */
  46382. using type = value_list<Value...>;
  46383. };
  46384. /**
  46385. * @brief Helper type.
  46386. * @tparam List Value lists to concatenate.
  46387. */
  46388. template<typename... List>
  46389. using value_list_cat_t = typename value_list_cat<List...>::type;
  46390. /*! @brief Same as std::is_invocable, but with tuples. */
  46391. template<typename, typename>
  46392. struct is_applicable: std::false_type {};
  46393. /**
  46394. * @copybrief is_applicable
  46395. * @tparam Func A valid function type.
  46396. * @tparam Tuple Tuple-like type.
  46397. * @tparam Args The list of arguments to use to probe the function type.
  46398. */
  46399. template<typename Func, template<typename...> class Tuple, typename... Args>
  46400. struct is_applicable<Func, Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  46401. /**
  46402. * @copybrief is_applicable
  46403. * @tparam Func A valid function type.
  46404. * @tparam Tuple Tuple-like type.
  46405. * @tparam Args The list of arguments to use to probe the function type.
  46406. */
  46407. template<typename Func, template<typename...> class Tuple, typename... Args>
  46408. struct is_applicable<Func, const Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  46409. /**
  46410. * @brief Helper variable template.
  46411. * @tparam Func A valid function type.
  46412. * @tparam Args The list of arguments to use to probe the function type.
  46413. */
  46414. template<typename Func, typename Args>
  46415. inline constexpr bool is_applicable_v = is_applicable<Func, Args>::value;
  46416. /*! @brief Same as std::is_invocable_r, but with tuples for arguments. */
  46417. template<typename, typename, typename>
  46418. struct is_applicable_r: std::false_type {};
  46419. /**
  46420. * @copybrief is_applicable_r
  46421. * @tparam Ret The type to which the return type of the function should be
  46422. * convertible.
  46423. * @tparam Func A valid function type.
  46424. * @tparam Args The list of arguments to use to probe the function type.
  46425. */
  46426. template<typename Ret, typename Func, typename... Args>
  46427. struct is_applicable_r<Ret, Func, std::tuple<Args...>>: std::is_invocable_r<Ret, Func, Args...> {};
  46428. /**
  46429. * @brief Helper variable template.
  46430. * @tparam Ret The type to which the return type of the function should be
  46431. * convertible.
  46432. * @tparam Func A valid function type.
  46433. * @tparam Args The list of arguments to use to probe the function type.
  46434. */
  46435. template<typename Ret, typename Func, typename Args>
  46436. inline constexpr bool is_applicable_r_v = is_applicable_r<Ret, Func, Args>::value;
  46437. /**
  46438. * @brief Provides the member constant `value` to true if a given type is
  46439. * complete, false otherwise.
  46440. * @tparam Type The type to test.
  46441. */
  46442. template<typename Type, typename = void>
  46443. struct is_complete: std::false_type {};
  46444. /*! @copydoc is_complete */
  46445. template<typename Type>
  46446. struct is_complete<Type, std::void_t<decltype(sizeof(Type))>>: std::true_type {};
  46447. /**
  46448. * @brief Helper variable template.
  46449. * @tparam Type The type to test.
  46450. */
  46451. template<typename Type>
  46452. inline constexpr bool is_complete_v = is_complete<Type>::value;
  46453. /**
  46454. * @brief Provides the member constant `value` to true if a given type is an
  46455. * iterator, false otherwise.
  46456. * @tparam Type The type to test.
  46457. */
  46458. template<typename Type, typename = void>
  46459. struct is_iterator: std::false_type {};
  46460. /**
  46461. * @cond TURN_OFF_DOXYGEN
  46462. * Internal details not to be documented.
  46463. */
  46464. namespace internal {
  46465. template<typename, typename = void>
  46466. struct has_iterator_category: std::false_type {};
  46467. template<typename Type>
  46468. struct has_iterator_category<Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>: std::true_type {};
  46469. } // namespace internal
  46470. /**
  46471. * Internal details not to be documented.
  46472. * @endcond
  46473. */
  46474. /*! @copydoc is_iterator */
  46475. template<typename Type>
  46476. struct is_iterator<Type, std::enable_if_t<!std::is_same_v<std::remove_const_t<std::remove_pointer_t<Type>>, void>>>
  46477. : internal::has_iterator_category<Type> {};
  46478. /**
  46479. * @brief Helper variable template.
  46480. * @tparam Type The type to test.
  46481. */
  46482. template<typename Type>
  46483. inline constexpr bool is_iterator_v = is_iterator<Type>::value;
  46484. /**
  46485. * @brief Provides the member constant `value` to true if a given type is both
  46486. * an empty and non-final class, false otherwise.
  46487. * @tparam Type The type to test
  46488. */
  46489. template<typename Type>
  46490. struct is_ebco_eligible
  46491. : std::conjunction<std::is_empty<Type>, std::negation<std::is_final<Type>>> {};
  46492. /**
  46493. * @brief Helper variable template.
  46494. * @tparam Type The type to test.
  46495. */
  46496. template<typename Type>
  46497. inline constexpr bool is_ebco_eligible_v = is_ebco_eligible<Type>::value;
  46498. /**
  46499. * @brief Provides the member constant `value` to true if `Type::is_transparent`
  46500. * is valid and denotes a type, false otherwise.
  46501. * @tparam Type The type to test.
  46502. */
  46503. template<typename Type, typename = void>
  46504. struct is_transparent: std::false_type {};
  46505. /*! @copydoc is_transparent */
  46506. template<typename Type>
  46507. struct is_transparent<Type, std::void_t<typename Type::is_transparent>>: std::true_type {};
  46508. /**
  46509. * @brief Helper variable template.
  46510. * @tparam Type The type to test.
  46511. */
  46512. template<typename Type>
  46513. inline constexpr bool is_transparent_v = is_transparent<Type>::value;
  46514. /**
  46515. * @brief Provides the member constant `value` to true if a given type is
  46516. * equality comparable, false otherwise.
  46517. * @tparam Type The type to test.
  46518. */
  46519. template<typename Type, typename = void>
  46520. struct is_equality_comparable: std::false_type {};
  46521. /**
  46522. * @cond TURN_OFF_DOXYGEN
  46523. * Internal details not to be documented.
  46524. */
  46525. namespace internal {
  46526. template<typename, typename = void>
  46527. struct has_tuple_size_value: std::false_type {};
  46528. template<typename Type>
  46529. struct has_tuple_size_value<Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>: std::true_type {};
  46530. template<typename Type, std::size_t... Index>
  46531. [[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
  46532. return (is_equality_comparable<std::tuple_element_t<Index, Type>>::value && ...);
  46533. }
  46534. template<typename>
  46535. [[nodiscard]] constexpr bool maybe_equality_comparable(choice_t<0>) {
  46536. return true;
  46537. }
  46538. template<typename Type>
  46539. [[nodiscard]] constexpr auto maybe_equality_comparable(choice_t<1>) -> decltype(std::declval<typename Type::value_type>(), bool{}) {
  46540. if constexpr(is_iterator_v<Type>) {
  46541. return true;
  46542. } else if constexpr(std::is_same_v<typename Type::value_type, Type>) {
  46543. return maybe_equality_comparable<Type>(choice<0>);
  46544. } else {
  46545. return is_equality_comparable<typename Type::value_type>::value;
  46546. }
  46547. }
  46548. template<typename Type>
  46549. [[nodiscard]] constexpr std::enable_if_t<is_complete_v<std::tuple_size<std::remove_const_t<Type>>>, bool> maybe_equality_comparable(choice_t<2>) {
  46550. if constexpr(has_tuple_size_value<Type>::value) {
  46551. return unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
  46552. } else {
  46553. return maybe_equality_comparable<Type>(choice<1>);
  46554. }
  46555. }
  46556. } // namespace internal
  46557. /**
  46558. * Internal details not to be documented.
  46559. * @endcond
  46560. */
  46561. /*! @copydoc is_equality_comparable */
  46562. template<typename Type>
  46563. struct is_equality_comparable<Type, std::void_t<decltype(std::declval<Type>() == std::declval<Type>())>>
  46564. : std::bool_constant<internal::maybe_equality_comparable<Type>(choice<2>)> {};
  46565. /**
  46566. * @brief Helper variable template.
  46567. * @tparam Type The type to test.
  46568. */
  46569. template<typename Type>
  46570. inline constexpr bool is_equality_comparable_v = is_equality_comparable<Type>::value;
  46571. /**
  46572. * @brief Transcribes the constness of a type to another type.
  46573. * @tparam To The type to which to transcribe the constness.
  46574. * @tparam From The type from which to transcribe the constness.
  46575. */
  46576. template<typename To, typename From>
  46577. struct constness_as {
  46578. /*! @brief The type resulting from the transcription of the constness. */
  46579. using type = std::remove_const_t<To>;
  46580. };
  46581. /*! @copydoc constness_as */
  46582. template<typename To, typename From>
  46583. struct constness_as<To, const From> {
  46584. /*! @brief The type resulting from the transcription of the constness. */
  46585. using type = std::add_const_t<To>;
  46586. };
  46587. /**
  46588. * @brief Alias template to facilitate the transcription of the constness.
  46589. * @tparam To The type to which to transcribe the constness.
  46590. * @tparam From The type from which to transcribe the constness.
  46591. */
  46592. template<typename To, typename From>
  46593. using constness_as_t = typename constness_as<To, From>::type;
  46594. /**
  46595. * @brief Extracts the class of a non-static member object or function.
  46596. * @tparam Member A pointer to a non-static member object or function.
  46597. */
  46598. template<typename Member>
  46599. class member_class {
  46600. static_assert(std::is_member_pointer_v<Member>, "Invalid pointer type to non-static member object or function");
  46601. template<typename Class, typename Ret, typename... Args>
  46602. static Class *clazz(Ret (Class::*)(Args...));
  46603. template<typename Class, typename Ret, typename... Args>
  46604. static Class *clazz(Ret (Class::*)(Args...) const);
  46605. template<typename Class, typename Type>
  46606. static Class *clazz(Type Class::*);
  46607. public:
  46608. /*! @brief The class of the given non-static member object or function. */
  46609. using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
  46610. };
  46611. /**
  46612. * @brief Helper type.
  46613. * @tparam Member A pointer to a non-static member object or function.
  46614. */
  46615. template<typename Member>
  46616. using member_class_t = typename member_class<Member>::type;
  46617. } // namespace entt
  46618. #endif
  46619. // #include "fwd.hpp"
  46620. #ifndef ENTT_CONTAINER_FWD_HPP
  46621. #define ENTT_CONTAINER_FWD_HPP
  46622. #include <functional>
  46623. #include <memory>
  46624. namespace entt {
  46625. template<
  46626. typename Key,
  46627. typename Type,
  46628. typename = std::hash<Key>,
  46629. typename = std::equal_to<Key>,
  46630. typename = std::allocator<std::pair<const Key, Type>>>
  46631. class dense_map;
  46632. template<
  46633. typename Type,
  46634. typename = std::hash<Type>,
  46635. typename = std::equal_to<Type>,
  46636. typename = std::allocator<Type>>
  46637. class dense_set;
  46638. } // namespace entt
  46639. #endif
  46640. namespace entt {
  46641. /**
  46642. * @cond TURN_OFF_DOXYGEN
  46643. * Internal details not to be documented.
  46644. */
  46645. namespace internal {
  46646. template<typename Key, typename Type>
  46647. struct dense_map_node final {
  46648. using value_type = std::pair<Key, Type>;
  46649. template<typename... Args>
  46650. dense_map_node(const std::size_t pos, Args &&...args)
  46651. : next{pos},
  46652. element{std::forward<Args>(args)...} {}
  46653. template<typename Allocator, typename... Args>
  46654. dense_map_node(std::allocator_arg_t, const Allocator &allocator, const std::size_t pos, Args &&...args)
  46655. : next{pos},
  46656. element{entt::make_obj_using_allocator<value_type>(allocator, std::forward<Args>(args)...)} {}
  46657. template<typename Allocator>
  46658. dense_map_node(std::allocator_arg_t, const Allocator &allocator, const dense_map_node &other)
  46659. : next{other.next},
  46660. element{entt::make_obj_using_allocator<value_type>(allocator, other.element)} {}
  46661. template<typename Allocator>
  46662. dense_map_node(std::allocator_arg_t, const Allocator &allocator, dense_map_node &&other)
  46663. : next{other.next},
  46664. element{entt::make_obj_using_allocator<value_type>(allocator, std::move(other.element))} {}
  46665. std::size_t next;
  46666. value_type element;
  46667. };
  46668. template<typename It>
  46669. class dense_map_iterator final {
  46670. template<typename>
  46671. friend class dense_map_iterator;
  46672. using first_type = decltype(std::as_const(std::declval<It>()->element.first));
  46673. using second_type = decltype((std::declval<It>()->element.second));
  46674. public:
  46675. using value_type = std::pair<first_type, second_type>;
  46676. using pointer = input_iterator_pointer<value_type>;
  46677. using reference = value_type;
  46678. using difference_type = std::ptrdiff_t;
  46679. using iterator_category = std::input_iterator_tag;
  46680. dense_map_iterator() ENTT_NOEXCEPT
  46681. : it{} {}
  46682. dense_map_iterator(const It iter) ENTT_NOEXCEPT
  46683. : it{iter} {}
  46684. template<typename Other, typename = std::enable_if_t<!std::is_same_v<It, Other> && std::is_constructible_v<It, Other>>>
  46685. dense_map_iterator(const dense_map_iterator<Other> &other) ENTT_NOEXCEPT
  46686. : it{other.it} {}
  46687. dense_map_iterator &operator++() ENTT_NOEXCEPT {
  46688. return ++it, *this;
  46689. }
  46690. dense_map_iterator operator++(int) ENTT_NOEXCEPT {
  46691. dense_map_iterator orig = *this;
  46692. return ++(*this), orig;
  46693. }
  46694. dense_map_iterator &operator--() ENTT_NOEXCEPT {
  46695. return --it, *this;
  46696. }
  46697. dense_map_iterator operator--(int) ENTT_NOEXCEPT {
  46698. dense_map_iterator orig = *this;
  46699. return operator--(), orig;
  46700. }
  46701. dense_map_iterator &operator+=(const difference_type value) ENTT_NOEXCEPT {
  46702. it += value;
  46703. return *this;
  46704. }
  46705. dense_map_iterator operator+(const difference_type value) const ENTT_NOEXCEPT {
  46706. dense_map_iterator copy = *this;
  46707. return (copy += value);
  46708. }
  46709. dense_map_iterator &operator-=(const difference_type value) ENTT_NOEXCEPT {
  46710. return (*this += -value);
  46711. }
  46712. dense_map_iterator operator-(const difference_type value) const ENTT_NOEXCEPT {
  46713. return (*this + -value);
  46714. }
  46715. [[nodiscard]] reference operator[](const difference_type value) const ENTT_NOEXCEPT {
  46716. return {it[value].element.first, it[value].element.second};
  46717. }
  46718. [[nodiscard]] pointer operator->() const ENTT_NOEXCEPT {
  46719. return operator*();
  46720. }
  46721. [[nodiscard]] reference operator*() const ENTT_NOEXCEPT {
  46722. return {it->element.first, it->element.second};
  46723. }
  46724. template<typename ILhs, typename IRhs>
  46725. friend std::ptrdiff_t operator-(const dense_map_iterator<ILhs> &, const dense_map_iterator<IRhs> &) ENTT_NOEXCEPT;
  46726. template<typename ILhs, typename IRhs>
  46727. friend bool operator==(const dense_map_iterator<ILhs> &, const dense_map_iterator<IRhs> &) ENTT_NOEXCEPT;
  46728. template<typename ILhs, typename IRhs>
  46729. friend bool operator<(const dense_map_iterator<ILhs> &, const dense_map_iterator<IRhs> &) ENTT_NOEXCEPT;
  46730. private:
  46731. It it;
  46732. };
  46733. template<typename ILhs, typename IRhs>
  46734. [[nodiscard]] std::ptrdiff_t operator-(const dense_map_iterator<ILhs> &lhs, const dense_map_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  46735. return lhs.it - rhs.it;
  46736. }
  46737. template<typename ILhs, typename IRhs>
  46738. [[nodiscard]] bool operator==(const dense_map_iterator<ILhs> &lhs, const dense_map_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  46739. return lhs.it == rhs.it;
  46740. }
  46741. template<typename ILhs, typename IRhs>
  46742. [[nodiscard]] bool operator!=(const dense_map_iterator<ILhs> &lhs, const dense_map_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  46743. return !(lhs == rhs);
  46744. }
  46745. template<typename ILhs, typename IRhs>
  46746. [[nodiscard]] bool operator<(const dense_map_iterator<ILhs> &lhs, const dense_map_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  46747. return lhs.it < rhs.it;
  46748. }
  46749. template<typename ILhs, typename IRhs>
  46750. [[nodiscard]] bool operator>(const dense_map_iterator<ILhs> &lhs, const dense_map_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  46751. return rhs < lhs;
  46752. }
  46753. template<typename ILhs, typename IRhs>
  46754. [[nodiscard]] bool operator<=(const dense_map_iterator<ILhs> &lhs, const dense_map_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  46755. return !(lhs > rhs);
  46756. }
  46757. template<typename ILhs, typename IRhs>
  46758. [[nodiscard]] bool operator>=(const dense_map_iterator<ILhs> &lhs, const dense_map_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  46759. return !(lhs < rhs);
  46760. }
  46761. template<typename It>
  46762. class dense_map_local_iterator final {
  46763. template<typename>
  46764. friend class dense_map_local_iterator;
  46765. using first_type = decltype(std::as_const(std::declval<It>()->element.first));
  46766. using second_type = decltype((std::declval<It>()->element.second));
  46767. public:
  46768. using value_type = std::pair<first_type, second_type>;
  46769. using pointer = input_iterator_pointer<value_type>;
  46770. using reference = value_type;
  46771. using difference_type = std::ptrdiff_t;
  46772. using iterator_category = std::input_iterator_tag;
  46773. dense_map_local_iterator() ENTT_NOEXCEPT
  46774. : it{},
  46775. offset{} {}
  46776. dense_map_local_iterator(It iter, const std::size_t pos) ENTT_NOEXCEPT
  46777. : it{iter},
  46778. offset{pos} {}
  46779. template<typename Other, typename = std::enable_if_t<!std::is_same_v<It, Other> && std::is_constructible_v<It, Other>>>
  46780. dense_map_local_iterator(const dense_map_local_iterator<Other> &other) ENTT_NOEXCEPT
  46781. : it{other.it},
  46782. offset{other.offset} {}
  46783. dense_map_local_iterator &operator++() ENTT_NOEXCEPT {
  46784. return offset = it[offset].next, *this;
  46785. }
  46786. dense_map_local_iterator operator++(int) ENTT_NOEXCEPT {
  46787. dense_map_local_iterator orig = *this;
  46788. return ++(*this), orig;
  46789. }
  46790. [[nodiscard]] pointer operator->() const ENTT_NOEXCEPT {
  46791. return operator*();
  46792. }
  46793. [[nodiscard]] reference operator*() const ENTT_NOEXCEPT {
  46794. return {it[offset].element.first, it[offset].element.second};
  46795. }
  46796. [[nodiscard]] std::size_t index() const ENTT_NOEXCEPT {
  46797. return offset;
  46798. }
  46799. private:
  46800. It it;
  46801. std::size_t offset;
  46802. };
  46803. template<typename ILhs, typename IRhs>
  46804. [[nodiscard]] bool operator==(const dense_map_local_iterator<ILhs> &lhs, const dense_map_local_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  46805. return lhs.index() == rhs.index();
  46806. }
  46807. template<typename ILhs, typename IRhs>
  46808. [[nodiscard]] bool operator!=(const dense_map_local_iterator<ILhs> &lhs, const dense_map_local_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  46809. return !(lhs == rhs);
  46810. }
  46811. } // namespace internal
  46812. /**
  46813. * Internal details not to be documented.
  46814. * @endcond
  46815. */
  46816. /**
  46817. * @brief Associative container for key-value pairs with unique keys.
  46818. *
  46819. * Internally, elements are organized into buckets. Which bucket an element is
  46820. * placed into depends entirely on the hash of its key. Keys with the same hash
  46821. * code appear in the same bucket.
  46822. *
  46823. * @tparam Key Key type of the associative container.
  46824. * @tparam Type Mapped type of the associative container.
  46825. * @tparam Hash Type of function to use to hash the keys.
  46826. * @tparam KeyEqual Type of function to use to compare the keys for equality.
  46827. * @tparam Allocator Type of allocator used to manage memory and elements.
  46828. */
  46829. template<typename Key, typename Type, typename Hash, typename KeyEqual, typename Allocator>
  46830. class dense_map {
  46831. static constexpr float default_threshold = 0.875f;
  46832. static constexpr std::size_t minimum_capacity = 8u;
  46833. using node_type = internal::dense_map_node<Key, Type>;
  46834. using alloc_traits = typename std::allocator_traits<Allocator>;
  46835. static_assert(std::is_same_v<typename alloc_traits::value_type, std::pair<const Key, Type>>, "Invalid value type");
  46836. using sparse_container_type = std::vector<std::size_t, typename alloc_traits::template rebind_alloc<std::size_t>>;
  46837. using packed_container_type = std::vector<node_type, typename alloc_traits::template rebind_alloc<node_type>>;
  46838. template<typename Other>
  46839. [[nodiscard]] std::size_t key_to_bucket(const Other &key) const ENTT_NOEXCEPT {
  46840. return fast_mod(sparse.second()(key), bucket_count());
  46841. }
  46842. template<typename Other>
  46843. [[nodiscard]] auto constrained_find(const Other &key, std::size_t bucket) {
  46844. for(auto it = begin(bucket), last = end(bucket); it != last; ++it) {
  46845. if(packed.second()(it->first, key)) {
  46846. return begin() + static_cast<typename iterator::difference_type>(it.index());
  46847. }
  46848. }
  46849. return end();
  46850. }
  46851. template<typename Other>
  46852. [[nodiscard]] auto constrained_find(const Other &key, std::size_t bucket) const {
  46853. for(auto it = cbegin(bucket), last = cend(bucket); it != last; ++it) {
  46854. if(packed.second()(it->first, key)) {
  46855. return cbegin() + static_cast<typename iterator::difference_type>(it.index());
  46856. }
  46857. }
  46858. return cend();
  46859. }
  46860. template<typename Other, typename... Args>
  46861. [[nodiscard]] auto insert_or_do_nothing(Other &&key, Args &&...args) {
  46862. const auto index = key_to_bucket(key);
  46863. if(auto it = constrained_find(key, index); it != end()) {
  46864. return std::make_pair(it, false);
  46865. }
  46866. 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)...));
  46867. sparse.first()[index] = packed.first().size() - 1u;
  46868. rehash_if_required();
  46869. return std::make_pair(--end(), true);
  46870. }
  46871. template<typename Other, typename Arg>
  46872. [[nodiscard]] auto insert_or_overwrite(Other &&key, Arg &&value) {
  46873. const auto index = key_to_bucket(key);
  46874. if(auto it = constrained_find(key, index); it != end()) {
  46875. it->second = std::forward<Arg>(value);
  46876. return std::make_pair(it, false);
  46877. }
  46878. packed.first().emplace_back(sparse.first()[index], std::forward<Other>(key), std::forward<Arg>(value));
  46879. sparse.first()[index] = packed.first().size() - 1u;
  46880. rehash_if_required();
  46881. return std::make_pair(--end(), true);
  46882. }
  46883. void move_and_pop(const std::size_t pos) {
  46884. if(const auto last = size() - 1u; pos != last) {
  46885. packed.first()[pos] = std::move(packed.first().back());
  46886. size_type *curr = sparse.first().data() + key_to_bucket(packed.first().back().element.first);
  46887. for(; *curr != last; curr = &packed.first()[*curr].next) {}
  46888. *curr = pos;
  46889. }
  46890. packed.first().pop_back();
  46891. }
  46892. void rehash_if_required() {
  46893. if(size() > (bucket_count() * max_load_factor())) {
  46894. rehash(bucket_count() * 2u);
  46895. }
  46896. }
  46897. public:
  46898. /*! @brief Key type of the container. */
  46899. using key_type = Key;
  46900. /*! @brief Mapped type of the container. */
  46901. using mapped_type = Type;
  46902. /*! @brief Key-value type of the container. */
  46903. using value_type = std::pair<const Key, Type>;
  46904. /*! @brief Unsigned integer type. */
  46905. using size_type = std::size_t;
  46906. /*! @brief Type of function to use to hash the keys. */
  46907. using hasher = Hash;
  46908. /*! @brief Type of function to use to compare the keys for equality. */
  46909. using key_equal = KeyEqual;
  46910. /*! @brief Allocator type. */
  46911. using allocator_type = Allocator;
  46912. /*! @brief Input iterator type. */
  46913. using iterator = internal::dense_map_iterator<typename packed_container_type::iterator>;
  46914. /*! @brief Constant input iterator type. */
  46915. using const_iterator = internal::dense_map_iterator<typename packed_container_type::const_iterator>;
  46916. /*! @brief Input iterator type. */
  46917. using local_iterator = internal::dense_map_local_iterator<typename packed_container_type::iterator>;
  46918. /*! @brief Constant input iterator type. */
  46919. using const_local_iterator = internal::dense_map_local_iterator<typename packed_container_type::const_iterator>;
  46920. /*! @brief Default constructor. */
  46921. dense_map()
  46922. : dense_map(minimum_capacity) {}
  46923. /**
  46924. * @brief Constructs an empty container with a given allocator.
  46925. * @param allocator The allocator to use.
  46926. */
  46927. explicit dense_map(const allocator_type &allocator)
  46928. : dense_map{minimum_capacity, hasher{}, key_equal{}, allocator} {}
  46929. /**
  46930. * @brief Constructs an empty container with a given allocator and user
  46931. * supplied minimal number of buckets.
  46932. * @param bucket_count Minimal number of buckets.
  46933. * @param allocator The allocator to use.
  46934. */
  46935. dense_map(const size_type bucket_count, const allocator_type &allocator)
  46936. : dense_map{bucket_count, hasher{}, key_equal{}, allocator} {}
  46937. /**
  46938. * @brief Constructs an empty container with a given allocator, hash
  46939. * function and user supplied minimal number of buckets.
  46940. * @param bucket_count Minimal number of buckets.
  46941. * @param hash Hash function to use.
  46942. * @param allocator The allocator to use.
  46943. */
  46944. dense_map(const size_type bucket_count, const hasher &hash, const allocator_type &allocator)
  46945. : dense_map{bucket_count, hash, key_equal{}, allocator} {}
  46946. /**
  46947. * @brief Constructs an empty container with a given allocator, hash
  46948. * function, compare function and user supplied minimal number of buckets.
  46949. * @param bucket_count Minimal number of buckets.
  46950. * @param hash Hash function to use.
  46951. * @param equal Compare function to use.
  46952. * @param allocator The allocator to use.
  46953. */
  46954. explicit dense_map(const size_type bucket_count, const hasher &hash = hasher{}, const key_equal &equal = key_equal{}, const allocator_type &allocator = allocator_type{})
  46955. : sparse{allocator, hash},
  46956. packed{allocator, equal},
  46957. threshold{default_threshold} {
  46958. rehash(bucket_count);
  46959. }
  46960. /*! @brief Default copy constructor. */
  46961. dense_map(const dense_map &) = default;
  46962. /**
  46963. * @brief Allocator-extended copy constructor.
  46964. * @param other The instance to copy from.
  46965. * @param allocator The allocator to use.
  46966. */
  46967. dense_map(const dense_map &other, const allocator_type &allocator)
  46968. : sparse{std::piecewise_construct, std::forward_as_tuple(other.sparse.first(), allocator), std::forward_as_tuple(other.sparse.second())},
  46969. packed{std::piecewise_construct, std::forward_as_tuple(other.packed.first(), allocator), std::forward_as_tuple(other.packed.second())},
  46970. threshold{other.threshold} {}
  46971. /*! @brief Default move constructor. */
  46972. dense_map(dense_map &&) = default;
  46973. /**
  46974. * @brief Allocator-extended move constructor.
  46975. * @param other The instance to move from.
  46976. * @param allocator The allocator to use.
  46977. */
  46978. dense_map(dense_map &&other, const allocator_type &allocator)
  46979. : sparse{std::piecewise_construct, std::forward_as_tuple(std::move(other.sparse.first()), allocator), std::forward_as_tuple(std::move(other.sparse.second()))},
  46980. packed{std::piecewise_construct, std::forward_as_tuple(std::move(other.packed.first()), allocator), std::forward_as_tuple(std::move(other.packed.second()))},
  46981. threshold{other.threshold} {}
  46982. /**
  46983. * @brief Default copy assignment operator.
  46984. * @return This container.
  46985. */
  46986. dense_map &operator=(const dense_map &) = default;
  46987. /**
  46988. * @brief Default move assignment operator.
  46989. * @return This container.
  46990. */
  46991. dense_map &operator=(dense_map &&) = default;
  46992. /**
  46993. * @brief Returns the associated allocator.
  46994. * @return The associated allocator.
  46995. */
  46996. [[nodiscard]] constexpr allocator_type get_allocator() const ENTT_NOEXCEPT {
  46997. return sparse.first().get_allocator();
  46998. }
  46999. /**
  47000. * @brief Returns an iterator to the beginning.
  47001. *
  47002. * The returned iterator points to the first instance of the internal array.
  47003. * If the array is empty, the returned iterator will be equal to `end()`.
  47004. *
  47005. * @return An iterator to the first instance of the internal array.
  47006. */
  47007. [[nodiscard]] const_iterator cbegin() const ENTT_NOEXCEPT {
  47008. return packed.first().begin();
  47009. }
  47010. /*! @copydoc cbegin */
  47011. [[nodiscard]] const_iterator begin() const ENTT_NOEXCEPT {
  47012. return cbegin();
  47013. }
  47014. /*! @copydoc begin */
  47015. [[nodiscard]] iterator begin() ENTT_NOEXCEPT {
  47016. return packed.first().begin();
  47017. }
  47018. /**
  47019. * @brief Returns an iterator to the end.
  47020. *
  47021. * The returned iterator points to the element following the last instance
  47022. * of the internal array. Attempting to dereference the returned iterator
  47023. * results in undefined behavior.
  47024. *
  47025. * @return An iterator to the element following the last instance of the
  47026. * internal array.
  47027. */
  47028. [[nodiscard]] const_iterator cend() const ENTT_NOEXCEPT {
  47029. return packed.first().end();
  47030. }
  47031. /*! @copydoc cend */
  47032. [[nodiscard]] const_iterator end() const ENTT_NOEXCEPT {
  47033. return cend();
  47034. }
  47035. /*! @copydoc end */
  47036. [[nodiscard]] iterator end() ENTT_NOEXCEPT {
  47037. return packed.first().end();
  47038. }
  47039. /**
  47040. * @brief Checks whether a container is empty.
  47041. * @return True if the container is empty, false otherwise.
  47042. */
  47043. [[nodiscard]] bool empty() const ENTT_NOEXCEPT {
  47044. return packed.first().empty();
  47045. }
  47046. /**
  47047. * @brief Returns the number of elements in a container.
  47048. * @return Number of elements in a container.
  47049. */
  47050. [[nodiscard]] size_type size() const ENTT_NOEXCEPT {
  47051. return packed.first().size();
  47052. }
  47053. /*! @brief Clears the container. */
  47054. void clear() ENTT_NOEXCEPT {
  47055. sparse.first().clear();
  47056. packed.first().clear();
  47057. rehash(0u);
  47058. }
  47059. /**
  47060. * @brief Inserts an element into the container, if the key does not exist.
  47061. * @param value A key-value pair eventually convertible to the value type.
  47062. * @return A pair consisting of an iterator to the inserted element (or to
  47063. * the element that prevented the insertion) and a bool denoting whether the
  47064. * insertion took place.
  47065. */
  47066. std::pair<iterator, bool> insert(const value_type &value) {
  47067. return insert_or_do_nothing(value.first, value.second);
  47068. }
  47069. /*! @copydoc insert */
  47070. std::pair<iterator, bool> insert(value_type &&value) {
  47071. return insert_or_do_nothing(std::move(value.first), std::move(value.second));
  47072. }
  47073. /**
  47074. * @copydoc insert
  47075. * @tparam Arg Type of the key-value pair to insert into the container.
  47076. */
  47077. template<typename Arg>
  47078. std::enable_if_t<std::is_constructible_v<value_type, Arg &&>, std::pair<iterator, bool>>
  47079. insert(Arg &&value) {
  47080. return insert_or_do_nothing(std::forward<Arg>(value).first, std::forward<Arg>(value).second);
  47081. }
  47082. /**
  47083. * @brief Inserts elements into the container, if their keys do not exist.
  47084. * @tparam It Type of input iterator.
  47085. * @param first An iterator to the first element of the range of elements.
  47086. * @param last An iterator past the last element of the range of elements.
  47087. */
  47088. template<typename It>
  47089. void insert(It first, It last) {
  47090. for(; first != last; ++first) {
  47091. insert(*first);
  47092. }
  47093. }
  47094. /**
  47095. * @brief Inserts an element into the container or assigns to the current
  47096. * element if the key already exists.
  47097. * @tparam Arg Type of the value to insert or assign.
  47098. * @param key A key used both to look up and to insert if not found.
  47099. * @param value A value to insert or assign.
  47100. * @return A pair consisting of an iterator to the element and a bool
  47101. * denoting whether the insertion took place.
  47102. */
  47103. template<typename Arg>
  47104. std::pair<iterator, bool> insert_or_assign(const key_type &key, Arg &&value) {
  47105. return insert_or_overwrite(key, std::forward<Arg>(value));
  47106. }
  47107. /*! @copydoc insert_or_assign */
  47108. template<typename Arg>
  47109. std::pair<iterator, bool> insert_or_assign(key_type &&key, Arg &&value) {
  47110. return insert_or_overwrite(std::move(key), std::forward<Arg>(value));
  47111. }
  47112. /**
  47113. * @brief Constructs an element in-place, if the key does not exist.
  47114. *
  47115. * The element is also constructed when the container already has the key,
  47116. * in which case the newly constructed object is destroyed immediately.
  47117. *
  47118. * @tparam Args Types of arguments to forward to the constructor of the
  47119. * element.
  47120. * @param args Arguments to forward to the constructor of the element.
  47121. * @return A pair consisting of an iterator to the inserted element (or to
  47122. * the element that prevented the insertion) and a bool denoting whether the
  47123. * insertion took place.
  47124. */
  47125. template<typename... Args>
  47126. std::pair<iterator, bool> emplace([[maybe_unused]] Args &&...args) {
  47127. if constexpr(sizeof...(Args) == 0u) {
  47128. return insert_or_do_nothing(key_type{});
  47129. } else if constexpr(sizeof...(Args) == 1u) {
  47130. return insert_or_do_nothing(std::forward<Args>(args).first..., std::forward<Args>(args).second...);
  47131. } else if constexpr(sizeof...(Args) == 2u) {
  47132. return insert_or_do_nothing(std::forward<Args>(args)...);
  47133. } else {
  47134. auto &node = packed.first().emplace_back(packed.first().size(), std::forward<Args>(args)...);
  47135. const auto index = key_to_bucket(node.element.first);
  47136. if(auto it = constrained_find(node.element.first, index); it != end()) {
  47137. packed.first().pop_back();
  47138. return std::make_pair(it, false);
  47139. }
  47140. std::swap(node.next, sparse.first()[index]);
  47141. rehash_if_required();
  47142. return std::make_pair(--end(), true);
  47143. }
  47144. }
  47145. /**
  47146. * @brief Inserts in-place if the key does not exist, does nothing if the
  47147. * key exists.
  47148. * @tparam Args Types of arguments to forward to the constructor of the
  47149. * element.
  47150. * @param key A key used both to look up and to insert if not found.
  47151. * @param args Arguments to forward to the constructor of the element.
  47152. * @return A pair consisting of an iterator to the inserted element (or to
  47153. * the element that prevented the insertion) and a bool denoting whether the
  47154. * insertion took place.
  47155. */
  47156. template<typename... Args>
  47157. std::pair<iterator, bool> try_emplace(const key_type &key, Args &&...args) {
  47158. return insert_or_do_nothing(key, std::forward<Args>(args)...);
  47159. }
  47160. /*! @copydoc try_emplace */
  47161. template<typename... Args>
  47162. std::pair<iterator, bool> try_emplace(key_type &&key, Args &&...args) {
  47163. return insert_or_do_nothing(std::move(key), std::forward<Args>(args)...);
  47164. }
  47165. /**
  47166. * @brief Removes an element from a given position.
  47167. * @param pos An iterator to the element to remove.
  47168. * @return An iterator following the removed element.
  47169. */
  47170. iterator erase(const_iterator pos) {
  47171. const auto diff = pos - cbegin();
  47172. erase(pos->first);
  47173. return begin() + diff;
  47174. }
  47175. /**
  47176. * @brief Removes the given elements from a container.
  47177. * @param first An iterator to the first element of the range of elements.
  47178. * @param last An iterator past the last element of the range of elements.
  47179. * @return An iterator following the last removed element.
  47180. */
  47181. iterator erase(const_iterator first, const_iterator last) {
  47182. const auto dist = first - cbegin();
  47183. for(auto from = last - cbegin(); from != dist; --from) {
  47184. erase(packed.first()[from - 1u].element.first);
  47185. }
  47186. return (begin() + dist);
  47187. }
  47188. /**
  47189. * @brief Removes the element associated with a given key.
  47190. * @param key A key value of an element to remove.
  47191. * @return Number of elements removed (either 0 or 1).
  47192. */
  47193. size_type erase(const key_type &key) {
  47194. for(size_type *curr = sparse.first().data() + key_to_bucket(key); *curr != (std::numeric_limits<size_type>::max)(); curr = &packed.first()[*curr].next) {
  47195. if(packed.second()(packed.first()[*curr].element.first, key)) {
  47196. const auto index = *curr;
  47197. *curr = packed.first()[*curr].next;
  47198. move_and_pop(index);
  47199. return 1u;
  47200. }
  47201. }
  47202. return 0u;
  47203. }
  47204. /**
  47205. * @brief Exchanges the contents with those of a given container.
  47206. * @param other Container to exchange the content with.
  47207. */
  47208. void swap(dense_map &other) {
  47209. using std::swap;
  47210. swap(sparse, other.sparse);
  47211. swap(packed, other.packed);
  47212. swap(threshold, other.threshold);
  47213. }
  47214. /**
  47215. * @brief Accesses a given element with bounds checking.
  47216. * @param key A key of an element to find.
  47217. * @return A reference to the mapped value of the requested element.
  47218. */
  47219. [[nodiscard]] mapped_type &at(const key_type &key) {
  47220. auto it = find(key);
  47221. ENTT_ASSERT(it != end(), "Invalid key");
  47222. return it->second;
  47223. }
  47224. /*! @copydoc at */
  47225. [[nodiscard]] const mapped_type &at(const key_type &key) const {
  47226. auto it = find(key);
  47227. ENTT_ASSERT(it != cend(), "Invalid key");
  47228. return it->second;
  47229. }
  47230. /**
  47231. * @brief Accesses or inserts a given element.
  47232. * @param key A key of an element to find or insert.
  47233. * @return A reference to the mapped value of the requested element.
  47234. */
  47235. [[nodiscard]] mapped_type &operator[](const key_type &key) {
  47236. return insert_or_do_nothing(key).first->second;
  47237. }
  47238. /**
  47239. * @brief Accesses or inserts a given element.
  47240. * @param key A key of an element to find or insert.
  47241. * @return A reference to the mapped value of the requested element.
  47242. */
  47243. [[nodiscard]] mapped_type &operator[](key_type &&key) {
  47244. return insert_or_do_nothing(std::move(key)).first->second;
  47245. }
  47246. /**
  47247. * @brief Finds an element with a given key.
  47248. * @param key Key value of an element to search for.
  47249. * @return An iterator to an element with the given key. If no such element
  47250. * is found, a past-the-end iterator is returned.
  47251. */
  47252. [[nodiscard]] iterator find(const key_type &key) {
  47253. return constrained_find(key, key_to_bucket(key));
  47254. }
  47255. /*! @copydoc find */
  47256. [[nodiscard]] const_iterator find(const key_type &key) const {
  47257. return constrained_find(key, key_to_bucket(key));
  47258. }
  47259. /**
  47260. * @brief Finds an element with a key that compares _equivalent_ to a given
  47261. * value.
  47262. * @tparam Other Type of the key value of an element to search for.
  47263. * @param key Key value of an element to search for.
  47264. * @return An iterator to an element with the given key. If no such element
  47265. * is found, a past-the-end iterator is returned.
  47266. */
  47267. template<typename Other>
  47268. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, iterator>>
  47269. find(const Other &key) {
  47270. return constrained_find(key, key_to_bucket(key));
  47271. }
  47272. /*! @copydoc find */
  47273. template<typename Other>
  47274. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, const_iterator>>
  47275. find(const Other &key) const {
  47276. return constrained_find(key, key_to_bucket(key));
  47277. }
  47278. /**
  47279. * @brief Checks if the container contains an element with a given key.
  47280. * @param key Key value of an element to search for.
  47281. * @return True if there is such an element, false otherwise.
  47282. */
  47283. [[nodiscard]] bool contains(const key_type &key) const {
  47284. return (find(key) != cend());
  47285. }
  47286. /**
  47287. * @brief Checks if the container contains an element with a key that
  47288. * compares _equivalent_ to a given value.
  47289. * @tparam Other Type of the key value of an element to search for.
  47290. * @param key Key value of an element to search for.
  47291. * @return True if there is such an element, false otherwise.
  47292. */
  47293. template<typename Other>
  47294. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, bool>>
  47295. contains(const Other &key) const {
  47296. return (find(key) != cend());
  47297. }
  47298. /**
  47299. * @brief Returns an iterator to the beginning of a given bucket.
  47300. * @param index An index of a bucket to access.
  47301. * @return An iterator to the beginning of the given bucket.
  47302. */
  47303. [[nodiscard]] const_local_iterator cbegin(const size_type index) const {
  47304. return {packed.first().begin(), sparse.first()[index]};
  47305. }
  47306. /**
  47307. * @brief Returns an iterator to the beginning of a given bucket.
  47308. * @param index An index of a bucket to access.
  47309. * @return An iterator to the beginning of the given bucket.
  47310. */
  47311. [[nodiscard]] const_local_iterator begin(const size_type index) const {
  47312. return cbegin(index);
  47313. }
  47314. /**
  47315. * @brief Returns an iterator to the beginning of a given bucket.
  47316. * @param index An index of a bucket to access.
  47317. * @return An iterator to the beginning of the given bucket.
  47318. */
  47319. [[nodiscard]] local_iterator begin(const size_type index) {
  47320. return {packed.first().begin(), sparse.first()[index]};
  47321. }
  47322. /**
  47323. * @brief Returns an iterator to the end of a given bucket.
  47324. * @param index An index of a bucket to access.
  47325. * @return An iterator to the end of the given bucket.
  47326. */
  47327. [[nodiscard]] const_local_iterator cend([[maybe_unused]] const size_type index) const {
  47328. return {packed.first().begin(), (std::numeric_limits<size_type>::max)()};
  47329. }
  47330. /**
  47331. * @brief Returns an iterator to the end of a given bucket.
  47332. * @param index An index of a bucket to access.
  47333. * @return An iterator to the end of the given bucket.
  47334. */
  47335. [[nodiscard]] const_local_iterator end([[maybe_unused]] const size_type index) const {
  47336. return cend(index);
  47337. }
  47338. /**
  47339. * @brief Returns an iterator to the end of a given bucket.
  47340. * @param index An index of a bucket to access.
  47341. * @return An iterator to the end of the given bucket.
  47342. */
  47343. [[nodiscard]] local_iterator end([[maybe_unused]] const size_type index) {
  47344. return {packed.first().begin(), (std::numeric_limits<size_type>::max)()};
  47345. }
  47346. /**
  47347. * @brief Returns the number of buckets.
  47348. * @return The number of buckets.
  47349. */
  47350. [[nodiscard]] size_type bucket_count() const {
  47351. return sparse.first().size();
  47352. }
  47353. /**
  47354. * @brief Returns the maximum number of buckets.
  47355. * @return The maximum number of buckets.
  47356. */
  47357. [[nodiscard]] size_type max_bucket_count() const {
  47358. return sparse.first().max_size();
  47359. }
  47360. /**
  47361. * @brief Returns the number of elements in a given bucket.
  47362. * @param index The index of the bucket to examine.
  47363. * @return The number of elements in the given bucket.
  47364. */
  47365. [[nodiscard]] size_type bucket_size(const size_type index) const {
  47366. return static_cast<size_type>(std::distance(begin(index), end(index)));
  47367. }
  47368. /**
  47369. * @brief Returns the bucket for a given key.
  47370. * @param key The value of the key to examine.
  47371. * @return The bucket for the given key.
  47372. */
  47373. [[nodiscard]] size_type bucket(const key_type &key) const {
  47374. return key_to_bucket(key);
  47375. }
  47376. /**
  47377. * @brief Returns the average number of elements per bucket.
  47378. * @return The average number of elements per bucket.
  47379. */
  47380. [[nodiscard]] float load_factor() const {
  47381. return size() / static_cast<float>(bucket_count());
  47382. }
  47383. /**
  47384. * @brief Returns the maximum average number of elements per bucket.
  47385. * @return The maximum average number of elements per bucket.
  47386. */
  47387. [[nodiscard]] float max_load_factor() const {
  47388. return threshold;
  47389. }
  47390. /**
  47391. * @brief Sets the desired maximum average number of elements per bucket.
  47392. * @param value A desired maximum average number of elements per bucket.
  47393. */
  47394. void max_load_factor(const float value) {
  47395. ENTT_ASSERT(value > 0.f, "Invalid load factor");
  47396. threshold = value;
  47397. rehash(0u);
  47398. }
  47399. /**
  47400. * @brief Reserves at least the specified number of buckets and regenerates
  47401. * the hash table.
  47402. * @param count New number of buckets.
  47403. */
  47404. void rehash(const size_type count) {
  47405. auto value = (std::max)(count, minimum_capacity);
  47406. value = (std::max)(value, static_cast<size_type>(size() / max_load_factor()));
  47407. if(const auto sz = next_power_of_two(value); sz != bucket_count()) {
  47408. sparse.first().resize(sz);
  47409. std::fill(sparse.first().begin(), sparse.first().end(), (std::numeric_limits<size_type>::max)());
  47410. for(size_type pos{}, last = size(); pos < last; ++pos) {
  47411. const auto index = key_to_bucket(packed.first()[pos].element.first);
  47412. packed.first()[pos].next = std::exchange(sparse.first()[index], pos);
  47413. }
  47414. }
  47415. }
  47416. /**
  47417. * @brief Reserves space for at least the specified number of elements and
  47418. * regenerates the hash table.
  47419. * @param count New number of elements.
  47420. */
  47421. void reserve(const size_type count) {
  47422. packed.first().reserve(count);
  47423. rehash(static_cast<size_type>(std::ceil(count / max_load_factor())));
  47424. }
  47425. /**
  47426. * @brief Returns the function used to hash the keys.
  47427. * @return The function used to hash the keys.
  47428. */
  47429. [[nodiscard]] hasher hash_function() const {
  47430. return sparse.second();
  47431. }
  47432. /**
  47433. * @brief Returns the function used to compare keys for equality.
  47434. * @return The function used to compare keys for equality.
  47435. */
  47436. [[nodiscard]] key_equal key_eq() const {
  47437. return packed.second();
  47438. }
  47439. private:
  47440. compressed_pair<sparse_container_type, hasher> sparse;
  47441. compressed_pair<packed_container_type, key_equal> packed;
  47442. float threshold;
  47443. };
  47444. } // namespace entt
  47445. /**
  47446. * @cond TURN_OFF_DOXYGEN
  47447. * Internal details not to be documented.
  47448. */
  47449. namespace std {
  47450. template<typename Key, typename Value, typename Allocator>
  47451. struct uses_allocator<entt::internal::dense_map_node<Key, Value>, Allocator>
  47452. : std::true_type {};
  47453. } // namespace std
  47454. /**
  47455. * Internal details not to be documented.
  47456. * @endcond
  47457. */
  47458. #endif
  47459. // #include "../core/compressed_pair.hpp"
  47460. #ifndef ENTT_CORE_COMPRESSED_PAIR_HPP
  47461. #define ENTT_CORE_COMPRESSED_PAIR_HPP
  47462. #include <cstddef>
  47463. #include <tuple>
  47464. #include <type_traits>
  47465. #include <utility>
  47466. // #include "../config/config.h"
  47467. #ifndef ENTT_CONFIG_CONFIG_H
  47468. #define ENTT_CONFIG_CONFIG_H
  47469. // #include "version.h"
  47470. #ifndef ENTT_CONFIG_VERSION_H
  47471. #define ENTT_CONFIG_VERSION_H
  47472. // #include "macro.h"
  47473. #ifndef ENTT_CONFIG_MACRO_H
  47474. #define ENTT_CONFIG_MACRO_H
  47475. #define ENTT_STR(arg) #arg
  47476. #define ENTT_XSTR(arg) ENTT_STR(arg)
  47477. #endif
  47478. #define ENTT_VERSION_MAJOR 3
  47479. #define ENTT_VERSION_MINOR 10
  47480. #define ENTT_VERSION_PATCH 3
  47481. #define ENTT_VERSION \
  47482. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  47483. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  47484. #endif
  47485. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  47486. # define ENTT_THROW throw
  47487. # define ENTT_TRY try
  47488. # define ENTT_CATCH catch(...)
  47489. #else
  47490. # define ENTT_THROW
  47491. # define ENTT_TRY if(true)
  47492. # define ENTT_CATCH if(false)
  47493. #endif
  47494. #ifndef ENTT_NOEXCEPT
  47495. # define ENTT_NOEXCEPT noexcept
  47496. # define ENTT_NOEXCEPT_IF(expr) noexcept(expr)
  47497. # else
  47498. # define ENTT_NOEXCEPT_IF(...)
  47499. #endif
  47500. #ifdef ENTT_USE_ATOMIC
  47501. # include <atomic>
  47502. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  47503. #else
  47504. # define ENTT_MAYBE_ATOMIC(Type) Type
  47505. #endif
  47506. #ifndef ENTT_ID_TYPE
  47507. # include <cstdint>
  47508. # define ENTT_ID_TYPE std::uint32_t
  47509. #endif
  47510. #ifndef ENTT_SPARSE_PAGE
  47511. # define ENTT_SPARSE_PAGE 4096
  47512. #endif
  47513. #ifndef ENTT_PACKED_PAGE
  47514. # define ENTT_PACKED_PAGE 1024
  47515. #endif
  47516. #ifdef ENTT_DISABLE_ASSERT
  47517. # undef ENTT_ASSERT
  47518. # define ENTT_ASSERT(...) (void(0))
  47519. #elif !defined ENTT_ASSERT
  47520. # include <cassert>
  47521. # define ENTT_ASSERT(condition, ...) assert(condition)
  47522. #endif
  47523. #ifdef ENTT_NO_ETO
  47524. # define ENTT_IGNORE_IF_EMPTY false
  47525. #else
  47526. # define ENTT_IGNORE_IF_EMPTY true
  47527. #endif
  47528. #ifdef ENTT_STANDARD_CPP
  47529. # define ENTT_NONSTD false
  47530. #else
  47531. # define ENTT_NONSTD true
  47532. # if defined __clang__ || defined __GNUC__
  47533. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  47534. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  47535. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  47536. # elif defined _MSC_VER
  47537. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  47538. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  47539. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  47540. # endif
  47541. #endif
  47542. #if defined _MSC_VER
  47543. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  47544. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  47545. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  47546. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  47547. #endif
  47548. #endif
  47549. // #include "type_traits.hpp"
  47550. #ifndef ENTT_CORE_TYPE_TRAITS_HPP
  47551. #define ENTT_CORE_TYPE_TRAITS_HPP
  47552. #include <cstddef>
  47553. #include <iterator>
  47554. #include <type_traits>
  47555. #include <utility>
  47556. // #include "../config/config.h"
  47557. // #include "fwd.hpp"
  47558. #ifndef ENTT_CORE_FWD_HPP
  47559. #define ENTT_CORE_FWD_HPP
  47560. #include <cstdint>
  47561. #include <type_traits>
  47562. // #include "../config/config.h"
  47563. namespace entt {
  47564. template<std::size_t Len = sizeof(double[2]), std::size_t = alignof(typename std::aligned_storage_t<Len + !Len>)>
  47565. class basic_any;
  47566. /*! @brief Alias declaration for type identifiers. */
  47567. using id_type = ENTT_ID_TYPE;
  47568. /*! @brief Alias declaration for the most common use case. */
  47569. using any = basic_any<>;
  47570. } // namespace entt
  47571. #endif
  47572. namespace entt {
  47573. /**
  47574. * @brief Utility class to disambiguate overloaded functions.
  47575. * @tparam N Number of choices available.
  47576. */
  47577. template<std::size_t N>
  47578. struct choice_t
  47579. // Unfortunately, doxygen cannot parse such a construct.
  47580. : /*! @cond TURN_OFF_DOXYGEN */ choice_t<N - 1> /*! @endcond */
  47581. {};
  47582. /*! @copybrief choice_t */
  47583. template<>
  47584. struct choice_t<0> {};
  47585. /**
  47586. * @brief Variable template for the choice trick.
  47587. * @tparam N Number of choices available.
  47588. */
  47589. template<std::size_t N>
  47590. inline constexpr choice_t<N> choice{};
  47591. /**
  47592. * @brief Identity type trait.
  47593. *
  47594. * Useful to establish non-deduced contexts in template argument deduction
  47595. * (waiting for C++20) or to provide types through function arguments.
  47596. *
  47597. * @tparam Type A type.
  47598. */
  47599. template<typename Type>
  47600. struct type_identity {
  47601. /*! @brief Identity type. */
  47602. using type = Type;
  47603. };
  47604. /**
  47605. * @brief Helper type.
  47606. * @tparam Type A type.
  47607. */
  47608. template<typename Type>
  47609. using type_identity_t = typename type_identity<Type>::type;
  47610. /**
  47611. * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains.
  47612. * @tparam Type The type of which to return the size.
  47613. * @tparam The size of the type if `sizeof` accepts it, 0 otherwise.
  47614. */
  47615. template<typename Type, typename = void>
  47616. struct size_of: std::integral_constant<std::size_t, 0u> {};
  47617. /*! @copydoc size_of */
  47618. template<typename Type>
  47619. struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
  47620. : std::integral_constant<std::size_t, sizeof(Type)> {};
  47621. /**
  47622. * @brief Helper variable template.
  47623. * @tparam Type The type of which to return the size.
  47624. */
  47625. template<typename Type>
  47626. inline constexpr std::size_t size_of_v = size_of<Type>::value;
  47627. /**
  47628. * @brief Using declaration to be used to _repeat_ the same type a number of
  47629. * times equal to the size of a given parameter pack.
  47630. * @tparam Type A type to repeat.
  47631. */
  47632. template<typename Type, typename>
  47633. using unpack_as_type = Type;
  47634. /**
  47635. * @brief Helper variable template to be used to _repeat_ the same value a
  47636. * number of times equal to the size of a given parameter pack.
  47637. * @tparam Value A value to repeat.
  47638. */
  47639. template<auto Value, typename>
  47640. inline constexpr auto unpack_as_value = Value;
  47641. /**
  47642. * @brief Wraps a static constant.
  47643. * @tparam Value A static constant.
  47644. */
  47645. template<auto Value>
  47646. using integral_constant = std::integral_constant<decltype(Value), Value>;
  47647. /**
  47648. * @brief Alias template to facilitate the creation of named values.
  47649. * @tparam Value A constant value at least convertible to `id_type`.
  47650. */
  47651. template<id_type Value>
  47652. using tag = integral_constant<Value>;
  47653. /**
  47654. * @brief A class to use to push around lists of types, nothing more.
  47655. * @tparam Type Types provided by the type list.
  47656. */
  47657. template<typename... Type>
  47658. struct type_list {
  47659. /*! @brief Type list type. */
  47660. using type = type_list;
  47661. /*! @brief Compile-time number of elements in the type list. */
  47662. static constexpr auto size = sizeof...(Type);
  47663. };
  47664. /*! @brief Primary template isn't defined on purpose. */
  47665. template<std::size_t, typename>
  47666. struct type_list_element;
  47667. /**
  47668. * @brief Provides compile-time indexed access to the types of a type list.
  47669. * @tparam Index Index of the type to return.
  47670. * @tparam Type First type provided by the type list.
  47671. * @tparam Other Other types provided by the type list.
  47672. */
  47673. template<std::size_t Index, typename Type, typename... Other>
  47674. struct type_list_element<Index, type_list<Type, Other...>>
  47675. : type_list_element<Index - 1u, type_list<Other...>> {};
  47676. /**
  47677. * @brief Provides compile-time indexed access to the types of a type list.
  47678. * @tparam Type First type provided by the type list.
  47679. * @tparam Other Other types provided by the type list.
  47680. */
  47681. template<typename Type, typename... Other>
  47682. struct type_list_element<0u, type_list<Type, Other...>> {
  47683. /*! @brief Searched type. */
  47684. using type = Type;
  47685. };
  47686. /**
  47687. * @brief Helper type.
  47688. * @tparam Index Index of the type to return.
  47689. * @tparam List Type list to search into.
  47690. */
  47691. template<std::size_t Index, typename List>
  47692. using type_list_element_t = typename type_list_element<Index, List>::type;
  47693. /**
  47694. * @brief Concatenates multiple type lists.
  47695. * @tparam Type Types provided by the first type list.
  47696. * @tparam Other Types provided by the second type list.
  47697. * @return A type list composed by the types of both the type lists.
  47698. */
  47699. template<typename... Type, typename... Other>
  47700. constexpr type_list<Type..., Other...> operator+(type_list<Type...>, type_list<Other...>) {
  47701. return {};
  47702. }
  47703. /*! @brief Primary template isn't defined on purpose. */
  47704. template<typename...>
  47705. struct type_list_cat;
  47706. /*! @brief Concatenates multiple type lists. */
  47707. template<>
  47708. struct type_list_cat<> {
  47709. /*! @brief A type list composed by the types of all the type lists. */
  47710. using type = type_list<>;
  47711. };
  47712. /**
  47713. * @brief Concatenates multiple type lists.
  47714. * @tparam Type Types provided by the first type list.
  47715. * @tparam Other Types provided by the second type list.
  47716. * @tparam List Other type lists, if any.
  47717. */
  47718. template<typename... Type, typename... Other, typename... List>
  47719. struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
  47720. /*! @brief A type list composed by the types of all the type lists. */
  47721. using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
  47722. };
  47723. /**
  47724. * @brief Concatenates multiple type lists.
  47725. * @tparam Type Types provided by the type list.
  47726. */
  47727. template<typename... Type>
  47728. struct type_list_cat<type_list<Type...>> {
  47729. /*! @brief A type list composed by the types of all the type lists. */
  47730. using type = type_list<Type...>;
  47731. };
  47732. /**
  47733. * @brief Helper type.
  47734. * @tparam List Type lists to concatenate.
  47735. */
  47736. template<typename... List>
  47737. using type_list_cat_t = typename type_list_cat<List...>::type;
  47738. /*! @brief Primary template isn't defined on purpose. */
  47739. template<typename>
  47740. struct type_list_unique;
  47741. /**
  47742. * @brief Removes duplicates types from a type list.
  47743. * @tparam Type One of the types provided by the given type list.
  47744. * @tparam Other The other types provided by the given type list.
  47745. */
  47746. template<typename Type, typename... Other>
  47747. struct type_list_unique<type_list<Type, Other...>> {
  47748. /*! @brief A type list without duplicate types. */
  47749. using type = std::conditional_t<
  47750. (std::is_same_v<Type, Other> || ...),
  47751. typename type_list_unique<type_list<Other...>>::type,
  47752. type_list_cat_t<type_list<Type>, typename type_list_unique<type_list<Other...>>::type>>;
  47753. };
  47754. /*! @brief Removes duplicates types from a type list. */
  47755. template<>
  47756. struct type_list_unique<type_list<>> {
  47757. /*! @brief A type list without duplicate types. */
  47758. using type = type_list<>;
  47759. };
  47760. /**
  47761. * @brief Helper type.
  47762. * @tparam Type A type list.
  47763. */
  47764. template<typename Type>
  47765. using type_list_unique_t = typename type_list_unique<Type>::type;
  47766. /**
  47767. * @brief Provides the member constant `value` to true if a type list contains a
  47768. * given type, false otherwise.
  47769. * @tparam List Type list.
  47770. * @tparam Type Type to look for.
  47771. */
  47772. template<typename List, typename Type>
  47773. struct type_list_contains;
  47774. /**
  47775. * @copybrief type_list_contains
  47776. * @tparam Type Types provided by the type list.
  47777. * @tparam Other Type to look for.
  47778. */
  47779. template<typename... Type, typename Other>
  47780. struct type_list_contains<type_list<Type...>, Other>: std::disjunction<std::is_same<Type, Other>...> {};
  47781. /**
  47782. * @brief Helper variable template.
  47783. * @tparam List Type list.
  47784. * @tparam Type Type to look for.
  47785. */
  47786. template<typename List, typename Type>
  47787. inline constexpr bool type_list_contains_v = type_list_contains<List, Type>::value;
  47788. /*! @brief Primary template isn't defined on purpose. */
  47789. template<typename...>
  47790. struct type_list_diff;
  47791. /**
  47792. * @brief Computes the difference between two type lists.
  47793. * @tparam Type Types provided by the first type list.
  47794. * @tparam Other Types provided by the second type list.
  47795. */
  47796. template<typename... Type, typename... Other>
  47797. struct type_list_diff<type_list<Type...>, type_list<Other...>> {
  47798. /*! @brief A type list that is the difference between the two type lists. */
  47799. using type = type_list_cat_t<std::conditional_t<type_list_contains_v<type_list<Other...>, Type>, type_list<>, type_list<Type>>...>;
  47800. };
  47801. /**
  47802. * @brief Helper type.
  47803. * @tparam List Type lists between which to compute the difference.
  47804. */
  47805. template<typename... List>
  47806. using type_list_diff_t = typename type_list_diff<List...>::type;
  47807. /**
  47808. * @brief A class to use to push around lists of constant values, nothing more.
  47809. * @tparam Value Values provided by the value list.
  47810. */
  47811. template<auto... Value>
  47812. struct value_list {
  47813. /*! @brief Value list type. */
  47814. using type = value_list;
  47815. /*! @brief Compile-time number of elements in the value list. */
  47816. static constexpr auto size = sizeof...(Value);
  47817. };
  47818. /*! @brief Primary template isn't defined on purpose. */
  47819. template<std::size_t, typename>
  47820. struct value_list_element;
  47821. /**
  47822. * @brief Provides compile-time indexed access to the values of a value list.
  47823. * @tparam Index Index of the value to return.
  47824. * @tparam Value First value provided by the value list.
  47825. * @tparam Other Other values provided by the value list.
  47826. */
  47827. template<std::size_t Index, auto Value, auto... Other>
  47828. struct value_list_element<Index, value_list<Value, Other...>>
  47829. : value_list_element<Index - 1u, value_list<Other...>> {};
  47830. /**
  47831. * @brief Provides compile-time indexed access to the types of a type list.
  47832. * @tparam Value First value provided by the value list.
  47833. * @tparam Other Other values provided by the value list.
  47834. */
  47835. template<auto Value, auto... Other>
  47836. struct value_list_element<0u, value_list<Value, Other...>> {
  47837. /*! @brief Searched value. */
  47838. static constexpr auto value = Value;
  47839. };
  47840. /**
  47841. * @brief Helper type.
  47842. * @tparam Index Index of the value to return.
  47843. * @tparam List Value list to search into.
  47844. */
  47845. template<std::size_t Index, typename List>
  47846. inline constexpr auto value_list_element_v = value_list_element<Index, List>::value;
  47847. /**
  47848. * @brief Concatenates multiple value lists.
  47849. * @tparam Value Values provided by the first value list.
  47850. * @tparam Other Values provided by the second value list.
  47851. * @return A value list composed by the values of both the value lists.
  47852. */
  47853. template<auto... Value, auto... Other>
  47854. constexpr value_list<Value..., Other...> operator+(value_list<Value...>, value_list<Other...>) {
  47855. return {};
  47856. }
  47857. /*! @brief Primary template isn't defined on purpose. */
  47858. template<typename...>
  47859. struct value_list_cat;
  47860. /*! @brief Concatenates multiple value lists. */
  47861. template<>
  47862. struct value_list_cat<> {
  47863. /*! @brief A value list composed by the values of all the value lists. */
  47864. using type = value_list<>;
  47865. };
  47866. /**
  47867. * @brief Concatenates multiple value lists.
  47868. * @tparam Value Values provided by the first value list.
  47869. * @tparam Other Values provided by the second value list.
  47870. * @tparam List Other value lists, if any.
  47871. */
  47872. template<auto... Value, auto... Other, typename... List>
  47873. struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
  47874. /*! @brief A value list composed by the values of all the value lists. */
  47875. using type = typename value_list_cat<value_list<Value..., Other...>, List...>::type;
  47876. };
  47877. /**
  47878. * @brief Concatenates multiple value lists.
  47879. * @tparam Value Values provided by the value list.
  47880. */
  47881. template<auto... Value>
  47882. struct value_list_cat<value_list<Value...>> {
  47883. /*! @brief A value list composed by the values of all the value lists. */
  47884. using type = value_list<Value...>;
  47885. };
  47886. /**
  47887. * @brief Helper type.
  47888. * @tparam List Value lists to concatenate.
  47889. */
  47890. template<typename... List>
  47891. using value_list_cat_t = typename value_list_cat<List...>::type;
  47892. /*! @brief Same as std::is_invocable, but with tuples. */
  47893. template<typename, typename>
  47894. struct is_applicable: std::false_type {};
  47895. /**
  47896. * @copybrief is_applicable
  47897. * @tparam Func A valid function type.
  47898. * @tparam Tuple Tuple-like type.
  47899. * @tparam Args The list of arguments to use to probe the function type.
  47900. */
  47901. template<typename Func, template<typename...> class Tuple, typename... Args>
  47902. struct is_applicable<Func, Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  47903. /**
  47904. * @copybrief is_applicable
  47905. * @tparam Func A valid function type.
  47906. * @tparam Tuple Tuple-like type.
  47907. * @tparam Args The list of arguments to use to probe the function type.
  47908. */
  47909. template<typename Func, template<typename...> class Tuple, typename... Args>
  47910. struct is_applicable<Func, const Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  47911. /**
  47912. * @brief Helper variable template.
  47913. * @tparam Func A valid function type.
  47914. * @tparam Args The list of arguments to use to probe the function type.
  47915. */
  47916. template<typename Func, typename Args>
  47917. inline constexpr bool is_applicable_v = is_applicable<Func, Args>::value;
  47918. /*! @brief Same as std::is_invocable_r, but with tuples for arguments. */
  47919. template<typename, typename, typename>
  47920. struct is_applicable_r: std::false_type {};
  47921. /**
  47922. * @copybrief is_applicable_r
  47923. * @tparam Ret The type to which the return type of the function should be
  47924. * convertible.
  47925. * @tparam Func A valid function type.
  47926. * @tparam Args The list of arguments to use to probe the function type.
  47927. */
  47928. template<typename Ret, typename Func, typename... Args>
  47929. struct is_applicable_r<Ret, Func, std::tuple<Args...>>: std::is_invocable_r<Ret, Func, Args...> {};
  47930. /**
  47931. * @brief Helper variable template.
  47932. * @tparam Ret The type to which the return type of the function should be
  47933. * convertible.
  47934. * @tparam Func A valid function type.
  47935. * @tparam Args The list of arguments to use to probe the function type.
  47936. */
  47937. template<typename Ret, typename Func, typename Args>
  47938. inline constexpr bool is_applicable_r_v = is_applicable_r<Ret, Func, Args>::value;
  47939. /**
  47940. * @brief Provides the member constant `value` to true if a given type is
  47941. * complete, false otherwise.
  47942. * @tparam Type The type to test.
  47943. */
  47944. template<typename Type, typename = void>
  47945. struct is_complete: std::false_type {};
  47946. /*! @copydoc is_complete */
  47947. template<typename Type>
  47948. struct is_complete<Type, std::void_t<decltype(sizeof(Type))>>: std::true_type {};
  47949. /**
  47950. * @brief Helper variable template.
  47951. * @tparam Type The type to test.
  47952. */
  47953. template<typename Type>
  47954. inline constexpr bool is_complete_v = is_complete<Type>::value;
  47955. /**
  47956. * @brief Provides the member constant `value` to true if a given type is an
  47957. * iterator, false otherwise.
  47958. * @tparam Type The type to test.
  47959. */
  47960. template<typename Type, typename = void>
  47961. struct is_iterator: std::false_type {};
  47962. /**
  47963. * @cond TURN_OFF_DOXYGEN
  47964. * Internal details not to be documented.
  47965. */
  47966. namespace internal {
  47967. template<typename, typename = void>
  47968. struct has_iterator_category: std::false_type {};
  47969. template<typename Type>
  47970. struct has_iterator_category<Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>: std::true_type {};
  47971. } // namespace internal
  47972. /**
  47973. * Internal details not to be documented.
  47974. * @endcond
  47975. */
  47976. /*! @copydoc is_iterator */
  47977. template<typename Type>
  47978. struct is_iterator<Type, std::enable_if_t<!std::is_same_v<std::remove_const_t<std::remove_pointer_t<Type>>, void>>>
  47979. : internal::has_iterator_category<Type> {};
  47980. /**
  47981. * @brief Helper variable template.
  47982. * @tparam Type The type to test.
  47983. */
  47984. template<typename Type>
  47985. inline constexpr bool is_iterator_v = is_iterator<Type>::value;
  47986. /**
  47987. * @brief Provides the member constant `value` to true if a given type is both
  47988. * an empty and non-final class, false otherwise.
  47989. * @tparam Type The type to test
  47990. */
  47991. template<typename Type>
  47992. struct is_ebco_eligible
  47993. : std::conjunction<std::is_empty<Type>, std::negation<std::is_final<Type>>> {};
  47994. /**
  47995. * @brief Helper variable template.
  47996. * @tparam Type The type to test.
  47997. */
  47998. template<typename Type>
  47999. inline constexpr bool is_ebco_eligible_v = is_ebco_eligible<Type>::value;
  48000. /**
  48001. * @brief Provides the member constant `value` to true if `Type::is_transparent`
  48002. * is valid and denotes a type, false otherwise.
  48003. * @tparam Type The type to test.
  48004. */
  48005. template<typename Type, typename = void>
  48006. struct is_transparent: std::false_type {};
  48007. /*! @copydoc is_transparent */
  48008. template<typename Type>
  48009. struct is_transparent<Type, std::void_t<typename Type::is_transparent>>: std::true_type {};
  48010. /**
  48011. * @brief Helper variable template.
  48012. * @tparam Type The type to test.
  48013. */
  48014. template<typename Type>
  48015. inline constexpr bool is_transparent_v = is_transparent<Type>::value;
  48016. /**
  48017. * @brief Provides the member constant `value` to true if a given type is
  48018. * equality comparable, false otherwise.
  48019. * @tparam Type The type to test.
  48020. */
  48021. template<typename Type, typename = void>
  48022. struct is_equality_comparable: std::false_type {};
  48023. /**
  48024. * @cond TURN_OFF_DOXYGEN
  48025. * Internal details not to be documented.
  48026. */
  48027. namespace internal {
  48028. template<typename, typename = void>
  48029. struct has_tuple_size_value: std::false_type {};
  48030. template<typename Type>
  48031. struct has_tuple_size_value<Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>: std::true_type {};
  48032. template<typename Type, std::size_t... Index>
  48033. [[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
  48034. return (is_equality_comparable<std::tuple_element_t<Index, Type>>::value && ...);
  48035. }
  48036. template<typename>
  48037. [[nodiscard]] constexpr bool maybe_equality_comparable(choice_t<0>) {
  48038. return true;
  48039. }
  48040. template<typename Type>
  48041. [[nodiscard]] constexpr auto maybe_equality_comparable(choice_t<1>) -> decltype(std::declval<typename Type::value_type>(), bool{}) {
  48042. if constexpr(is_iterator_v<Type>) {
  48043. return true;
  48044. } else if constexpr(std::is_same_v<typename Type::value_type, Type>) {
  48045. return maybe_equality_comparable<Type>(choice<0>);
  48046. } else {
  48047. return is_equality_comparable<typename Type::value_type>::value;
  48048. }
  48049. }
  48050. template<typename Type>
  48051. [[nodiscard]] constexpr std::enable_if_t<is_complete_v<std::tuple_size<std::remove_const_t<Type>>>, bool> maybe_equality_comparable(choice_t<2>) {
  48052. if constexpr(has_tuple_size_value<Type>::value) {
  48053. return unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
  48054. } else {
  48055. return maybe_equality_comparable<Type>(choice<1>);
  48056. }
  48057. }
  48058. } // namespace internal
  48059. /**
  48060. * Internal details not to be documented.
  48061. * @endcond
  48062. */
  48063. /*! @copydoc is_equality_comparable */
  48064. template<typename Type>
  48065. struct is_equality_comparable<Type, std::void_t<decltype(std::declval<Type>() == std::declval<Type>())>>
  48066. : std::bool_constant<internal::maybe_equality_comparable<Type>(choice<2>)> {};
  48067. /**
  48068. * @brief Helper variable template.
  48069. * @tparam Type The type to test.
  48070. */
  48071. template<typename Type>
  48072. inline constexpr bool is_equality_comparable_v = is_equality_comparable<Type>::value;
  48073. /**
  48074. * @brief Transcribes the constness of a type to another type.
  48075. * @tparam To The type to which to transcribe the constness.
  48076. * @tparam From The type from which to transcribe the constness.
  48077. */
  48078. template<typename To, typename From>
  48079. struct constness_as {
  48080. /*! @brief The type resulting from the transcription of the constness. */
  48081. using type = std::remove_const_t<To>;
  48082. };
  48083. /*! @copydoc constness_as */
  48084. template<typename To, typename From>
  48085. struct constness_as<To, const From> {
  48086. /*! @brief The type resulting from the transcription of the constness. */
  48087. using type = std::add_const_t<To>;
  48088. };
  48089. /**
  48090. * @brief Alias template to facilitate the transcription of the constness.
  48091. * @tparam To The type to which to transcribe the constness.
  48092. * @tparam From The type from which to transcribe the constness.
  48093. */
  48094. template<typename To, typename From>
  48095. using constness_as_t = typename constness_as<To, From>::type;
  48096. /**
  48097. * @brief Extracts the class of a non-static member object or function.
  48098. * @tparam Member A pointer to a non-static member object or function.
  48099. */
  48100. template<typename Member>
  48101. class member_class {
  48102. static_assert(std::is_member_pointer_v<Member>, "Invalid pointer type to non-static member object or function");
  48103. template<typename Class, typename Ret, typename... Args>
  48104. static Class *clazz(Ret (Class::*)(Args...));
  48105. template<typename Class, typename Ret, typename... Args>
  48106. static Class *clazz(Ret (Class::*)(Args...) const);
  48107. template<typename Class, typename Type>
  48108. static Class *clazz(Type Class::*);
  48109. public:
  48110. /*! @brief The class of the given non-static member object or function. */
  48111. using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
  48112. };
  48113. /**
  48114. * @brief Helper type.
  48115. * @tparam Member A pointer to a non-static member object or function.
  48116. */
  48117. template<typename Member>
  48118. using member_class_t = typename member_class<Member>::type;
  48119. } // namespace entt
  48120. #endif
  48121. namespace entt {
  48122. /**
  48123. * @cond TURN_OFF_DOXYGEN
  48124. * Internal details not to be documented.
  48125. */
  48126. namespace internal {
  48127. template<typename Type, std::size_t, typename = void>
  48128. struct compressed_pair_element {
  48129. using reference = Type &;
  48130. using const_reference = const Type &;
  48131. template<bool Dummy = true, typename = std::enable_if_t<Dummy && std::is_default_constructible_v<Type>>>
  48132. compressed_pair_element()
  48133. : value{} {}
  48134. template<typename Args, typename = std::enable_if_t<!std::is_same_v<std::remove_cv_t<std::remove_reference_t<Args>>, compressed_pair_element>>>
  48135. compressed_pair_element(Args &&args)
  48136. : value{std::forward<Args>(args)} {}
  48137. template<typename... Args, std::size_t... Index>
  48138. compressed_pair_element(std::tuple<Args...> args, std::index_sequence<Index...>)
  48139. : value{std::forward<Args>(std::get<Index>(args))...} {}
  48140. [[nodiscard]] reference get() ENTT_NOEXCEPT {
  48141. return value;
  48142. }
  48143. [[nodiscard]] const_reference get() const ENTT_NOEXCEPT {
  48144. return value;
  48145. }
  48146. private:
  48147. Type value;
  48148. };
  48149. template<typename Type, std::size_t Tag>
  48150. struct compressed_pair_element<Type, Tag, std::enable_if_t<is_ebco_eligible_v<Type>>>: Type {
  48151. using reference = Type &;
  48152. using const_reference = const Type &;
  48153. using base_type = Type;
  48154. template<bool Dummy = true, typename = std::enable_if_t<Dummy && std::is_default_constructible_v<base_type>>>
  48155. compressed_pair_element()
  48156. : base_type{} {}
  48157. template<typename Args, typename = std::enable_if_t<!std::is_same_v<std::remove_cv_t<std::remove_reference_t<Args>>, compressed_pair_element>>>
  48158. compressed_pair_element(Args &&args)
  48159. : base_type{std::forward<Args>(args)} {}
  48160. template<typename... Args, std::size_t... Index>
  48161. compressed_pair_element(std::tuple<Args...> args, std::index_sequence<Index...>)
  48162. : base_type{std::forward<Args>(std::get<Index>(args))...} {}
  48163. [[nodiscard]] reference get() ENTT_NOEXCEPT {
  48164. return *this;
  48165. }
  48166. [[nodiscard]] const_reference get() const ENTT_NOEXCEPT {
  48167. return *this;
  48168. }
  48169. };
  48170. } // namespace internal
  48171. /**
  48172. * Internal details not to be documented.
  48173. * @endcond
  48174. */
  48175. /**
  48176. * @brief A compressed pair.
  48177. *
  48178. * A pair that exploits the _Empty Base Class Optimization_ (or _EBCO_) to
  48179. * reduce its final size to a minimum.
  48180. *
  48181. * @tparam First The type of the first element that the pair stores.
  48182. * @tparam Second The type of the second element that the pair stores.
  48183. */
  48184. template<typename First, typename Second>
  48185. class compressed_pair final
  48186. : internal::compressed_pair_element<First, 0u>,
  48187. internal::compressed_pair_element<Second, 1u> {
  48188. using first_base = internal::compressed_pair_element<First, 0u>;
  48189. using second_base = internal::compressed_pair_element<Second, 1u>;
  48190. public:
  48191. /*! @brief The type of the first element that the pair stores. */
  48192. using first_type = First;
  48193. /*! @brief The type of the second element that the pair stores. */
  48194. using second_type = Second;
  48195. /**
  48196. * @brief Default constructor, conditionally enabled.
  48197. *
  48198. * This constructor is only available when the types that the pair stores
  48199. * are both at least default constructible.
  48200. *
  48201. * @tparam Dummy Dummy template parameter used for internal purposes.
  48202. */
  48203. template<bool Dummy = true, typename = std::enable_if_t<Dummy && std::is_default_constructible_v<first_type> && std::is_default_constructible_v<second_type>>>
  48204. constexpr compressed_pair()
  48205. : first_base{},
  48206. second_base{} {}
  48207. /**
  48208. * @brief Copy constructor.
  48209. * @param other The instance to copy from.
  48210. */
  48211. constexpr compressed_pair(const compressed_pair &other) = default;
  48212. /**
  48213. * @brief Move constructor.
  48214. * @param other The instance to move from.
  48215. */
  48216. constexpr compressed_pair(compressed_pair &&other) = default;
  48217. /**
  48218. * @brief Constructs a pair from its values.
  48219. * @tparam Arg Type of value to use to initialize the first element.
  48220. * @tparam Other Type of value to use to initialize the second element.
  48221. * @param arg Value to use to initialize the first element.
  48222. * @param other Value to use to initialize the second element.
  48223. */
  48224. template<typename Arg, typename Other>
  48225. constexpr compressed_pair(Arg &&arg, Other &&other)
  48226. : first_base{std::forward<Arg>(arg)},
  48227. second_base{std::forward<Other>(other)} {}
  48228. /**
  48229. * @brief Constructs a pair by forwarding the arguments to its parts.
  48230. * @tparam Args Types of arguments to use to initialize the first element.
  48231. * @tparam Other Types of arguments to use to initialize the second element.
  48232. * @param args Arguments to use to initialize the first element.
  48233. * @param other Arguments to use to initialize the second element.
  48234. */
  48235. template<typename... Args, typename... Other>
  48236. constexpr compressed_pair(std::piecewise_construct_t, std::tuple<Args...> args, std::tuple<Other...> other)
  48237. : first_base{std::move(args), std::index_sequence_for<Args...>{}},
  48238. second_base{std::move(other), std::index_sequence_for<Other...>{}} {}
  48239. /**
  48240. * @brief Copy assignment operator.
  48241. * @param other The instance to copy from.
  48242. * @return This compressed pair object.
  48243. */
  48244. constexpr compressed_pair &operator=(const compressed_pair &other) = default;
  48245. /**
  48246. * @brief Move assignment operator.
  48247. * @param other The instance to move from.
  48248. * @return This compressed pair object.
  48249. */
  48250. constexpr compressed_pair &operator=(compressed_pair &&other) = default;
  48251. /**
  48252. * @brief Returns the first element that a pair stores.
  48253. * @return The first element that a pair stores.
  48254. */
  48255. [[nodiscard]] first_type &first() ENTT_NOEXCEPT {
  48256. return static_cast<first_base &>(*this).get();
  48257. }
  48258. /*! @copydoc first */
  48259. [[nodiscard]] const first_type &first() const ENTT_NOEXCEPT {
  48260. return static_cast<const first_base &>(*this).get();
  48261. }
  48262. /**
  48263. * @brief Returns the second element that a pair stores.
  48264. * @return The second element that a pair stores.
  48265. */
  48266. [[nodiscard]] second_type &second() ENTT_NOEXCEPT {
  48267. return static_cast<second_base &>(*this).get();
  48268. }
  48269. /*! @copydoc second */
  48270. [[nodiscard]] const second_type &second() const ENTT_NOEXCEPT {
  48271. return static_cast<const second_base &>(*this).get();
  48272. }
  48273. /**
  48274. * @brief Swaps two compressed pair objects.
  48275. * @param other The compressed pair to swap with.
  48276. */
  48277. void swap(compressed_pair &other) {
  48278. using std::swap;
  48279. swap(first(), other.first());
  48280. swap(second(), other.second());
  48281. }
  48282. /**
  48283. * @brief Extracts an element from the compressed pair.
  48284. * @tparam Index An integer value that is either 0 or 1.
  48285. * @return Returns a reference to the first element if `Index` is 0 and a
  48286. * reference to the second element if `Index` is 1.
  48287. */
  48288. template<std::size_t Index>
  48289. decltype(auto) get() ENTT_NOEXCEPT {
  48290. if constexpr(Index == 0u) {
  48291. return first();
  48292. } else {
  48293. static_assert(Index == 1u, "Index out of bounds");
  48294. return second();
  48295. }
  48296. }
  48297. /*! @copydoc get */
  48298. template<std::size_t Index>
  48299. decltype(auto) get() const ENTT_NOEXCEPT {
  48300. if constexpr(Index == 0u) {
  48301. return first();
  48302. } else {
  48303. static_assert(Index == 1u, "Index out of bounds");
  48304. return second();
  48305. }
  48306. }
  48307. };
  48308. /**
  48309. * @brief Deduction guide.
  48310. * @tparam Type Type of value to use to initialize the first element.
  48311. * @tparam Other Type of value to use to initialize the second element.
  48312. */
  48313. template<typename Type, typename Other>
  48314. compressed_pair(Type &&, Other &&) -> compressed_pair<std::decay_t<Type>, std::decay_t<Other>>;
  48315. /**
  48316. * @brief Swaps two compressed pair objects.
  48317. * @tparam First The type of the first element that the pairs store.
  48318. * @tparam Second The type of the second element that the pairs store.
  48319. * @param lhs A valid compressed pair object.
  48320. * @param rhs A valid compressed pair object.
  48321. */
  48322. template<typename First, typename Second>
  48323. inline void swap(compressed_pair<First, Second> &lhs, compressed_pair<First, Second> &rhs) {
  48324. lhs.swap(rhs);
  48325. }
  48326. } // namespace entt
  48327. // disable structured binding support for clang 6, it messes when specializing tuple_size
  48328. #if !defined __clang_major__ || __clang_major__ > 6
  48329. namespace std {
  48330. /**
  48331. * @brief `std::tuple_size` specialization for `compressed_pair`s.
  48332. * @tparam First The type of the first element that the pair stores.
  48333. * @tparam Second The type of the second element that the pair stores.
  48334. */
  48335. template<typename First, typename Second>
  48336. struct tuple_size<entt::compressed_pair<First, Second>>: integral_constant<size_t, 2u> {};
  48337. /**
  48338. * @brief `std::tuple_element` specialization for `compressed_pair`s.
  48339. * @tparam Index The index of the type to return.
  48340. * @tparam First The type of the first element that the pair stores.
  48341. * @tparam Second The type of the second element that the pair stores.
  48342. */
  48343. template<size_t Index, typename First, typename Second>
  48344. struct tuple_element<Index, entt::compressed_pair<First, Second>>: conditional<Index == 0u, First, Second> {
  48345. static_assert(Index < 2u, "Index out of bounds");
  48346. };
  48347. } // namespace std
  48348. #endif
  48349. #endif
  48350. // #include "../core/fwd.hpp"
  48351. #ifndef ENTT_CORE_FWD_HPP
  48352. #define ENTT_CORE_FWD_HPP
  48353. #include <cstdint>
  48354. #include <type_traits>
  48355. // #include "../config/config.h"
  48356. namespace entt {
  48357. template<std::size_t Len = sizeof(double[2]), std::size_t = alignof(typename std::aligned_storage_t<Len + !Len>)>
  48358. class basic_any;
  48359. /*! @brief Alias declaration for type identifiers. */
  48360. using id_type = ENTT_ID_TYPE;
  48361. /*! @brief Alias declaration for the most common use case. */
  48362. using any = basic_any<>;
  48363. } // namespace entt
  48364. #endif
  48365. // #include "../core/iterator.hpp"
  48366. #ifndef ENTT_CORE_ITERATOR_HPP
  48367. #define ENTT_CORE_ITERATOR_HPP
  48368. #include <iterator>
  48369. #include <memory>
  48370. #include <utility>
  48371. // #include "../config/config.h"
  48372. namespace entt {
  48373. /**
  48374. * @brief Helper type to use as pointer with input iterators.
  48375. * @tparam Type of wrapped value.
  48376. */
  48377. template<typename Type>
  48378. struct input_iterator_pointer final {
  48379. /*! @brief Pointer type. */
  48380. using pointer = Type *;
  48381. /*! @brief Default copy constructor, deleted on purpose. */
  48382. input_iterator_pointer(const input_iterator_pointer &) = delete;
  48383. /*! @brief Default move constructor. */
  48384. input_iterator_pointer(input_iterator_pointer &&) = default;
  48385. /**
  48386. * @brief Constructs a proxy object by move.
  48387. * @param val Value to use to initialize the proxy object.
  48388. */
  48389. input_iterator_pointer(Type &&val)
  48390. : value{std::move(val)} {}
  48391. /**
  48392. * @brief Default copy assignment operator, deleted on purpose.
  48393. * @return This proxy object.
  48394. */
  48395. input_iterator_pointer &operator=(const input_iterator_pointer &) = delete;
  48396. /**
  48397. * @brief Default move assignment operator.
  48398. * @return This proxy object.
  48399. */
  48400. input_iterator_pointer &operator=(input_iterator_pointer &&) = default;
  48401. /**
  48402. * @brief Access operator for accessing wrapped values.
  48403. * @return A pointer to the wrapped value.
  48404. */
  48405. [[nodiscard]] pointer operator->() ENTT_NOEXCEPT {
  48406. return std::addressof(value);
  48407. }
  48408. private:
  48409. Type value;
  48410. };
  48411. /**
  48412. * @brief Utility class to create an iterable object from a pair of iterators.
  48413. * @tparam It Type of iterator.
  48414. * @tparam Sentinel Type of sentinel.
  48415. */
  48416. template<typename It, typename Sentinel = It>
  48417. struct iterable_adaptor final {
  48418. /*! @brief Value type. */
  48419. using value_type = typename std::iterator_traits<It>::value_type;
  48420. /*! @brief Iterator type. */
  48421. using iterator = It;
  48422. /*! @brief Sentinel type. */
  48423. using sentinel = Sentinel;
  48424. /*! @brief Default constructor. */
  48425. iterable_adaptor() = default;
  48426. /**
  48427. * @brief Creates an iterable object from a pair of iterators.
  48428. * @param from Begin iterator.
  48429. * @param to End iterator.
  48430. */
  48431. iterable_adaptor(iterator from, sentinel to)
  48432. : first{from},
  48433. last{to} {}
  48434. /**
  48435. * @brief Returns an iterator to the beginning.
  48436. * @return An iterator to the first element of the range.
  48437. */
  48438. [[nodiscard]] iterator begin() const ENTT_NOEXCEPT {
  48439. return first;
  48440. }
  48441. /**
  48442. * @brief Returns an iterator to the end.
  48443. * @return An iterator to the element following the last element of the
  48444. * range.
  48445. */
  48446. [[nodiscard]] sentinel end() const ENTT_NOEXCEPT {
  48447. return last;
  48448. }
  48449. /*! @copydoc begin */
  48450. [[nodiscard]] iterator cbegin() const ENTT_NOEXCEPT {
  48451. return begin();
  48452. }
  48453. /*! @copydoc end */
  48454. [[nodiscard]] sentinel cend() const ENTT_NOEXCEPT {
  48455. return end();
  48456. }
  48457. private:
  48458. It first;
  48459. Sentinel last;
  48460. };
  48461. } // namespace entt
  48462. #endif
  48463. // #include "../core/utility.hpp"
  48464. #ifndef ENTT_CORE_UTILITY_HPP
  48465. #define ENTT_CORE_UTILITY_HPP
  48466. #include <utility>
  48467. // #include "../config/config.h"
  48468. namespace entt {
  48469. /*! @brief Identity function object (waiting for C++20). */
  48470. struct identity {
  48471. /*! @brief Indicates that this is a transparent function object. */
  48472. using is_transparent = void;
  48473. /**
  48474. * @brief Returns its argument unchanged.
  48475. * @tparam Type Type of the argument.
  48476. * @param value The actual argument.
  48477. * @return The submitted value as-is.
  48478. */
  48479. template<class Type>
  48480. [[nodiscard]] constexpr Type &&operator()(Type &&value) const ENTT_NOEXCEPT {
  48481. return std::forward<Type>(value);
  48482. }
  48483. };
  48484. /**
  48485. * @brief Constant utility to disambiguate overloaded members of a class.
  48486. * @tparam Type Type of the desired overload.
  48487. * @tparam Class Type of class to which the member belongs.
  48488. * @param member A valid pointer to a member.
  48489. * @return Pointer to the member.
  48490. */
  48491. template<typename Type, typename Class>
  48492. [[nodiscard]] constexpr auto overload(Type Class::*member) ENTT_NOEXCEPT {
  48493. return member;
  48494. }
  48495. /**
  48496. * @brief Constant utility to disambiguate overloaded functions.
  48497. * @tparam Func Function type of the desired overload.
  48498. * @param func A valid pointer to a function.
  48499. * @return Pointer to the function.
  48500. */
  48501. template<typename Func>
  48502. [[nodiscard]] constexpr auto overload(Func *func) ENTT_NOEXCEPT {
  48503. return func;
  48504. }
  48505. /**
  48506. * @brief Helper type for visitors.
  48507. * @tparam Func Types of function objects.
  48508. */
  48509. template<class... Func>
  48510. struct overloaded: Func... {
  48511. using Func::operator()...;
  48512. };
  48513. /**
  48514. * @brief Deduction guide.
  48515. * @tparam Func Types of function objects.
  48516. */
  48517. template<class... Func>
  48518. overloaded(Func...) -> overloaded<Func...>;
  48519. /**
  48520. * @brief Basic implementation of a y-combinator.
  48521. * @tparam Func Type of a potentially recursive function.
  48522. */
  48523. template<class Func>
  48524. struct y_combinator {
  48525. /**
  48526. * @brief Constructs a y-combinator from a given function.
  48527. * @param recursive A potentially recursive function.
  48528. */
  48529. y_combinator(Func recursive)
  48530. : func{std::move(recursive)} {}
  48531. /**
  48532. * @brief Invokes a y-combinator and therefore its underlying function.
  48533. * @tparam Args Types of arguments to use to invoke the underlying function.
  48534. * @param args Parameters to use to invoke the underlying function.
  48535. * @return Return value of the underlying function, if any.
  48536. */
  48537. template<class... Args>
  48538. decltype(auto) operator()(Args &&...args) const {
  48539. return func(*this, std::forward<Args>(args)...);
  48540. }
  48541. /*! @copydoc operator()() */
  48542. template<class... Args>
  48543. decltype(auto) operator()(Args &&...args) {
  48544. return func(*this, std::forward<Args>(args)...);
  48545. }
  48546. private:
  48547. Func func;
  48548. };
  48549. } // namespace entt
  48550. #endif
  48551. // #include "fwd.hpp"
  48552. #ifndef ENTT_RESOURCE_FWD_HPP
  48553. #define ENTT_RESOURCE_FWD_HPP
  48554. #include <memory>
  48555. namespace entt {
  48556. template<typename>
  48557. struct resource_loader;
  48558. template<typename Type, typename = resource_loader<Type>, typename = std::allocator<Type>>
  48559. class resource_cache;
  48560. template<typename>
  48561. class resource;
  48562. } // namespace entt
  48563. #endif
  48564. // #include "loader.hpp"
  48565. #ifndef ENTT_RESOURCE_LOADEr_HPP
  48566. #define ENTT_RESOURCE_LOADEr_HPP
  48567. #include <memory>
  48568. #include <utility>
  48569. // #include "fwd.hpp"
  48570. namespace entt {
  48571. /**
  48572. * @brief Transparent loader for shared resources.
  48573. * @tparam Type Type of resources created by the loader.
  48574. */
  48575. template<typename Type>
  48576. struct resource_loader {
  48577. /*! @brief Result type. */
  48578. using result_type = std::shared_ptr<Type>;
  48579. /**
  48580. * @brief Constructs a shared pointer to a resource from its arguments.
  48581. * @tparam Args Types of arguments to use to construct the resource.
  48582. * @param args Parameters to use to construct the resource.
  48583. * @return A shared pointer to a resource of the given type.
  48584. */
  48585. template<typename... Args>
  48586. result_type operator()(Args &&...args) const {
  48587. return std::make_shared<Type>(std::forward<Args>(args)...);
  48588. }
  48589. };
  48590. } // namespace entt
  48591. #endif
  48592. // #include "resource.hpp"
  48593. #ifndef ENTT_RESOURCE_RESOURCE_HPP
  48594. #define ENTT_RESOURCE_RESOURCE_HPP
  48595. #include <memory>
  48596. #include <type_traits>
  48597. #include <utility>
  48598. // #include "../config/config.h"
  48599. // #include "fwd.hpp"
  48600. namespace entt {
  48601. /**
  48602. * @brief Basic resource handle.
  48603. *
  48604. * A handle wraps a resource and extends its lifetime. It also shares the same
  48605. * resource with all other handles constructed from the same element.<br/>
  48606. * As a rule of thumb, resources should never be copied nor moved. Handles are
  48607. * the way to go to push references around.
  48608. *
  48609. * @tparam Type Type of resource managed by a handle.
  48610. */
  48611. template<typename Type>
  48612. class resource {
  48613. /*! @brief Resource handles are friends with each other. */
  48614. template<typename>
  48615. friend class resource;
  48616. template<typename Other>
  48617. static constexpr bool is_acceptable_v = !std::is_same_v<Type, Other> && std::is_constructible_v<Type &, Other &>;
  48618. public:
  48619. /*! @brief Default constructor. */
  48620. resource() ENTT_NOEXCEPT
  48621. : value{} {}
  48622. /**
  48623. * @brief Creates a handle from a weak pointer, namely a resource.
  48624. * @param res A weak pointer to a resource.
  48625. */
  48626. explicit resource(std::shared_ptr<Type> res) ENTT_NOEXCEPT
  48627. : value{std::move(res)} {}
  48628. /*! @brief Default copy constructor. */
  48629. resource(const resource &) ENTT_NOEXCEPT = default;
  48630. /*! @brief Default move constructor. */
  48631. resource(resource &&) ENTT_NOEXCEPT = default;
  48632. /**
  48633. * @brief Aliasing constructor.
  48634. * @tparam Other Type of resource managed by the received handle.
  48635. * @param other The handle with which to share ownership information.
  48636. * @param res Unrelated and unmanaged resources.
  48637. */
  48638. template<typename Other>
  48639. resource(const resource<Other> &other, Type &res) ENTT_NOEXCEPT
  48640. : value{other.value, std::addressof(res)} {}
  48641. /**
  48642. * @brief Copy constructs a handle which shares ownership of the resource.
  48643. * @tparam Other Type of resource managed by the received handle.
  48644. * @param other The handle to copy from.
  48645. */
  48646. template<typename Other, typename = std::enable_if_t<is_acceptable_v<Other>>>
  48647. resource(const resource<Other> &other) ENTT_NOEXCEPT
  48648. : value{other.value} {}
  48649. /**
  48650. * @brief Move constructs a handle which takes ownership of the resource.
  48651. * @tparam Other Type of resource managed by the received handle.
  48652. * @param other The handle to move from.
  48653. */
  48654. template<typename Other, typename = std::enable_if_t<is_acceptable_v<Other>>>
  48655. resource(resource<Other> &&other) ENTT_NOEXCEPT
  48656. : value{std::move(other.value)} {}
  48657. /**
  48658. * @brief Default copy assignment operator.
  48659. * @return This resource handle.
  48660. */
  48661. resource &operator=(const resource &) ENTT_NOEXCEPT = default;
  48662. /**
  48663. * @brief Default move assignment operator.
  48664. * @return This resource handle.
  48665. */
  48666. resource &operator=(resource &&) ENTT_NOEXCEPT = default;
  48667. /**
  48668. * @brief Copy assignment operator from foreign handle.
  48669. * @tparam Other Type of resource managed by the received handle.
  48670. * @param other The handle to copy from.
  48671. * @return This resource handle.
  48672. */
  48673. template<typename Other>
  48674. std::enable_if_t<is_acceptable_v<Other>, resource &>
  48675. operator=(const resource<Other> &other) ENTT_NOEXCEPT {
  48676. value = other.value;
  48677. return *this;
  48678. }
  48679. /**
  48680. * @brief Move assignment operator from foreign handle.
  48681. * @tparam Other Type of resource managed by the received handle.
  48682. * @param other The handle to move from.
  48683. * @return This resource handle.
  48684. */
  48685. template<typename Other>
  48686. std::enable_if_t<is_acceptable_v<Other>, resource &>
  48687. operator=(resource<Other> &&other) ENTT_NOEXCEPT {
  48688. value = std::move(other.value);
  48689. return *this;
  48690. }
  48691. /**
  48692. * @brief Returns a reference to the managed resource.
  48693. *
  48694. * @warning
  48695. * The behavior is undefined if the handle doesn't contain a resource.
  48696. *
  48697. * @return A reference to the managed resource.
  48698. */
  48699. [[nodiscard]] Type &operator*() const ENTT_NOEXCEPT {
  48700. return *value;
  48701. }
  48702. /*! @copydoc operator* */
  48703. [[nodiscard]] operator Type &() const ENTT_NOEXCEPT {
  48704. return *value;
  48705. }
  48706. /**
  48707. * @brief Returns a pointer to the managed resource.
  48708. * @return A pointer to the managed resource.
  48709. */
  48710. [[nodiscard]] Type *operator->() const ENTT_NOEXCEPT {
  48711. return value.get();
  48712. }
  48713. /**
  48714. * @brief Returns true if a handle contains a resource, false otherwise.
  48715. * @return True if the handle contains a resource, false otherwise.
  48716. */
  48717. [[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
  48718. return static_cast<bool>(value);
  48719. }
  48720. /**
  48721. * @brief Returns the number of handles pointing the same resource.
  48722. * @return The number of handles pointing the same resource.
  48723. */
  48724. [[nodiscard]] long use_count() const ENTT_NOEXCEPT {
  48725. return value.use_count();
  48726. }
  48727. private:
  48728. std::shared_ptr<Type> value;
  48729. };
  48730. /**
  48731. * @brief Compares two handles.
  48732. * @tparam Res Type of resource managed by the first handle.
  48733. * @tparam Other Type of resource managed by the second handle.
  48734. * @param lhs A valid handle.
  48735. * @param rhs A valid handle.
  48736. * @return True if both handles refer to the same resource, false otherwise.
  48737. */
  48738. template<typename Res, typename Other>
  48739. [[nodiscard]] bool operator==(const resource<Res> &lhs, const resource<Other> &rhs) ENTT_NOEXCEPT {
  48740. return (std::addressof(*lhs) == std::addressof(*rhs));
  48741. }
  48742. /**
  48743. * @brief Compares two handles.
  48744. * @tparam Res Type of resource managed by the first handle.
  48745. * @tparam Other Type of resource managed by the second handle.
  48746. * @param lhs A valid handle.
  48747. * @param rhs A valid handle.
  48748. * @return False if both handles refer to the same registry, true otherwise.
  48749. */
  48750. template<typename Res, typename Other>
  48751. [[nodiscard]] bool operator!=(const resource<Res> &lhs, const resource<Other> &rhs) ENTT_NOEXCEPT {
  48752. return !(lhs == rhs);
  48753. }
  48754. /**
  48755. * @brief Compares two handles.
  48756. * @tparam Res Type of resource managed by the first handle.
  48757. * @tparam Other Type of resource managed by the second handle.
  48758. * @param lhs A valid handle.
  48759. * @param rhs A valid handle.
  48760. * @return True if the first handle is less than the second, false otherwise.
  48761. */
  48762. template<typename Res, typename Other>
  48763. [[nodiscard]] bool operator<(const resource<Res> &lhs, const resource<Other> &rhs) ENTT_NOEXCEPT {
  48764. return (std::addressof(*lhs) < std::addressof(*rhs));
  48765. }
  48766. /**
  48767. * @brief Compares two handles.
  48768. * @tparam Res Type of resource managed by the first handle.
  48769. * @tparam Other Type of resource managed by the second handle.
  48770. * @param lhs A valid handle.
  48771. * @param rhs A valid handle.
  48772. * @return True if the first handle is greater than the second, false otherwise.
  48773. */
  48774. template<typename Res, typename Other>
  48775. [[nodiscard]] bool operator>(const resource<Res> &lhs, const resource<Other> &rhs) ENTT_NOEXCEPT {
  48776. return (std::addressof(*lhs) > std::addressof(*rhs));
  48777. }
  48778. /**
  48779. * @brief Compares two handles.
  48780. * @tparam Res Type of resource managed by the first handle.
  48781. * @tparam Other Type of resource managed by the second handle.
  48782. * @param lhs A valid handle.
  48783. * @param rhs A valid handle.
  48784. * @return True if the first handle is less than or equal to the second, false
  48785. * otherwise.
  48786. */
  48787. template<typename Res, typename Other>
  48788. [[nodiscard]] bool operator<=(const resource<Res> &lhs, const resource<Other> &rhs) ENTT_NOEXCEPT {
  48789. return !(lhs > rhs);
  48790. }
  48791. /**
  48792. * @brief Compares two handles.
  48793. * @tparam Res Type of resource managed by the first handle.
  48794. * @tparam Other Type of resource managed by the second handle.
  48795. * @param lhs A valid handle.
  48796. * @param rhs A valid handle.
  48797. * @return True if the first handle is greater than or equal to the second,
  48798. * false otherwise.
  48799. */
  48800. template<typename Res, typename Other>
  48801. [[nodiscard]] bool operator>=(const resource<Res> &lhs, const resource<Other> &rhs) ENTT_NOEXCEPT {
  48802. return !(lhs < rhs);
  48803. }
  48804. } // namespace entt
  48805. #endif
  48806. namespace entt {
  48807. /**
  48808. * @cond TURN_OFF_DOXYGEN
  48809. * Internal details not to be documented.
  48810. */
  48811. namespace internal {
  48812. template<typename Type, typename It>
  48813. class resource_cache_iterator final {
  48814. template<typename, typename>
  48815. friend class resource_cache_iterator;
  48816. public:
  48817. using value_type = std::pair<id_type, resource<Type>>;
  48818. using pointer = input_iterator_pointer<value_type>;
  48819. using reference = value_type;
  48820. using difference_type = std::ptrdiff_t;
  48821. using iterator_category = std::input_iterator_tag;
  48822. resource_cache_iterator() ENTT_NOEXCEPT = default;
  48823. resource_cache_iterator(const It iter) ENTT_NOEXCEPT
  48824. : it{iter} {}
  48825. template<typename Other, typename = std::enable_if_t<!std::is_same_v<It, Other> && std::is_constructible_v<It, Other>>>
  48826. resource_cache_iterator(const resource_cache_iterator<std::remove_const_t<Type>, Other> &other) ENTT_NOEXCEPT
  48827. : it{other.it} {}
  48828. resource_cache_iterator &operator++() ENTT_NOEXCEPT {
  48829. return ++it, *this;
  48830. }
  48831. resource_cache_iterator operator++(int) ENTT_NOEXCEPT {
  48832. resource_cache_iterator orig = *this;
  48833. return ++(*this), orig;
  48834. }
  48835. resource_cache_iterator &operator--() ENTT_NOEXCEPT {
  48836. return --it, *this;
  48837. }
  48838. resource_cache_iterator operator--(int) ENTT_NOEXCEPT {
  48839. resource_cache_iterator orig = *this;
  48840. return operator--(), orig;
  48841. }
  48842. resource_cache_iterator &operator+=(const difference_type value) ENTT_NOEXCEPT {
  48843. it += value;
  48844. return *this;
  48845. }
  48846. resource_cache_iterator operator+(const difference_type value) const ENTT_NOEXCEPT {
  48847. resource_cache_iterator copy = *this;
  48848. return (copy += value);
  48849. }
  48850. resource_cache_iterator &operator-=(const difference_type value) ENTT_NOEXCEPT {
  48851. return (*this += -value);
  48852. }
  48853. resource_cache_iterator operator-(const difference_type value) const ENTT_NOEXCEPT {
  48854. return (*this + -value);
  48855. }
  48856. [[nodiscard]] reference operator[](const difference_type value) const ENTT_NOEXCEPT {
  48857. return {it[value].first, resource<Type>{it[value].second}};
  48858. }
  48859. [[nodiscard]] reference operator*() const ENTT_NOEXCEPT {
  48860. return (*this)[0];
  48861. }
  48862. [[nodiscard]] pointer operator->() const ENTT_NOEXCEPT {
  48863. return operator*();
  48864. }
  48865. template<typename TLhs, typename ILhs, typename TRhs, typename IRhs>
  48866. friend std::ptrdiff_t operator-(const resource_cache_iterator<TLhs, ILhs> &, const resource_cache_iterator<TRhs, IRhs> &) ENTT_NOEXCEPT;
  48867. template<typename TLhs, typename ILhs, typename TRhs, typename IRhs>
  48868. friend bool operator==(const resource_cache_iterator<TLhs, ILhs> &, const resource_cache_iterator<TRhs, IRhs> &) ENTT_NOEXCEPT;
  48869. template<typename TLhs, typename ILhs, typename TRhs, typename IRhs>
  48870. friend bool operator<(const resource_cache_iterator<TLhs, ILhs> &, const resource_cache_iterator<TRhs, IRhs> &) ENTT_NOEXCEPT;
  48871. private:
  48872. It it;
  48873. };
  48874. template<typename TLhs, typename ILhs, typename TRhs, typename IRhs>
  48875. [[nodiscard]] std::ptrdiff_t operator-(const resource_cache_iterator<TLhs, ILhs> &lhs, const resource_cache_iterator<TRhs, IRhs> &rhs) ENTT_NOEXCEPT {
  48876. return lhs.it - rhs.it;
  48877. }
  48878. template<typename TLhs, typename ILhs, typename TRhs, typename IRhs>
  48879. [[nodiscard]] bool operator==(const resource_cache_iterator<TLhs, ILhs> &lhs, const resource_cache_iterator<TRhs, IRhs> &rhs) ENTT_NOEXCEPT {
  48880. return lhs.it == rhs.it;
  48881. }
  48882. template<typename TLhs, typename ILhs, typename TRhs, typename IRhs>
  48883. [[nodiscard]] bool operator!=(const resource_cache_iterator<TLhs, ILhs> &lhs, const resource_cache_iterator<TRhs, IRhs> &rhs) ENTT_NOEXCEPT {
  48884. return !(lhs == rhs);
  48885. }
  48886. template<typename TLhs, typename ILhs, typename TRhs, typename IRhs>
  48887. [[nodiscard]] bool operator<(const resource_cache_iterator<TLhs, ILhs> &lhs, const resource_cache_iterator<TRhs, IRhs> &rhs) ENTT_NOEXCEPT {
  48888. return lhs.it < rhs.it;
  48889. }
  48890. template<typename TLhs, typename ILhs, typename TRhs, typename IRhs>
  48891. [[nodiscard]] bool operator>(const resource_cache_iterator<TLhs, ILhs> &lhs, const resource_cache_iterator<TRhs, IRhs> &rhs) ENTT_NOEXCEPT {
  48892. return rhs < lhs;
  48893. }
  48894. template<typename TLhs, typename ILhs, typename TRhs, typename IRhs>
  48895. [[nodiscard]] bool operator<=(const resource_cache_iterator<TLhs, ILhs> &lhs, const resource_cache_iterator<TRhs, IRhs> &rhs) ENTT_NOEXCEPT {
  48896. return !(lhs > rhs);
  48897. }
  48898. template<typename TLhs, typename ILhs, typename TRhs, typename IRhs>
  48899. [[nodiscard]] bool operator>=(const resource_cache_iterator<TLhs, ILhs> &lhs, const resource_cache_iterator<TRhs, IRhs> &rhs) ENTT_NOEXCEPT {
  48900. return !(lhs < rhs);
  48901. }
  48902. } // namespace internal
  48903. /**
  48904. * Internal details not to be documented.
  48905. * @endcond
  48906. */
  48907. /**
  48908. * @brief Basic cache for resources of any type.
  48909. * @tparam Type Type of resources managed by a cache.
  48910. * @tparam Loader Type of loader used to create the resources.
  48911. * @tparam Allocator Type of allocator used to manage memory and elements.
  48912. */
  48913. template<typename Type, typename Loader, typename Allocator>
  48914. class resource_cache {
  48915. using alloc_traits = typename std::allocator_traits<Allocator>;
  48916. static_assert(std::is_same_v<typename alloc_traits::value_type, Type>, "Invalid value type");
  48917. using container_allocator = typename alloc_traits::template rebind_alloc<std::pair<const id_type, typename Loader::result_type>>;
  48918. using container_type = dense_map<id_type, typename Loader::result_type, identity, std::equal_to<id_type>, container_allocator>;
  48919. public:
  48920. /*! @brief Resource type. */
  48921. using value_type = Type;
  48922. /*! @brief Unsigned integer type. */
  48923. using size_type = std::size_t;
  48924. /*! @brief Loader type. */
  48925. using loader_type = Loader;
  48926. /*! @brief Allocator type. */
  48927. using allocator_type = Allocator;
  48928. /*! @brief Input iterator type. */
  48929. using iterator = internal::resource_cache_iterator<Type, typename container_type::iterator>;
  48930. /*! @brief Constant input iterator type. */
  48931. using const_iterator = internal::resource_cache_iterator<const Type, typename container_type::const_iterator>;
  48932. /*! @brief Default constructor. */
  48933. resource_cache()
  48934. : resource_cache{loader_type{}} {}
  48935. /**
  48936. * @brief Constructs an empty cache with a given allocator.
  48937. * @param allocator The allocator to use.
  48938. */
  48939. explicit resource_cache(const allocator_type &allocator)
  48940. : resource_cache{loader_type{}, allocator} {}
  48941. /**
  48942. * @brief Constructs an empty cache with a given allocator and loader.
  48943. * @param callable The loader to use.
  48944. * @param allocator The allocator to use.
  48945. */
  48946. explicit resource_cache(const loader_type &callable, const allocator_type &allocator = allocator_type{})
  48947. : pool{container_type{allocator}, callable} {}
  48948. /*! @brief Default copy constructor. */
  48949. resource_cache(const resource_cache &) = default;
  48950. /**
  48951. * @brief Allocator-extended copy constructor.
  48952. * @param other The instance to copy from.
  48953. * @param allocator The allocator to use.
  48954. */
  48955. resource_cache(const resource_cache &other, const allocator_type &allocator)
  48956. : pool{std::piecewise_construct, std::forward_as_tuple(other.pool.first(), allocator), std::forward_as_tuple(other.pool.second())} {}
  48957. /*! @brief Default move constructor. */
  48958. resource_cache(resource_cache &&) = default;
  48959. /**
  48960. * @brief Allocator-extended move constructor.
  48961. * @param other The instance to move from.
  48962. * @param allocator The allocator to use.
  48963. */
  48964. resource_cache(resource_cache &&other, const allocator_type &allocator)
  48965. : pool{std::piecewise_construct, std::forward_as_tuple(std::move(other.pool.first()), allocator), std::forward_as_tuple(std::move(other.pool.second()))} {}
  48966. /**
  48967. * @brief Default copy assignment operator.
  48968. * @return This cache.
  48969. */
  48970. resource_cache &operator=(const resource_cache &) = default;
  48971. /**
  48972. * @brief Default move assignment operator.
  48973. * @return This cache.
  48974. */
  48975. resource_cache &operator=(resource_cache &&) = default;
  48976. /**
  48977. * @brief Returns the associated allocator.
  48978. * @return The associated allocator.
  48979. */
  48980. [[nodiscard]] constexpr allocator_type get_allocator() const ENTT_NOEXCEPT {
  48981. return pool.first().get_allocator();
  48982. }
  48983. /**
  48984. * @brief Returns an iterator to the beginning.
  48985. *
  48986. * The returned iterator points to the first instance of the cache. If the
  48987. * cache is empty, the returned iterator will be equal to `end()`.
  48988. *
  48989. * @return An iterator to the first instance of the internal cache.
  48990. */
  48991. [[nodiscard]] const_iterator cbegin() const ENTT_NOEXCEPT {
  48992. return pool.first().begin();
  48993. }
  48994. /*! @copydoc cbegin */
  48995. [[nodiscard]] const_iterator begin() const ENTT_NOEXCEPT {
  48996. return cbegin();
  48997. }
  48998. /*! @copydoc begin */
  48999. [[nodiscard]] iterator begin() ENTT_NOEXCEPT {
  49000. return pool.first().begin();
  49001. }
  49002. /**
  49003. * @brief Returns an iterator to the end.
  49004. *
  49005. * The returned iterator points to the element following the last instance
  49006. * of the cache. Attempting to dereference the returned iterator results in
  49007. * undefined behavior.
  49008. *
  49009. * @return An iterator to the element following the last instance of the
  49010. * internal cache.
  49011. */
  49012. [[nodiscard]] const_iterator cend() const ENTT_NOEXCEPT {
  49013. return pool.first().end();
  49014. }
  49015. /*! @copydoc cend */
  49016. [[nodiscard]] const_iterator end() const ENTT_NOEXCEPT {
  49017. return cend();
  49018. }
  49019. /*! @copydoc end */
  49020. [[nodiscard]] iterator end() ENTT_NOEXCEPT {
  49021. return pool.first().end();
  49022. }
  49023. /**
  49024. * @brief Returns true if a cache contains no resources, false otherwise.
  49025. * @return True if the cache contains no resources, false otherwise.
  49026. */
  49027. [[nodiscard]] bool empty() const ENTT_NOEXCEPT {
  49028. return pool.first().empty();
  49029. }
  49030. /**
  49031. * @brief Number of resources managed by a cache.
  49032. * @return Number of resources currently stored.
  49033. */
  49034. [[nodiscard]] size_type size() const ENTT_NOEXCEPT {
  49035. return pool.first().size();
  49036. }
  49037. /*! @brief Clears a cache. */
  49038. void clear() ENTT_NOEXCEPT {
  49039. pool.first().clear();
  49040. }
  49041. /**
  49042. * @brief Loads a resource, if its identifier does not exist.
  49043. *
  49044. * Arguments are forwarded directly to the loader and _consumed_ only if the
  49045. * resource doesn't already exist.
  49046. *
  49047. * @warning
  49048. * If the resource isn't loaded correctly, the returned handle could be
  49049. * invalid and any use of it will result in undefined behavior.
  49050. *
  49051. * @tparam Args Types of arguments to use to load the resource if required.
  49052. * @param id Unique resource identifier.
  49053. * @param args Arguments to use to load the resource if required.
  49054. * @return A pair consisting of an iterator to the inserted element (or to
  49055. * the element that prevented the insertion) and a bool denoting whether the
  49056. * insertion took place.
  49057. */
  49058. template<typename... Args>
  49059. std::pair<iterator, bool> load(const id_type id, Args &&...args) {
  49060. if(auto it = pool.first().find(id); it != pool.first().end()) {
  49061. return {it, false};
  49062. }
  49063. return pool.first().emplace(id, pool.second()(std::forward<Args>(args)...));
  49064. }
  49065. /**
  49066. * @brief Force loads a resource, if its identifier does not exist.
  49067. * @copydetails load
  49068. */
  49069. template<typename... Args>
  49070. std::pair<iterator, bool> force_load(const id_type id, Args &&...args) {
  49071. return {pool.first().insert_or_assign(id, pool.second()(std::forward<Args>(args)...)).first, true};
  49072. }
  49073. /**
  49074. * @brief Returns a handle for a given resource identifier.
  49075. *
  49076. * @warning
  49077. * There is no guarantee that the returned handle is valid.<br/>
  49078. * If it is not, any use will result in indefinite behavior.
  49079. *
  49080. * @param id Unique resource identifier.
  49081. * @return A handle for the given resource.
  49082. */
  49083. [[nodiscard]] resource<const value_type> operator[](const id_type id) const {
  49084. if(auto it = pool.first().find(id); it != pool.first().cend()) {
  49085. return resource<const value_type>{it->second};
  49086. }
  49087. return {};
  49088. }
  49089. /*! @copydoc operator[] */
  49090. [[nodiscard]] resource<value_type> operator[](const id_type id) {
  49091. if(auto it = pool.first().find(id); it != pool.first().end()) {
  49092. return resource<value_type>{it->second};
  49093. }
  49094. return {};
  49095. }
  49096. /**
  49097. * @brief Checks if a cache contains a given identifier.
  49098. * @param id Unique resource identifier.
  49099. * @return True if the cache contains the resource, false otherwise.
  49100. */
  49101. [[nodiscard]] bool contains(const id_type id) const {
  49102. return pool.first().contains(id);
  49103. }
  49104. /**
  49105. * @brief Removes an element from a given position.
  49106. * @param pos An iterator to the element to remove.
  49107. * @return An iterator following the removed element.
  49108. */
  49109. iterator erase(const_iterator pos) {
  49110. const auto it = pool.first().begin();
  49111. return pool.first().erase(it + (pos - const_iterator{it}));
  49112. }
  49113. /**
  49114. * @brief Removes the given elements from a cache.
  49115. * @param first An iterator to the first element of the range of elements.
  49116. * @param last An iterator past the last element of the range of elements.
  49117. * @return An iterator following the last removed element.
  49118. */
  49119. iterator erase(const_iterator first, const_iterator last) {
  49120. const auto it = pool.first().begin();
  49121. return pool.first().erase(it + (first - const_iterator{it}), it + (last - const_iterator{it}));
  49122. }
  49123. /**
  49124. * @brief Removes the given elements from a cache.
  49125. * @param id Unique resource identifier.
  49126. * @return Number of resources erased (either 0 or 1).
  49127. */
  49128. size_type erase(const id_type id) {
  49129. return pool.first().erase(id);
  49130. }
  49131. /**
  49132. * @brief Returns the loader used to create resources.
  49133. * @return The loader used to create resources.
  49134. */
  49135. [[nodiscard]] loader_type loader() const {
  49136. return pool.second();
  49137. }
  49138. private:
  49139. compressed_pair<container_type, loader_type> pool;
  49140. };
  49141. } // namespace entt
  49142. #endif
  49143. // #include "resource/loader.hpp"
  49144. #ifndef ENTT_RESOURCE_LOADEr_HPP
  49145. #define ENTT_RESOURCE_LOADEr_HPP
  49146. #include <memory>
  49147. #include <utility>
  49148. // #include "fwd.hpp"
  49149. namespace entt {
  49150. /**
  49151. * @brief Transparent loader for shared resources.
  49152. * @tparam Type Type of resources created by the loader.
  49153. */
  49154. template<typename Type>
  49155. struct resource_loader {
  49156. /*! @brief Result type. */
  49157. using result_type = std::shared_ptr<Type>;
  49158. /**
  49159. * @brief Constructs a shared pointer to a resource from its arguments.
  49160. * @tparam Args Types of arguments to use to construct the resource.
  49161. * @param args Parameters to use to construct the resource.
  49162. * @return A shared pointer to a resource of the given type.
  49163. */
  49164. template<typename... Args>
  49165. result_type operator()(Args &&...args) const {
  49166. return std::make_shared<Type>(std::forward<Args>(args)...);
  49167. }
  49168. };
  49169. } // namespace entt
  49170. #endif
  49171. // #include "resource/resource.hpp"
  49172. #ifndef ENTT_RESOURCE_RESOURCE_HPP
  49173. #define ENTT_RESOURCE_RESOURCE_HPP
  49174. #include <memory>
  49175. #include <type_traits>
  49176. #include <utility>
  49177. // #include "../config/config.h"
  49178. // #include "fwd.hpp"
  49179. namespace entt {
  49180. /**
  49181. * @brief Basic resource handle.
  49182. *
  49183. * A handle wraps a resource and extends its lifetime. It also shares the same
  49184. * resource with all other handles constructed from the same element.<br/>
  49185. * As a rule of thumb, resources should never be copied nor moved. Handles are
  49186. * the way to go to push references around.
  49187. *
  49188. * @tparam Type Type of resource managed by a handle.
  49189. */
  49190. template<typename Type>
  49191. class resource {
  49192. /*! @brief Resource handles are friends with each other. */
  49193. template<typename>
  49194. friend class resource;
  49195. template<typename Other>
  49196. static constexpr bool is_acceptable_v = !std::is_same_v<Type, Other> && std::is_constructible_v<Type &, Other &>;
  49197. public:
  49198. /*! @brief Default constructor. */
  49199. resource() ENTT_NOEXCEPT
  49200. : value{} {}
  49201. /**
  49202. * @brief Creates a handle from a weak pointer, namely a resource.
  49203. * @param res A weak pointer to a resource.
  49204. */
  49205. explicit resource(std::shared_ptr<Type> res) ENTT_NOEXCEPT
  49206. : value{std::move(res)} {}
  49207. /*! @brief Default copy constructor. */
  49208. resource(const resource &) ENTT_NOEXCEPT = default;
  49209. /*! @brief Default move constructor. */
  49210. resource(resource &&) ENTT_NOEXCEPT = default;
  49211. /**
  49212. * @brief Aliasing constructor.
  49213. * @tparam Other Type of resource managed by the received handle.
  49214. * @param other The handle with which to share ownership information.
  49215. * @param res Unrelated and unmanaged resources.
  49216. */
  49217. template<typename Other>
  49218. resource(const resource<Other> &other, Type &res) ENTT_NOEXCEPT
  49219. : value{other.value, std::addressof(res)} {}
  49220. /**
  49221. * @brief Copy constructs a handle which shares ownership of the resource.
  49222. * @tparam Other Type of resource managed by the received handle.
  49223. * @param other The handle to copy from.
  49224. */
  49225. template<typename Other, typename = std::enable_if_t<is_acceptable_v<Other>>>
  49226. resource(const resource<Other> &other) ENTT_NOEXCEPT
  49227. : value{other.value} {}
  49228. /**
  49229. * @brief Move constructs a handle which takes ownership of the resource.
  49230. * @tparam Other Type of resource managed by the received handle.
  49231. * @param other The handle to move from.
  49232. */
  49233. template<typename Other, typename = std::enable_if_t<is_acceptable_v<Other>>>
  49234. resource(resource<Other> &&other) ENTT_NOEXCEPT
  49235. : value{std::move(other.value)} {}
  49236. /**
  49237. * @brief Default copy assignment operator.
  49238. * @return This resource handle.
  49239. */
  49240. resource &operator=(const resource &) ENTT_NOEXCEPT = default;
  49241. /**
  49242. * @brief Default move assignment operator.
  49243. * @return This resource handle.
  49244. */
  49245. resource &operator=(resource &&) ENTT_NOEXCEPT = default;
  49246. /**
  49247. * @brief Copy assignment operator from foreign handle.
  49248. * @tparam Other Type of resource managed by the received handle.
  49249. * @param other The handle to copy from.
  49250. * @return This resource handle.
  49251. */
  49252. template<typename Other>
  49253. std::enable_if_t<is_acceptable_v<Other>, resource &>
  49254. operator=(const resource<Other> &other) ENTT_NOEXCEPT {
  49255. value = other.value;
  49256. return *this;
  49257. }
  49258. /**
  49259. * @brief Move assignment operator from foreign handle.
  49260. * @tparam Other Type of resource managed by the received handle.
  49261. * @param other The handle to move from.
  49262. * @return This resource handle.
  49263. */
  49264. template<typename Other>
  49265. std::enable_if_t<is_acceptable_v<Other>, resource &>
  49266. operator=(resource<Other> &&other) ENTT_NOEXCEPT {
  49267. value = std::move(other.value);
  49268. return *this;
  49269. }
  49270. /**
  49271. * @brief Returns a reference to the managed resource.
  49272. *
  49273. * @warning
  49274. * The behavior is undefined if the handle doesn't contain a resource.
  49275. *
  49276. * @return A reference to the managed resource.
  49277. */
  49278. [[nodiscard]] Type &operator*() const ENTT_NOEXCEPT {
  49279. return *value;
  49280. }
  49281. /*! @copydoc operator* */
  49282. [[nodiscard]] operator Type &() const ENTT_NOEXCEPT {
  49283. return *value;
  49284. }
  49285. /**
  49286. * @brief Returns a pointer to the managed resource.
  49287. * @return A pointer to the managed resource.
  49288. */
  49289. [[nodiscard]] Type *operator->() const ENTT_NOEXCEPT {
  49290. return value.get();
  49291. }
  49292. /**
  49293. * @brief Returns true if a handle contains a resource, false otherwise.
  49294. * @return True if the handle contains a resource, false otherwise.
  49295. */
  49296. [[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
  49297. return static_cast<bool>(value);
  49298. }
  49299. /**
  49300. * @brief Returns the number of handles pointing the same resource.
  49301. * @return The number of handles pointing the same resource.
  49302. */
  49303. [[nodiscard]] long use_count() const ENTT_NOEXCEPT {
  49304. return value.use_count();
  49305. }
  49306. private:
  49307. std::shared_ptr<Type> value;
  49308. };
  49309. /**
  49310. * @brief Compares two handles.
  49311. * @tparam Res Type of resource managed by the first handle.
  49312. * @tparam Other Type of resource managed by the second handle.
  49313. * @param lhs A valid handle.
  49314. * @param rhs A valid handle.
  49315. * @return True if both handles refer to the same resource, false otherwise.
  49316. */
  49317. template<typename Res, typename Other>
  49318. [[nodiscard]] bool operator==(const resource<Res> &lhs, const resource<Other> &rhs) ENTT_NOEXCEPT {
  49319. return (std::addressof(*lhs) == std::addressof(*rhs));
  49320. }
  49321. /**
  49322. * @brief Compares two handles.
  49323. * @tparam Res Type of resource managed by the first handle.
  49324. * @tparam Other Type of resource managed by the second handle.
  49325. * @param lhs A valid handle.
  49326. * @param rhs A valid handle.
  49327. * @return False if both handles refer to the same registry, true otherwise.
  49328. */
  49329. template<typename Res, typename Other>
  49330. [[nodiscard]] bool operator!=(const resource<Res> &lhs, const resource<Other> &rhs) ENTT_NOEXCEPT {
  49331. return !(lhs == rhs);
  49332. }
  49333. /**
  49334. * @brief Compares two handles.
  49335. * @tparam Res Type of resource managed by the first handle.
  49336. * @tparam Other Type of resource managed by the second handle.
  49337. * @param lhs A valid handle.
  49338. * @param rhs A valid handle.
  49339. * @return True if the first handle is less than the second, false otherwise.
  49340. */
  49341. template<typename Res, typename Other>
  49342. [[nodiscard]] bool operator<(const resource<Res> &lhs, const resource<Other> &rhs) ENTT_NOEXCEPT {
  49343. return (std::addressof(*lhs) < std::addressof(*rhs));
  49344. }
  49345. /**
  49346. * @brief Compares two handles.
  49347. * @tparam Res Type of resource managed by the first handle.
  49348. * @tparam Other Type of resource managed by the second handle.
  49349. * @param lhs A valid handle.
  49350. * @param rhs A valid handle.
  49351. * @return True if the first handle is greater than the second, false otherwise.
  49352. */
  49353. template<typename Res, typename Other>
  49354. [[nodiscard]] bool operator>(const resource<Res> &lhs, const resource<Other> &rhs) ENTT_NOEXCEPT {
  49355. return (std::addressof(*lhs) > std::addressof(*rhs));
  49356. }
  49357. /**
  49358. * @brief Compares two handles.
  49359. * @tparam Res Type of resource managed by the first handle.
  49360. * @tparam Other Type of resource managed by the second handle.
  49361. * @param lhs A valid handle.
  49362. * @param rhs A valid handle.
  49363. * @return True if the first handle is less than or equal to the second, false
  49364. * otherwise.
  49365. */
  49366. template<typename Res, typename Other>
  49367. [[nodiscard]] bool operator<=(const resource<Res> &lhs, const resource<Other> &rhs) ENTT_NOEXCEPT {
  49368. return !(lhs > rhs);
  49369. }
  49370. /**
  49371. * @brief Compares two handles.
  49372. * @tparam Res Type of resource managed by the first handle.
  49373. * @tparam Other Type of resource managed by the second handle.
  49374. * @param lhs A valid handle.
  49375. * @param rhs A valid handle.
  49376. * @return True if the first handle is greater than or equal to the second,
  49377. * false otherwise.
  49378. */
  49379. template<typename Res, typename Other>
  49380. [[nodiscard]] bool operator>=(const resource<Res> &lhs, const resource<Other> &rhs) ENTT_NOEXCEPT {
  49381. return !(lhs < rhs);
  49382. }
  49383. } // namespace entt
  49384. #endif
  49385. // #include "signal/delegate.hpp"
  49386. #ifndef ENTT_SIGNAL_DELEGATE_HPP
  49387. #define ENTT_SIGNAL_DELEGATE_HPP
  49388. #include <cstddef>
  49389. #include <functional>
  49390. #include <tuple>
  49391. #include <type_traits>
  49392. #include <utility>
  49393. // #include "../config/config.h"
  49394. #ifndef ENTT_CONFIG_CONFIG_H
  49395. #define ENTT_CONFIG_CONFIG_H
  49396. // #include "version.h"
  49397. #ifndef ENTT_CONFIG_VERSION_H
  49398. #define ENTT_CONFIG_VERSION_H
  49399. // #include "macro.h"
  49400. #ifndef ENTT_CONFIG_MACRO_H
  49401. #define ENTT_CONFIG_MACRO_H
  49402. #define ENTT_STR(arg) #arg
  49403. #define ENTT_XSTR(arg) ENTT_STR(arg)
  49404. #endif
  49405. #define ENTT_VERSION_MAJOR 3
  49406. #define ENTT_VERSION_MINOR 10
  49407. #define ENTT_VERSION_PATCH 3
  49408. #define ENTT_VERSION \
  49409. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  49410. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  49411. #endif
  49412. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  49413. # define ENTT_THROW throw
  49414. # define ENTT_TRY try
  49415. # define ENTT_CATCH catch(...)
  49416. #else
  49417. # define ENTT_THROW
  49418. # define ENTT_TRY if(true)
  49419. # define ENTT_CATCH if(false)
  49420. #endif
  49421. #ifndef ENTT_NOEXCEPT
  49422. # define ENTT_NOEXCEPT noexcept
  49423. # define ENTT_NOEXCEPT_IF(expr) noexcept(expr)
  49424. # else
  49425. # define ENTT_NOEXCEPT_IF(...)
  49426. #endif
  49427. #ifdef ENTT_USE_ATOMIC
  49428. # include <atomic>
  49429. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  49430. #else
  49431. # define ENTT_MAYBE_ATOMIC(Type) Type
  49432. #endif
  49433. #ifndef ENTT_ID_TYPE
  49434. # include <cstdint>
  49435. # define ENTT_ID_TYPE std::uint32_t
  49436. #endif
  49437. #ifndef ENTT_SPARSE_PAGE
  49438. # define ENTT_SPARSE_PAGE 4096
  49439. #endif
  49440. #ifndef ENTT_PACKED_PAGE
  49441. # define ENTT_PACKED_PAGE 1024
  49442. #endif
  49443. #ifdef ENTT_DISABLE_ASSERT
  49444. # undef ENTT_ASSERT
  49445. # define ENTT_ASSERT(...) (void(0))
  49446. #elif !defined ENTT_ASSERT
  49447. # include <cassert>
  49448. # define ENTT_ASSERT(condition, ...) assert(condition)
  49449. #endif
  49450. #ifdef ENTT_NO_ETO
  49451. # define ENTT_IGNORE_IF_EMPTY false
  49452. #else
  49453. # define ENTT_IGNORE_IF_EMPTY true
  49454. #endif
  49455. #ifdef ENTT_STANDARD_CPP
  49456. # define ENTT_NONSTD false
  49457. #else
  49458. # define ENTT_NONSTD true
  49459. # if defined __clang__ || defined __GNUC__
  49460. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  49461. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  49462. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  49463. # elif defined _MSC_VER
  49464. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  49465. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  49466. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  49467. # endif
  49468. #endif
  49469. #if defined _MSC_VER
  49470. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  49471. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  49472. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  49473. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  49474. #endif
  49475. #endif
  49476. // #include "../core/type_traits.hpp"
  49477. #ifndef ENTT_CORE_TYPE_TRAITS_HPP
  49478. #define ENTT_CORE_TYPE_TRAITS_HPP
  49479. #include <cstddef>
  49480. #include <iterator>
  49481. #include <type_traits>
  49482. #include <utility>
  49483. // #include "../config/config.h"
  49484. #ifndef ENTT_CONFIG_CONFIG_H
  49485. #define ENTT_CONFIG_CONFIG_H
  49486. // #include "version.h"
  49487. #ifndef ENTT_CONFIG_VERSION_H
  49488. #define ENTT_CONFIG_VERSION_H
  49489. // #include "macro.h"
  49490. #ifndef ENTT_CONFIG_MACRO_H
  49491. #define ENTT_CONFIG_MACRO_H
  49492. #define ENTT_STR(arg) #arg
  49493. #define ENTT_XSTR(arg) ENTT_STR(arg)
  49494. #endif
  49495. #define ENTT_VERSION_MAJOR 3
  49496. #define ENTT_VERSION_MINOR 10
  49497. #define ENTT_VERSION_PATCH 3
  49498. #define ENTT_VERSION \
  49499. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  49500. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  49501. #endif
  49502. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  49503. # define ENTT_THROW throw
  49504. # define ENTT_TRY try
  49505. # define ENTT_CATCH catch(...)
  49506. #else
  49507. # define ENTT_THROW
  49508. # define ENTT_TRY if(true)
  49509. # define ENTT_CATCH if(false)
  49510. #endif
  49511. #ifndef ENTT_NOEXCEPT
  49512. # define ENTT_NOEXCEPT noexcept
  49513. # define ENTT_NOEXCEPT_IF(expr) noexcept(expr)
  49514. # else
  49515. # define ENTT_NOEXCEPT_IF(...)
  49516. #endif
  49517. #ifdef ENTT_USE_ATOMIC
  49518. # include <atomic>
  49519. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  49520. #else
  49521. # define ENTT_MAYBE_ATOMIC(Type) Type
  49522. #endif
  49523. #ifndef ENTT_ID_TYPE
  49524. # include <cstdint>
  49525. # define ENTT_ID_TYPE std::uint32_t
  49526. #endif
  49527. #ifndef ENTT_SPARSE_PAGE
  49528. # define ENTT_SPARSE_PAGE 4096
  49529. #endif
  49530. #ifndef ENTT_PACKED_PAGE
  49531. # define ENTT_PACKED_PAGE 1024
  49532. #endif
  49533. #ifdef ENTT_DISABLE_ASSERT
  49534. # undef ENTT_ASSERT
  49535. # define ENTT_ASSERT(...) (void(0))
  49536. #elif !defined ENTT_ASSERT
  49537. # include <cassert>
  49538. # define ENTT_ASSERT(condition, ...) assert(condition)
  49539. #endif
  49540. #ifdef ENTT_NO_ETO
  49541. # define ENTT_IGNORE_IF_EMPTY false
  49542. #else
  49543. # define ENTT_IGNORE_IF_EMPTY true
  49544. #endif
  49545. #ifdef ENTT_STANDARD_CPP
  49546. # define ENTT_NONSTD false
  49547. #else
  49548. # define ENTT_NONSTD true
  49549. # if defined __clang__ || defined __GNUC__
  49550. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  49551. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  49552. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  49553. # elif defined _MSC_VER
  49554. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  49555. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  49556. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  49557. # endif
  49558. #endif
  49559. #if defined _MSC_VER
  49560. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  49561. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  49562. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  49563. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  49564. #endif
  49565. #endif
  49566. // #include "fwd.hpp"
  49567. #ifndef ENTT_CORE_FWD_HPP
  49568. #define ENTT_CORE_FWD_HPP
  49569. #include <cstdint>
  49570. #include <type_traits>
  49571. // #include "../config/config.h"
  49572. namespace entt {
  49573. template<std::size_t Len = sizeof(double[2]), std::size_t = alignof(typename std::aligned_storage_t<Len + !Len>)>
  49574. class basic_any;
  49575. /*! @brief Alias declaration for type identifiers. */
  49576. using id_type = ENTT_ID_TYPE;
  49577. /*! @brief Alias declaration for the most common use case. */
  49578. using any = basic_any<>;
  49579. } // namespace entt
  49580. #endif
  49581. namespace entt {
  49582. /**
  49583. * @brief Utility class to disambiguate overloaded functions.
  49584. * @tparam N Number of choices available.
  49585. */
  49586. template<std::size_t N>
  49587. struct choice_t
  49588. // Unfortunately, doxygen cannot parse such a construct.
  49589. : /*! @cond TURN_OFF_DOXYGEN */ choice_t<N - 1> /*! @endcond */
  49590. {};
  49591. /*! @copybrief choice_t */
  49592. template<>
  49593. struct choice_t<0> {};
  49594. /**
  49595. * @brief Variable template for the choice trick.
  49596. * @tparam N Number of choices available.
  49597. */
  49598. template<std::size_t N>
  49599. inline constexpr choice_t<N> choice{};
  49600. /**
  49601. * @brief Identity type trait.
  49602. *
  49603. * Useful to establish non-deduced contexts in template argument deduction
  49604. * (waiting for C++20) or to provide types through function arguments.
  49605. *
  49606. * @tparam Type A type.
  49607. */
  49608. template<typename Type>
  49609. struct type_identity {
  49610. /*! @brief Identity type. */
  49611. using type = Type;
  49612. };
  49613. /**
  49614. * @brief Helper type.
  49615. * @tparam Type A type.
  49616. */
  49617. template<typename Type>
  49618. using type_identity_t = typename type_identity<Type>::type;
  49619. /**
  49620. * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains.
  49621. * @tparam Type The type of which to return the size.
  49622. * @tparam The size of the type if `sizeof` accepts it, 0 otherwise.
  49623. */
  49624. template<typename Type, typename = void>
  49625. struct size_of: std::integral_constant<std::size_t, 0u> {};
  49626. /*! @copydoc size_of */
  49627. template<typename Type>
  49628. struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
  49629. : std::integral_constant<std::size_t, sizeof(Type)> {};
  49630. /**
  49631. * @brief Helper variable template.
  49632. * @tparam Type The type of which to return the size.
  49633. */
  49634. template<typename Type>
  49635. inline constexpr std::size_t size_of_v = size_of<Type>::value;
  49636. /**
  49637. * @brief Using declaration to be used to _repeat_ the same type a number of
  49638. * times equal to the size of a given parameter pack.
  49639. * @tparam Type A type to repeat.
  49640. */
  49641. template<typename Type, typename>
  49642. using unpack_as_type = Type;
  49643. /**
  49644. * @brief Helper variable template to be used to _repeat_ the same value a
  49645. * number of times equal to the size of a given parameter pack.
  49646. * @tparam Value A value to repeat.
  49647. */
  49648. template<auto Value, typename>
  49649. inline constexpr auto unpack_as_value = Value;
  49650. /**
  49651. * @brief Wraps a static constant.
  49652. * @tparam Value A static constant.
  49653. */
  49654. template<auto Value>
  49655. using integral_constant = std::integral_constant<decltype(Value), Value>;
  49656. /**
  49657. * @brief Alias template to facilitate the creation of named values.
  49658. * @tparam Value A constant value at least convertible to `id_type`.
  49659. */
  49660. template<id_type Value>
  49661. using tag = integral_constant<Value>;
  49662. /**
  49663. * @brief A class to use to push around lists of types, nothing more.
  49664. * @tparam Type Types provided by the type list.
  49665. */
  49666. template<typename... Type>
  49667. struct type_list {
  49668. /*! @brief Type list type. */
  49669. using type = type_list;
  49670. /*! @brief Compile-time number of elements in the type list. */
  49671. static constexpr auto size = sizeof...(Type);
  49672. };
  49673. /*! @brief Primary template isn't defined on purpose. */
  49674. template<std::size_t, typename>
  49675. struct type_list_element;
  49676. /**
  49677. * @brief Provides compile-time indexed access to the types of a type list.
  49678. * @tparam Index Index of the type to return.
  49679. * @tparam Type First type provided by the type list.
  49680. * @tparam Other Other types provided by the type list.
  49681. */
  49682. template<std::size_t Index, typename Type, typename... Other>
  49683. struct type_list_element<Index, type_list<Type, Other...>>
  49684. : type_list_element<Index - 1u, type_list<Other...>> {};
  49685. /**
  49686. * @brief Provides compile-time indexed access to the types of a type list.
  49687. * @tparam Type First type provided by the type list.
  49688. * @tparam Other Other types provided by the type list.
  49689. */
  49690. template<typename Type, typename... Other>
  49691. struct type_list_element<0u, type_list<Type, Other...>> {
  49692. /*! @brief Searched type. */
  49693. using type = Type;
  49694. };
  49695. /**
  49696. * @brief Helper type.
  49697. * @tparam Index Index of the type to return.
  49698. * @tparam List Type list to search into.
  49699. */
  49700. template<std::size_t Index, typename List>
  49701. using type_list_element_t = typename type_list_element<Index, List>::type;
  49702. /**
  49703. * @brief Concatenates multiple type lists.
  49704. * @tparam Type Types provided by the first type list.
  49705. * @tparam Other Types provided by the second type list.
  49706. * @return A type list composed by the types of both the type lists.
  49707. */
  49708. template<typename... Type, typename... Other>
  49709. constexpr type_list<Type..., Other...> operator+(type_list<Type...>, type_list<Other...>) {
  49710. return {};
  49711. }
  49712. /*! @brief Primary template isn't defined on purpose. */
  49713. template<typename...>
  49714. struct type_list_cat;
  49715. /*! @brief Concatenates multiple type lists. */
  49716. template<>
  49717. struct type_list_cat<> {
  49718. /*! @brief A type list composed by the types of all the type lists. */
  49719. using type = type_list<>;
  49720. };
  49721. /**
  49722. * @brief Concatenates multiple type lists.
  49723. * @tparam Type Types provided by the first type list.
  49724. * @tparam Other Types provided by the second type list.
  49725. * @tparam List Other type lists, if any.
  49726. */
  49727. template<typename... Type, typename... Other, typename... List>
  49728. struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
  49729. /*! @brief A type list composed by the types of all the type lists. */
  49730. using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
  49731. };
  49732. /**
  49733. * @brief Concatenates multiple type lists.
  49734. * @tparam Type Types provided by the type list.
  49735. */
  49736. template<typename... Type>
  49737. struct type_list_cat<type_list<Type...>> {
  49738. /*! @brief A type list composed by the types of all the type lists. */
  49739. using type = type_list<Type...>;
  49740. };
  49741. /**
  49742. * @brief Helper type.
  49743. * @tparam List Type lists to concatenate.
  49744. */
  49745. template<typename... List>
  49746. using type_list_cat_t = typename type_list_cat<List...>::type;
  49747. /*! @brief Primary template isn't defined on purpose. */
  49748. template<typename>
  49749. struct type_list_unique;
  49750. /**
  49751. * @brief Removes duplicates types from a type list.
  49752. * @tparam Type One of the types provided by the given type list.
  49753. * @tparam Other The other types provided by the given type list.
  49754. */
  49755. template<typename Type, typename... Other>
  49756. struct type_list_unique<type_list<Type, Other...>> {
  49757. /*! @brief A type list without duplicate types. */
  49758. using type = std::conditional_t<
  49759. (std::is_same_v<Type, Other> || ...),
  49760. typename type_list_unique<type_list<Other...>>::type,
  49761. type_list_cat_t<type_list<Type>, typename type_list_unique<type_list<Other...>>::type>>;
  49762. };
  49763. /*! @brief Removes duplicates types from a type list. */
  49764. template<>
  49765. struct type_list_unique<type_list<>> {
  49766. /*! @brief A type list without duplicate types. */
  49767. using type = type_list<>;
  49768. };
  49769. /**
  49770. * @brief Helper type.
  49771. * @tparam Type A type list.
  49772. */
  49773. template<typename Type>
  49774. using type_list_unique_t = typename type_list_unique<Type>::type;
  49775. /**
  49776. * @brief Provides the member constant `value` to true if a type list contains a
  49777. * given type, false otherwise.
  49778. * @tparam List Type list.
  49779. * @tparam Type Type to look for.
  49780. */
  49781. template<typename List, typename Type>
  49782. struct type_list_contains;
  49783. /**
  49784. * @copybrief type_list_contains
  49785. * @tparam Type Types provided by the type list.
  49786. * @tparam Other Type to look for.
  49787. */
  49788. template<typename... Type, typename Other>
  49789. struct type_list_contains<type_list<Type...>, Other>: std::disjunction<std::is_same<Type, Other>...> {};
  49790. /**
  49791. * @brief Helper variable template.
  49792. * @tparam List Type list.
  49793. * @tparam Type Type to look for.
  49794. */
  49795. template<typename List, typename Type>
  49796. inline constexpr bool type_list_contains_v = type_list_contains<List, Type>::value;
  49797. /*! @brief Primary template isn't defined on purpose. */
  49798. template<typename...>
  49799. struct type_list_diff;
  49800. /**
  49801. * @brief Computes the difference between two type lists.
  49802. * @tparam Type Types provided by the first type list.
  49803. * @tparam Other Types provided by the second type list.
  49804. */
  49805. template<typename... Type, typename... Other>
  49806. struct type_list_diff<type_list<Type...>, type_list<Other...>> {
  49807. /*! @brief A type list that is the difference between the two type lists. */
  49808. using type = type_list_cat_t<std::conditional_t<type_list_contains_v<type_list<Other...>, Type>, type_list<>, type_list<Type>>...>;
  49809. };
  49810. /**
  49811. * @brief Helper type.
  49812. * @tparam List Type lists between which to compute the difference.
  49813. */
  49814. template<typename... List>
  49815. using type_list_diff_t = typename type_list_diff<List...>::type;
  49816. /**
  49817. * @brief A class to use to push around lists of constant values, nothing more.
  49818. * @tparam Value Values provided by the value list.
  49819. */
  49820. template<auto... Value>
  49821. struct value_list {
  49822. /*! @brief Value list type. */
  49823. using type = value_list;
  49824. /*! @brief Compile-time number of elements in the value list. */
  49825. static constexpr auto size = sizeof...(Value);
  49826. };
  49827. /*! @brief Primary template isn't defined on purpose. */
  49828. template<std::size_t, typename>
  49829. struct value_list_element;
  49830. /**
  49831. * @brief Provides compile-time indexed access to the values of a value list.
  49832. * @tparam Index Index of the value to return.
  49833. * @tparam Value First value provided by the value list.
  49834. * @tparam Other Other values provided by the value list.
  49835. */
  49836. template<std::size_t Index, auto Value, auto... Other>
  49837. struct value_list_element<Index, value_list<Value, Other...>>
  49838. : value_list_element<Index - 1u, value_list<Other...>> {};
  49839. /**
  49840. * @brief Provides compile-time indexed access to the types of a type list.
  49841. * @tparam Value First value provided by the value list.
  49842. * @tparam Other Other values provided by the value list.
  49843. */
  49844. template<auto Value, auto... Other>
  49845. struct value_list_element<0u, value_list<Value, Other...>> {
  49846. /*! @brief Searched value. */
  49847. static constexpr auto value = Value;
  49848. };
  49849. /**
  49850. * @brief Helper type.
  49851. * @tparam Index Index of the value to return.
  49852. * @tparam List Value list to search into.
  49853. */
  49854. template<std::size_t Index, typename List>
  49855. inline constexpr auto value_list_element_v = value_list_element<Index, List>::value;
  49856. /**
  49857. * @brief Concatenates multiple value lists.
  49858. * @tparam Value Values provided by the first value list.
  49859. * @tparam Other Values provided by the second value list.
  49860. * @return A value list composed by the values of both the value lists.
  49861. */
  49862. template<auto... Value, auto... Other>
  49863. constexpr value_list<Value..., Other...> operator+(value_list<Value...>, value_list<Other...>) {
  49864. return {};
  49865. }
  49866. /*! @brief Primary template isn't defined on purpose. */
  49867. template<typename...>
  49868. struct value_list_cat;
  49869. /*! @brief Concatenates multiple value lists. */
  49870. template<>
  49871. struct value_list_cat<> {
  49872. /*! @brief A value list composed by the values of all the value lists. */
  49873. using type = value_list<>;
  49874. };
  49875. /**
  49876. * @brief Concatenates multiple value lists.
  49877. * @tparam Value Values provided by the first value list.
  49878. * @tparam Other Values provided by the second value list.
  49879. * @tparam List Other value lists, if any.
  49880. */
  49881. template<auto... Value, auto... Other, typename... List>
  49882. struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
  49883. /*! @brief A value list composed by the values of all the value lists. */
  49884. using type = typename value_list_cat<value_list<Value..., Other...>, List...>::type;
  49885. };
  49886. /**
  49887. * @brief Concatenates multiple value lists.
  49888. * @tparam Value Values provided by the value list.
  49889. */
  49890. template<auto... Value>
  49891. struct value_list_cat<value_list<Value...>> {
  49892. /*! @brief A value list composed by the values of all the value lists. */
  49893. using type = value_list<Value...>;
  49894. };
  49895. /**
  49896. * @brief Helper type.
  49897. * @tparam List Value lists to concatenate.
  49898. */
  49899. template<typename... List>
  49900. using value_list_cat_t = typename value_list_cat<List...>::type;
  49901. /*! @brief Same as std::is_invocable, but with tuples. */
  49902. template<typename, typename>
  49903. struct is_applicable: std::false_type {};
  49904. /**
  49905. * @copybrief is_applicable
  49906. * @tparam Func A valid function type.
  49907. * @tparam Tuple Tuple-like type.
  49908. * @tparam Args The list of arguments to use to probe the function type.
  49909. */
  49910. template<typename Func, template<typename...> class Tuple, typename... Args>
  49911. struct is_applicable<Func, Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  49912. /**
  49913. * @copybrief is_applicable
  49914. * @tparam Func A valid function type.
  49915. * @tparam Tuple Tuple-like type.
  49916. * @tparam Args The list of arguments to use to probe the function type.
  49917. */
  49918. template<typename Func, template<typename...> class Tuple, typename... Args>
  49919. struct is_applicable<Func, const Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  49920. /**
  49921. * @brief Helper variable template.
  49922. * @tparam Func A valid function type.
  49923. * @tparam Args The list of arguments to use to probe the function type.
  49924. */
  49925. template<typename Func, typename Args>
  49926. inline constexpr bool is_applicable_v = is_applicable<Func, Args>::value;
  49927. /*! @brief Same as std::is_invocable_r, but with tuples for arguments. */
  49928. template<typename, typename, typename>
  49929. struct is_applicable_r: std::false_type {};
  49930. /**
  49931. * @copybrief is_applicable_r
  49932. * @tparam Ret The type to which the return type of the function should be
  49933. * convertible.
  49934. * @tparam Func A valid function type.
  49935. * @tparam Args The list of arguments to use to probe the function type.
  49936. */
  49937. template<typename Ret, typename Func, typename... Args>
  49938. struct is_applicable_r<Ret, Func, std::tuple<Args...>>: std::is_invocable_r<Ret, Func, Args...> {};
  49939. /**
  49940. * @brief Helper variable template.
  49941. * @tparam Ret The type to which the return type of the function should be
  49942. * convertible.
  49943. * @tparam Func A valid function type.
  49944. * @tparam Args The list of arguments to use to probe the function type.
  49945. */
  49946. template<typename Ret, typename Func, typename Args>
  49947. inline constexpr bool is_applicable_r_v = is_applicable_r<Ret, Func, Args>::value;
  49948. /**
  49949. * @brief Provides the member constant `value` to true if a given type is
  49950. * complete, false otherwise.
  49951. * @tparam Type The type to test.
  49952. */
  49953. template<typename Type, typename = void>
  49954. struct is_complete: std::false_type {};
  49955. /*! @copydoc is_complete */
  49956. template<typename Type>
  49957. struct is_complete<Type, std::void_t<decltype(sizeof(Type))>>: std::true_type {};
  49958. /**
  49959. * @brief Helper variable template.
  49960. * @tparam Type The type to test.
  49961. */
  49962. template<typename Type>
  49963. inline constexpr bool is_complete_v = is_complete<Type>::value;
  49964. /**
  49965. * @brief Provides the member constant `value` to true if a given type is an
  49966. * iterator, false otherwise.
  49967. * @tparam Type The type to test.
  49968. */
  49969. template<typename Type, typename = void>
  49970. struct is_iterator: std::false_type {};
  49971. /**
  49972. * @cond TURN_OFF_DOXYGEN
  49973. * Internal details not to be documented.
  49974. */
  49975. namespace internal {
  49976. template<typename, typename = void>
  49977. struct has_iterator_category: std::false_type {};
  49978. template<typename Type>
  49979. struct has_iterator_category<Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>: std::true_type {};
  49980. } // namespace internal
  49981. /**
  49982. * Internal details not to be documented.
  49983. * @endcond
  49984. */
  49985. /*! @copydoc is_iterator */
  49986. template<typename Type>
  49987. struct is_iterator<Type, std::enable_if_t<!std::is_same_v<std::remove_const_t<std::remove_pointer_t<Type>>, void>>>
  49988. : internal::has_iterator_category<Type> {};
  49989. /**
  49990. * @brief Helper variable template.
  49991. * @tparam Type The type to test.
  49992. */
  49993. template<typename Type>
  49994. inline constexpr bool is_iterator_v = is_iterator<Type>::value;
  49995. /**
  49996. * @brief Provides the member constant `value` to true if a given type is both
  49997. * an empty and non-final class, false otherwise.
  49998. * @tparam Type The type to test
  49999. */
  50000. template<typename Type>
  50001. struct is_ebco_eligible
  50002. : std::conjunction<std::is_empty<Type>, std::negation<std::is_final<Type>>> {};
  50003. /**
  50004. * @brief Helper variable template.
  50005. * @tparam Type The type to test.
  50006. */
  50007. template<typename Type>
  50008. inline constexpr bool is_ebco_eligible_v = is_ebco_eligible<Type>::value;
  50009. /**
  50010. * @brief Provides the member constant `value` to true if `Type::is_transparent`
  50011. * is valid and denotes a type, false otherwise.
  50012. * @tparam Type The type to test.
  50013. */
  50014. template<typename Type, typename = void>
  50015. struct is_transparent: std::false_type {};
  50016. /*! @copydoc is_transparent */
  50017. template<typename Type>
  50018. struct is_transparent<Type, std::void_t<typename Type::is_transparent>>: std::true_type {};
  50019. /**
  50020. * @brief Helper variable template.
  50021. * @tparam Type The type to test.
  50022. */
  50023. template<typename Type>
  50024. inline constexpr bool is_transparent_v = is_transparent<Type>::value;
  50025. /**
  50026. * @brief Provides the member constant `value` to true if a given type is
  50027. * equality comparable, false otherwise.
  50028. * @tparam Type The type to test.
  50029. */
  50030. template<typename Type, typename = void>
  50031. struct is_equality_comparable: std::false_type {};
  50032. /**
  50033. * @cond TURN_OFF_DOXYGEN
  50034. * Internal details not to be documented.
  50035. */
  50036. namespace internal {
  50037. template<typename, typename = void>
  50038. struct has_tuple_size_value: std::false_type {};
  50039. template<typename Type>
  50040. struct has_tuple_size_value<Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>: std::true_type {};
  50041. template<typename Type, std::size_t... Index>
  50042. [[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
  50043. return (is_equality_comparable<std::tuple_element_t<Index, Type>>::value && ...);
  50044. }
  50045. template<typename>
  50046. [[nodiscard]] constexpr bool maybe_equality_comparable(choice_t<0>) {
  50047. return true;
  50048. }
  50049. template<typename Type>
  50050. [[nodiscard]] constexpr auto maybe_equality_comparable(choice_t<1>) -> decltype(std::declval<typename Type::value_type>(), bool{}) {
  50051. if constexpr(is_iterator_v<Type>) {
  50052. return true;
  50053. } else if constexpr(std::is_same_v<typename Type::value_type, Type>) {
  50054. return maybe_equality_comparable<Type>(choice<0>);
  50055. } else {
  50056. return is_equality_comparable<typename Type::value_type>::value;
  50057. }
  50058. }
  50059. template<typename Type>
  50060. [[nodiscard]] constexpr std::enable_if_t<is_complete_v<std::tuple_size<std::remove_const_t<Type>>>, bool> maybe_equality_comparable(choice_t<2>) {
  50061. if constexpr(has_tuple_size_value<Type>::value) {
  50062. return unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
  50063. } else {
  50064. return maybe_equality_comparable<Type>(choice<1>);
  50065. }
  50066. }
  50067. } // namespace internal
  50068. /**
  50069. * Internal details not to be documented.
  50070. * @endcond
  50071. */
  50072. /*! @copydoc is_equality_comparable */
  50073. template<typename Type>
  50074. struct is_equality_comparable<Type, std::void_t<decltype(std::declval<Type>() == std::declval<Type>())>>
  50075. : std::bool_constant<internal::maybe_equality_comparable<Type>(choice<2>)> {};
  50076. /**
  50077. * @brief Helper variable template.
  50078. * @tparam Type The type to test.
  50079. */
  50080. template<typename Type>
  50081. inline constexpr bool is_equality_comparable_v = is_equality_comparable<Type>::value;
  50082. /**
  50083. * @brief Transcribes the constness of a type to another type.
  50084. * @tparam To The type to which to transcribe the constness.
  50085. * @tparam From The type from which to transcribe the constness.
  50086. */
  50087. template<typename To, typename From>
  50088. struct constness_as {
  50089. /*! @brief The type resulting from the transcription of the constness. */
  50090. using type = std::remove_const_t<To>;
  50091. };
  50092. /*! @copydoc constness_as */
  50093. template<typename To, typename From>
  50094. struct constness_as<To, const From> {
  50095. /*! @brief The type resulting from the transcription of the constness. */
  50096. using type = std::add_const_t<To>;
  50097. };
  50098. /**
  50099. * @brief Alias template to facilitate the transcription of the constness.
  50100. * @tparam To The type to which to transcribe the constness.
  50101. * @tparam From The type from which to transcribe the constness.
  50102. */
  50103. template<typename To, typename From>
  50104. using constness_as_t = typename constness_as<To, From>::type;
  50105. /**
  50106. * @brief Extracts the class of a non-static member object or function.
  50107. * @tparam Member A pointer to a non-static member object or function.
  50108. */
  50109. template<typename Member>
  50110. class member_class {
  50111. static_assert(std::is_member_pointer_v<Member>, "Invalid pointer type to non-static member object or function");
  50112. template<typename Class, typename Ret, typename... Args>
  50113. static Class *clazz(Ret (Class::*)(Args...));
  50114. template<typename Class, typename Ret, typename... Args>
  50115. static Class *clazz(Ret (Class::*)(Args...) const);
  50116. template<typename Class, typename Type>
  50117. static Class *clazz(Type Class::*);
  50118. public:
  50119. /*! @brief The class of the given non-static member object or function. */
  50120. using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
  50121. };
  50122. /**
  50123. * @brief Helper type.
  50124. * @tparam Member A pointer to a non-static member object or function.
  50125. */
  50126. template<typename Member>
  50127. using member_class_t = typename member_class<Member>::type;
  50128. } // namespace entt
  50129. #endif
  50130. // #include "fwd.hpp"
  50131. #ifndef ENTT_SIGNAL_FWD_HPP
  50132. #define ENTT_SIGNAL_FWD_HPP
  50133. #include <memory>
  50134. namespace entt {
  50135. template<typename>
  50136. class delegate;
  50137. template<typename = std::allocator<char>>
  50138. class basic_dispatcher;
  50139. template<typename>
  50140. class emitter;
  50141. class connection;
  50142. struct scoped_connection;
  50143. template<typename>
  50144. class sink;
  50145. template<typename Type, typename = std::allocator<Type *>>
  50146. class sigh;
  50147. /*! @brief Alias declaration for the most common use case. */
  50148. using dispatcher = basic_dispatcher<>;
  50149. } // namespace entt
  50150. #endif
  50151. namespace entt {
  50152. /**
  50153. * @cond TURN_OFF_DOXYGEN
  50154. * Internal details not to be documented.
  50155. */
  50156. namespace internal {
  50157. template<typename Ret, typename... Args>
  50158. auto function_pointer(Ret (*)(Args...)) -> Ret (*)(Args...);
  50159. template<typename Ret, typename Type, typename... Args, typename Other>
  50160. auto function_pointer(Ret (*)(Type, Args...), Other &&) -> Ret (*)(Args...);
  50161. template<typename Class, typename Ret, typename... Args, typename... Other>
  50162. auto function_pointer(Ret (Class::*)(Args...), Other &&...) -> Ret (*)(Args...);
  50163. template<typename Class, typename Ret, typename... Args, typename... Other>
  50164. auto function_pointer(Ret (Class::*)(Args...) const, Other &&...) -> Ret (*)(Args...);
  50165. template<typename Class, typename Type, typename... Other>
  50166. auto function_pointer(Type Class::*, Other &&...) -> Type (*)();
  50167. template<typename... Type>
  50168. using function_pointer_t = decltype(internal::function_pointer(std::declval<Type>()...));
  50169. template<typename... Class, typename Ret, typename... Args>
  50170. [[nodiscard]] constexpr auto index_sequence_for(Ret (*)(Args...)) {
  50171. return std::index_sequence_for<Class..., Args...>{};
  50172. }
  50173. } // namespace internal
  50174. /**
  50175. * Internal details not to be documented.
  50176. * @endcond
  50177. */
  50178. /*! @brief Used to wrap a function or a member of a specified type. */
  50179. template<auto>
  50180. struct connect_arg_t {};
  50181. /*! @brief Constant of type connect_arg_t used to disambiguate calls. */
  50182. template<auto Func>
  50183. inline constexpr connect_arg_t<Func> connect_arg{};
  50184. /**
  50185. * @brief Basic delegate implementation.
  50186. *
  50187. * Primary template isn't defined on purpose. All the specializations give a
  50188. * compile-time error unless the template parameter is a function type.
  50189. */
  50190. template<typename>
  50191. class delegate;
  50192. /**
  50193. * @brief Utility class to use to send around functions and members.
  50194. *
  50195. * Unmanaged delegate for function pointers and members. Users of this class are
  50196. * in charge of disconnecting instances before deleting them.
  50197. *
  50198. * A delegate can be used as a general purpose invoker without memory overhead
  50199. * for free functions possibly with payloads and bound or unbound members.
  50200. *
  50201. * @tparam Ret Return type of a function type.
  50202. * @tparam Args Types of arguments of a function type.
  50203. */
  50204. template<typename Ret, typename... Args>
  50205. class delegate<Ret(Args...)> {
  50206. template<auto Candidate, std::size_t... Index>
  50207. [[nodiscard]] auto wrap(std::index_sequence<Index...>) ENTT_NOEXCEPT {
  50208. return [](const void *, Args... args) -> Ret {
  50209. [[maybe_unused]] const auto arguments = std::forward_as_tuple(std::forward<Args>(args)...);
  50210. return static_cast<Ret>(std::invoke(Candidate, std::forward<type_list_element_t<Index, type_list<Args...>>>(std::get<Index>(arguments))...));
  50211. };
  50212. }
  50213. template<auto Candidate, typename Type, std::size_t... Index>
  50214. [[nodiscard]] auto wrap(Type &, std::index_sequence<Index...>) ENTT_NOEXCEPT {
  50215. return [](const void *payload, Args... args) -> Ret {
  50216. [[maybe_unused]] const auto arguments = std::forward_as_tuple(std::forward<Args>(args)...);
  50217. Type *curr = static_cast<Type *>(const_cast<constness_as_t<void, Type> *>(payload));
  50218. return static_cast<Ret>(std::invoke(Candidate, *curr, std::forward<type_list_element_t<Index, type_list<Args...>>>(std::get<Index>(arguments))...));
  50219. };
  50220. }
  50221. template<auto Candidate, typename Type, std::size_t... Index>
  50222. [[nodiscard]] auto wrap(Type *, std::index_sequence<Index...>) ENTT_NOEXCEPT {
  50223. return [](const void *payload, Args... args) -> Ret {
  50224. [[maybe_unused]] const auto arguments = std::forward_as_tuple(std::forward<Args>(args)...);
  50225. Type *curr = static_cast<Type *>(const_cast<constness_as_t<void, Type> *>(payload));
  50226. return static_cast<Ret>(std::invoke(Candidate, curr, std::forward<type_list_element_t<Index, type_list<Args...>>>(std::get<Index>(arguments))...));
  50227. };
  50228. }
  50229. public:
  50230. /*! @brief Function type of the contained target. */
  50231. using function_type = Ret(const void *, Args...);
  50232. /*! @brief Function type of the delegate. */
  50233. using type = Ret(Args...);
  50234. /*! @brief Return type of the delegate. */
  50235. using result_type = Ret;
  50236. /*! @brief Default constructor. */
  50237. delegate() ENTT_NOEXCEPT
  50238. : instance{nullptr},
  50239. fn{nullptr} {}
  50240. /**
  50241. * @brief Constructs a delegate and connects a free function or an unbound
  50242. * member.
  50243. * @tparam Candidate Function or member to connect to the delegate.
  50244. */
  50245. template<auto Candidate>
  50246. delegate(connect_arg_t<Candidate>) ENTT_NOEXCEPT {
  50247. connect<Candidate>();
  50248. }
  50249. /**
  50250. * @brief Constructs a delegate and connects a free function with payload or
  50251. * a bound member.
  50252. * @tparam Candidate Function or member to connect to the delegate.
  50253. * @tparam Type Type of class or type of payload.
  50254. * @param value_or_instance A valid object that fits the purpose.
  50255. */
  50256. template<auto Candidate, typename Type>
  50257. delegate(connect_arg_t<Candidate>, Type &&value_or_instance) ENTT_NOEXCEPT {
  50258. connect<Candidate>(std::forward<Type>(value_or_instance));
  50259. }
  50260. /**
  50261. * @brief Constructs a delegate and connects an user defined function with
  50262. * optional payload.
  50263. * @param function Function to connect to the delegate.
  50264. * @param payload User defined arbitrary data.
  50265. */
  50266. delegate(function_type *function, const void *payload = nullptr) ENTT_NOEXCEPT {
  50267. connect(function, payload);
  50268. }
  50269. /**
  50270. * @brief Connects a free function or an unbound member to a delegate.
  50271. * @tparam Candidate Function or member to connect to the delegate.
  50272. */
  50273. template<auto Candidate>
  50274. void connect() ENTT_NOEXCEPT {
  50275. instance = nullptr;
  50276. if constexpr(std::is_invocable_r_v<Ret, decltype(Candidate), Args...>) {
  50277. fn = [](const void *, Args... args) -> Ret {
  50278. return Ret(std::invoke(Candidate, std::forward<Args>(args)...));
  50279. };
  50280. } else if constexpr(std::is_member_pointer_v<decltype(Candidate)>) {
  50281. fn = wrap<Candidate>(internal::index_sequence_for<type_list_element_t<0, type_list<Args...>>>(internal::function_pointer_t<decltype(Candidate)>{}));
  50282. } else {
  50283. fn = wrap<Candidate>(internal::index_sequence_for(internal::function_pointer_t<decltype(Candidate)>{}));
  50284. }
  50285. }
  50286. /**
  50287. * @brief Connects a free function with payload or a bound member to a
  50288. * delegate.
  50289. *
  50290. * The delegate isn't responsible for the connected object or the payload.
  50291. * Users must always guarantee that the lifetime of the instance overcomes
  50292. * the one of the delegate.<br/>
  50293. * When used to connect a free function with payload, its signature must be
  50294. * such that the instance is the first argument before the ones used to
  50295. * define the delegate itself.
  50296. *
  50297. * @tparam Candidate Function or member to connect to the delegate.
  50298. * @tparam Type Type of class or type of payload.
  50299. * @param value_or_instance A valid reference that fits the purpose.
  50300. */
  50301. template<auto Candidate, typename Type>
  50302. void connect(Type &value_or_instance) ENTT_NOEXCEPT {
  50303. instance = &value_or_instance;
  50304. if constexpr(std::is_invocable_r_v<Ret, decltype(Candidate), Type &, Args...>) {
  50305. fn = [](const void *payload, Args... args) -> Ret {
  50306. Type *curr = static_cast<Type *>(const_cast<constness_as_t<void, Type> *>(payload));
  50307. return Ret(std::invoke(Candidate, *curr, std::forward<Args>(args)...));
  50308. };
  50309. } else {
  50310. fn = wrap<Candidate>(value_or_instance, internal::index_sequence_for(internal::function_pointer_t<decltype(Candidate), Type>{}));
  50311. }
  50312. }
  50313. /**
  50314. * @brief Connects a free function with payload or a bound member to a
  50315. * delegate.
  50316. *
  50317. * @sa connect(Type &)
  50318. *
  50319. * @tparam Candidate Function or member to connect to the delegate.
  50320. * @tparam Type Type of class or type of payload.
  50321. * @param value_or_instance A valid pointer that fits the purpose.
  50322. */
  50323. template<auto Candidate, typename Type>
  50324. void connect(Type *value_or_instance) ENTT_NOEXCEPT {
  50325. instance = value_or_instance;
  50326. if constexpr(std::is_invocable_r_v<Ret, decltype(Candidate), Type *, Args...>) {
  50327. fn = [](const void *payload, Args... args) -> Ret {
  50328. Type *curr = static_cast<Type *>(const_cast<constness_as_t<void, Type> *>(payload));
  50329. return Ret(std::invoke(Candidate, curr, std::forward<Args>(args)...));
  50330. };
  50331. } else {
  50332. fn = wrap<Candidate>(value_or_instance, internal::index_sequence_for(internal::function_pointer_t<decltype(Candidate), Type>{}));
  50333. }
  50334. }
  50335. /**
  50336. * @brief Connects an user defined function with optional payload to a
  50337. * delegate.
  50338. *
  50339. * The delegate isn't responsible for the connected object or the payload.
  50340. * Users must always guarantee that the lifetime of an instance overcomes
  50341. * the one of the delegate.<br/>
  50342. * The payload is returned as the first argument to the target function in
  50343. * all cases.
  50344. *
  50345. * @param function Function to connect to the delegate.
  50346. * @param payload User defined arbitrary data.
  50347. */
  50348. void connect(function_type *function, const void *payload = nullptr) ENTT_NOEXCEPT {
  50349. instance = payload;
  50350. fn = function;
  50351. }
  50352. /**
  50353. * @brief Resets a delegate.
  50354. *
  50355. * After a reset, a delegate cannot be invoked anymore.
  50356. */
  50357. void reset() ENTT_NOEXCEPT {
  50358. instance = nullptr;
  50359. fn = nullptr;
  50360. }
  50361. /**
  50362. * @brief Returns the instance or the payload linked to a delegate, if any.
  50363. * @return An opaque pointer to the underlying data.
  50364. */
  50365. [[nodiscard]] const void *data() const ENTT_NOEXCEPT {
  50366. return instance;
  50367. }
  50368. /**
  50369. * @brief Triggers a delegate.
  50370. *
  50371. * The delegate invokes the underlying function and returns the result.
  50372. *
  50373. * @warning
  50374. * Attempting to trigger an invalid delegate results in undefined
  50375. * behavior.
  50376. *
  50377. * @param args Arguments to use to invoke the underlying function.
  50378. * @return The value returned by the underlying function.
  50379. */
  50380. Ret operator()(Args... args) const {
  50381. ENTT_ASSERT(static_cast<bool>(*this), "Uninitialized delegate");
  50382. return fn(instance, std::forward<Args>(args)...);
  50383. }
  50384. /**
  50385. * @brief Checks whether a delegate actually stores a listener.
  50386. * @return False if the delegate is empty, true otherwise.
  50387. */
  50388. [[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
  50389. // no need to also test instance
  50390. return !(fn == nullptr);
  50391. }
  50392. /**
  50393. * @brief Compares the contents of two delegates.
  50394. * @param other Delegate with which to compare.
  50395. * @return False if the two contents differ, true otherwise.
  50396. */
  50397. [[nodiscard]] bool operator==(const delegate<Ret(Args...)> &other) const ENTT_NOEXCEPT {
  50398. return fn == other.fn && instance == other.instance;
  50399. }
  50400. private:
  50401. const void *instance;
  50402. function_type *fn;
  50403. };
  50404. /**
  50405. * @brief Compares the contents of two delegates.
  50406. * @tparam Ret Return type of a function type.
  50407. * @tparam Args Types of arguments of a function type.
  50408. * @param lhs A valid delegate object.
  50409. * @param rhs A valid delegate object.
  50410. * @return True if the two contents differ, false otherwise.
  50411. */
  50412. template<typename Ret, typename... Args>
  50413. [[nodiscard]] bool operator!=(const delegate<Ret(Args...)> &lhs, const delegate<Ret(Args...)> &rhs) ENTT_NOEXCEPT {
  50414. return !(lhs == rhs);
  50415. }
  50416. /**
  50417. * @brief Deduction guide.
  50418. * @tparam Candidate Function or member to connect to the delegate.
  50419. */
  50420. template<auto Candidate>
  50421. delegate(connect_arg_t<Candidate>) -> delegate<std::remove_pointer_t<internal::function_pointer_t<decltype(Candidate)>>>;
  50422. /**
  50423. * @brief Deduction guide.
  50424. * @tparam Candidate Function or member to connect to the delegate.
  50425. * @tparam Type Type of class or type of payload.
  50426. */
  50427. template<auto Candidate, typename Type>
  50428. delegate(connect_arg_t<Candidate>, Type &&) -> delegate<std::remove_pointer_t<internal::function_pointer_t<decltype(Candidate), Type>>>;
  50429. /**
  50430. * @brief Deduction guide.
  50431. * @tparam Ret Return type of a function type.
  50432. * @tparam Args Types of arguments of a function type.
  50433. */
  50434. template<typename Ret, typename... Args>
  50435. delegate(Ret (*)(const void *, Args...), const void * = nullptr) -> delegate<Ret(Args...)>;
  50436. } // namespace entt
  50437. #endif
  50438. // #include "signal/dispatcher.hpp"
  50439. #ifndef ENTT_SIGNAL_DISPATCHER_HPP
  50440. #define ENTT_SIGNAL_DISPATCHER_HPP
  50441. #include <algorithm>
  50442. #include <cstddef>
  50443. #include <memory>
  50444. #include <type_traits>
  50445. #include <utility>
  50446. #include <vector>
  50447. // #include "../config/config.h"
  50448. // #include "../container/dense_map.hpp"
  50449. #ifndef ENTT_CONTAINER_DENSE_MAP_HPP
  50450. #define ENTT_CONTAINER_DENSE_MAP_HPP
  50451. #include <algorithm>
  50452. #include <cmath>
  50453. #include <cstddef>
  50454. #include <functional>
  50455. #include <iterator>
  50456. #include <limits>
  50457. #include <memory>
  50458. #include <tuple>
  50459. #include <type_traits>
  50460. #include <utility>
  50461. #include <vector>
  50462. // #include "../config/config.h"
  50463. #ifndef ENTT_CONFIG_CONFIG_H
  50464. #define ENTT_CONFIG_CONFIG_H
  50465. // #include "version.h"
  50466. #ifndef ENTT_CONFIG_VERSION_H
  50467. #define ENTT_CONFIG_VERSION_H
  50468. // #include "macro.h"
  50469. #ifndef ENTT_CONFIG_MACRO_H
  50470. #define ENTT_CONFIG_MACRO_H
  50471. #define ENTT_STR(arg) #arg
  50472. #define ENTT_XSTR(arg) ENTT_STR(arg)
  50473. #endif
  50474. #define ENTT_VERSION_MAJOR 3
  50475. #define ENTT_VERSION_MINOR 10
  50476. #define ENTT_VERSION_PATCH 3
  50477. #define ENTT_VERSION \
  50478. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  50479. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  50480. #endif
  50481. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  50482. # define ENTT_THROW throw
  50483. # define ENTT_TRY try
  50484. # define ENTT_CATCH catch(...)
  50485. #else
  50486. # define ENTT_THROW
  50487. # define ENTT_TRY if(true)
  50488. # define ENTT_CATCH if(false)
  50489. #endif
  50490. #ifndef ENTT_NOEXCEPT
  50491. # define ENTT_NOEXCEPT noexcept
  50492. # define ENTT_NOEXCEPT_IF(expr) noexcept(expr)
  50493. # else
  50494. # define ENTT_NOEXCEPT_IF(...)
  50495. #endif
  50496. #ifdef ENTT_USE_ATOMIC
  50497. # include <atomic>
  50498. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  50499. #else
  50500. # define ENTT_MAYBE_ATOMIC(Type) Type
  50501. #endif
  50502. #ifndef ENTT_ID_TYPE
  50503. # include <cstdint>
  50504. # define ENTT_ID_TYPE std::uint32_t
  50505. #endif
  50506. #ifndef ENTT_SPARSE_PAGE
  50507. # define ENTT_SPARSE_PAGE 4096
  50508. #endif
  50509. #ifndef ENTT_PACKED_PAGE
  50510. # define ENTT_PACKED_PAGE 1024
  50511. #endif
  50512. #ifdef ENTT_DISABLE_ASSERT
  50513. # undef ENTT_ASSERT
  50514. # define ENTT_ASSERT(...) (void(0))
  50515. #elif !defined ENTT_ASSERT
  50516. # include <cassert>
  50517. # define ENTT_ASSERT(condition, ...) assert(condition)
  50518. #endif
  50519. #ifdef ENTT_NO_ETO
  50520. # define ENTT_IGNORE_IF_EMPTY false
  50521. #else
  50522. # define ENTT_IGNORE_IF_EMPTY true
  50523. #endif
  50524. #ifdef ENTT_STANDARD_CPP
  50525. # define ENTT_NONSTD false
  50526. #else
  50527. # define ENTT_NONSTD true
  50528. # if defined __clang__ || defined __GNUC__
  50529. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  50530. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  50531. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  50532. # elif defined _MSC_VER
  50533. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  50534. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  50535. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  50536. # endif
  50537. #endif
  50538. #if defined _MSC_VER
  50539. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  50540. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  50541. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  50542. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  50543. #endif
  50544. #endif
  50545. // #include "../core/compressed_pair.hpp"
  50546. #ifndef ENTT_CORE_COMPRESSED_PAIR_HPP
  50547. #define ENTT_CORE_COMPRESSED_PAIR_HPP
  50548. #include <cstddef>
  50549. #include <tuple>
  50550. #include <type_traits>
  50551. #include <utility>
  50552. // #include "../config/config.h"
  50553. #ifndef ENTT_CONFIG_CONFIG_H
  50554. #define ENTT_CONFIG_CONFIG_H
  50555. // #include "version.h"
  50556. #ifndef ENTT_CONFIG_VERSION_H
  50557. #define ENTT_CONFIG_VERSION_H
  50558. // #include "macro.h"
  50559. #ifndef ENTT_CONFIG_MACRO_H
  50560. #define ENTT_CONFIG_MACRO_H
  50561. #define ENTT_STR(arg) #arg
  50562. #define ENTT_XSTR(arg) ENTT_STR(arg)
  50563. #endif
  50564. #define ENTT_VERSION_MAJOR 3
  50565. #define ENTT_VERSION_MINOR 10
  50566. #define ENTT_VERSION_PATCH 3
  50567. #define ENTT_VERSION \
  50568. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  50569. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  50570. #endif
  50571. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  50572. # define ENTT_THROW throw
  50573. # define ENTT_TRY try
  50574. # define ENTT_CATCH catch(...)
  50575. #else
  50576. # define ENTT_THROW
  50577. # define ENTT_TRY if(true)
  50578. # define ENTT_CATCH if(false)
  50579. #endif
  50580. #ifndef ENTT_NOEXCEPT
  50581. # define ENTT_NOEXCEPT noexcept
  50582. # define ENTT_NOEXCEPT_IF(expr) noexcept(expr)
  50583. # else
  50584. # define ENTT_NOEXCEPT_IF(...)
  50585. #endif
  50586. #ifdef ENTT_USE_ATOMIC
  50587. # include <atomic>
  50588. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  50589. #else
  50590. # define ENTT_MAYBE_ATOMIC(Type) Type
  50591. #endif
  50592. #ifndef ENTT_ID_TYPE
  50593. # include <cstdint>
  50594. # define ENTT_ID_TYPE std::uint32_t
  50595. #endif
  50596. #ifndef ENTT_SPARSE_PAGE
  50597. # define ENTT_SPARSE_PAGE 4096
  50598. #endif
  50599. #ifndef ENTT_PACKED_PAGE
  50600. # define ENTT_PACKED_PAGE 1024
  50601. #endif
  50602. #ifdef ENTT_DISABLE_ASSERT
  50603. # undef ENTT_ASSERT
  50604. # define ENTT_ASSERT(...) (void(0))
  50605. #elif !defined ENTT_ASSERT
  50606. # include <cassert>
  50607. # define ENTT_ASSERT(condition, ...) assert(condition)
  50608. #endif
  50609. #ifdef ENTT_NO_ETO
  50610. # define ENTT_IGNORE_IF_EMPTY false
  50611. #else
  50612. # define ENTT_IGNORE_IF_EMPTY true
  50613. #endif
  50614. #ifdef ENTT_STANDARD_CPP
  50615. # define ENTT_NONSTD false
  50616. #else
  50617. # define ENTT_NONSTD true
  50618. # if defined __clang__ || defined __GNUC__
  50619. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  50620. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  50621. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  50622. # elif defined _MSC_VER
  50623. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  50624. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  50625. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  50626. # endif
  50627. #endif
  50628. #if defined _MSC_VER
  50629. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  50630. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  50631. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  50632. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  50633. #endif
  50634. #endif
  50635. // #include "type_traits.hpp"
  50636. #ifndef ENTT_CORE_TYPE_TRAITS_HPP
  50637. #define ENTT_CORE_TYPE_TRAITS_HPP
  50638. #include <cstddef>
  50639. #include <iterator>
  50640. #include <type_traits>
  50641. #include <utility>
  50642. // #include "../config/config.h"
  50643. // #include "fwd.hpp"
  50644. #ifndef ENTT_CORE_FWD_HPP
  50645. #define ENTT_CORE_FWD_HPP
  50646. #include <cstdint>
  50647. #include <type_traits>
  50648. // #include "../config/config.h"
  50649. namespace entt {
  50650. template<std::size_t Len = sizeof(double[2]), std::size_t = alignof(typename std::aligned_storage_t<Len + !Len>)>
  50651. class basic_any;
  50652. /*! @brief Alias declaration for type identifiers. */
  50653. using id_type = ENTT_ID_TYPE;
  50654. /*! @brief Alias declaration for the most common use case. */
  50655. using any = basic_any<>;
  50656. } // namespace entt
  50657. #endif
  50658. namespace entt {
  50659. /**
  50660. * @brief Utility class to disambiguate overloaded functions.
  50661. * @tparam N Number of choices available.
  50662. */
  50663. template<std::size_t N>
  50664. struct choice_t
  50665. // Unfortunately, doxygen cannot parse such a construct.
  50666. : /*! @cond TURN_OFF_DOXYGEN */ choice_t<N - 1> /*! @endcond */
  50667. {};
  50668. /*! @copybrief choice_t */
  50669. template<>
  50670. struct choice_t<0> {};
  50671. /**
  50672. * @brief Variable template for the choice trick.
  50673. * @tparam N Number of choices available.
  50674. */
  50675. template<std::size_t N>
  50676. inline constexpr choice_t<N> choice{};
  50677. /**
  50678. * @brief Identity type trait.
  50679. *
  50680. * Useful to establish non-deduced contexts in template argument deduction
  50681. * (waiting for C++20) or to provide types through function arguments.
  50682. *
  50683. * @tparam Type A type.
  50684. */
  50685. template<typename Type>
  50686. struct type_identity {
  50687. /*! @brief Identity type. */
  50688. using type = Type;
  50689. };
  50690. /**
  50691. * @brief Helper type.
  50692. * @tparam Type A type.
  50693. */
  50694. template<typename Type>
  50695. using type_identity_t = typename type_identity<Type>::type;
  50696. /**
  50697. * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains.
  50698. * @tparam Type The type of which to return the size.
  50699. * @tparam The size of the type if `sizeof` accepts it, 0 otherwise.
  50700. */
  50701. template<typename Type, typename = void>
  50702. struct size_of: std::integral_constant<std::size_t, 0u> {};
  50703. /*! @copydoc size_of */
  50704. template<typename Type>
  50705. struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
  50706. : std::integral_constant<std::size_t, sizeof(Type)> {};
  50707. /**
  50708. * @brief Helper variable template.
  50709. * @tparam Type The type of which to return the size.
  50710. */
  50711. template<typename Type>
  50712. inline constexpr std::size_t size_of_v = size_of<Type>::value;
  50713. /**
  50714. * @brief Using declaration to be used to _repeat_ the same type a number of
  50715. * times equal to the size of a given parameter pack.
  50716. * @tparam Type A type to repeat.
  50717. */
  50718. template<typename Type, typename>
  50719. using unpack_as_type = Type;
  50720. /**
  50721. * @brief Helper variable template to be used to _repeat_ the same value a
  50722. * number of times equal to the size of a given parameter pack.
  50723. * @tparam Value A value to repeat.
  50724. */
  50725. template<auto Value, typename>
  50726. inline constexpr auto unpack_as_value = Value;
  50727. /**
  50728. * @brief Wraps a static constant.
  50729. * @tparam Value A static constant.
  50730. */
  50731. template<auto Value>
  50732. using integral_constant = std::integral_constant<decltype(Value), Value>;
  50733. /**
  50734. * @brief Alias template to facilitate the creation of named values.
  50735. * @tparam Value A constant value at least convertible to `id_type`.
  50736. */
  50737. template<id_type Value>
  50738. using tag = integral_constant<Value>;
  50739. /**
  50740. * @brief A class to use to push around lists of types, nothing more.
  50741. * @tparam Type Types provided by the type list.
  50742. */
  50743. template<typename... Type>
  50744. struct type_list {
  50745. /*! @brief Type list type. */
  50746. using type = type_list;
  50747. /*! @brief Compile-time number of elements in the type list. */
  50748. static constexpr auto size = sizeof...(Type);
  50749. };
  50750. /*! @brief Primary template isn't defined on purpose. */
  50751. template<std::size_t, typename>
  50752. struct type_list_element;
  50753. /**
  50754. * @brief Provides compile-time indexed access to the types of a type list.
  50755. * @tparam Index Index of the type to return.
  50756. * @tparam Type First type provided by the type list.
  50757. * @tparam Other Other types provided by the type list.
  50758. */
  50759. template<std::size_t Index, typename Type, typename... Other>
  50760. struct type_list_element<Index, type_list<Type, Other...>>
  50761. : type_list_element<Index - 1u, type_list<Other...>> {};
  50762. /**
  50763. * @brief Provides compile-time indexed access to the types of a type list.
  50764. * @tparam Type First type provided by the type list.
  50765. * @tparam Other Other types provided by the type list.
  50766. */
  50767. template<typename Type, typename... Other>
  50768. struct type_list_element<0u, type_list<Type, Other...>> {
  50769. /*! @brief Searched type. */
  50770. using type = Type;
  50771. };
  50772. /**
  50773. * @brief Helper type.
  50774. * @tparam Index Index of the type to return.
  50775. * @tparam List Type list to search into.
  50776. */
  50777. template<std::size_t Index, typename List>
  50778. using type_list_element_t = typename type_list_element<Index, List>::type;
  50779. /**
  50780. * @brief Concatenates multiple type lists.
  50781. * @tparam Type Types provided by the first type list.
  50782. * @tparam Other Types provided by the second type list.
  50783. * @return A type list composed by the types of both the type lists.
  50784. */
  50785. template<typename... Type, typename... Other>
  50786. constexpr type_list<Type..., Other...> operator+(type_list<Type...>, type_list<Other...>) {
  50787. return {};
  50788. }
  50789. /*! @brief Primary template isn't defined on purpose. */
  50790. template<typename...>
  50791. struct type_list_cat;
  50792. /*! @brief Concatenates multiple type lists. */
  50793. template<>
  50794. struct type_list_cat<> {
  50795. /*! @brief A type list composed by the types of all the type lists. */
  50796. using type = type_list<>;
  50797. };
  50798. /**
  50799. * @brief Concatenates multiple type lists.
  50800. * @tparam Type Types provided by the first type list.
  50801. * @tparam Other Types provided by the second type list.
  50802. * @tparam List Other type lists, if any.
  50803. */
  50804. template<typename... Type, typename... Other, typename... List>
  50805. struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
  50806. /*! @brief A type list composed by the types of all the type lists. */
  50807. using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
  50808. };
  50809. /**
  50810. * @brief Concatenates multiple type lists.
  50811. * @tparam Type Types provided by the type list.
  50812. */
  50813. template<typename... Type>
  50814. struct type_list_cat<type_list<Type...>> {
  50815. /*! @brief A type list composed by the types of all the type lists. */
  50816. using type = type_list<Type...>;
  50817. };
  50818. /**
  50819. * @brief Helper type.
  50820. * @tparam List Type lists to concatenate.
  50821. */
  50822. template<typename... List>
  50823. using type_list_cat_t = typename type_list_cat<List...>::type;
  50824. /*! @brief Primary template isn't defined on purpose. */
  50825. template<typename>
  50826. struct type_list_unique;
  50827. /**
  50828. * @brief Removes duplicates types from a type list.
  50829. * @tparam Type One of the types provided by the given type list.
  50830. * @tparam Other The other types provided by the given type list.
  50831. */
  50832. template<typename Type, typename... Other>
  50833. struct type_list_unique<type_list<Type, Other...>> {
  50834. /*! @brief A type list without duplicate types. */
  50835. using type = std::conditional_t<
  50836. (std::is_same_v<Type, Other> || ...),
  50837. typename type_list_unique<type_list<Other...>>::type,
  50838. type_list_cat_t<type_list<Type>, typename type_list_unique<type_list<Other...>>::type>>;
  50839. };
  50840. /*! @brief Removes duplicates types from a type list. */
  50841. template<>
  50842. struct type_list_unique<type_list<>> {
  50843. /*! @brief A type list without duplicate types. */
  50844. using type = type_list<>;
  50845. };
  50846. /**
  50847. * @brief Helper type.
  50848. * @tparam Type A type list.
  50849. */
  50850. template<typename Type>
  50851. using type_list_unique_t = typename type_list_unique<Type>::type;
  50852. /**
  50853. * @brief Provides the member constant `value` to true if a type list contains a
  50854. * given type, false otherwise.
  50855. * @tparam List Type list.
  50856. * @tparam Type Type to look for.
  50857. */
  50858. template<typename List, typename Type>
  50859. struct type_list_contains;
  50860. /**
  50861. * @copybrief type_list_contains
  50862. * @tparam Type Types provided by the type list.
  50863. * @tparam Other Type to look for.
  50864. */
  50865. template<typename... Type, typename Other>
  50866. struct type_list_contains<type_list<Type...>, Other>: std::disjunction<std::is_same<Type, Other>...> {};
  50867. /**
  50868. * @brief Helper variable template.
  50869. * @tparam List Type list.
  50870. * @tparam Type Type to look for.
  50871. */
  50872. template<typename List, typename Type>
  50873. inline constexpr bool type_list_contains_v = type_list_contains<List, Type>::value;
  50874. /*! @brief Primary template isn't defined on purpose. */
  50875. template<typename...>
  50876. struct type_list_diff;
  50877. /**
  50878. * @brief Computes the difference between two type lists.
  50879. * @tparam Type Types provided by the first type list.
  50880. * @tparam Other Types provided by the second type list.
  50881. */
  50882. template<typename... Type, typename... Other>
  50883. struct type_list_diff<type_list<Type...>, type_list<Other...>> {
  50884. /*! @brief A type list that is the difference between the two type lists. */
  50885. using type = type_list_cat_t<std::conditional_t<type_list_contains_v<type_list<Other...>, Type>, type_list<>, type_list<Type>>...>;
  50886. };
  50887. /**
  50888. * @brief Helper type.
  50889. * @tparam List Type lists between which to compute the difference.
  50890. */
  50891. template<typename... List>
  50892. using type_list_diff_t = typename type_list_diff<List...>::type;
  50893. /**
  50894. * @brief A class to use to push around lists of constant values, nothing more.
  50895. * @tparam Value Values provided by the value list.
  50896. */
  50897. template<auto... Value>
  50898. struct value_list {
  50899. /*! @brief Value list type. */
  50900. using type = value_list;
  50901. /*! @brief Compile-time number of elements in the value list. */
  50902. static constexpr auto size = sizeof...(Value);
  50903. };
  50904. /*! @brief Primary template isn't defined on purpose. */
  50905. template<std::size_t, typename>
  50906. struct value_list_element;
  50907. /**
  50908. * @brief Provides compile-time indexed access to the values of a value list.
  50909. * @tparam Index Index of the value to return.
  50910. * @tparam Value First value provided by the value list.
  50911. * @tparam Other Other values provided by the value list.
  50912. */
  50913. template<std::size_t Index, auto Value, auto... Other>
  50914. struct value_list_element<Index, value_list<Value, Other...>>
  50915. : value_list_element<Index - 1u, value_list<Other...>> {};
  50916. /**
  50917. * @brief Provides compile-time indexed access to the types of a type list.
  50918. * @tparam Value First value provided by the value list.
  50919. * @tparam Other Other values provided by the value list.
  50920. */
  50921. template<auto Value, auto... Other>
  50922. struct value_list_element<0u, value_list<Value, Other...>> {
  50923. /*! @brief Searched value. */
  50924. static constexpr auto value = Value;
  50925. };
  50926. /**
  50927. * @brief Helper type.
  50928. * @tparam Index Index of the value to return.
  50929. * @tparam List Value list to search into.
  50930. */
  50931. template<std::size_t Index, typename List>
  50932. inline constexpr auto value_list_element_v = value_list_element<Index, List>::value;
  50933. /**
  50934. * @brief Concatenates multiple value lists.
  50935. * @tparam Value Values provided by the first value list.
  50936. * @tparam Other Values provided by the second value list.
  50937. * @return A value list composed by the values of both the value lists.
  50938. */
  50939. template<auto... Value, auto... Other>
  50940. constexpr value_list<Value..., Other...> operator+(value_list<Value...>, value_list<Other...>) {
  50941. return {};
  50942. }
  50943. /*! @brief Primary template isn't defined on purpose. */
  50944. template<typename...>
  50945. struct value_list_cat;
  50946. /*! @brief Concatenates multiple value lists. */
  50947. template<>
  50948. struct value_list_cat<> {
  50949. /*! @brief A value list composed by the values of all the value lists. */
  50950. using type = value_list<>;
  50951. };
  50952. /**
  50953. * @brief Concatenates multiple value lists.
  50954. * @tparam Value Values provided by the first value list.
  50955. * @tparam Other Values provided by the second value list.
  50956. * @tparam List Other value lists, if any.
  50957. */
  50958. template<auto... Value, auto... Other, typename... List>
  50959. struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
  50960. /*! @brief A value list composed by the values of all the value lists. */
  50961. using type = typename value_list_cat<value_list<Value..., Other...>, List...>::type;
  50962. };
  50963. /**
  50964. * @brief Concatenates multiple value lists.
  50965. * @tparam Value Values provided by the value list.
  50966. */
  50967. template<auto... Value>
  50968. struct value_list_cat<value_list<Value...>> {
  50969. /*! @brief A value list composed by the values of all the value lists. */
  50970. using type = value_list<Value...>;
  50971. };
  50972. /**
  50973. * @brief Helper type.
  50974. * @tparam List Value lists to concatenate.
  50975. */
  50976. template<typename... List>
  50977. using value_list_cat_t = typename value_list_cat<List...>::type;
  50978. /*! @brief Same as std::is_invocable, but with tuples. */
  50979. template<typename, typename>
  50980. struct is_applicable: std::false_type {};
  50981. /**
  50982. * @copybrief is_applicable
  50983. * @tparam Func A valid function type.
  50984. * @tparam Tuple Tuple-like type.
  50985. * @tparam Args The list of arguments to use to probe the function type.
  50986. */
  50987. template<typename Func, template<typename...> class Tuple, typename... Args>
  50988. struct is_applicable<Func, Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  50989. /**
  50990. * @copybrief is_applicable
  50991. * @tparam Func A valid function type.
  50992. * @tparam Tuple Tuple-like type.
  50993. * @tparam Args The list of arguments to use to probe the function type.
  50994. */
  50995. template<typename Func, template<typename...> class Tuple, typename... Args>
  50996. struct is_applicable<Func, const Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  50997. /**
  50998. * @brief Helper variable template.
  50999. * @tparam Func A valid function type.
  51000. * @tparam Args The list of arguments to use to probe the function type.
  51001. */
  51002. template<typename Func, typename Args>
  51003. inline constexpr bool is_applicable_v = is_applicable<Func, Args>::value;
  51004. /*! @brief Same as std::is_invocable_r, but with tuples for arguments. */
  51005. template<typename, typename, typename>
  51006. struct is_applicable_r: std::false_type {};
  51007. /**
  51008. * @copybrief is_applicable_r
  51009. * @tparam Ret The type to which the return type of the function should be
  51010. * convertible.
  51011. * @tparam Func A valid function type.
  51012. * @tparam Args The list of arguments to use to probe the function type.
  51013. */
  51014. template<typename Ret, typename Func, typename... Args>
  51015. struct is_applicable_r<Ret, Func, std::tuple<Args...>>: std::is_invocable_r<Ret, Func, Args...> {};
  51016. /**
  51017. * @brief Helper variable template.
  51018. * @tparam Ret The type to which the return type of the function should be
  51019. * convertible.
  51020. * @tparam Func A valid function type.
  51021. * @tparam Args The list of arguments to use to probe the function type.
  51022. */
  51023. template<typename Ret, typename Func, typename Args>
  51024. inline constexpr bool is_applicable_r_v = is_applicable_r<Ret, Func, Args>::value;
  51025. /**
  51026. * @brief Provides the member constant `value` to true if a given type is
  51027. * complete, false otherwise.
  51028. * @tparam Type The type to test.
  51029. */
  51030. template<typename Type, typename = void>
  51031. struct is_complete: std::false_type {};
  51032. /*! @copydoc is_complete */
  51033. template<typename Type>
  51034. struct is_complete<Type, std::void_t<decltype(sizeof(Type))>>: std::true_type {};
  51035. /**
  51036. * @brief Helper variable template.
  51037. * @tparam Type The type to test.
  51038. */
  51039. template<typename Type>
  51040. inline constexpr bool is_complete_v = is_complete<Type>::value;
  51041. /**
  51042. * @brief Provides the member constant `value` to true if a given type is an
  51043. * iterator, false otherwise.
  51044. * @tparam Type The type to test.
  51045. */
  51046. template<typename Type, typename = void>
  51047. struct is_iterator: std::false_type {};
  51048. /**
  51049. * @cond TURN_OFF_DOXYGEN
  51050. * Internal details not to be documented.
  51051. */
  51052. namespace internal {
  51053. template<typename, typename = void>
  51054. struct has_iterator_category: std::false_type {};
  51055. template<typename Type>
  51056. struct has_iterator_category<Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>: std::true_type {};
  51057. } // namespace internal
  51058. /**
  51059. * Internal details not to be documented.
  51060. * @endcond
  51061. */
  51062. /*! @copydoc is_iterator */
  51063. template<typename Type>
  51064. struct is_iterator<Type, std::enable_if_t<!std::is_same_v<std::remove_const_t<std::remove_pointer_t<Type>>, void>>>
  51065. : internal::has_iterator_category<Type> {};
  51066. /**
  51067. * @brief Helper variable template.
  51068. * @tparam Type The type to test.
  51069. */
  51070. template<typename Type>
  51071. inline constexpr bool is_iterator_v = is_iterator<Type>::value;
  51072. /**
  51073. * @brief Provides the member constant `value` to true if a given type is both
  51074. * an empty and non-final class, false otherwise.
  51075. * @tparam Type The type to test
  51076. */
  51077. template<typename Type>
  51078. struct is_ebco_eligible
  51079. : std::conjunction<std::is_empty<Type>, std::negation<std::is_final<Type>>> {};
  51080. /**
  51081. * @brief Helper variable template.
  51082. * @tparam Type The type to test.
  51083. */
  51084. template<typename Type>
  51085. inline constexpr bool is_ebco_eligible_v = is_ebco_eligible<Type>::value;
  51086. /**
  51087. * @brief Provides the member constant `value` to true if `Type::is_transparent`
  51088. * is valid and denotes a type, false otherwise.
  51089. * @tparam Type The type to test.
  51090. */
  51091. template<typename Type, typename = void>
  51092. struct is_transparent: std::false_type {};
  51093. /*! @copydoc is_transparent */
  51094. template<typename Type>
  51095. struct is_transparent<Type, std::void_t<typename Type::is_transparent>>: std::true_type {};
  51096. /**
  51097. * @brief Helper variable template.
  51098. * @tparam Type The type to test.
  51099. */
  51100. template<typename Type>
  51101. inline constexpr bool is_transparent_v = is_transparent<Type>::value;
  51102. /**
  51103. * @brief Provides the member constant `value` to true if a given type is
  51104. * equality comparable, false otherwise.
  51105. * @tparam Type The type to test.
  51106. */
  51107. template<typename Type, typename = void>
  51108. struct is_equality_comparable: std::false_type {};
  51109. /**
  51110. * @cond TURN_OFF_DOXYGEN
  51111. * Internal details not to be documented.
  51112. */
  51113. namespace internal {
  51114. template<typename, typename = void>
  51115. struct has_tuple_size_value: std::false_type {};
  51116. template<typename Type>
  51117. struct has_tuple_size_value<Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>: std::true_type {};
  51118. template<typename Type, std::size_t... Index>
  51119. [[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
  51120. return (is_equality_comparable<std::tuple_element_t<Index, Type>>::value && ...);
  51121. }
  51122. template<typename>
  51123. [[nodiscard]] constexpr bool maybe_equality_comparable(choice_t<0>) {
  51124. return true;
  51125. }
  51126. template<typename Type>
  51127. [[nodiscard]] constexpr auto maybe_equality_comparable(choice_t<1>) -> decltype(std::declval<typename Type::value_type>(), bool{}) {
  51128. if constexpr(is_iterator_v<Type>) {
  51129. return true;
  51130. } else if constexpr(std::is_same_v<typename Type::value_type, Type>) {
  51131. return maybe_equality_comparable<Type>(choice<0>);
  51132. } else {
  51133. return is_equality_comparable<typename Type::value_type>::value;
  51134. }
  51135. }
  51136. template<typename Type>
  51137. [[nodiscard]] constexpr std::enable_if_t<is_complete_v<std::tuple_size<std::remove_const_t<Type>>>, bool> maybe_equality_comparable(choice_t<2>) {
  51138. if constexpr(has_tuple_size_value<Type>::value) {
  51139. return unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
  51140. } else {
  51141. return maybe_equality_comparable<Type>(choice<1>);
  51142. }
  51143. }
  51144. } // namespace internal
  51145. /**
  51146. * Internal details not to be documented.
  51147. * @endcond
  51148. */
  51149. /*! @copydoc is_equality_comparable */
  51150. template<typename Type>
  51151. struct is_equality_comparable<Type, std::void_t<decltype(std::declval<Type>() == std::declval<Type>())>>
  51152. : std::bool_constant<internal::maybe_equality_comparable<Type>(choice<2>)> {};
  51153. /**
  51154. * @brief Helper variable template.
  51155. * @tparam Type The type to test.
  51156. */
  51157. template<typename Type>
  51158. inline constexpr bool is_equality_comparable_v = is_equality_comparable<Type>::value;
  51159. /**
  51160. * @brief Transcribes the constness of a type to another type.
  51161. * @tparam To The type to which to transcribe the constness.
  51162. * @tparam From The type from which to transcribe the constness.
  51163. */
  51164. template<typename To, typename From>
  51165. struct constness_as {
  51166. /*! @brief The type resulting from the transcription of the constness. */
  51167. using type = std::remove_const_t<To>;
  51168. };
  51169. /*! @copydoc constness_as */
  51170. template<typename To, typename From>
  51171. struct constness_as<To, const From> {
  51172. /*! @brief The type resulting from the transcription of the constness. */
  51173. using type = std::add_const_t<To>;
  51174. };
  51175. /**
  51176. * @brief Alias template to facilitate the transcription of the constness.
  51177. * @tparam To The type to which to transcribe the constness.
  51178. * @tparam From The type from which to transcribe the constness.
  51179. */
  51180. template<typename To, typename From>
  51181. using constness_as_t = typename constness_as<To, From>::type;
  51182. /**
  51183. * @brief Extracts the class of a non-static member object or function.
  51184. * @tparam Member A pointer to a non-static member object or function.
  51185. */
  51186. template<typename Member>
  51187. class member_class {
  51188. static_assert(std::is_member_pointer_v<Member>, "Invalid pointer type to non-static member object or function");
  51189. template<typename Class, typename Ret, typename... Args>
  51190. static Class *clazz(Ret (Class::*)(Args...));
  51191. template<typename Class, typename Ret, typename... Args>
  51192. static Class *clazz(Ret (Class::*)(Args...) const);
  51193. template<typename Class, typename Type>
  51194. static Class *clazz(Type Class::*);
  51195. public:
  51196. /*! @brief The class of the given non-static member object or function. */
  51197. using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
  51198. };
  51199. /**
  51200. * @brief Helper type.
  51201. * @tparam Member A pointer to a non-static member object or function.
  51202. */
  51203. template<typename Member>
  51204. using member_class_t = typename member_class<Member>::type;
  51205. } // namespace entt
  51206. #endif
  51207. namespace entt {
  51208. /**
  51209. * @cond TURN_OFF_DOXYGEN
  51210. * Internal details not to be documented.
  51211. */
  51212. namespace internal {
  51213. template<typename Type, std::size_t, typename = void>
  51214. struct compressed_pair_element {
  51215. using reference = Type &;
  51216. using const_reference = const Type &;
  51217. template<bool Dummy = true, typename = std::enable_if_t<Dummy && std::is_default_constructible_v<Type>>>
  51218. compressed_pair_element()
  51219. : value{} {}
  51220. template<typename Args, typename = std::enable_if_t<!std::is_same_v<std::remove_cv_t<std::remove_reference_t<Args>>, compressed_pair_element>>>
  51221. compressed_pair_element(Args &&args)
  51222. : value{std::forward<Args>(args)} {}
  51223. template<typename... Args, std::size_t... Index>
  51224. compressed_pair_element(std::tuple<Args...> args, std::index_sequence<Index...>)
  51225. : value{std::forward<Args>(std::get<Index>(args))...} {}
  51226. [[nodiscard]] reference get() ENTT_NOEXCEPT {
  51227. return value;
  51228. }
  51229. [[nodiscard]] const_reference get() const ENTT_NOEXCEPT {
  51230. return value;
  51231. }
  51232. private:
  51233. Type value;
  51234. };
  51235. template<typename Type, std::size_t Tag>
  51236. struct compressed_pair_element<Type, Tag, std::enable_if_t<is_ebco_eligible_v<Type>>>: Type {
  51237. using reference = Type &;
  51238. using const_reference = const Type &;
  51239. using base_type = Type;
  51240. template<bool Dummy = true, typename = std::enable_if_t<Dummy && std::is_default_constructible_v<base_type>>>
  51241. compressed_pair_element()
  51242. : base_type{} {}
  51243. template<typename Args, typename = std::enable_if_t<!std::is_same_v<std::remove_cv_t<std::remove_reference_t<Args>>, compressed_pair_element>>>
  51244. compressed_pair_element(Args &&args)
  51245. : base_type{std::forward<Args>(args)} {}
  51246. template<typename... Args, std::size_t... Index>
  51247. compressed_pair_element(std::tuple<Args...> args, std::index_sequence<Index...>)
  51248. : base_type{std::forward<Args>(std::get<Index>(args))...} {}
  51249. [[nodiscard]] reference get() ENTT_NOEXCEPT {
  51250. return *this;
  51251. }
  51252. [[nodiscard]] const_reference get() const ENTT_NOEXCEPT {
  51253. return *this;
  51254. }
  51255. };
  51256. } // namespace internal
  51257. /**
  51258. * Internal details not to be documented.
  51259. * @endcond
  51260. */
  51261. /**
  51262. * @brief A compressed pair.
  51263. *
  51264. * A pair that exploits the _Empty Base Class Optimization_ (or _EBCO_) to
  51265. * reduce its final size to a minimum.
  51266. *
  51267. * @tparam First The type of the first element that the pair stores.
  51268. * @tparam Second The type of the second element that the pair stores.
  51269. */
  51270. template<typename First, typename Second>
  51271. class compressed_pair final
  51272. : internal::compressed_pair_element<First, 0u>,
  51273. internal::compressed_pair_element<Second, 1u> {
  51274. using first_base = internal::compressed_pair_element<First, 0u>;
  51275. using second_base = internal::compressed_pair_element<Second, 1u>;
  51276. public:
  51277. /*! @brief The type of the first element that the pair stores. */
  51278. using first_type = First;
  51279. /*! @brief The type of the second element that the pair stores. */
  51280. using second_type = Second;
  51281. /**
  51282. * @brief Default constructor, conditionally enabled.
  51283. *
  51284. * This constructor is only available when the types that the pair stores
  51285. * are both at least default constructible.
  51286. *
  51287. * @tparam Dummy Dummy template parameter used for internal purposes.
  51288. */
  51289. template<bool Dummy = true, typename = std::enable_if_t<Dummy && std::is_default_constructible_v<first_type> && std::is_default_constructible_v<second_type>>>
  51290. constexpr compressed_pair()
  51291. : first_base{},
  51292. second_base{} {}
  51293. /**
  51294. * @brief Copy constructor.
  51295. * @param other The instance to copy from.
  51296. */
  51297. constexpr compressed_pair(const compressed_pair &other) = default;
  51298. /**
  51299. * @brief Move constructor.
  51300. * @param other The instance to move from.
  51301. */
  51302. constexpr compressed_pair(compressed_pair &&other) = default;
  51303. /**
  51304. * @brief Constructs a pair from its values.
  51305. * @tparam Arg Type of value to use to initialize the first element.
  51306. * @tparam Other Type of value to use to initialize the second element.
  51307. * @param arg Value to use to initialize the first element.
  51308. * @param other Value to use to initialize the second element.
  51309. */
  51310. template<typename Arg, typename Other>
  51311. constexpr compressed_pair(Arg &&arg, Other &&other)
  51312. : first_base{std::forward<Arg>(arg)},
  51313. second_base{std::forward<Other>(other)} {}
  51314. /**
  51315. * @brief Constructs a pair by forwarding the arguments to its parts.
  51316. * @tparam Args Types of arguments to use to initialize the first element.
  51317. * @tparam Other Types of arguments to use to initialize the second element.
  51318. * @param args Arguments to use to initialize the first element.
  51319. * @param other Arguments to use to initialize the second element.
  51320. */
  51321. template<typename... Args, typename... Other>
  51322. constexpr compressed_pair(std::piecewise_construct_t, std::tuple<Args...> args, std::tuple<Other...> other)
  51323. : first_base{std::move(args), std::index_sequence_for<Args...>{}},
  51324. second_base{std::move(other), std::index_sequence_for<Other...>{}} {}
  51325. /**
  51326. * @brief Copy assignment operator.
  51327. * @param other The instance to copy from.
  51328. * @return This compressed pair object.
  51329. */
  51330. constexpr compressed_pair &operator=(const compressed_pair &other) = default;
  51331. /**
  51332. * @brief Move assignment operator.
  51333. * @param other The instance to move from.
  51334. * @return This compressed pair object.
  51335. */
  51336. constexpr compressed_pair &operator=(compressed_pair &&other) = default;
  51337. /**
  51338. * @brief Returns the first element that a pair stores.
  51339. * @return The first element that a pair stores.
  51340. */
  51341. [[nodiscard]] first_type &first() ENTT_NOEXCEPT {
  51342. return static_cast<first_base &>(*this).get();
  51343. }
  51344. /*! @copydoc first */
  51345. [[nodiscard]] const first_type &first() const ENTT_NOEXCEPT {
  51346. return static_cast<const first_base &>(*this).get();
  51347. }
  51348. /**
  51349. * @brief Returns the second element that a pair stores.
  51350. * @return The second element that a pair stores.
  51351. */
  51352. [[nodiscard]] second_type &second() ENTT_NOEXCEPT {
  51353. return static_cast<second_base &>(*this).get();
  51354. }
  51355. /*! @copydoc second */
  51356. [[nodiscard]] const second_type &second() const ENTT_NOEXCEPT {
  51357. return static_cast<const second_base &>(*this).get();
  51358. }
  51359. /**
  51360. * @brief Swaps two compressed pair objects.
  51361. * @param other The compressed pair to swap with.
  51362. */
  51363. void swap(compressed_pair &other) {
  51364. using std::swap;
  51365. swap(first(), other.first());
  51366. swap(second(), other.second());
  51367. }
  51368. /**
  51369. * @brief Extracts an element from the compressed pair.
  51370. * @tparam Index An integer value that is either 0 or 1.
  51371. * @return Returns a reference to the first element if `Index` is 0 and a
  51372. * reference to the second element if `Index` is 1.
  51373. */
  51374. template<std::size_t Index>
  51375. decltype(auto) get() ENTT_NOEXCEPT {
  51376. if constexpr(Index == 0u) {
  51377. return first();
  51378. } else {
  51379. static_assert(Index == 1u, "Index out of bounds");
  51380. return second();
  51381. }
  51382. }
  51383. /*! @copydoc get */
  51384. template<std::size_t Index>
  51385. decltype(auto) get() const ENTT_NOEXCEPT {
  51386. if constexpr(Index == 0u) {
  51387. return first();
  51388. } else {
  51389. static_assert(Index == 1u, "Index out of bounds");
  51390. return second();
  51391. }
  51392. }
  51393. };
  51394. /**
  51395. * @brief Deduction guide.
  51396. * @tparam Type Type of value to use to initialize the first element.
  51397. * @tparam Other Type of value to use to initialize the second element.
  51398. */
  51399. template<typename Type, typename Other>
  51400. compressed_pair(Type &&, Other &&) -> compressed_pair<std::decay_t<Type>, std::decay_t<Other>>;
  51401. /**
  51402. * @brief Swaps two compressed pair objects.
  51403. * @tparam First The type of the first element that the pairs store.
  51404. * @tparam Second The type of the second element that the pairs store.
  51405. * @param lhs A valid compressed pair object.
  51406. * @param rhs A valid compressed pair object.
  51407. */
  51408. template<typename First, typename Second>
  51409. inline void swap(compressed_pair<First, Second> &lhs, compressed_pair<First, Second> &rhs) {
  51410. lhs.swap(rhs);
  51411. }
  51412. } // namespace entt
  51413. // disable structured binding support for clang 6, it messes when specializing tuple_size
  51414. #if !defined __clang_major__ || __clang_major__ > 6
  51415. namespace std {
  51416. /**
  51417. * @brief `std::tuple_size` specialization for `compressed_pair`s.
  51418. * @tparam First The type of the first element that the pair stores.
  51419. * @tparam Second The type of the second element that the pair stores.
  51420. */
  51421. template<typename First, typename Second>
  51422. struct tuple_size<entt::compressed_pair<First, Second>>: integral_constant<size_t, 2u> {};
  51423. /**
  51424. * @brief `std::tuple_element` specialization for `compressed_pair`s.
  51425. * @tparam Index The index of the type to return.
  51426. * @tparam First The type of the first element that the pair stores.
  51427. * @tparam Second The type of the second element that the pair stores.
  51428. */
  51429. template<size_t Index, typename First, typename Second>
  51430. struct tuple_element<Index, entt::compressed_pair<First, Second>>: conditional<Index == 0u, First, Second> {
  51431. static_assert(Index < 2u, "Index out of bounds");
  51432. };
  51433. } // namespace std
  51434. #endif
  51435. #endif
  51436. // #include "../core/iterator.hpp"
  51437. #ifndef ENTT_CORE_ITERATOR_HPP
  51438. #define ENTT_CORE_ITERATOR_HPP
  51439. #include <iterator>
  51440. #include <memory>
  51441. #include <utility>
  51442. // #include "../config/config.h"
  51443. namespace entt {
  51444. /**
  51445. * @brief Helper type to use as pointer with input iterators.
  51446. * @tparam Type of wrapped value.
  51447. */
  51448. template<typename Type>
  51449. struct input_iterator_pointer final {
  51450. /*! @brief Pointer type. */
  51451. using pointer = Type *;
  51452. /*! @brief Default copy constructor, deleted on purpose. */
  51453. input_iterator_pointer(const input_iterator_pointer &) = delete;
  51454. /*! @brief Default move constructor. */
  51455. input_iterator_pointer(input_iterator_pointer &&) = default;
  51456. /**
  51457. * @brief Constructs a proxy object by move.
  51458. * @param val Value to use to initialize the proxy object.
  51459. */
  51460. input_iterator_pointer(Type &&val)
  51461. : value{std::move(val)} {}
  51462. /**
  51463. * @brief Default copy assignment operator, deleted on purpose.
  51464. * @return This proxy object.
  51465. */
  51466. input_iterator_pointer &operator=(const input_iterator_pointer &) = delete;
  51467. /**
  51468. * @brief Default move assignment operator.
  51469. * @return This proxy object.
  51470. */
  51471. input_iterator_pointer &operator=(input_iterator_pointer &&) = default;
  51472. /**
  51473. * @brief Access operator for accessing wrapped values.
  51474. * @return A pointer to the wrapped value.
  51475. */
  51476. [[nodiscard]] pointer operator->() ENTT_NOEXCEPT {
  51477. return std::addressof(value);
  51478. }
  51479. private:
  51480. Type value;
  51481. };
  51482. /**
  51483. * @brief Utility class to create an iterable object from a pair of iterators.
  51484. * @tparam It Type of iterator.
  51485. * @tparam Sentinel Type of sentinel.
  51486. */
  51487. template<typename It, typename Sentinel = It>
  51488. struct iterable_adaptor final {
  51489. /*! @brief Value type. */
  51490. using value_type = typename std::iterator_traits<It>::value_type;
  51491. /*! @brief Iterator type. */
  51492. using iterator = It;
  51493. /*! @brief Sentinel type. */
  51494. using sentinel = Sentinel;
  51495. /*! @brief Default constructor. */
  51496. iterable_adaptor() = default;
  51497. /**
  51498. * @brief Creates an iterable object from a pair of iterators.
  51499. * @param from Begin iterator.
  51500. * @param to End iterator.
  51501. */
  51502. iterable_adaptor(iterator from, sentinel to)
  51503. : first{from},
  51504. last{to} {}
  51505. /**
  51506. * @brief Returns an iterator to the beginning.
  51507. * @return An iterator to the first element of the range.
  51508. */
  51509. [[nodiscard]] iterator begin() const ENTT_NOEXCEPT {
  51510. return first;
  51511. }
  51512. /**
  51513. * @brief Returns an iterator to the end.
  51514. * @return An iterator to the element following the last element of the
  51515. * range.
  51516. */
  51517. [[nodiscard]] sentinel end() const ENTT_NOEXCEPT {
  51518. return last;
  51519. }
  51520. /*! @copydoc begin */
  51521. [[nodiscard]] iterator cbegin() const ENTT_NOEXCEPT {
  51522. return begin();
  51523. }
  51524. /*! @copydoc end */
  51525. [[nodiscard]] sentinel cend() const ENTT_NOEXCEPT {
  51526. return end();
  51527. }
  51528. private:
  51529. It first;
  51530. Sentinel last;
  51531. };
  51532. } // namespace entt
  51533. #endif
  51534. // #include "../core/memory.hpp"
  51535. #ifndef ENTT_CORE_MEMORY_HPP
  51536. #define ENTT_CORE_MEMORY_HPP
  51537. #include <cstddef>
  51538. #include <limits>
  51539. #include <memory>
  51540. #include <tuple>
  51541. #include <type_traits>
  51542. #include <utility>
  51543. // #include "../config/config.h"
  51544. namespace entt {
  51545. /**
  51546. * @brief Unwraps fancy pointers, does nothing otherwise (waiting for C++20).
  51547. * @tparam Type Pointer type.
  51548. * @param ptr Fancy or raw pointer.
  51549. * @return A raw pointer that represents the address of the original pointer.
  51550. */
  51551. template<typename Type>
  51552. [[nodiscard]] constexpr auto to_address(Type &&ptr) ENTT_NOEXCEPT {
  51553. if constexpr(std::is_pointer_v<std::remove_cv_t<std::remove_reference_t<Type>>>) {
  51554. return ptr;
  51555. } else {
  51556. return to_address(std::forward<Type>(ptr).operator->());
  51557. }
  51558. }
  51559. /**
  51560. * @brief Utility function to design allocation-aware containers.
  51561. * @tparam Allocator Type of allocator.
  51562. * @param lhs A valid allocator.
  51563. * @param rhs Another valid allocator.
  51564. */
  51565. template<typename Allocator>
  51566. constexpr void propagate_on_container_copy_assignment([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) ENTT_NOEXCEPT {
  51567. if constexpr(std::allocator_traits<Allocator>::propagate_on_container_copy_assignment::value) {
  51568. lhs = rhs;
  51569. }
  51570. }
  51571. /**
  51572. * @brief Utility function to design allocation-aware containers.
  51573. * @tparam Allocator Type of allocator.
  51574. * @param lhs A valid allocator.
  51575. * @param rhs Another valid allocator.
  51576. */
  51577. template<typename Allocator>
  51578. constexpr void propagate_on_container_move_assignment([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) ENTT_NOEXCEPT {
  51579. if constexpr(std::allocator_traits<Allocator>::propagate_on_container_move_assignment::value) {
  51580. lhs = std::move(rhs);
  51581. }
  51582. }
  51583. /**
  51584. * @brief Utility function to design allocation-aware containers.
  51585. * @tparam Allocator Type of allocator.
  51586. * @param lhs A valid allocator.
  51587. * @param rhs Another valid allocator.
  51588. */
  51589. template<typename Allocator>
  51590. constexpr void propagate_on_container_swap([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) ENTT_NOEXCEPT {
  51591. ENTT_ASSERT(std::allocator_traits<Allocator>::propagate_on_container_swap::value || lhs == rhs, "Cannot swap the containers");
  51592. if constexpr(std::allocator_traits<Allocator>::propagate_on_container_swap::value) {
  51593. using std::swap;
  51594. swap(lhs, rhs);
  51595. }
  51596. }
  51597. /**
  51598. * @brief Checks whether a value is a power of two or not.
  51599. * @param value A value that may or may not be a power of two.
  51600. * @return True if the value is a power of two, false otherwise.
  51601. */
  51602. [[nodiscard]] inline constexpr bool is_power_of_two(const std::size_t value) ENTT_NOEXCEPT {
  51603. return value && ((value & (value - 1)) == 0);
  51604. }
  51605. /**
  51606. * @brief Computes the smallest power of two greater than or equal to a value.
  51607. * @param value The value to use.
  51608. * @return The smallest power of two greater than or equal to the given value.
  51609. */
  51610. [[nodiscard]] inline constexpr std::size_t next_power_of_two(const std::size_t value) ENTT_NOEXCEPT {
  51611. ENTT_ASSERT(value < (std::size_t{1u} << (std::numeric_limits<std::size_t>::digits - 1)), "Numeric limits exceeded");
  51612. std::size_t curr = value - (value != 0u);
  51613. for(int next = 1; next < std::numeric_limits<std::size_t>::digits; next = next * 2) {
  51614. curr |= curr >> next;
  51615. }
  51616. return ++curr;
  51617. }
  51618. /**
  51619. * @brief Fast module utility function (powers of two only).
  51620. * @param value A value for which to calculate the modulus.
  51621. * @param mod _Modulus_, it must be a power of two.
  51622. * @return The common remainder.
  51623. */
  51624. [[nodiscard]] inline constexpr std::size_t fast_mod(const std::size_t value, const std::size_t mod) ENTT_NOEXCEPT {
  51625. ENTT_ASSERT(is_power_of_two(mod), "Value must be a power of two");
  51626. return value & (mod - 1u);
  51627. }
  51628. /**
  51629. * @brief Deleter for allocator-aware unique pointers (waiting for C++20).
  51630. * @tparam Args Types of arguments to use to construct the object.
  51631. */
  51632. template<typename Allocator>
  51633. struct allocation_deleter: private Allocator {
  51634. /*! @brief Allocator type. */
  51635. using allocator_type = Allocator;
  51636. /*! @brief Pointer type. */
  51637. using pointer = typename std::allocator_traits<Allocator>::pointer;
  51638. /**
  51639. * @brief Inherited constructors.
  51640. * @param alloc The allocator to use.
  51641. */
  51642. allocation_deleter(const allocator_type &alloc)
  51643. : Allocator{alloc} {}
  51644. /**
  51645. * @brief Destroys the pointed object and deallocates its memory.
  51646. * @param ptr A valid pointer to an object of the given type.
  51647. */
  51648. void operator()(pointer ptr) {
  51649. using alloc_traits = typename std::allocator_traits<Allocator>;
  51650. alloc_traits::destroy(*this, to_address(ptr));
  51651. alloc_traits::deallocate(*this, ptr, 1u);
  51652. }
  51653. };
  51654. /**
  51655. * @brief Allows `std::unique_ptr` to use allocators (waiting for C++20).
  51656. * @tparam Type Type of object to allocate for and to construct.
  51657. * @tparam Allocator Type of allocator used to manage memory and elements.
  51658. * @tparam Args Types of arguments to use to construct the object.
  51659. * @param allocator The allocator to use.
  51660. * @param args Parameters to use to construct the object.
  51661. * @return A properly initialized unique pointer with a custom deleter.
  51662. */
  51663. template<typename Type, typename Allocator, typename... Args>
  51664. auto allocate_unique(Allocator &allocator, Args &&...args) {
  51665. static_assert(!std::is_array_v<Type>, "Array types are not supported");
  51666. using alloc_traits = typename std::allocator_traits<Allocator>::template rebind_traits<Type>;
  51667. using allocator_type = typename alloc_traits::allocator_type;
  51668. allocator_type alloc{allocator};
  51669. auto ptr = alloc_traits::allocate(alloc, 1u);
  51670. ENTT_TRY {
  51671. alloc_traits::construct(alloc, to_address(ptr), std::forward<Args>(args)...);
  51672. }
  51673. ENTT_CATCH {
  51674. alloc_traits::deallocate(alloc, ptr, 1u);
  51675. ENTT_THROW;
  51676. }
  51677. return std::unique_ptr<Type, allocation_deleter<allocator_type>>{ptr, alloc};
  51678. }
  51679. /**
  51680. * @cond TURN_OFF_DOXYGEN
  51681. * Internal details not to be documented.
  51682. */
  51683. namespace internal {
  51684. template<typename Type>
  51685. struct uses_allocator_construction {
  51686. template<typename Allocator, typename... Params>
  51687. static constexpr auto args([[maybe_unused]] const Allocator &allocator, Params &&...params) ENTT_NOEXCEPT {
  51688. if constexpr(!std::uses_allocator_v<Type, Allocator> && std::is_constructible_v<Type, Params...>) {
  51689. return std::forward_as_tuple(std::forward<Params>(params)...);
  51690. } else {
  51691. static_assert(std::uses_allocator_v<Type, Allocator>, "Ill-formed request");
  51692. if constexpr(std::is_constructible_v<Type, std::allocator_arg_t, const Allocator &, Params...>) {
  51693. return std::tuple<std::allocator_arg_t, const Allocator &, Params &&...>(std::allocator_arg, allocator, std::forward<Params>(params)...);
  51694. } else {
  51695. static_assert(std::is_constructible_v<Type, Params..., const Allocator &>, "Ill-formed request");
  51696. return std::forward_as_tuple(std::forward<Params>(params)..., allocator);
  51697. }
  51698. }
  51699. }
  51700. };
  51701. template<typename Type, typename Other>
  51702. struct uses_allocator_construction<std::pair<Type, Other>> {
  51703. using type = std::pair<Type, Other>;
  51704. template<typename Allocator, typename First, typename Second>
  51705. static constexpr auto args(const Allocator &allocator, std::piecewise_construct_t, First &&first, Second &&second) ENTT_NOEXCEPT {
  51706. return std::make_tuple(
  51707. std::piecewise_construct,
  51708. std::apply([&allocator](auto &&...curr) { return uses_allocator_construction<Type>::args(allocator, std::forward<decltype(curr)>(curr)...); }, std::forward<First>(first)),
  51709. std::apply([&allocator](auto &&...curr) { return uses_allocator_construction<Other>::args(allocator, std::forward<decltype(curr)>(curr)...); }, std::forward<Second>(second)));
  51710. }
  51711. template<typename Allocator>
  51712. static constexpr auto args(const Allocator &allocator) ENTT_NOEXCEPT {
  51713. return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::tuple<>{}, std::tuple<>{});
  51714. }
  51715. template<typename Allocator, typename First, typename Second>
  51716. static constexpr auto args(const Allocator &allocator, First &&first, Second &&second) ENTT_NOEXCEPT {
  51717. 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)));
  51718. }
  51719. template<typename Allocator, typename First, typename Second>
  51720. static constexpr auto args(const Allocator &allocator, const std::pair<First, Second> &value) ENTT_NOEXCEPT {
  51721. return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::forward_as_tuple(value.first), std::forward_as_tuple(value.second));
  51722. }
  51723. template<typename Allocator, typename First, typename Second>
  51724. static constexpr auto args(const Allocator &allocator, std::pair<First, Second> &&value) ENTT_NOEXCEPT {
  51725. 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)));
  51726. }
  51727. };
  51728. } // namespace internal
  51729. /**
  51730. * Internal details not to be documented.
  51731. * @endcond
  51732. */
  51733. /**
  51734. * @brief Uses-allocator construction utility (waiting for C++20).
  51735. *
  51736. * Primarily intended for internal use. Prepares the argument list needed to
  51737. * create an object of a given type by means of uses-allocator construction.
  51738. *
  51739. * @tparam Type Type to return arguments for.
  51740. * @tparam Allocator Type of allocator used to manage memory and elements.
  51741. * @tparam Args Types of arguments to use to construct the object.
  51742. * @param allocator The allocator to use.
  51743. * @param args Parameters to use to construct the object.
  51744. * @return The arguments needed to create an object of the given type.
  51745. */
  51746. template<typename Type, typename Allocator, typename... Args>
  51747. constexpr auto uses_allocator_construction_args(const Allocator &allocator, Args &&...args) ENTT_NOEXCEPT {
  51748. return internal::uses_allocator_construction<Type>::args(allocator, std::forward<Args>(args)...);
  51749. }
  51750. /**
  51751. * @brief Uses-allocator construction utility (waiting for C++20).
  51752. *
  51753. * Primarily intended for internal use. Creates an object of a given type by
  51754. * means of uses-allocator construction.
  51755. *
  51756. * @tparam Type Type of object to create.
  51757. * @tparam Allocator Type of allocator used to manage memory and elements.
  51758. * @tparam Args Types of arguments to use to construct the object.
  51759. * @param allocator The allocator to use.
  51760. * @param args Parameters to use to construct the object.
  51761. * @return A newly created object of the given type.
  51762. */
  51763. template<typename Type, typename Allocator, typename... Args>
  51764. constexpr Type make_obj_using_allocator(const Allocator &allocator, Args &&...args) {
  51765. return std::make_from_tuple<Type>(internal::uses_allocator_construction<Type>::args(allocator, std::forward<Args>(args)...));
  51766. }
  51767. /**
  51768. * @brief Uses-allocator construction utility (waiting for C++20).
  51769. *
  51770. * Primarily intended for internal use. Creates an object of a given type by
  51771. * means of uses-allocator construction at an uninitialized memory location.
  51772. *
  51773. * @tparam Type Type of object to create.
  51774. * @tparam Allocator Type of allocator used to manage memory and elements.
  51775. * @tparam Args Types of arguments to use to construct the object.
  51776. * @param value Memory location in which to place the object.
  51777. * @param allocator The allocator to use.
  51778. * @param args Parameters to use to construct the object.
  51779. * @return A pointer to the newly created object of the given type.
  51780. */
  51781. template<typename Type, typename Allocator, typename... Args>
  51782. constexpr Type *uninitialized_construct_using_allocator(Type *value, const Allocator &allocator, Args &&...args) {
  51783. return std::apply([&](auto &&...curr) { return new(value) Type(std::forward<decltype(curr)>(curr)...); }, internal::uses_allocator_construction<Type>::args(allocator, std::forward<Args>(args)...));
  51784. }
  51785. } // namespace entt
  51786. #endif
  51787. // #include "../core/type_traits.hpp"
  51788. #ifndef ENTT_CORE_TYPE_TRAITS_HPP
  51789. #define ENTT_CORE_TYPE_TRAITS_HPP
  51790. #include <cstddef>
  51791. #include <iterator>
  51792. #include <type_traits>
  51793. #include <utility>
  51794. // #include "../config/config.h"
  51795. // #include "fwd.hpp"
  51796. namespace entt {
  51797. /**
  51798. * @brief Utility class to disambiguate overloaded functions.
  51799. * @tparam N Number of choices available.
  51800. */
  51801. template<std::size_t N>
  51802. struct choice_t
  51803. // Unfortunately, doxygen cannot parse such a construct.
  51804. : /*! @cond TURN_OFF_DOXYGEN */ choice_t<N - 1> /*! @endcond */
  51805. {};
  51806. /*! @copybrief choice_t */
  51807. template<>
  51808. struct choice_t<0> {};
  51809. /**
  51810. * @brief Variable template for the choice trick.
  51811. * @tparam N Number of choices available.
  51812. */
  51813. template<std::size_t N>
  51814. inline constexpr choice_t<N> choice{};
  51815. /**
  51816. * @brief Identity type trait.
  51817. *
  51818. * Useful to establish non-deduced contexts in template argument deduction
  51819. * (waiting for C++20) or to provide types through function arguments.
  51820. *
  51821. * @tparam Type A type.
  51822. */
  51823. template<typename Type>
  51824. struct type_identity {
  51825. /*! @brief Identity type. */
  51826. using type = Type;
  51827. };
  51828. /**
  51829. * @brief Helper type.
  51830. * @tparam Type A type.
  51831. */
  51832. template<typename Type>
  51833. using type_identity_t = typename type_identity<Type>::type;
  51834. /**
  51835. * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains.
  51836. * @tparam Type The type of which to return the size.
  51837. * @tparam The size of the type if `sizeof` accepts it, 0 otherwise.
  51838. */
  51839. template<typename Type, typename = void>
  51840. struct size_of: std::integral_constant<std::size_t, 0u> {};
  51841. /*! @copydoc size_of */
  51842. template<typename Type>
  51843. struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
  51844. : std::integral_constant<std::size_t, sizeof(Type)> {};
  51845. /**
  51846. * @brief Helper variable template.
  51847. * @tparam Type The type of which to return the size.
  51848. */
  51849. template<typename Type>
  51850. inline constexpr std::size_t size_of_v = size_of<Type>::value;
  51851. /**
  51852. * @brief Using declaration to be used to _repeat_ the same type a number of
  51853. * times equal to the size of a given parameter pack.
  51854. * @tparam Type A type to repeat.
  51855. */
  51856. template<typename Type, typename>
  51857. using unpack_as_type = Type;
  51858. /**
  51859. * @brief Helper variable template to be used to _repeat_ the same value a
  51860. * number of times equal to the size of a given parameter pack.
  51861. * @tparam Value A value to repeat.
  51862. */
  51863. template<auto Value, typename>
  51864. inline constexpr auto unpack_as_value = Value;
  51865. /**
  51866. * @brief Wraps a static constant.
  51867. * @tparam Value A static constant.
  51868. */
  51869. template<auto Value>
  51870. using integral_constant = std::integral_constant<decltype(Value), Value>;
  51871. /**
  51872. * @brief Alias template to facilitate the creation of named values.
  51873. * @tparam Value A constant value at least convertible to `id_type`.
  51874. */
  51875. template<id_type Value>
  51876. using tag = integral_constant<Value>;
  51877. /**
  51878. * @brief A class to use to push around lists of types, nothing more.
  51879. * @tparam Type Types provided by the type list.
  51880. */
  51881. template<typename... Type>
  51882. struct type_list {
  51883. /*! @brief Type list type. */
  51884. using type = type_list;
  51885. /*! @brief Compile-time number of elements in the type list. */
  51886. static constexpr auto size = sizeof...(Type);
  51887. };
  51888. /*! @brief Primary template isn't defined on purpose. */
  51889. template<std::size_t, typename>
  51890. struct type_list_element;
  51891. /**
  51892. * @brief Provides compile-time indexed access to the types of a type list.
  51893. * @tparam Index Index of the type to return.
  51894. * @tparam Type First type provided by the type list.
  51895. * @tparam Other Other types provided by the type list.
  51896. */
  51897. template<std::size_t Index, typename Type, typename... Other>
  51898. struct type_list_element<Index, type_list<Type, Other...>>
  51899. : type_list_element<Index - 1u, type_list<Other...>> {};
  51900. /**
  51901. * @brief Provides compile-time indexed access to the types of a type list.
  51902. * @tparam Type First type provided by the type list.
  51903. * @tparam Other Other types provided by the type list.
  51904. */
  51905. template<typename Type, typename... Other>
  51906. struct type_list_element<0u, type_list<Type, Other...>> {
  51907. /*! @brief Searched type. */
  51908. using type = Type;
  51909. };
  51910. /**
  51911. * @brief Helper type.
  51912. * @tparam Index Index of the type to return.
  51913. * @tparam List Type list to search into.
  51914. */
  51915. template<std::size_t Index, typename List>
  51916. using type_list_element_t = typename type_list_element<Index, List>::type;
  51917. /**
  51918. * @brief Concatenates multiple type lists.
  51919. * @tparam Type Types provided by the first type list.
  51920. * @tparam Other Types provided by the second type list.
  51921. * @return A type list composed by the types of both the type lists.
  51922. */
  51923. template<typename... Type, typename... Other>
  51924. constexpr type_list<Type..., Other...> operator+(type_list<Type...>, type_list<Other...>) {
  51925. return {};
  51926. }
  51927. /*! @brief Primary template isn't defined on purpose. */
  51928. template<typename...>
  51929. struct type_list_cat;
  51930. /*! @brief Concatenates multiple type lists. */
  51931. template<>
  51932. struct type_list_cat<> {
  51933. /*! @brief A type list composed by the types of all the type lists. */
  51934. using type = type_list<>;
  51935. };
  51936. /**
  51937. * @brief Concatenates multiple type lists.
  51938. * @tparam Type Types provided by the first type list.
  51939. * @tparam Other Types provided by the second type list.
  51940. * @tparam List Other type lists, if any.
  51941. */
  51942. template<typename... Type, typename... Other, typename... List>
  51943. struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
  51944. /*! @brief A type list composed by the types of all the type lists. */
  51945. using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
  51946. };
  51947. /**
  51948. * @brief Concatenates multiple type lists.
  51949. * @tparam Type Types provided by the type list.
  51950. */
  51951. template<typename... Type>
  51952. struct type_list_cat<type_list<Type...>> {
  51953. /*! @brief A type list composed by the types of all the type lists. */
  51954. using type = type_list<Type...>;
  51955. };
  51956. /**
  51957. * @brief Helper type.
  51958. * @tparam List Type lists to concatenate.
  51959. */
  51960. template<typename... List>
  51961. using type_list_cat_t = typename type_list_cat<List...>::type;
  51962. /*! @brief Primary template isn't defined on purpose. */
  51963. template<typename>
  51964. struct type_list_unique;
  51965. /**
  51966. * @brief Removes duplicates types from a type list.
  51967. * @tparam Type One of the types provided by the given type list.
  51968. * @tparam Other The other types provided by the given type list.
  51969. */
  51970. template<typename Type, typename... Other>
  51971. struct type_list_unique<type_list<Type, Other...>> {
  51972. /*! @brief A type list without duplicate types. */
  51973. using type = std::conditional_t<
  51974. (std::is_same_v<Type, Other> || ...),
  51975. typename type_list_unique<type_list<Other...>>::type,
  51976. type_list_cat_t<type_list<Type>, typename type_list_unique<type_list<Other...>>::type>>;
  51977. };
  51978. /*! @brief Removes duplicates types from a type list. */
  51979. template<>
  51980. struct type_list_unique<type_list<>> {
  51981. /*! @brief A type list without duplicate types. */
  51982. using type = type_list<>;
  51983. };
  51984. /**
  51985. * @brief Helper type.
  51986. * @tparam Type A type list.
  51987. */
  51988. template<typename Type>
  51989. using type_list_unique_t = typename type_list_unique<Type>::type;
  51990. /**
  51991. * @brief Provides the member constant `value` to true if a type list contains a
  51992. * given type, false otherwise.
  51993. * @tparam List Type list.
  51994. * @tparam Type Type to look for.
  51995. */
  51996. template<typename List, typename Type>
  51997. struct type_list_contains;
  51998. /**
  51999. * @copybrief type_list_contains
  52000. * @tparam Type Types provided by the type list.
  52001. * @tparam Other Type to look for.
  52002. */
  52003. template<typename... Type, typename Other>
  52004. struct type_list_contains<type_list<Type...>, Other>: std::disjunction<std::is_same<Type, Other>...> {};
  52005. /**
  52006. * @brief Helper variable template.
  52007. * @tparam List Type list.
  52008. * @tparam Type Type to look for.
  52009. */
  52010. template<typename List, typename Type>
  52011. inline constexpr bool type_list_contains_v = type_list_contains<List, Type>::value;
  52012. /*! @brief Primary template isn't defined on purpose. */
  52013. template<typename...>
  52014. struct type_list_diff;
  52015. /**
  52016. * @brief Computes the difference between two type lists.
  52017. * @tparam Type Types provided by the first type list.
  52018. * @tparam Other Types provided by the second type list.
  52019. */
  52020. template<typename... Type, typename... Other>
  52021. struct type_list_diff<type_list<Type...>, type_list<Other...>> {
  52022. /*! @brief A type list that is the difference between the two type lists. */
  52023. using type = type_list_cat_t<std::conditional_t<type_list_contains_v<type_list<Other...>, Type>, type_list<>, type_list<Type>>...>;
  52024. };
  52025. /**
  52026. * @brief Helper type.
  52027. * @tparam List Type lists between which to compute the difference.
  52028. */
  52029. template<typename... List>
  52030. using type_list_diff_t = typename type_list_diff<List...>::type;
  52031. /**
  52032. * @brief A class to use to push around lists of constant values, nothing more.
  52033. * @tparam Value Values provided by the value list.
  52034. */
  52035. template<auto... Value>
  52036. struct value_list {
  52037. /*! @brief Value list type. */
  52038. using type = value_list;
  52039. /*! @brief Compile-time number of elements in the value list. */
  52040. static constexpr auto size = sizeof...(Value);
  52041. };
  52042. /*! @brief Primary template isn't defined on purpose. */
  52043. template<std::size_t, typename>
  52044. struct value_list_element;
  52045. /**
  52046. * @brief Provides compile-time indexed access to the values of a value list.
  52047. * @tparam Index Index of the value to return.
  52048. * @tparam Value First value provided by the value list.
  52049. * @tparam Other Other values provided by the value list.
  52050. */
  52051. template<std::size_t Index, auto Value, auto... Other>
  52052. struct value_list_element<Index, value_list<Value, Other...>>
  52053. : value_list_element<Index - 1u, value_list<Other...>> {};
  52054. /**
  52055. * @brief Provides compile-time indexed access to the types of a type list.
  52056. * @tparam Value First value provided by the value list.
  52057. * @tparam Other Other values provided by the value list.
  52058. */
  52059. template<auto Value, auto... Other>
  52060. struct value_list_element<0u, value_list<Value, Other...>> {
  52061. /*! @brief Searched value. */
  52062. static constexpr auto value = Value;
  52063. };
  52064. /**
  52065. * @brief Helper type.
  52066. * @tparam Index Index of the value to return.
  52067. * @tparam List Value list to search into.
  52068. */
  52069. template<std::size_t Index, typename List>
  52070. inline constexpr auto value_list_element_v = value_list_element<Index, List>::value;
  52071. /**
  52072. * @brief Concatenates multiple value lists.
  52073. * @tparam Value Values provided by the first value list.
  52074. * @tparam Other Values provided by the second value list.
  52075. * @return A value list composed by the values of both the value lists.
  52076. */
  52077. template<auto... Value, auto... Other>
  52078. constexpr value_list<Value..., Other...> operator+(value_list<Value...>, value_list<Other...>) {
  52079. return {};
  52080. }
  52081. /*! @brief Primary template isn't defined on purpose. */
  52082. template<typename...>
  52083. struct value_list_cat;
  52084. /*! @brief Concatenates multiple value lists. */
  52085. template<>
  52086. struct value_list_cat<> {
  52087. /*! @brief A value list composed by the values of all the value lists. */
  52088. using type = value_list<>;
  52089. };
  52090. /**
  52091. * @brief Concatenates multiple value lists.
  52092. * @tparam Value Values provided by the first value list.
  52093. * @tparam Other Values provided by the second value list.
  52094. * @tparam List Other value lists, if any.
  52095. */
  52096. template<auto... Value, auto... Other, typename... List>
  52097. struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
  52098. /*! @brief A value list composed by the values of all the value lists. */
  52099. using type = typename value_list_cat<value_list<Value..., Other...>, List...>::type;
  52100. };
  52101. /**
  52102. * @brief Concatenates multiple value lists.
  52103. * @tparam Value Values provided by the value list.
  52104. */
  52105. template<auto... Value>
  52106. struct value_list_cat<value_list<Value...>> {
  52107. /*! @brief A value list composed by the values of all the value lists. */
  52108. using type = value_list<Value...>;
  52109. };
  52110. /**
  52111. * @brief Helper type.
  52112. * @tparam List Value lists to concatenate.
  52113. */
  52114. template<typename... List>
  52115. using value_list_cat_t = typename value_list_cat<List...>::type;
  52116. /*! @brief Same as std::is_invocable, but with tuples. */
  52117. template<typename, typename>
  52118. struct is_applicable: std::false_type {};
  52119. /**
  52120. * @copybrief is_applicable
  52121. * @tparam Func A valid function type.
  52122. * @tparam Tuple Tuple-like type.
  52123. * @tparam Args The list of arguments to use to probe the function type.
  52124. */
  52125. template<typename Func, template<typename...> class Tuple, typename... Args>
  52126. struct is_applicable<Func, Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  52127. /**
  52128. * @copybrief is_applicable
  52129. * @tparam Func A valid function type.
  52130. * @tparam Tuple Tuple-like type.
  52131. * @tparam Args The list of arguments to use to probe the function type.
  52132. */
  52133. template<typename Func, template<typename...> class Tuple, typename... Args>
  52134. struct is_applicable<Func, const Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  52135. /**
  52136. * @brief Helper variable template.
  52137. * @tparam Func A valid function type.
  52138. * @tparam Args The list of arguments to use to probe the function type.
  52139. */
  52140. template<typename Func, typename Args>
  52141. inline constexpr bool is_applicable_v = is_applicable<Func, Args>::value;
  52142. /*! @brief Same as std::is_invocable_r, but with tuples for arguments. */
  52143. template<typename, typename, typename>
  52144. struct is_applicable_r: std::false_type {};
  52145. /**
  52146. * @copybrief is_applicable_r
  52147. * @tparam Ret The type to which the return type of the function should be
  52148. * convertible.
  52149. * @tparam Func A valid function type.
  52150. * @tparam Args The list of arguments to use to probe the function type.
  52151. */
  52152. template<typename Ret, typename Func, typename... Args>
  52153. struct is_applicable_r<Ret, Func, std::tuple<Args...>>: std::is_invocable_r<Ret, Func, Args...> {};
  52154. /**
  52155. * @brief Helper variable template.
  52156. * @tparam Ret The type to which the return type of the function should be
  52157. * convertible.
  52158. * @tparam Func A valid function type.
  52159. * @tparam Args The list of arguments to use to probe the function type.
  52160. */
  52161. template<typename Ret, typename Func, typename Args>
  52162. inline constexpr bool is_applicable_r_v = is_applicable_r<Ret, Func, Args>::value;
  52163. /**
  52164. * @brief Provides the member constant `value` to true if a given type is
  52165. * complete, false otherwise.
  52166. * @tparam Type The type to test.
  52167. */
  52168. template<typename Type, typename = void>
  52169. struct is_complete: std::false_type {};
  52170. /*! @copydoc is_complete */
  52171. template<typename Type>
  52172. struct is_complete<Type, std::void_t<decltype(sizeof(Type))>>: std::true_type {};
  52173. /**
  52174. * @brief Helper variable template.
  52175. * @tparam Type The type to test.
  52176. */
  52177. template<typename Type>
  52178. inline constexpr bool is_complete_v = is_complete<Type>::value;
  52179. /**
  52180. * @brief Provides the member constant `value` to true if a given type is an
  52181. * iterator, false otherwise.
  52182. * @tparam Type The type to test.
  52183. */
  52184. template<typename Type, typename = void>
  52185. struct is_iterator: std::false_type {};
  52186. /**
  52187. * @cond TURN_OFF_DOXYGEN
  52188. * Internal details not to be documented.
  52189. */
  52190. namespace internal {
  52191. template<typename, typename = void>
  52192. struct has_iterator_category: std::false_type {};
  52193. template<typename Type>
  52194. struct has_iterator_category<Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>: std::true_type {};
  52195. } // namespace internal
  52196. /**
  52197. * Internal details not to be documented.
  52198. * @endcond
  52199. */
  52200. /*! @copydoc is_iterator */
  52201. template<typename Type>
  52202. struct is_iterator<Type, std::enable_if_t<!std::is_same_v<std::remove_const_t<std::remove_pointer_t<Type>>, void>>>
  52203. : internal::has_iterator_category<Type> {};
  52204. /**
  52205. * @brief Helper variable template.
  52206. * @tparam Type The type to test.
  52207. */
  52208. template<typename Type>
  52209. inline constexpr bool is_iterator_v = is_iterator<Type>::value;
  52210. /**
  52211. * @brief Provides the member constant `value` to true if a given type is both
  52212. * an empty and non-final class, false otherwise.
  52213. * @tparam Type The type to test
  52214. */
  52215. template<typename Type>
  52216. struct is_ebco_eligible
  52217. : std::conjunction<std::is_empty<Type>, std::negation<std::is_final<Type>>> {};
  52218. /**
  52219. * @brief Helper variable template.
  52220. * @tparam Type The type to test.
  52221. */
  52222. template<typename Type>
  52223. inline constexpr bool is_ebco_eligible_v = is_ebco_eligible<Type>::value;
  52224. /**
  52225. * @brief Provides the member constant `value` to true if `Type::is_transparent`
  52226. * is valid and denotes a type, false otherwise.
  52227. * @tparam Type The type to test.
  52228. */
  52229. template<typename Type, typename = void>
  52230. struct is_transparent: std::false_type {};
  52231. /*! @copydoc is_transparent */
  52232. template<typename Type>
  52233. struct is_transparent<Type, std::void_t<typename Type::is_transparent>>: std::true_type {};
  52234. /**
  52235. * @brief Helper variable template.
  52236. * @tparam Type The type to test.
  52237. */
  52238. template<typename Type>
  52239. inline constexpr bool is_transparent_v = is_transparent<Type>::value;
  52240. /**
  52241. * @brief Provides the member constant `value` to true if a given type is
  52242. * equality comparable, false otherwise.
  52243. * @tparam Type The type to test.
  52244. */
  52245. template<typename Type, typename = void>
  52246. struct is_equality_comparable: std::false_type {};
  52247. /**
  52248. * @cond TURN_OFF_DOXYGEN
  52249. * Internal details not to be documented.
  52250. */
  52251. namespace internal {
  52252. template<typename, typename = void>
  52253. struct has_tuple_size_value: std::false_type {};
  52254. template<typename Type>
  52255. struct has_tuple_size_value<Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>: std::true_type {};
  52256. template<typename Type, std::size_t... Index>
  52257. [[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
  52258. return (is_equality_comparable<std::tuple_element_t<Index, Type>>::value && ...);
  52259. }
  52260. template<typename>
  52261. [[nodiscard]] constexpr bool maybe_equality_comparable(choice_t<0>) {
  52262. return true;
  52263. }
  52264. template<typename Type>
  52265. [[nodiscard]] constexpr auto maybe_equality_comparable(choice_t<1>) -> decltype(std::declval<typename Type::value_type>(), bool{}) {
  52266. if constexpr(is_iterator_v<Type>) {
  52267. return true;
  52268. } else if constexpr(std::is_same_v<typename Type::value_type, Type>) {
  52269. return maybe_equality_comparable<Type>(choice<0>);
  52270. } else {
  52271. return is_equality_comparable<typename Type::value_type>::value;
  52272. }
  52273. }
  52274. template<typename Type>
  52275. [[nodiscard]] constexpr std::enable_if_t<is_complete_v<std::tuple_size<std::remove_const_t<Type>>>, bool> maybe_equality_comparable(choice_t<2>) {
  52276. if constexpr(has_tuple_size_value<Type>::value) {
  52277. return unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
  52278. } else {
  52279. return maybe_equality_comparable<Type>(choice<1>);
  52280. }
  52281. }
  52282. } // namespace internal
  52283. /**
  52284. * Internal details not to be documented.
  52285. * @endcond
  52286. */
  52287. /*! @copydoc is_equality_comparable */
  52288. template<typename Type>
  52289. struct is_equality_comparable<Type, std::void_t<decltype(std::declval<Type>() == std::declval<Type>())>>
  52290. : std::bool_constant<internal::maybe_equality_comparable<Type>(choice<2>)> {};
  52291. /**
  52292. * @brief Helper variable template.
  52293. * @tparam Type The type to test.
  52294. */
  52295. template<typename Type>
  52296. inline constexpr bool is_equality_comparable_v = is_equality_comparable<Type>::value;
  52297. /**
  52298. * @brief Transcribes the constness of a type to another type.
  52299. * @tparam To The type to which to transcribe the constness.
  52300. * @tparam From The type from which to transcribe the constness.
  52301. */
  52302. template<typename To, typename From>
  52303. struct constness_as {
  52304. /*! @brief The type resulting from the transcription of the constness. */
  52305. using type = std::remove_const_t<To>;
  52306. };
  52307. /*! @copydoc constness_as */
  52308. template<typename To, typename From>
  52309. struct constness_as<To, const From> {
  52310. /*! @brief The type resulting from the transcription of the constness. */
  52311. using type = std::add_const_t<To>;
  52312. };
  52313. /**
  52314. * @brief Alias template to facilitate the transcription of the constness.
  52315. * @tparam To The type to which to transcribe the constness.
  52316. * @tparam From The type from which to transcribe the constness.
  52317. */
  52318. template<typename To, typename From>
  52319. using constness_as_t = typename constness_as<To, From>::type;
  52320. /**
  52321. * @brief Extracts the class of a non-static member object or function.
  52322. * @tparam Member A pointer to a non-static member object or function.
  52323. */
  52324. template<typename Member>
  52325. class member_class {
  52326. static_assert(std::is_member_pointer_v<Member>, "Invalid pointer type to non-static member object or function");
  52327. template<typename Class, typename Ret, typename... Args>
  52328. static Class *clazz(Ret (Class::*)(Args...));
  52329. template<typename Class, typename Ret, typename... Args>
  52330. static Class *clazz(Ret (Class::*)(Args...) const);
  52331. template<typename Class, typename Type>
  52332. static Class *clazz(Type Class::*);
  52333. public:
  52334. /*! @brief The class of the given non-static member object or function. */
  52335. using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
  52336. };
  52337. /**
  52338. * @brief Helper type.
  52339. * @tparam Member A pointer to a non-static member object or function.
  52340. */
  52341. template<typename Member>
  52342. using member_class_t = typename member_class<Member>::type;
  52343. } // namespace entt
  52344. #endif
  52345. // #include "fwd.hpp"
  52346. #ifndef ENTT_CONTAINER_FWD_HPP
  52347. #define ENTT_CONTAINER_FWD_HPP
  52348. #include <functional>
  52349. #include <memory>
  52350. namespace entt {
  52351. template<
  52352. typename Key,
  52353. typename Type,
  52354. typename = std::hash<Key>,
  52355. typename = std::equal_to<Key>,
  52356. typename = std::allocator<std::pair<const Key, Type>>>
  52357. class dense_map;
  52358. template<
  52359. typename Type,
  52360. typename = std::hash<Type>,
  52361. typename = std::equal_to<Type>,
  52362. typename = std::allocator<Type>>
  52363. class dense_set;
  52364. } // namespace entt
  52365. #endif
  52366. namespace entt {
  52367. /**
  52368. * @cond TURN_OFF_DOXYGEN
  52369. * Internal details not to be documented.
  52370. */
  52371. namespace internal {
  52372. template<typename Key, typename Type>
  52373. struct dense_map_node final {
  52374. using value_type = std::pair<Key, Type>;
  52375. template<typename... Args>
  52376. dense_map_node(const std::size_t pos, Args &&...args)
  52377. : next{pos},
  52378. element{std::forward<Args>(args)...} {}
  52379. template<typename Allocator, typename... Args>
  52380. dense_map_node(std::allocator_arg_t, const Allocator &allocator, const std::size_t pos, Args &&...args)
  52381. : next{pos},
  52382. element{entt::make_obj_using_allocator<value_type>(allocator, std::forward<Args>(args)...)} {}
  52383. template<typename Allocator>
  52384. dense_map_node(std::allocator_arg_t, const Allocator &allocator, const dense_map_node &other)
  52385. : next{other.next},
  52386. element{entt::make_obj_using_allocator<value_type>(allocator, other.element)} {}
  52387. template<typename Allocator>
  52388. dense_map_node(std::allocator_arg_t, const Allocator &allocator, dense_map_node &&other)
  52389. : next{other.next},
  52390. element{entt::make_obj_using_allocator<value_type>(allocator, std::move(other.element))} {}
  52391. std::size_t next;
  52392. value_type element;
  52393. };
  52394. template<typename It>
  52395. class dense_map_iterator final {
  52396. template<typename>
  52397. friend class dense_map_iterator;
  52398. using first_type = decltype(std::as_const(std::declval<It>()->element.first));
  52399. using second_type = decltype((std::declval<It>()->element.second));
  52400. public:
  52401. using value_type = std::pair<first_type, second_type>;
  52402. using pointer = input_iterator_pointer<value_type>;
  52403. using reference = value_type;
  52404. using difference_type = std::ptrdiff_t;
  52405. using iterator_category = std::input_iterator_tag;
  52406. dense_map_iterator() ENTT_NOEXCEPT
  52407. : it{} {}
  52408. dense_map_iterator(const It iter) ENTT_NOEXCEPT
  52409. : it{iter} {}
  52410. template<typename Other, typename = std::enable_if_t<!std::is_same_v<It, Other> && std::is_constructible_v<It, Other>>>
  52411. dense_map_iterator(const dense_map_iterator<Other> &other) ENTT_NOEXCEPT
  52412. : it{other.it} {}
  52413. dense_map_iterator &operator++() ENTT_NOEXCEPT {
  52414. return ++it, *this;
  52415. }
  52416. dense_map_iterator operator++(int) ENTT_NOEXCEPT {
  52417. dense_map_iterator orig = *this;
  52418. return ++(*this), orig;
  52419. }
  52420. dense_map_iterator &operator--() ENTT_NOEXCEPT {
  52421. return --it, *this;
  52422. }
  52423. dense_map_iterator operator--(int) ENTT_NOEXCEPT {
  52424. dense_map_iterator orig = *this;
  52425. return operator--(), orig;
  52426. }
  52427. dense_map_iterator &operator+=(const difference_type value) ENTT_NOEXCEPT {
  52428. it += value;
  52429. return *this;
  52430. }
  52431. dense_map_iterator operator+(const difference_type value) const ENTT_NOEXCEPT {
  52432. dense_map_iterator copy = *this;
  52433. return (copy += value);
  52434. }
  52435. dense_map_iterator &operator-=(const difference_type value) ENTT_NOEXCEPT {
  52436. return (*this += -value);
  52437. }
  52438. dense_map_iterator operator-(const difference_type value) const ENTT_NOEXCEPT {
  52439. return (*this + -value);
  52440. }
  52441. [[nodiscard]] reference operator[](const difference_type value) const ENTT_NOEXCEPT {
  52442. return {it[value].element.first, it[value].element.second};
  52443. }
  52444. [[nodiscard]] pointer operator->() const ENTT_NOEXCEPT {
  52445. return operator*();
  52446. }
  52447. [[nodiscard]] reference operator*() const ENTT_NOEXCEPT {
  52448. return {it->element.first, it->element.second};
  52449. }
  52450. template<typename ILhs, typename IRhs>
  52451. friend std::ptrdiff_t operator-(const dense_map_iterator<ILhs> &, const dense_map_iterator<IRhs> &) ENTT_NOEXCEPT;
  52452. template<typename ILhs, typename IRhs>
  52453. friend bool operator==(const dense_map_iterator<ILhs> &, const dense_map_iterator<IRhs> &) ENTT_NOEXCEPT;
  52454. template<typename ILhs, typename IRhs>
  52455. friend bool operator<(const dense_map_iterator<ILhs> &, const dense_map_iterator<IRhs> &) ENTT_NOEXCEPT;
  52456. private:
  52457. It it;
  52458. };
  52459. template<typename ILhs, typename IRhs>
  52460. [[nodiscard]] std::ptrdiff_t operator-(const dense_map_iterator<ILhs> &lhs, const dense_map_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  52461. return lhs.it - rhs.it;
  52462. }
  52463. template<typename ILhs, typename IRhs>
  52464. [[nodiscard]] bool operator==(const dense_map_iterator<ILhs> &lhs, const dense_map_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  52465. return lhs.it == rhs.it;
  52466. }
  52467. template<typename ILhs, typename IRhs>
  52468. [[nodiscard]] bool operator!=(const dense_map_iterator<ILhs> &lhs, const dense_map_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  52469. return !(lhs == rhs);
  52470. }
  52471. template<typename ILhs, typename IRhs>
  52472. [[nodiscard]] bool operator<(const dense_map_iterator<ILhs> &lhs, const dense_map_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  52473. return lhs.it < rhs.it;
  52474. }
  52475. template<typename ILhs, typename IRhs>
  52476. [[nodiscard]] bool operator>(const dense_map_iterator<ILhs> &lhs, const dense_map_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  52477. return rhs < lhs;
  52478. }
  52479. template<typename ILhs, typename IRhs>
  52480. [[nodiscard]] bool operator<=(const dense_map_iterator<ILhs> &lhs, const dense_map_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  52481. return !(lhs > rhs);
  52482. }
  52483. template<typename ILhs, typename IRhs>
  52484. [[nodiscard]] bool operator>=(const dense_map_iterator<ILhs> &lhs, const dense_map_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  52485. return !(lhs < rhs);
  52486. }
  52487. template<typename It>
  52488. class dense_map_local_iterator final {
  52489. template<typename>
  52490. friend class dense_map_local_iterator;
  52491. using first_type = decltype(std::as_const(std::declval<It>()->element.first));
  52492. using second_type = decltype((std::declval<It>()->element.second));
  52493. public:
  52494. using value_type = std::pair<first_type, second_type>;
  52495. using pointer = input_iterator_pointer<value_type>;
  52496. using reference = value_type;
  52497. using difference_type = std::ptrdiff_t;
  52498. using iterator_category = std::input_iterator_tag;
  52499. dense_map_local_iterator() ENTT_NOEXCEPT
  52500. : it{},
  52501. offset{} {}
  52502. dense_map_local_iterator(It iter, const std::size_t pos) ENTT_NOEXCEPT
  52503. : it{iter},
  52504. offset{pos} {}
  52505. template<typename Other, typename = std::enable_if_t<!std::is_same_v<It, Other> && std::is_constructible_v<It, Other>>>
  52506. dense_map_local_iterator(const dense_map_local_iterator<Other> &other) ENTT_NOEXCEPT
  52507. : it{other.it},
  52508. offset{other.offset} {}
  52509. dense_map_local_iterator &operator++() ENTT_NOEXCEPT {
  52510. return offset = it[offset].next, *this;
  52511. }
  52512. dense_map_local_iterator operator++(int) ENTT_NOEXCEPT {
  52513. dense_map_local_iterator orig = *this;
  52514. return ++(*this), orig;
  52515. }
  52516. [[nodiscard]] pointer operator->() const ENTT_NOEXCEPT {
  52517. return operator*();
  52518. }
  52519. [[nodiscard]] reference operator*() const ENTT_NOEXCEPT {
  52520. return {it[offset].element.first, it[offset].element.second};
  52521. }
  52522. [[nodiscard]] std::size_t index() const ENTT_NOEXCEPT {
  52523. return offset;
  52524. }
  52525. private:
  52526. It it;
  52527. std::size_t offset;
  52528. };
  52529. template<typename ILhs, typename IRhs>
  52530. [[nodiscard]] bool operator==(const dense_map_local_iterator<ILhs> &lhs, const dense_map_local_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  52531. return lhs.index() == rhs.index();
  52532. }
  52533. template<typename ILhs, typename IRhs>
  52534. [[nodiscard]] bool operator!=(const dense_map_local_iterator<ILhs> &lhs, const dense_map_local_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
  52535. return !(lhs == rhs);
  52536. }
  52537. } // namespace internal
  52538. /**
  52539. * Internal details not to be documented.
  52540. * @endcond
  52541. */
  52542. /**
  52543. * @brief Associative container for key-value pairs with unique keys.
  52544. *
  52545. * Internally, elements are organized into buckets. Which bucket an element is
  52546. * placed into depends entirely on the hash of its key. Keys with the same hash
  52547. * code appear in the same bucket.
  52548. *
  52549. * @tparam Key Key type of the associative container.
  52550. * @tparam Type Mapped type of the associative container.
  52551. * @tparam Hash Type of function to use to hash the keys.
  52552. * @tparam KeyEqual Type of function to use to compare the keys for equality.
  52553. * @tparam Allocator Type of allocator used to manage memory and elements.
  52554. */
  52555. template<typename Key, typename Type, typename Hash, typename KeyEqual, typename Allocator>
  52556. class dense_map {
  52557. static constexpr float default_threshold = 0.875f;
  52558. static constexpr std::size_t minimum_capacity = 8u;
  52559. using node_type = internal::dense_map_node<Key, Type>;
  52560. using alloc_traits = typename std::allocator_traits<Allocator>;
  52561. static_assert(std::is_same_v<typename alloc_traits::value_type, std::pair<const Key, Type>>, "Invalid value type");
  52562. using sparse_container_type = std::vector<std::size_t, typename alloc_traits::template rebind_alloc<std::size_t>>;
  52563. using packed_container_type = std::vector<node_type, typename alloc_traits::template rebind_alloc<node_type>>;
  52564. template<typename Other>
  52565. [[nodiscard]] std::size_t key_to_bucket(const Other &key) const ENTT_NOEXCEPT {
  52566. return fast_mod(sparse.second()(key), bucket_count());
  52567. }
  52568. template<typename Other>
  52569. [[nodiscard]] auto constrained_find(const Other &key, std::size_t bucket) {
  52570. for(auto it = begin(bucket), last = end(bucket); it != last; ++it) {
  52571. if(packed.second()(it->first, key)) {
  52572. return begin() + static_cast<typename iterator::difference_type>(it.index());
  52573. }
  52574. }
  52575. return end();
  52576. }
  52577. template<typename Other>
  52578. [[nodiscard]] auto constrained_find(const Other &key, std::size_t bucket) const {
  52579. for(auto it = cbegin(bucket), last = cend(bucket); it != last; ++it) {
  52580. if(packed.second()(it->first, key)) {
  52581. return cbegin() + static_cast<typename iterator::difference_type>(it.index());
  52582. }
  52583. }
  52584. return cend();
  52585. }
  52586. template<typename Other, typename... Args>
  52587. [[nodiscard]] auto insert_or_do_nothing(Other &&key, Args &&...args) {
  52588. const auto index = key_to_bucket(key);
  52589. if(auto it = constrained_find(key, index); it != end()) {
  52590. return std::make_pair(it, false);
  52591. }
  52592. 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)...));
  52593. sparse.first()[index] = packed.first().size() - 1u;
  52594. rehash_if_required();
  52595. return std::make_pair(--end(), true);
  52596. }
  52597. template<typename Other, typename Arg>
  52598. [[nodiscard]] auto insert_or_overwrite(Other &&key, Arg &&value) {
  52599. const auto index = key_to_bucket(key);
  52600. if(auto it = constrained_find(key, index); it != end()) {
  52601. it->second = std::forward<Arg>(value);
  52602. return std::make_pair(it, false);
  52603. }
  52604. packed.first().emplace_back(sparse.first()[index], std::forward<Other>(key), std::forward<Arg>(value));
  52605. sparse.first()[index] = packed.first().size() - 1u;
  52606. rehash_if_required();
  52607. return std::make_pair(--end(), true);
  52608. }
  52609. void move_and_pop(const std::size_t pos) {
  52610. if(const auto last = size() - 1u; pos != last) {
  52611. packed.first()[pos] = std::move(packed.first().back());
  52612. size_type *curr = sparse.first().data() + key_to_bucket(packed.first().back().element.first);
  52613. for(; *curr != last; curr = &packed.first()[*curr].next) {}
  52614. *curr = pos;
  52615. }
  52616. packed.first().pop_back();
  52617. }
  52618. void rehash_if_required() {
  52619. if(size() > (bucket_count() * max_load_factor())) {
  52620. rehash(bucket_count() * 2u);
  52621. }
  52622. }
  52623. public:
  52624. /*! @brief Key type of the container. */
  52625. using key_type = Key;
  52626. /*! @brief Mapped type of the container. */
  52627. using mapped_type = Type;
  52628. /*! @brief Key-value type of the container. */
  52629. using value_type = std::pair<const Key, Type>;
  52630. /*! @brief Unsigned integer type. */
  52631. using size_type = std::size_t;
  52632. /*! @brief Type of function to use to hash the keys. */
  52633. using hasher = Hash;
  52634. /*! @brief Type of function to use to compare the keys for equality. */
  52635. using key_equal = KeyEqual;
  52636. /*! @brief Allocator type. */
  52637. using allocator_type = Allocator;
  52638. /*! @brief Input iterator type. */
  52639. using iterator = internal::dense_map_iterator<typename packed_container_type::iterator>;
  52640. /*! @brief Constant input iterator type. */
  52641. using const_iterator = internal::dense_map_iterator<typename packed_container_type::const_iterator>;
  52642. /*! @brief Input iterator type. */
  52643. using local_iterator = internal::dense_map_local_iterator<typename packed_container_type::iterator>;
  52644. /*! @brief Constant input iterator type. */
  52645. using const_local_iterator = internal::dense_map_local_iterator<typename packed_container_type::const_iterator>;
  52646. /*! @brief Default constructor. */
  52647. dense_map()
  52648. : dense_map(minimum_capacity) {}
  52649. /**
  52650. * @brief Constructs an empty container with a given allocator.
  52651. * @param allocator The allocator to use.
  52652. */
  52653. explicit dense_map(const allocator_type &allocator)
  52654. : dense_map{minimum_capacity, hasher{}, key_equal{}, allocator} {}
  52655. /**
  52656. * @brief Constructs an empty container with a given allocator and user
  52657. * supplied minimal number of buckets.
  52658. * @param bucket_count Minimal number of buckets.
  52659. * @param allocator The allocator to use.
  52660. */
  52661. dense_map(const size_type bucket_count, const allocator_type &allocator)
  52662. : dense_map{bucket_count, hasher{}, key_equal{}, allocator} {}
  52663. /**
  52664. * @brief Constructs an empty container with a given allocator, hash
  52665. * function and user supplied minimal number of buckets.
  52666. * @param bucket_count Minimal number of buckets.
  52667. * @param hash Hash function to use.
  52668. * @param allocator The allocator to use.
  52669. */
  52670. dense_map(const size_type bucket_count, const hasher &hash, const allocator_type &allocator)
  52671. : dense_map{bucket_count, hash, key_equal{}, allocator} {}
  52672. /**
  52673. * @brief Constructs an empty container with a given allocator, hash
  52674. * function, compare function and user supplied minimal number of buckets.
  52675. * @param bucket_count Minimal number of buckets.
  52676. * @param hash Hash function to use.
  52677. * @param equal Compare function to use.
  52678. * @param allocator The allocator to use.
  52679. */
  52680. explicit dense_map(const size_type bucket_count, const hasher &hash = hasher{}, const key_equal &equal = key_equal{}, const allocator_type &allocator = allocator_type{})
  52681. : sparse{allocator, hash},
  52682. packed{allocator, equal},
  52683. threshold{default_threshold} {
  52684. rehash(bucket_count);
  52685. }
  52686. /*! @brief Default copy constructor. */
  52687. dense_map(const dense_map &) = default;
  52688. /**
  52689. * @brief Allocator-extended copy constructor.
  52690. * @param other The instance to copy from.
  52691. * @param allocator The allocator to use.
  52692. */
  52693. dense_map(const dense_map &other, const allocator_type &allocator)
  52694. : sparse{std::piecewise_construct, std::forward_as_tuple(other.sparse.first(), allocator), std::forward_as_tuple(other.sparse.second())},
  52695. packed{std::piecewise_construct, std::forward_as_tuple(other.packed.first(), allocator), std::forward_as_tuple(other.packed.second())},
  52696. threshold{other.threshold} {}
  52697. /*! @brief Default move constructor. */
  52698. dense_map(dense_map &&) = default;
  52699. /**
  52700. * @brief Allocator-extended move constructor.
  52701. * @param other The instance to move from.
  52702. * @param allocator The allocator to use.
  52703. */
  52704. dense_map(dense_map &&other, const allocator_type &allocator)
  52705. : sparse{std::piecewise_construct, std::forward_as_tuple(std::move(other.sparse.first()), allocator), std::forward_as_tuple(std::move(other.sparse.second()))},
  52706. packed{std::piecewise_construct, std::forward_as_tuple(std::move(other.packed.first()), allocator), std::forward_as_tuple(std::move(other.packed.second()))},
  52707. threshold{other.threshold} {}
  52708. /**
  52709. * @brief Default copy assignment operator.
  52710. * @return This container.
  52711. */
  52712. dense_map &operator=(const dense_map &) = default;
  52713. /**
  52714. * @brief Default move assignment operator.
  52715. * @return This container.
  52716. */
  52717. dense_map &operator=(dense_map &&) = default;
  52718. /**
  52719. * @brief Returns the associated allocator.
  52720. * @return The associated allocator.
  52721. */
  52722. [[nodiscard]] constexpr allocator_type get_allocator() const ENTT_NOEXCEPT {
  52723. return sparse.first().get_allocator();
  52724. }
  52725. /**
  52726. * @brief Returns an iterator to the beginning.
  52727. *
  52728. * The returned iterator points to the first instance of the internal array.
  52729. * If the array is empty, the returned iterator will be equal to `end()`.
  52730. *
  52731. * @return An iterator to the first instance of the internal array.
  52732. */
  52733. [[nodiscard]] const_iterator cbegin() const ENTT_NOEXCEPT {
  52734. return packed.first().begin();
  52735. }
  52736. /*! @copydoc cbegin */
  52737. [[nodiscard]] const_iterator begin() const ENTT_NOEXCEPT {
  52738. return cbegin();
  52739. }
  52740. /*! @copydoc begin */
  52741. [[nodiscard]] iterator begin() ENTT_NOEXCEPT {
  52742. return packed.first().begin();
  52743. }
  52744. /**
  52745. * @brief Returns an iterator to the end.
  52746. *
  52747. * The returned iterator points to the element following the last instance
  52748. * of the internal array. Attempting to dereference the returned iterator
  52749. * results in undefined behavior.
  52750. *
  52751. * @return An iterator to the element following the last instance of the
  52752. * internal array.
  52753. */
  52754. [[nodiscard]] const_iterator cend() const ENTT_NOEXCEPT {
  52755. return packed.first().end();
  52756. }
  52757. /*! @copydoc cend */
  52758. [[nodiscard]] const_iterator end() const ENTT_NOEXCEPT {
  52759. return cend();
  52760. }
  52761. /*! @copydoc end */
  52762. [[nodiscard]] iterator end() ENTT_NOEXCEPT {
  52763. return packed.first().end();
  52764. }
  52765. /**
  52766. * @brief Checks whether a container is empty.
  52767. * @return True if the container is empty, false otherwise.
  52768. */
  52769. [[nodiscard]] bool empty() const ENTT_NOEXCEPT {
  52770. return packed.first().empty();
  52771. }
  52772. /**
  52773. * @brief Returns the number of elements in a container.
  52774. * @return Number of elements in a container.
  52775. */
  52776. [[nodiscard]] size_type size() const ENTT_NOEXCEPT {
  52777. return packed.first().size();
  52778. }
  52779. /*! @brief Clears the container. */
  52780. void clear() ENTT_NOEXCEPT {
  52781. sparse.first().clear();
  52782. packed.first().clear();
  52783. rehash(0u);
  52784. }
  52785. /**
  52786. * @brief Inserts an element into the container, if the key does not exist.
  52787. * @param value A key-value pair eventually convertible to the value type.
  52788. * @return A pair consisting of an iterator to the inserted element (or to
  52789. * the element that prevented the insertion) and a bool denoting whether the
  52790. * insertion took place.
  52791. */
  52792. std::pair<iterator, bool> insert(const value_type &value) {
  52793. return insert_or_do_nothing(value.first, value.second);
  52794. }
  52795. /*! @copydoc insert */
  52796. std::pair<iterator, bool> insert(value_type &&value) {
  52797. return insert_or_do_nothing(std::move(value.first), std::move(value.second));
  52798. }
  52799. /**
  52800. * @copydoc insert
  52801. * @tparam Arg Type of the key-value pair to insert into the container.
  52802. */
  52803. template<typename Arg>
  52804. std::enable_if_t<std::is_constructible_v<value_type, Arg &&>, std::pair<iterator, bool>>
  52805. insert(Arg &&value) {
  52806. return insert_or_do_nothing(std::forward<Arg>(value).first, std::forward<Arg>(value).second);
  52807. }
  52808. /**
  52809. * @brief Inserts elements into the container, if their keys do not exist.
  52810. * @tparam It Type of input iterator.
  52811. * @param first An iterator to the first element of the range of elements.
  52812. * @param last An iterator past the last element of the range of elements.
  52813. */
  52814. template<typename It>
  52815. void insert(It first, It last) {
  52816. for(; first != last; ++first) {
  52817. insert(*first);
  52818. }
  52819. }
  52820. /**
  52821. * @brief Inserts an element into the container or assigns to the current
  52822. * element if the key already exists.
  52823. * @tparam Arg Type of the value to insert or assign.
  52824. * @param key A key used both to look up and to insert if not found.
  52825. * @param value A value to insert or assign.
  52826. * @return A pair consisting of an iterator to the element and a bool
  52827. * denoting whether the insertion took place.
  52828. */
  52829. template<typename Arg>
  52830. std::pair<iterator, bool> insert_or_assign(const key_type &key, Arg &&value) {
  52831. return insert_or_overwrite(key, std::forward<Arg>(value));
  52832. }
  52833. /*! @copydoc insert_or_assign */
  52834. template<typename Arg>
  52835. std::pair<iterator, bool> insert_or_assign(key_type &&key, Arg &&value) {
  52836. return insert_or_overwrite(std::move(key), std::forward<Arg>(value));
  52837. }
  52838. /**
  52839. * @brief Constructs an element in-place, if the key does not exist.
  52840. *
  52841. * The element is also constructed when the container already has the key,
  52842. * in which case the newly constructed object is destroyed immediately.
  52843. *
  52844. * @tparam Args Types of arguments to forward to the constructor of the
  52845. * element.
  52846. * @param args Arguments to forward to the constructor of the element.
  52847. * @return A pair consisting of an iterator to the inserted element (or to
  52848. * the element that prevented the insertion) and a bool denoting whether the
  52849. * insertion took place.
  52850. */
  52851. template<typename... Args>
  52852. std::pair<iterator, bool> emplace([[maybe_unused]] Args &&...args) {
  52853. if constexpr(sizeof...(Args) == 0u) {
  52854. return insert_or_do_nothing(key_type{});
  52855. } else if constexpr(sizeof...(Args) == 1u) {
  52856. return insert_or_do_nothing(std::forward<Args>(args).first..., std::forward<Args>(args).second...);
  52857. } else if constexpr(sizeof...(Args) == 2u) {
  52858. return insert_or_do_nothing(std::forward<Args>(args)...);
  52859. } else {
  52860. auto &node = packed.first().emplace_back(packed.first().size(), std::forward<Args>(args)...);
  52861. const auto index = key_to_bucket(node.element.first);
  52862. if(auto it = constrained_find(node.element.first, index); it != end()) {
  52863. packed.first().pop_back();
  52864. return std::make_pair(it, false);
  52865. }
  52866. std::swap(node.next, sparse.first()[index]);
  52867. rehash_if_required();
  52868. return std::make_pair(--end(), true);
  52869. }
  52870. }
  52871. /**
  52872. * @brief Inserts in-place if the key does not exist, does nothing if the
  52873. * key exists.
  52874. * @tparam Args Types of arguments to forward to the constructor of the
  52875. * element.
  52876. * @param key A key used both to look up and to insert if not found.
  52877. * @param args Arguments to forward to the constructor of the element.
  52878. * @return A pair consisting of an iterator to the inserted element (or to
  52879. * the element that prevented the insertion) and a bool denoting whether the
  52880. * insertion took place.
  52881. */
  52882. template<typename... Args>
  52883. std::pair<iterator, bool> try_emplace(const key_type &key, Args &&...args) {
  52884. return insert_or_do_nothing(key, std::forward<Args>(args)...);
  52885. }
  52886. /*! @copydoc try_emplace */
  52887. template<typename... Args>
  52888. std::pair<iterator, bool> try_emplace(key_type &&key, Args &&...args) {
  52889. return insert_or_do_nothing(std::move(key), std::forward<Args>(args)...);
  52890. }
  52891. /**
  52892. * @brief Removes an element from a given position.
  52893. * @param pos An iterator to the element to remove.
  52894. * @return An iterator following the removed element.
  52895. */
  52896. iterator erase(const_iterator pos) {
  52897. const auto diff = pos - cbegin();
  52898. erase(pos->first);
  52899. return begin() + diff;
  52900. }
  52901. /**
  52902. * @brief Removes the given elements from a container.
  52903. * @param first An iterator to the first element of the range of elements.
  52904. * @param last An iterator past the last element of the range of elements.
  52905. * @return An iterator following the last removed element.
  52906. */
  52907. iterator erase(const_iterator first, const_iterator last) {
  52908. const auto dist = first - cbegin();
  52909. for(auto from = last - cbegin(); from != dist; --from) {
  52910. erase(packed.first()[from - 1u].element.first);
  52911. }
  52912. return (begin() + dist);
  52913. }
  52914. /**
  52915. * @brief Removes the element associated with a given key.
  52916. * @param key A key value of an element to remove.
  52917. * @return Number of elements removed (either 0 or 1).
  52918. */
  52919. size_type erase(const key_type &key) {
  52920. for(size_type *curr = sparse.first().data() + key_to_bucket(key); *curr != (std::numeric_limits<size_type>::max)(); curr = &packed.first()[*curr].next) {
  52921. if(packed.second()(packed.first()[*curr].element.first, key)) {
  52922. const auto index = *curr;
  52923. *curr = packed.first()[*curr].next;
  52924. move_and_pop(index);
  52925. return 1u;
  52926. }
  52927. }
  52928. return 0u;
  52929. }
  52930. /**
  52931. * @brief Exchanges the contents with those of a given container.
  52932. * @param other Container to exchange the content with.
  52933. */
  52934. void swap(dense_map &other) {
  52935. using std::swap;
  52936. swap(sparse, other.sparse);
  52937. swap(packed, other.packed);
  52938. swap(threshold, other.threshold);
  52939. }
  52940. /**
  52941. * @brief Accesses a given element with bounds checking.
  52942. * @param key A key of an element to find.
  52943. * @return A reference to the mapped value of the requested element.
  52944. */
  52945. [[nodiscard]] mapped_type &at(const key_type &key) {
  52946. auto it = find(key);
  52947. ENTT_ASSERT(it != end(), "Invalid key");
  52948. return it->second;
  52949. }
  52950. /*! @copydoc at */
  52951. [[nodiscard]] const mapped_type &at(const key_type &key) const {
  52952. auto it = find(key);
  52953. ENTT_ASSERT(it != cend(), "Invalid key");
  52954. return it->second;
  52955. }
  52956. /**
  52957. * @brief Accesses or inserts a given element.
  52958. * @param key A key of an element to find or insert.
  52959. * @return A reference to the mapped value of the requested element.
  52960. */
  52961. [[nodiscard]] mapped_type &operator[](const key_type &key) {
  52962. return insert_or_do_nothing(key).first->second;
  52963. }
  52964. /**
  52965. * @brief Accesses or inserts a given element.
  52966. * @param key A key of an element to find or insert.
  52967. * @return A reference to the mapped value of the requested element.
  52968. */
  52969. [[nodiscard]] mapped_type &operator[](key_type &&key) {
  52970. return insert_or_do_nothing(std::move(key)).first->second;
  52971. }
  52972. /**
  52973. * @brief Finds an element with a given key.
  52974. * @param key Key value of an element to search for.
  52975. * @return An iterator to an element with the given key. If no such element
  52976. * is found, a past-the-end iterator is returned.
  52977. */
  52978. [[nodiscard]] iterator find(const key_type &key) {
  52979. return constrained_find(key, key_to_bucket(key));
  52980. }
  52981. /*! @copydoc find */
  52982. [[nodiscard]] const_iterator find(const key_type &key) const {
  52983. return constrained_find(key, key_to_bucket(key));
  52984. }
  52985. /**
  52986. * @brief Finds an element with a key that compares _equivalent_ to a given
  52987. * value.
  52988. * @tparam Other Type of the key value of an element to search for.
  52989. * @param key Key value of an element to search for.
  52990. * @return An iterator to an element with the given key. If no such element
  52991. * is found, a past-the-end iterator is returned.
  52992. */
  52993. template<typename Other>
  52994. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, iterator>>
  52995. find(const Other &key) {
  52996. return constrained_find(key, key_to_bucket(key));
  52997. }
  52998. /*! @copydoc find */
  52999. template<typename Other>
  53000. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, const_iterator>>
  53001. find(const Other &key) const {
  53002. return constrained_find(key, key_to_bucket(key));
  53003. }
  53004. /**
  53005. * @brief Checks if the container contains an element with a given key.
  53006. * @param key Key value of an element to search for.
  53007. * @return True if there is such an element, false otherwise.
  53008. */
  53009. [[nodiscard]] bool contains(const key_type &key) const {
  53010. return (find(key) != cend());
  53011. }
  53012. /**
  53013. * @brief Checks if the container contains an element with a key that
  53014. * compares _equivalent_ to a given value.
  53015. * @tparam Other Type of the key value of an element to search for.
  53016. * @param key Key value of an element to search for.
  53017. * @return True if there is such an element, false otherwise.
  53018. */
  53019. template<typename Other>
  53020. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, bool>>
  53021. contains(const Other &key) const {
  53022. return (find(key) != cend());
  53023. }
  53024. /**
  53025. * @brief Returns an iterator to the beginning of a given bucket.
  53026. * @param index An index of a bucket to access.
  53027. * @return An iterator to the beginning of the given bucket.
  53028. */
  53029. [[nodiscard]] const_local_iterator cbegin(const size_type index) const {
  53030. return {packed.first().begin(), sparse.first()[index]};
  53031. }
  53032. /**
  53033. * @brief Returns an iterator to the beginning of a given bucket.
  53034. * @param index An index of a bucket to access.
  53035. * @return An iterator to the beginning of the given bucket.
  53036. */
  53037. [[nodiscard]] const_local_iterator begin(const size_type index) const {
  53038. return cbegin(index);
  53039. }
  53040. /**
  53041. * @brief Returns an iterator to the beginning of a given bucket.
  53042. * @param index An index of a bucket to access.
  53043. * @return An iterator to the beginning of the given bucket.
  53044. */
  53045. [[nodiscard]] local_iterator begin(const size_type index) {
  53046. return {packed.first().begin(), sparse.first()[index]};
  53047. }
  53048. /**
  53049. * @brief Returns an iterator to the end of a given bucket.
  53050. * @param index An index of a bucket to access.
  53051. * @return An iterator to the end of the given bucket.
  53052. */
  53053. [[nodiscard]] const_local_iterator cend([[maybe_unused]] const size_type index) const {
  53054. return {packed.first().begin(), (std::numeric_limits<size_type>::max)()};
  53055. }
  53056. /**
  53057. * @brief Returns an iterator to the end of a given bucket.
  53058. * @param index An index of a bucket to access.
  53059. * @return An iterator to the end of the given bucket.
  53060. */
  53061. [[nodiscard]] const_local_iterator end([[maybe_unused]] const size_type index) const {
  53062. return cend(index);
  53063. }
  53064. /**
  53065. * @brief Returns an iterator to the end of a given bucket.
  53066. * @param index An index of a bucket to access.
  53067. * @return An iterator to the end of the given bucket.
  53068. */
  53069. [[nodiscard]] local_iterator end([[maybe_unused]] const size_type index) {
  53070. return {packed.first().begin(), (std::numeric_limits<size_type>::max)()};
  53071. }
  53072. /**
  53073. * @brief Returns the number of buckets.
  53074. * @return The number of buckets.
  53075. */
  53076. [[nodiscard]] size_type bucket_count() const {
  53077. return sparse.first().size();
  53078. }
  53079. /**
  53080. * @brief Returns the maximum number of buckets.
  53081. * @return The maximum number of buckets.
  53082. */
  53083. [[nodiscard]] size_type max_bucket_count() const {
  53084. return sparse.first().max_size();
  53085. }
  53086. /**
  53087. * @brief Returns the number of elements in a given bucket.
  53088. * @param index The index of the bucket to examine.
  53089. * @return The number of elements in the given bucket.
  53090. */
  53091. [[nodiscard]] size_type bucket_size(const size_type index) const {
  53092. return static_cast<size_type>(std::distance(begin(index), end(index)));
  53093. }
  53094. /**
  53095. * @brief Returns the bucket for a given key.
  53096. * @param key The value of the key to examine.
  53097. * @return The bucket for the given key.
  53098. */
  53099. [[nodiscard]] size_type bucket(const key_type &key) const {
  53100. return key_to_bucket(key);
  53101. }
  53102. /**
  53103. * @brief Returns the average number of elements per bucket.
  53104. * @return The average number of elements per bucket.
  53105. */
  53106. [[nodiscard]] float load_factor() const {
  53107. return size() / static_cast<float>(bucket_count());
  53108. }
  53109. /**
  53110. * @brief Returns the maximum average number of elements per bucket.
  53111. * @return The maximum average number of elements per bucket.
  53112. */
  53113. [[nodiscard]] float max_load_factor() const {
  53114. return threshold;
  53115. }
  53116. /**
  53117. * @brief Sets the desired maximum average number of elements per bucket.
  53118. * @param value A desired maximum average number of elements per bucket.
  53119. */
  53120. void max_load_factor(const float value) {
  53121. ENTT_ASSERT(value > 0.f, "Invalid load factor");
  53122. threshold = value;
  53123. rehash(0u);
  53124. }
  53125. /**
  53126. * @brief Reserves at least the specified number of buckets and regenerates
  53127. * the hash table.
  53128. * @param count New number of buckets.
  53129. */
  53130. void rehash(const size_type count) {
  53131. auto value = (std::max)(count, minimum_capacity);
  53132. value = (std::max)(value, static_cast<size_type>(size() / max_load_factor()));
  53133. if(const auto sz = next_power_of_two(value); sz != bucket_count()) {
  53134. sparse.first().resize(sz);
  53135. std::fill(sparse.first().begin(), sparse.first().end(), (std::numeric_limits<size_type>::max)());
  53136. for(size_type pos{}, last = size(); pos < last; ++pos) {
  53137. const auto index = key_to_bucket(packed.first()[pos].element.first);
  53138. packed.first()[pos].next = std::exchange(sparse.first()[index], pos);
  53139. }
  53140. }
  53141. }
  53142. /**
  53143. * @brief Reserves space for at least the specified number of elements and
  53144. * regenerates the hash table.
  53145. * @param count New number of elements.
  53146. */
  53147. void reserve(const size_type count) {
  53148. packed.first().reserve(count);
  53149. rehash(static_cast<size_type>(std::ceil(count / max_load_factor())));
  53150. }
  53151. /**
  53152. * @brief Returns the function used to hash the keys.
  53153. * @return The function used to hash the keys.
  53154. */
  53155. [[nodiscard]] hasher hash_function() const {
  53156. return sparse.second();
  53157. }
  53158. /**
  53159. * @brief Returns the function used to compare keys for equality.
  53160. * @return The function used to compare keys for equality.
  53161. */
  53162. [[nodiscard]] key_equal key_eq() const {
  53163. return packed.second();
  53164. }
  53165. private:
  53166. compressed_pair<sparse_container_type, hasher> sparse;
  53167. compressed_pair<packed_container_type, key_equal> packed;
  53168. float threshold;
  53169. };
  53170. } // namespace entt
  53171. /**
  53172. * @cond TURN_OFF_DOXYGEN
  53173. * Internal details not to be documented.
  53174. */
  53175. namespace std {
  53176. template<typename Key, typename Value, typename Allocator>
  53177. struct uses_allocator<entt::internal::dense_map_node<Key, Value>, Allocator>
  53178. : std::true_type {};
  53179. } // namespace std
  53180. /**
  53181. * Internal details not to be documented.
  53182. * @endcond
  53183. */
  53184. #endif
  53185. // #include "../core/compressed_pair.hpp"
  53186. #ifndef ENTT_CORE_COMPRESSED_PAIR_HPP
  53187. #define ENTT_CORE_COMPRESSED_PAIR_HPP
  53188. #include <cstddef>
  53189. #include <tuple>
  53190. #include <type_traits>
  53191. #include <utility>
  53192. // #include "../config/config.h"
  53193. // #include "type_traits.hpp"
  53194. #ifndef ENTT_CORE_TYPE_TRAITS_HPP
  53195. #define ENTT_CORE_TYPE_TRAITS_HPP
  53196. #include <cstddef>
  53197. #include <iterator>
  53198. #include <type_traits>
  53199. #include <utility>
  53200. // #include "../config/config.h"
  53201. // #include "fwd.hpp"
  53202. namespace entt {
  53203. /**
  53204. * @brief Utility class to disambiguate overloaded functions.
  53205. * @tparam N Number of choices available.
  53206. */
  53207. template<std::size_t N>
  53208. struct choice_t
  53209. // Unfortunately, doxygen cannot parse such a construct.
  53210. : /*! @cond TURN_OFF_DOXYGEN */ choice_t<N - 1> /*! @endcond */
  53211. {};
  53212. /*! @copybrief choice_t */
  53213. template<>
  53214. struct choice_t<0> {};
  53215. /**
  53216. * @brief Variable template for the choice trick.
  53217. * @tparam N Number of choices available.
  53218. */
  53219. template<std::size_t N>
  53220. inline constexpr choice_t<N> choice{};
  53221. /**
  53222. * @brief Identity type trait.
  53223. *
  53224. * Useful to establish non-deduced contexts in template argument deduction
  53225. * (waiting for C++20) or to provide types through function arguments.
  53226. *
  53227. * @tparam Type A type.
  53228. */
  53229. template<typename Type>
  53230. struct type_identity {
  53231. /*! @brief Identity type. */
  53232. using type = Type;
  53233. };
  53234. /**
  53235. * @brief Helper type.
  53236. * @tparam Type A type.
  53237. */
  53238. template<typename Type>
  53239. using type_identity_t = typename type_identity<Type>::type;
  53240. /**
  53241. * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains.
  53242. * @tparam Type The type of which to return the size.
  53243. * @tparam The size of the type if `sizeof` accepts it, 0 otherwise.
  53244. */
  53245. template<typename Type, typename = void>
  53246. struct size_of: std::integral_constant<std::size_t, 0u> {};
  53247. /*! @copydoc size_of */
  53248. template<typename Type>
  53249. struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
  53250. : std::integral_constant<std::size_t, sizeof(Type)> {};
  53251. /**
  53252. * @brief Helper variable template.
  53253. * @tparam Type The type of which to return the size.
  53254. */
  53255. template<typename Type>
  53256. inline constexpr std::size_t size_of_v = size_of<Type>::value;
  53257. /**
  53258. * @brief Using declaration to be used to _repeat_ the same type a number of
  53259. * times equal to the size of a given parameter pack.
  53260. * @tparam Type A type to repeat.
  53261. */
  53262. template<typename Type, typename>
  53263. using unpack_as_type = Type;
  53264. /**
  53265. * @brief Helper variable template to be used to _repeat_ the same value a
  53266. * number of times equal to the size of a given parameter pack.
  53267. * @tparam Value A value to repeat.
  53268. */
  53269. template<auto Value, typename>
  53270. inline constexpr auto unpack_as_value = Value;
  53271. /**
  53272. * @brief Wraps a static constant.
  53273. * @tparam Value A static constant.
  53274. */
  53275. template<auto Value>
  53276. using integral_constant = std::integral_constant<decltype(Value), Value>;
  53277. /**
  53278. * @brief Alias template to facilitate the creation of named values.
  53279. * @tparam Value A constant value at least convertible to `id_type`.
  53280. */
  53281. template<id_type Value>
  53282. using tag = integral_constant<Value>;
  53283. /**
  53284. * @brief A class to use to push around lists of types, nothing more.
  53285. * @tparam Type Types provided by the type list.
  53286. */
  53287. template<typename... Type>
  53288. struct type_list {
  53289. /*! @brief Type list type. */
  53290. using type = type_list;
  53291. /*! @brief Compile-time number of elements in the type list. */
  53292. static constexpr auto size = sizeof...(Type);
  53293. };
  53294. /*! @brief Primary template isn't defined on purpose. */
  53295. template<std::size_t, typename>
  53296. struct type_list_element;
  53297. /**
  53298. * @brief Provides compile-time indexed access to the types of a type list.
  53299. * @tparam Index Index of the type to return.
  53300. * @tparam Type First type provided by the type list.
  53301. * @tparam Other Other types provided by the type list.
  53302. */
  53303. template<std::size_t Index, typename Type, typename... Other>
  53304. struct type_list_element<Index, type_list<Type, Other...>>
  53305. : type_list_element<Index - 1u, type_list<Other...>> {};
  53306. /**
  53307. * @brief Provides compile-time indexed access to the types of a type list.
  53308. * @tparam Type First type provided by the type list.
  53309. * @tparam Other Other types provided by the type list.
  53310. */
  53311. template<typename Type, typename... Other>
  53312. struct type_list_element<0u, type_list<Type, Other...>> {
  53313. /*! @brief Searched type. */
  53314. using type = Type;
  53315. };
  53316. /**
  53317. * @brief Helper type.
  53318. * @tparam Index Index of the type to return.
  53319. * @tparam List Type list to search into.
  53320. */
  53321. template<std::size_t Index, typename List>
  53322. using type_list_element_t = typename type_list_element<Index, List>::type;
  53323. /**
  53324. * @brief Concatenates multiple type lists.
  53325. * @tparam Type Types provided by the first type list.
  53326. * @tparam Other Types provided by the second type list.
  53327. * @return A type list composed by the types of both the type lists.
  53328. */
  53329. template<typename... Type, typename... Other>
  53330. constexpr type_list<Type..., Other...> operator+(type_list<Type...>, type_list<Other...>) {
  53331. return {};
  53332. }
  53333. /*! @brief Primary template isn't defined on purpose. */
  53334. template<typename...>
  53335. struct type_list_cat;
  53336. /*! @brief Concatenates multiple type lists. */
  53337. template<>
  53338. struct type_list_cat<> {
  53339. /*! @brief A type list composed by the types of all the type lists. */
  53340. using type = type_list<>;
  53341. };
  53342. /**
  53343. * @brief Concatenates multiple type lists.
  53344. * @tparam Type Types provided by the first type list.
  53345. * @tparam Other Types provided by the second type list.
  53346. * @tparam List Other type lists, if any.
  53347. */
  53348. template<typename... Type, typename... Other, typename... List>
  53349. struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
  53350. /*! @brief A type list composed by the types of all the type lists. */
  53351. using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
  53352. };
  53353. /**
  53354. * @brief Concatenates multiple type lists.
  53355. * @tparam Type Types provided by the type list.
  53356. */
  53357. template<typename... Type>
  53358. struct type_list_cat<type_list<Type...>> {
  53359. /*! @brief A type list composed by the types of all the type lists. */
  53360. using type = type_list<Type...>;
  53361. };
  53362. /**
  53363. * @brief Helper type.
  53364. * @tparam List Type lists to concatenate.
  53365. */
  53366. template<typename... List>
  53367. using type_list_cat_t = typename type_list_cat<List...>::type;
  53368. /*! @brief Primary template isn't defined on purpose. */
  53369. template<typename>
  53370. struct type_list_unique;
  53371. /**
  53372. * @brief Removes duplicates types from a type list.
  53373. * @tparam Type One of the types provided by the given type list.
  53374. * @tparam Other The other types provided by the given type list.
  53375. */
  53376. template<typename Type, typename... Other>
  53377. struct type_list_unique<type_list<Type, Other...>> {
  53378. /*! @brief A type list without duplicate types. */
  53379. using type = std::conditional_t<
  53380. (std::is_same_v<Type, Other> || ...),
  53381. typename type_list_unique<type_list<Other...>>::type,
  53382. type_list_cat_t<type_list<Type>, typename type_list_unique<type_list<Other...>>::type>>;
  53383. };
  53384. /*! @brief Removes duplicates types from a type list. */
  53385. template<>
  53386. struct type_list_unique<type_list<>> {
  53387. /*! @brief A type list without duplicate types. */
  53388. using type = type_list<>;
  53389. };
  53390. /**
  53391. * @brief Helper type.
  53392. * @tparam Type A type list.
  53393. */
  53394. template<typename Type>
  53395. using type_list_unique_t = typename type_list_unique<Type>::type;
  53396. /**
  53397. * @brief Provides the member constant `value` to true if a type list contains a
  53398. * given type, false otherwise.
  53399. * @tparam List Type list.
  53400. * @tparam Type Type to look for.
  53401. */
  53402. template<typename List, typename Type>
  53403. struct type_list_contains;
  53404. /**
  53405. * @copybrief type_list_contains
  53406. * @tparam Type Types provided by the type list.
  53407. * @tparam Other Type to look for.
  53408. */
  53409. template<typename... Type, typename Other>
  53410. struct type_list_contains<type_list<Type...>, Other>: std::disjunction<std::is_same<Type, Other>...> {};
  53411. /**
  53412. * @brief Helper variable template.
  53413. * @tparam List Type list.
  53414. * @tparam Type Type to look for.
  53415. */
  53416. template<typename List, typename Type>
  53417. inline constexpr bool type_list_contains_v = type_list_contains<List, Type>::value;
  53418. /*! @brief Primary template isn't defined on purpose. */
  53419. template<typename...>
  53420. struct type_list_diff;
  53421. /**
  53422. * @brief Computes the difference between two type lists.
  53423. * @tparam Type Types provided by the first type list.
  53424. * @tparam Other Types provided by the second type list.
  53425. */
  53426. template<typename... Type, typename... Other>
  53427. struct type_list_diff<type_list<Type...>, type_list<Other...>> {
  53428. /*! @brief A type list that is the difference between the two type lists. */
  53429. using type = type_list_cat_t<std::conditional_t<type_list_contains_v<type_list<Other...>, Type>, type_list<>, type_list<Type>>...>;
  53430. };
  53431. /**
  53432. * @brief Helper type.
  53433. * @tparam List Type lists between which to compute the difference.
  53434. */
  53435. template<typename... List>
  53436. using type_list_diff_t = typename type_list_diff<List...>::type;
  53437. /**
  53438. * @brief A class to use to push around lists of constant values, nothing more.
  53439. * @tparam Value Values provided by the value list.
  53440. */
  53441. template<auto... Value>
  53442. struct value_list {
  53443. /*! @brief Value list type. */
  53444. using type = value_list;
  53445. /*! @brief Compile-time number of elements in the value list. */
  53446. static constexpr auto size = sizeof...(Value);
  53447. };
  53448. /*! @brief Primary template isn't defined on purpose. */
  53449. template<std::size_t, typename>
  53450. struct value_list_element;
  53451. /**
  53452. * @brief Provides compile-time indexed access to the values of a value list.
  53453. * @tparam Index Index of the value to return.
  53454. * @tparam Value First value provided by the value list.
  53455. * @tparam Other Other values provided by the value list.
  53456. */
  53457. template<std::size_t Index, auto Value, auto... Other>
  53458. struct value_list_element<Index, value_list<Value, Other...>>
  53459. : value_list_element<Index - 1u, value_list<Other...>> {};
  53460. /**
  53461. * @brief Provides compile-time indexed access to the types of a type list.
  53462. * @tparam Value First value provided by the value list.
  53463. * @tparam Other Other values provided by the value list.
  53464. */
  53465. template<auto Value, auto... Other>
  53466. struct value_list_element<0u, value_list<Value, Other...>> {
  53467. /*! @brief Searched value. */
  53468. static constexpr auto value = Value;
  53469. };
  53470. /**
  53471. * @brief Helper type.
  53472. * @tparam Index Index of the value to return.
  53473. * @tparam List Value list to search into.
  53474. */
  53475. template<std::size_t Index, typename List>
  53476. inline constexpr auto value_list_element_v = value_list_element<Index, List>::value;
  53477. /**
  53478. * @brief Concatenates multiple value lists.
  53479. * @tparam Value Values provided by the first value list.
  53480. * @tparam Other Values provided by the second value list.
  53481. * @return A value list composed by the values of both the value lists.
  53482. */
  53483. template<auto... Value, auto... Other>
  53484. constexpr value_list<Value..., Other...> operator+(value_list<Value...>, value_list<Other...>) {
  53485. return {};
  53486. }
  53487. /*! @brief Primary template isn't defined on purpose. */
  53488. template<typename...>
  53489. struct value_list_cat;
  53490. /*! @brief Concatenates multiple value lists. */
  53491. template<>
  53492. struct value_list_cat<> {
  53493. /*! @brief A value list composed by the values of all the value lists. */
  53494. using type = value_list<>;
  53495. };
  53496. /**
  53497. * @brief Concatenates multiple value lists.
  53498. * @tparam Value Values provided by the first value list.
  53499. * @tparam Other Values provided by the second value list.
  53500. * @tparam List Other value lists, if any.
  53501. */
  53502. template<auto... Value, auto... Other, typename... List>
  53503. struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
  53504. /*! @brief A value list composed by the values of all the value lists. */
  53505. using type = typename value_list_cat<value_list<Value..., Other...>, List...>::type;
  53506. };
  53507. /**
  53508. * @brief Concatenates multiple value lists.
  53509. * @tparam Value Values provided by the value list.
  53510. */
  53511. template<auto... Value>
  53512. struct value_list_cat<value_list<Value...>> {
  53513. /*! @brief A value list composed by the values of all the value lists. */
  53514. using type = value_list<Value...>;
  53515. };
  53516. /**
  53517. * @brief Helper type.
  53518. * @tparam List Value lists to concatenate.
  53519. */
  53520. template<typename... List>
  53521. using value_list_cat_t = typename value_list_cat<List...>::type;
  53522. /*! @brief Same as std::is_invocable, but with tuples. */
  53523. template<typename, typename>
  53524. struct is_applicable: std::false_type {};
  53525. /**
  53526. * @copybrief is_applicable
  53527. * @tparam Func A valid function type.
  53528. * @tparam Tuple Tuple-like type.
  53529. * @tparam Args The list of arguments to use to probe the function type.
  53530. */
  53531. template<typename Func, template<typename...> class Tuple, typename... Args>
  53532. struct is_applicable<Func, Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  53533. /**
  53534. * @copybrief is_applicable
  53535. * @tparam Func A valid function type.
  53536. * @tparam Tuple Tuple-like type.
  53537. * @tparam Args The list of arguments to use to probe the function type.
  53538. */
  53539. template<typename Func, template<typename...> class Tuple, typename... Args>
  53540. struct is_applicable<Func, const Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  53541. /**
  53542. * @brief Helper variable template.
  53543. * @tparam Func A valid function type.
  53544. * @tparam Args The list of arguments to use to probe the function type.
  53545. */
  53546. template<typename Func, typename Args>
  53547. inline constexpr bool is_applicable_v = is_applicable<Func, Args>::value;
  53548. /*! @brief Same as std::is_invocable_r, but with tuples for arguments. */
  53549. template<typename, typename, typename>
  53550. struct is_applicable_r: std::false_type {};
  53551. /**
  53552. * @copybrief is_applicable_r
  53553. * @tparam Ret The type to which the return type of the function should be
  53554. * convertible.
  53555. * @tparam Func A valid function type.
  53556. * @tparam Args The list of arguments to use to probe the function type.
  53557. */
  53558. template<typename Ret, typename Func, typename... Args>
  53559. struct is_applicable_r<Ret, Func, std::tuple<Args...>>: std::is_invocable_r<Ret, Func, Args...> {};
  53560. /**
  53561. * @brief Helper variable template.
  53562. * @tparam Ret The type to which the return type of the function should be
  53563. * convertible.
  53564. * @tparam Func A valid function type.
  53565. * @tparam Args The list of arguments to use to probe the function type.
  53566. */
  53567. template<typename Ret, typename Func, typename Args>
  53568. inline constexpr bool is_applicable_r_v = is_applicable_r<Ret, Func, Args>::value;
  53569. /**
  53570. * @brief Provides the member constant `value` to true if a given type is
  53571. * complete, false otherwise.
  53572. * @tparam Type The type to test.
  53573. */
  53574. template<typename Type, typename = void>
  53575. struct is_complete: std::false_type {};
  53576. /*! @copydoc is_complete */
  53577. template<typename Type>
  53578. struct is_complete<Type, std::void_t<decltype(sizeof(Type))>>: std::true_type {};
  53579. /**
  53580. * @brief Helper variable template.
  53581. * @tparam Type The type to test.
  53582. */
  53583. template<typename Type>
  53584. inline constexpr bool is_complete_v = is_complete<Type>::value;
  53585. /**
  53586. * @brief Provides the member constant `value` to true if a given type is an
  53587. * iterator, false otherwise.
  53588. * @tparam Type The type to test.
  53589. */
  53590. template<typename Type, typename = void>
  53591. struct is_iterator: std::false_type {};
  53592. /**
  53593. * @cond TURN_OFF_DOXYGEN
  53594. * Internal details not to be documented.
  53595. */
  53596. namespace internal {
  53597. template<typename, typename = void>
  53598. struct has_iterator_category: std::false_type {};
  53599. template<typename Type>
  53600. struct has_iterator_category<Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>: std::true_type {};
  53601. } // namespace internal
  53602. /**
  53603. * Internal details not to be documented.
  53604. * @endcond
  53605. */
  53606. /*! @copydoc is_iterator */
  53607. template<typename Type>
  53608. struct is_iterator<Type, std::enable_if_t<!std::is_same_v<std::remove_const_t<std::remove_pointer_t<Type>>, void>>>
  53609. : internal::has_iterator_category<Type> {};
  53610. /**
  53611. * @brief Helper variable template.
  53612. * @tparam Type The type to test.
  53613. */
  53614. template<typename Type>
  53615. inline constexpr bool is_iterator_v = is_iterator<Type>::value;
  53616. /**
  53617. * @brief Provides the member constant `value` to true if a given type is both
  53618. * an empty and non-final class, false otherwise.
  53619. * @tparam Type The type to test
  53620. */
  53621. template<typename Type>
  53622. struct is_ebco_eligible
  53623. : std::conjunction<std::is_empty<Type>, std::negation<std::is_final<Type>>> {};
  53624. /**
  53625. * @brief Helper variable template.
  53626. * @tparam Type The type to test.
  53627. */
  53628. template<typename Type>
  53629. inline constexpr bool is_ebco_eligible_v = is_ebco_eligible<Type>::value;
  53630. /**
  53631. * @brief Provides the member constant `value` to true if `Type::is_transparent`
  53632. * is valid and denotes a type, false otherwise.
  53633. * @tparam Type The type to test.
  53634. */
  53635. template<typename Type, typename = void>
  53636. struct is_transparent: std::false_type {};
  53637. /*! @copydoc is_transparent */
  53638. template<typename Type>
  53639. struct is_transparent<Type, std::void_t<typename Type::is_transparent>>: std::true_type {};
  53640. /**
  53641. * @brief Helper variable template.
  53642. * @tparam Type The type to test.
  53643. */
  53644. template<typename Type>
  53645. inline constexpr bool is_transparent_v = is_transparent<Type>::value;
  53646. /**
  53647. * @brief Provides the member constant `value` to true if a given type is
  53648. * equality comparable, false otherwise.
  53649. * @tparam Type The type to test.
  53650. */
  53651. template<typename Type, typename = void>
  53652. struct is_equality_comparable: std::false_type {};
  53653. /**
  53654. * @cond TURN_OFF_DOXYGEN
  53655. * Internal details not to be documented.
  53656. */
  53657. namespace internal {
  53658. template<typename, typename = void>
  53659. struct has_tuple_size_value: std::false_type {};
  53660. template<typename Type>
  53661. struct has_tuple_size_value<Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>: std::true_type {};
  53662. template<typename Type, std::size_t... Index>
  53663. [[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
  53664. return (is_equality_comparable<std::tuple_element_t<Index, Type>>::value && ...);
  53665. }
  53666. template<typename>
  53667. [[nodiscard]] constexpr bool maybe_equality_comparable(choice_t<0>) {
  53668. return true;
  53669. }
  53670. template<typename Type>
  53671. [[nodiscard]] constexpr auto maybe_equality_comparable(choice_t<1>) -> decltype(std::declval<typename Type::value_type>(), bool{}) {
  53672. if constexpr(is_iterator_v<Type>) {
  53673. return true;
  53674. } else if constexpr(std::is_same_v<typename Type::value_type, Type>) {
  53675. return maybe_equality_comparable<Type>(choice<0>);
  53676. } else {
  53677. return is_equality_comparable<typename Type::value_type>::value;
  53678. }
  53679. }
  53680. template<typename Type>
  53681. [[nodiscard]] constexpr std::enable_if_t<is_complete_v<std::tuple_size<std::remove_const_t<Type>>>, bool> maybe_equality_comparable(choice_t<2>) {
  53682. if constexpr(has_tuple_size_value<Type>::value) {
  53683. return unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
  53684. } else {
  53685. return maybe_equality_comparable<Type>(choice<1>);
  53686. }
  53687. }
  53688. } // namespace internal
  53689. /**
  53690. * Internal details not to be documented.
  53691. * @endcond
  53692. */
  53693. /*! @copydoc is_equality_comparable */
  53694. template<typename Type>
  53695. struct is_equality_comparable<Type, std::void_t<decltype(std::declval<Type>() == std::declval<Type>())>>
  53696. : std::bool_constant<internal::maybe_equality_comparable<Type>(choice<2>)> {};
  53697. /**
  53698. * @brief Helper variable template.
  53699. * @tparam Type The type to test.
  53700. */
  53701. template<typename Type>
  53702. inline constexpr bool is_equality_comparable_v = is_equality_comparable<Type>::value;
  53703. /**
  53704. * @brief Transcribes the constness of a type to another type.
  53705. * @tparam To The type to which to transcribe the constness.
  53706. * @tparam From The type from which to transcribe the constness.
  53707. */
  53708. template<typename To, typename From>
  53709. struct constness_as {
  53710. /*! @brief The type resulting from the transcription of the constness. */
  53711. using type = std::remove_const_t<To>;
  53712. };
  53713. /*! @copydoc constness_as */
  53714. template<typename To, typename From>
  53715. struct constness_as<To, const From> {
  53716. /*! @brief The type resulting from the transcription of the constness. */
  53717. using type = std::add_const_t<To>;
  53718. };
  53719. /**
  53720. * @brief Alias template to facilitate the transcription of the constness.
  53721. * @tparam To The type to which to transcribe the constness.
  53722. * @tparam From The type from which to transcribe the constness.
  53723. */
  53724. template<typename To, typename From>
  53725. using constness_as_t = typename constness_as<To, From>::type;
  53726. /**
  53727. * @brief Extracts the class of a non-static member object or function.
  53728. * @tparam Member A pointer to a non-static member object or function.
  53729. */
  53730. template<typename Member>
  53731. class member_class {
  53732. static_assert(std::is_member_pointer_v<Member>, "Invalid pointer type to non-static member object or function");
  53733. template<typename Class, typename Ret, typename... Args>
  53734. static Class *clazz(Ret (Class::*)(Args...));
  53735. template<typename Class, typename Ret, typename... Args>
  53736. static Class *clazz(Ret (Class::*)(Args...) const);
  53737. template<typename Class, typename Type>
  53738. static Class *clazz(Type Class::*);
  53739. public:
  53740. /*! @brief The class of the given non-static member object or function. */
  53741. using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
  53742. };
  53743. /**
  53744. * @brief Helper type.
  53745. * @tparam Member A pointer to a non-static member object or function.
  53746. */
  53747. template<typename Member>
  53748. using member_class_t = typename member_class<Member>::type;
  53749. } // namespace entt
  53750. #endif
  53751. namespace entt {
  53752. /**
  53753. * @cond TURN_OFF_DOXYGEN
  53754. * Internal details not to be documented.
  53755. */
  53756. namespace internal {
  53757. template<typename Type, std::size_t, typename = void>
  53758. struct compressed_pair_element {
  53759. using reference = Type &;
  53760. using const_reference = const Type &;
  53761. template<bool Dummy = true, typename = std::enable_if_t<Dummy && std::is_default_constructible_v<Type>>>
  53762. compressed_pair_element()
  53763. : value{} {}
  53764. template<typename Args, typename = std::enable_if_t<!std::is_same_v<std::remove_cv_t<std::remove_reference_t<Args>>, compressed_pair_element>>>
  53765. compressed_pair_element(Args &&args)
  53766. : value{std::forward<Args>(args)} {}
  53767. template<typename... Args, std::size_t... Index>
  53768. compressed_pair_element(std::tuple<Args...> args, std::index_sequence<Index...>)
  53769. : value{std::forward<Args>(std::get<Index>(args))...} {}
  53770. [[nodiscard]] reference get() ENTT_NOEXCEPT {
  53771. return value;
  53772. }
  53773. [[nodiscard]] const_reference get() const ENTT_NOEXCEPT {
  53774. return value;
  53775. }
  53776. private:
  53777. Type value;
  53778. };
  53779. template<typename Type, std::size_t Tag>
  53780. struct compressed_pair_element<Type, Tag, std::enable_if_t<is_ebco_eligible_v<Type>>>: Type {
  53781. using reference = Type &;
  53782. using const_reference = const Type &;
  53783. using base_type = Type;
  53784. template<bool Dummy = true, typename = std::enable_if_t<Dummy && std::is_default_constructible_v<base_type>>>
  53785. compressed_pair_element()
  53786. : base_type{} {}
  53787. template<typename Args, typename = std::enable_if_t<!std::is_same_v<std::remove_cv_t<std::remove_reference_t<Args>>, compressed_pair_element>>>
  53788. compressed_pair_element(Args &&args)
  53789. : base_type{std::forward<Args>(args)} {}
  53790. template<typename... Args, std::size_t... Index>
  53791. compressed_pair_element(std::tuple<Args...> args, std::index_sequence<Index...>)
  53792. : base_type{std::forward<Args>(std::get<Index>(args))...} {}
  53793. [[nodiscard]] reference get() ENTT_NOEXCEPT {
  53794. return *this;
  53795. }
  53796. [[nodiscard]] const_reference get() const ENTT_NOEXCEPT {
  53797. return *this;
  53798. }
  53799. };
  53800. } // namespace internal
  53801. /**
  53802. * Internal details not to be documented.
  53803. * @endcond
  53804. */
  53805. /**
  53806. * @brief A compressed pair.
  53807. *
  53808. * A pair that exploits the _Empty Base Class Optimization_ (or _EBCO_) to
  53809. * reduce its final size to a minimum.
  53810. *
  53811. * @tparam First The type of the first element that the pair stores.
  53812. * @tparam Second The type of the second element that the pair stores.
  53813. */
  53814. template<typename First, typename Second>
  53815. class compressed_pair final
  53816. : internal::compressed_pair_element<First, 0u>,
  53817. internal::compressed_pair_element<Second, 1u> {
  53818. using first_base = internal::compressed_pair_element<First, 0u>;
  53819. using second_base = internal::compressed_pair_element<Second, 1u>;
  53820. public:
  53821. /*! @brief The type of the first element that the pair stores. */
  53822. using first_type = First;
  53823. /*! @brief The type of the second element that the pair stores. */
  53824. using second_type = Second;
  53825. /**
  53826. * @brief Default constructor, conditionally enabled.
  53827. *
  53828. * This constructor is only available when the types that the pair stores
  53829. * are both at least default constructible.
  53830. *
  53831. * @tparam Dummy Dummy template parameter used for internal purposes.
  53832. */
  53833. template<bool Dummy = true, typename = std::enable_if_t<Dummy && std::is_default_constructible_v<first_type> && std::is_default_constructible_v<second_type>>>
  53834. constexpr compressed_pair()
  53835. : first_base{},
  53836. second_base{} {}
  53837. /**
  53838. * @brief Copy constructor.
  53839. * @param other The instance to copy from.
  53840. */
  53841. constexpr compressed_pair(const compressed_pair &other) = default;
  53842. /**
  53843. * @brief Move constructor.
  53844. * @param other The instance to move from.
  53845. */
  53846. constexpr compressed_pair(compressed_pair &&other) = default;
  53847. /**
  53848. * @brief Constructs a pair from its values.
  53849. * @tparam Arg Type of value to use to initialize the first element.
  53850. * @tparam Other Type of value to use to initialize the second element.
  53851. * @param arg Value to use to initialize the first element.
  53852. * @param other Value to use to initialize the second element.
  53853. */
  53854. template<typename Arg, typename Other>
  53855. constexpr compressed_pair(Arg &&arg, Other &&other)
  53856. : first_base{std::forward<Arg>(arg)},
  53857. second_base{std::forward<Other>(other)} {}
  53858. /**
  53859. * @brief Constructs a pair by forwarding the arguments to its parts.
  53860. * @tparam Args Types of arguments to use to initialize the first element.
  53861. * @tparam Other Types of arguments to use to initialize the second element.
  53862. * @param args Arguments to use to initialize the first element.
  53863. * @param other Arguments to use to initialize the second element.
  53864. */
  53865. template<typename... Args, typename... Other>
  53866. constexpr compressed_pair(std::piecewise_construct_t, std::tuple<Args...> args, std::tuple<Other...> other)
  53867. : first_base{std::move(args), std::index_sequence_for<Args...>{}},
  53868. second_base{std::move(other), std::index_sequence_for<Other...>{}} {}
  53869. /**
  53870. * @brief Copy assignment operator.
  53871. * @param other The instance to copy from.
  53872. * @return This compressed pair object.
  53873. */
  53874. constexpr compressed_pair &operator=(const compressed_pair &other) = default;
  53875. /**
  53876. * @brief Move assignment operator.
  53877. * @param other The instance to move from.
  53878. * @return This compressed pair object.
  53879. */
  53880. constexpr compressed_pair &operator=(compressed_pair &&other) = default;
  53881. /**
  53882. * @brief Returns the first element that a pair stores.
  53883. * @return The first element that a pair stores.
  53884. */
  53885. [[nodiscard]] first_type &first() ENTT_NOEXCEPT {
  53886. return static_cast<first_base &>(*this).get();
  53887. }
  53888. /*! @copydoc first */
  53889. [[nodiscard]] const first_type &first() const ENTT_NOEXCEPT {
  53890. return static_cast<const first_base &>(*this).get();
  53891. }
  53892. /**
  53893. * @brief Returns the second element that a pair stores.
  53894. * @return The second element that a pair stores.
  53895. */
  53896. [[nodiscard]] second_type &second() ENTT_NOEXCEPT {
  53897. return static_cast<second_base &>(*this).get();
  53898. }
  53899. /*! @copydoc second */
  53900. [[nodiscard]] const second_type &second() const ENTT_NOEXCEPT {
  53901. return static_cast<const second_base &>(*this).get();
  53902. }
  53903. /**
  53904. * @brief Swaps two compressed pair objects.
  53905. * @param other The compressed pair to swap with.
  53906. */
  53907. void swap(compressed_pair &other) {
  53908. using std::swap;
  53909. swap(first(), other.first());
  53910. swap(second(), other.second());
  53911. }
  53912. /**
  53913. * @brief Extracts an element from the compressed pair.
  53914. * @tparam Index An integer value that is either 0 or 1.
  53915. * @return Returns a reference to the first element if `Index` is 0 and a
  53916. * reference to the second element if `Index` is 1.
  53917. */
  53918. template<std::size_t Index>
  53919. decltype(auto) get() ENTT_NOEXCEPT {
  53920. if constexpr(Index == 0u) {
  53921. return first();
  53922. } else {
  53923. static_assert(Index == 1u, "Index out of bounds");
  53924. return second();
  53925. }
  53926. }
  53927. /*! @copydoc get */
  53928. template<std::size_t Index>
  53929. decltype(auto) get() const ENTT_NOEXCEPT {
  53930. if constexpr(Index == 0u) {
  53931. return first();
  53932. } else {
  53933. static_assert(Index == 1u, "Index out of bounds");
  53934. return second();
  53935. }
  53936. }
  53937. };
  53938. /**
  53939. * @brief Deduction guide.
  53940. * @tparam Type Type of value to use to initialize the first element.
  53941. * @tparam Other Type of value to use to initialize the second element.
  53942. */
  53943. template<typename Type, typename Other>
  53944. compressed_pair(Type &&, Other &&) -> compressed_pair<std::decay_t<Type>, std::decay_t<Other>>;
  53945. /**
  53946. * @brief Swaps two compressed pair objects.
  53947. * @tparam First The type of the first element that the pairs store.
  53948. * @tparam Second The type of the second element that the pairs store.
  53949. * @param lhs A valid compressed pair object.
  53950. * @param rhs A valid compressed pair object.
  53951. */
  53952. template<typename First, typename Second>
  53953. inline void swap(compressed_pair<First, Second> &lhs, compressed_pair<First, Second> &rhs) {
  53954. lhs.swap(rhs);
  53955. }
  53956. } // namespace entt
  53957. // disable structured binding support for clang 6, it messes when specializing tuple_size
  53958. #if !defined __clang_major__ || __clang_major__ > 6
  53959. namespace std {
  53960. /**
  53961. * @brief `std::tuple_size` specialization for `compressed_pair`s.
  53962. * @tparam First The type of the first element that the pair stores.
  53963. * @tparam Second The type of the second element that the pair stores.
  53964. */
  53965. template<typename First, typename Second>
  53966. struct tuple_size<entt::compressed_pair<First, Second>>: integral_constant<size_t, 2u> {};
  53967. /**
  53968. * @brief `std::tuple_element` specialization for `compressed_pair`s.
  53969. * @tparam Index The index of the type to return.
  53970. * @tparam First The type of the first element that the pair stores.
  53971. * @tparam Second The type of the second element that the pair stores.
  53972. */
  53973. template<size_t Index, typename First, typename Second>
  53974. struct tuple_element<Index, entt::compressed_pair<First, Second>>: conditional<Index == 0u, First, Second> {
  53975. static_assert(Index < 2u, "Index out of bounds");
  53976. };
  53977. } // namespace std
  53978. #endif
  53979. #endif
  53980. // #include "../core/fwd.hpp"
  53981. #ifndef ENTT_CORE_FWD_HPP
  53982. #define ENTT_CORE_FWD_HPP
  53983. #include <cstdint>
  53984. #include <type_traits>
  53985. // #include "../config/config.h"
  53986. namespace entt {
  53987. template<std::size_t Len = sizeof(double[2]), std::size_t = alignof(typename std::aligned_storage_t<Len + !Len>)>
  53988. class basic_any;
  53989. /*! @brief Alias declaration for type identifiers. */
  53990. using id_type = ENTT_ID_TYPE;
  53991. /*! @brief Alias declaration for the most common use case. */
  53992. using any = basic_any<>;
  53993. } // namespace entt
  53994. #endif
  53995. // #include "../core/type_info.hpp"
  53996. #ifndef ENTT_CORE_TYPE_INFO_HPP
  53997. #define ENTT_CORE_TYPE_INFO_HPP
  53998. #include <string_view>
  53999. #include <type_traits>
  54000. #include <utility>
  54001. // #include "../config/config.h"
  54002. // #include "../core/attribute.h"
  54003. #ifndef ENTT_CORE_ATTRIBUTE_H
  54004. #define ENTT_CORE_ATTRIBUTE_H
  54005. #ifndef ENTT_EXPORT
  54006. # if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER
  54007. # define ENTT_EXPORT __declspec(dllexport)
  54008. # define ENTT_IMPORT __declspec(dllimport)
  54009. # define ENTT_HIDDEN
  54010. # elif defined __GNUC__ && __GNUC__ >= 4
  54011. # define ENTT_EXPORT __attribute__((visibility("default")))
  54012. # define ENTT_IMPORT __attribute__((visibility("default")))
  54013. # define ENTT_HIDDEN __attribute__((visibility("hidden")))
  54014. # else /* Unsupported compiler */
  54015. # define ENTT_EXPORT
  54016. # define ENTT_IMPORT
  54017. # define ENTT_HIDDEN
  54018. # endif
  54019. #endif
  54020. #ifndef ENTT_API
  54021. # if defined ENTT_API_EXPORT
  54022. # define ENTT_API ENTT_EXPORT
  54023. # elif defined ENTT_API_IMPORT
  54024. # define ENTT_API ENTT_IMPORT
  54025. # else /* No API */
  54026. # define ENTT_API
  54027. # endif
  54028. #endif
  54029. #endif
  54030. // #include "fwd.hpp"
  54031. // #include "hashed_string.hpp"
  54032. #ifndef ENTT_CORE_HASHED_STRING_HPP
  54033. #define ENTT_CORE_HASHED_STRING_HPP
  54034. #include <cstddef>
  54035. #include <cstdint>
  54036. // #include "../config/config.h"
  54037. // #include "fwd.hpp"
  54038. namespace entt {
  54039. /**
  54040. * @cond TURN_OFF_DOXYGEN
  54041. * Internal details not to be documented.
  54042. */
  54043. namespace internal {
  54044. template<typename>
  54045. struct fnv1a_traits;
  54046. template<>
  54047. struct fnv1a_traits<std::uint32_t> {
  54048. using type = std::uint32_t;
  54049. static constexpr std::uint32_t offset = 2166136261;
  54050. static constexpr std::uint32_t prime = 16777619;
  54051. };
  54052. template<>
  54053. struct fnv1a_traits<std::uint64_t> {
  54054. using type = std::uint64_t;
  54055. static constexpr std::uint64_t offset = 14695981039346656037ull;
  54056. static constexpr std::uint64_t prime = 1099511628211ull;
  54057. };
  54058. template<typename Char>
  54059. struct basic_hashed_string {
  54060. using value_type = Char;
  54061. using size_type = std::size_t;
  54062. using hash_type = id_type;
  54063. const value_type *repr;
  54064. size_type length;
  54065. hash_type hash;
  54066. };
  54067. } // namespace internal
  54068. /**
  54069. * Internal details not to be documented.
  54070. * @endcond
  54071. */
  54072. /**
  54073. * @brief Zero overhead unique identifier.
  54074. *
  54075. * A hashed string is a compile-time tool that allows users to use
  54076. * human-readable identifiers in the codebase while using their numeric
  54077. * counterparts at runtime.<br/>
  54078. * Because of that, a hashed string can also be used in constant expressions if
  54079. * required.
  54080. *
  54081. * @warning
  54082. * This class doesn't take ownership of user-supplied strings nor does it make a
  54083. * copy of them.
  54084. *
  54085. * @tparam Char Character type.
  54086. */
  54087. template<typename Char>
  54088. class basic_hashed_string: internal::basic_hashed_string<Char> {
  54089. using base_type = internal::basic_hashed_string<Char>;
  54090. using hs_traits = internal::fnv1a_traits<id_type>;
  54091. struct const_wrapper {
  54092. // non-explicit constructor on purpose
  54093. constexpr const_wrapper(const Char *str) ENTT_NOEXCEPT: repr{str} {}
  54094. const Char *repr;
  54095. };
  54096. // Fowler–Noll–Vo hash function v. 1a - the good
  54097. [[nodiscard]] static constexpr auto helper(const Char *str) ENTT_NOEXCEPT {
  54098. base_type base{str, 0u, hs_traits::offset};
  54099. for(; str[base.length]; ++base.length) {
  54100. base.hash = (base.hash ^ static_cast<hs_traits::type>(str[base.length])) * hs_traits::prime;
  54101. }
  54102. return base;
  54103. }
  54104. // Fowler–Noll–Vo hash function v. 1a - the good
  54105. [[nodiscard]] static constexpr auto helper(const Char *str, const std::size_t len) ENTT_NOEXCEPT {
  54106. base_type base{str, len, hs_traits::offset};
  54107. for(size_type pos{}; pos < len; ++pos) {
  54108. base.hash = (base.hash ^ static_cast<hs_traits::type>(str[pos])) * hs_traits::prime;
  54109. }
  54110. return base;
  54111. }
  54112. public:
  54113. /*! @brief Character type. */
  54114. using value_type = typename base_type::value_type;
  54115. /*! @brief Unsigned integer type. */
  54116. using size_type = typename base_type::size_type;
  54117. /*! @brief Unsigned integer type. */
  54118. using hash_type = typename base_type::hash_type;
  54119. /**
  54120. * @brief Returns directly the numeric representation of a string view.
  54121. * @param str Human-readable identifier.
  54122. * @param len Length of the string to hash.
  54123. * @return The numeric representation of the string.
  54124. */
  54125. [[nodiscard]] static constexpr hash_type value(const value_type *str, const size_type len) ENTT_NOEXCEPT {
  54126. return basic_hashed_string{str, len};
  54127. }
  54128. /**
  54129. * @brief Returns directly the numeric representation of a string.
  54130. * @tparam N Number of characters of the identifier.
  54131. * @param str Human-readable identifier.
  54132. * @return The numeric representation of the string.
  54133. */
  54134. template<std::size_t N>
  54135. [[nodiscard]] static constexpr hash_type value(const value_type (&str)[N]) ENTT_NOEXCEPT {
  54136. return basic_hashed_string{str};
  54137. }
  54138. /**
  54139. * @brief Returns directly the numeric representation of a string.
  54140. * @param wrapper Helps achieving the purpose by relying on overloading.
  54141. * @return The numeric representation of the string.
  54142. */
  54143. [[nodiscard]] static constexpr hash_type value(const_wrapper wrapper) ENTT_NOEXCEPT {
  54144. return basic_hashed_string{wrapper};
  54145. }
  54146. /*! @brief Constructs an empty hashed string. */
  54147. constexpr basic_hashed_string() ENTT_NOEXCEPT
  54148. : base_type{} {}
  54149. /**
  54150. * @brief Constructs a hashed string from a string view.
  54151. * @param str Human-readable identifier.
  54152. * @param len Length of the string to hash.
  54153. */
  54154. constexpr basic_hashed_string(const value_type *str, const size_type len) ENTT_NOEXCEPT
  54155. : base_type{helper(str, len)} {}
  54156. /**
  54157. * @brief Constructs a hashed string from an array of const characters.
  54158. * @tparam N Number of characters of the identifier.
  54159. * @param str Human-readable identifier.
  54160. */
  54161. template<std::size_t N>
  54162. constexpr basic_hashed_string(const value_type (&str)[N]) ENTT_NOEXCEPT
  54163. : base_type{helper(str)} {}
  54164. /**
  54165. * @brief Explicit constructor on purpose to avoid constructing a hashed
  54166. * string directly from a `const value_type *`.
  54167. *
  54168. * @warning
  54169. * The lifetime of the string is not extended nor is it copied.
  54170. *
  54171. * @param wrapper Helps achieving the purpose by relying on overloading.
  54172. */
  54173. explicit constexpr basic_hashed_string(const_wrapper wrapper) ENTT_NOEXCEPT
  54174. : base_type{helper(wrapper.repr)} {}
  54175. /**
  54176. * @brief Returns the size a hashed string.
  54177. * @return The size of the hashed string.
  54178. */
  54179. [[nodiscard]] constexpr size_type size() const ENTT_NOEXCEPT {
  54180. return base_type::length;
  54181. }
  54182. /**
  54183. * @brief Returns the human-readable representation of a hashed string.
  54184. * @return The string used to initialize the hashed string.
  54185. */
  54186. [[nodiscard]] constexpr const value_type *data() const ENTT_NOEXCEPT {
  54187. return base_type::repr;
  54188. }
  54189. /**
  54190. * @brief Returns the numeric representation of a hashed string.
  54191. * @return The numeric representation of the hashed string.
  54192. */
  54193. [[nodiscard]] constexpr hash_type value() const ENTT_NOEXCEPT {
  54194. return base_type::hash;
  54195. }
  54196. /*! @copydoc data */
  54197. [[nodiscard]] constexpr operator const value_type *() const ENTT_NOEXCEPT {
  54198. return data();
  54199. }
  54200. /**
  54201. * @brief Returns the numeric representation of a hashed string.
  54202. * @return The numeric representation of the hashed string.
  54203. */
  54204. [[nodiscard]] constexpr operator hash_type() const ENTT_NOEXCEPT {
  54205. return value();
  54206. }
  54207. };
  54208. /**
  54209. * @brief Deduction guide.
  54210. * @tparam Char Character type.
  54211. * @param str Human-readable identifier.
  54212. * @param len Length of the string to hash.
  54213. */
  54214. template<typename Char>
  54215. basic_hashed_string(const Char *str, const std::size_t len) -> basic_hashed_string<Char>;
  54216. /**
  54217. * @brief Deduction guide.
  54218. * @tparam Char Character type.
  54219. * @tparam N Number of characters of the identifier.
  54220. * @param str Human-readable identifier.
  54221. */
  54222. template<typename Char, std::size_t N>
  54223. basic_hashed_string(const Char (&str)[N]) -> basic_hashed_string<Char>;
  54224. /**
  54225. * @brief Compares two hashed strings.
  54226. * @tparam Char Character type.
  54227. * @param lhs A valid hashed string.
  54228. * @param rhs A valid hashed string.
  54229. * @return True if the two hashed strings are identical, false otherwise.
  54230. */
  54231. template<typename Char>
  54232. [[nodiscard]] constexpr bool operator==(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) ENTT_NOEXCEPT {
  54233. return lhs.value() == rhs.value();
  54234. }
  54235. /**
  54236. * @brief Compares two hashed strings.
  54237. * @tparam Char Character type.
  54238. * @param lhs A valid hashed string.
  54239. * @param rhs A valid hashed string.
  54240. * @return True if the two hashed strings differ, false otherwise.
  54241. */
  54242. template<typename Char>
  54243. [[nodiscard]] constexpr bool operator!=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) ENTT_NOEXCEPT {
  54244. return !(lhs == rhs);
  54245. }
  54246. /**
  54247. * @brief Compares two hashed strings.
  54248. * @tparam Char Character type.
  54249. * @param lhs A valid hashed string.
  54250. * @param rhs A valid hashed string.
  54251. * @return True if the first element is less than the second, false otherwise.
  54252. */
  54253. template<typename Char>
  54254. [[nodiscard]] constexpr bool operator<(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) ENTT_NOEXCEPT {
  54255. return lhs.value() < rhs.value();
  54256. }
  54257. /**
  54258. * @brief Compares two hashed strings.
  54259. * @tparam Char Character type.
  54260. * @param lhs A valid hashed string.
  54261. * @param rhs A valid hashed string.
  54262. * @return True if the first element is less than or equal to the second, false
  54263. * otherwise.
  54264. */
  54265. template<typename Char>
  54266. [[nodiscard]] constexpr bool operator<=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) ENTT_NOEXCEPT {
  54267. return !(rhs < lhs);
  54268. }
  54269. /**
  54270. * @brief Compares two hashed strings.
  54271. * @tparam Char Character type.
  54272. * @param lhs A valid hashed string.
  54273. * @param rhs A valid hashed string.
  54274. * @return True if the first element is greater than the second, false
  54275. * otherwise.
  54276. */
  54277. template<typename Char>
  54278. [[nodiscard]] constexpr bool operator>(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) ENTT_NOEXCEPT {
  54279. return rhs < lhs;
  54280. }
  54281. /**
  54282. * @brief Compares two hashed strings.
  54283. * @tparam Char Character type.
  54284. * @param lhs A valid hashed string.
  54285. * @param rhs A valid hashed string.
  54286. * @return True if the first element is greater than or equal to the second,
  54287. * false otherwise.
  54288. */
  54289. template<typename Char>
  54290. [[nodiscard]] constexpr bool operator>=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) ENTT_NOEXCEPT {
  54291. return !(lhs < rhs);
  54292. }
  54293. /*! @brief Aliases for common character types. */
  54294. using hashed_string = basic_hashed_string<char>;
  54295. /*! @brief Aliases for common character types. */
  54296. using hashed_wstring = basic_hashed_string<wchar_t>;
  54297. inline namespace literals {
  54298. /**
  54299. * @brief User defined literal for hashed strings.
  54300. * @param str The literal without its suffix.
  54301. * @return A properly initialized hashed string.
  54302. */
  54303. [[nodiscard]] constexpr hashed_string operator"" _hs(const char *str, std::size_t) ENTT_NOEXCEPT {
  54304. return hashed_string{str};
  54305. }
  54306. /**
  54307. * @brief User defined literal for hashed wstrings.
  54308. * @param str The literal without its suffix.
  54309. * @return A properly initialized hashed wstring.
  54310. */
  54311. [[nodiscard]] constexpr hashed_wstring operator"" _hws(const wchar_t *str, std::size_t) ENTT_NOEXCEPT {
  54312. return hashed_wstring{str};
  54313. }
  54314. } // namespace literals
  54315. } // namespace entt
  54316. #endif
  54317. namespace entt {
  54318. /**
  54319. * @cond TURN_OFF_DOXYGEN
  54320. * Internal details not to be documented.
  54321. */
  54322. namespace internal {
  54323. struct ENTT_API type_index final {
  54324. [[nodiscard]] static id_type next() ENTT_NOEXCEPT {
  54325. static ENTT_MAYBE_ATOMIC(id_type) value{};
  54326. return value++;
  54327. }
  54328. };
  54329. template<typename Type>
  54330. [[nodiscard]] constexpr auto stripped_type_name() ENTT_NOEXCEPT {
  54331. #if defined ENTT_PRETTY_FUNCTION
  54332. std::string_view pretty_function{ENTT_PRETTY_FUNCTION};
  54333. auto first = pretty_function.find_first_not_of(' ', pretty_function.find_first_of(ENTT_PRETTY_FUNCTION_PREFIX) + 1);
  54334. auto value = pretty_function.substr(first, pretty_function.find_last_of(ENTT_PRETTY_FUNCTION_SUFFIX) - first);
  54335. return value;
  54336. #else
  54337. return std::string_view{""};
  54338. #endif
  54339. }
  54340. template<typename Type, auto = stripped_type_name<Type>().find_first_of('.')>
  54341. [[nodiscard]] static constexpr std::string_view type_name(int) ENTT_NOEXCEPT {
  54342. constexpr auto value = stripped_type_name<Type>();
  54343. return value;
  54344. }
  54345. template<typename Type>
  54346. [[nodiscard]] static std::string_view type_name(char) ENTT_NOEXCEPT {
  54347. static const auto value = stripped_type_name<Type>();
  54348. return value;
  54349. }
  54350. template<typename Type, auto = stripped_type_name<Type>().find_first_of('.')>
  54351. [[nodiscard]] static constexpr id_type type_hash(int) ENTT_NOEXCEPT {
  54352. constexpr auto stripped = stripped_type_name<Type>();
  54353. constexpr auto value = hashed_string::value(stripped.data(), stripped.size());
  54354. return value;
  54355. }
  54356. template<typename Type>
  54357. [[nodiscard]] static id_type type_hash(char) ENTT_NOEXCEPT {
  54358. static const auto value = [](const auto stripped) {
  54359. return hashed_string::value(stripped.data(), stripped.size());
  54360. }(stripped_type_name<Type>());
  54361. return value;
  54362. }
  54363. } // namespace internal
  54364. /**
  54365. * Internal details not to be documented.
  54366. * @endcond
  54367. */
  54368. /**
  54369. * @brief Type sequential identifier.
  54370. * @tparam Type Type for which to generate a sequential identifier.
  54371. */
  54372. template<typename Type, typename = void>
  54373. struct ENTT_API type_index final {
  54374. /**
  54375. * @brief Returns the sequential identifier of a given type.
  54376. * @return The sequential identifier of a given type.
  54377. */
  54378. [[nodiscard]] static id_type value() ENTT_NOEXCEPT {
  54379. static const id_type value = internal::type_index::next();
  54380. return value;
  54381. }
  54382. /*! @copydoc value */
  54383. [[nodiscard]] constexpr operator id_type() const ENTT_NOEXCEPT {
  54384. return value();
  54385. }
  54386. };
  54387. /**
  54388. * @brief Type hash.
  54389. * @tparam Type Type for which to generate a hash value.
  54390. */
  54391. template<typename Type, typename = void>
  54392. struct type_hash final {
  54393. /**
  54394. * @brief Returns the numeric representation of a given type.
  54395. * @return The numeric representation of the given type.
  54396. */
  54397. #if defined ENTT_PRETTY_FUNCTION
  54398. [[nodiscard]] static constexpr id_type value() ENTT_NOEXCEPT {
  54399. return internal::type_hash<Type>(0);
  54400. #else
  54401. [[nodiscard]] static constexpr id_type value() ENTT_NOEXCEPT {
  54402. return type_index<Type>::value();
  54403. #endif
  54404. }
  54405. /*! @copydoc value */
  54406. [[nodiscard]] constexpr operator id_type() const ENTT_NOEXCEPT {
  54407. return value();
  54408. }
  54409. };
  54410. /**
  54411. * @brief Type name.
  54412. * @tparam Type Type for which to generate a name.
  54413. */
  54414. template<typename Type, typename = void>
  54415. struct type_name final {
  54416. /**
  54417. * @brief Returns the name of a given type.
  54418. * @return The name of the given type.
  54419. */
  54420. [[nodiscard]] static constexpr std::string_view value() ENTT_NOEXCEPT {
  54421. return internal::type_name<Type>(0);
  54422. }
  54423. /*! @copydoc value */
  54424. [[nodiscard]] constexpr operator std::string_view() const ENTT_NOEXCEPT {
  54425. return value();
  54426. }
  54427. };
  54428. /*! @brief Implementation specific information about a type. */
  54429. struct type_info final {
  54430. /**
  54431. * @brief Constructs a type info object for a given type.
  54432. * @tparam Type Type for which to construct a type info object.
  54433. */
  54434. template<typename Type>
  54435. constexpr type_info(std::in_place_type_t<Type>) ENTT_NOEXCEPT
  54436. : seq{type_index<std::remove_cv_t<std::remove_reference_t<Type>>>::value()},
  54437. identifier{type_hash<std::remove_cv_t<std::remove_reference_t<Type>>>::value()},
  54438. alias{type_name<std::remove_cv_t<std::remove_reference_t<Type>>>::value()} {}
  54439. /**
  54440. * @brief Type index.
  54441. * @return Type index.
  54442. */
  54443. [[nodiscard]] constexpr id_type index() const ENTT_NOEXCEPT {
  54444. return seq;
  54445. }
  54446. /**
  54447. * @brief Type hash.
  54448. * @return Type hash.
  54449. */
  54450. [[nodiscard]] constexpr id_type hash() const ENTT_NOEXCEPT {
  54451. return identifier;
  54452. }
  54453. /**
  54454. * @brief Type name.
  54455. * @return Type name.
  54456. */
  54457. [[nodiscard]] constexpr std::string_view name() const ENTT_NOEXCEPT {
  54458. return alias;
  54459. }
  54460. private:
  54461. id_type seq;
  54462. id_type identifier;
  54463. std::string_view alias;
  54464. };
  54465. /**
  54466. * @brief Compares the contents of two type info objects.
  54467. * @param lhs A type info object.
  54468. * @param rhs A type info object.
  54469. * @return True if the two type info objects are identical, false otherwise.
  54470. */
  54471. [[nodiscard]] inline constexpr bool operator==(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT {
  54472. return lhs.hash() == rhs.hash();
  54473. }
  54474. /**
  54475. * @brief Compares the contents of two type info objects.
  54476. * @param lhs A type info object.
  54477. * @param rhs A type info object.
  54478. * @return True if the two type info objects differ, false otherwise.
  54479. */
  54480. [[nodiscard]] inline constexpr bool operator!=(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT {
  54481. return !(lhs == rhs);
  54482. }
  54483. /**
  54484. * @brief Compares two type info objects.
  54485. * @param lhs A valid type info object.
  54486. * @param rhs A valid type info object.
  54487. * @return True if the first element is less than the second, false otherwise.
  54488. */
  54489. [[nodiscard]] constexpr bool operator<(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT {
  54490. return lhs.index() < rhs.index();
  54491. }
  54492. /**
  54493. * @brief Compares two type info objects.
  54494. * @param lhs A valid type info object.
  54495. * @param rhs A valid type info object.
  54496. * @return True if the first element is less than or equal to the second, false
  54497. * otherwise.
  54498. */
  54499. [[nodiscard]] constexpr bool operator<=(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT {
  54500. return !(rhs < lhs);
  54501. }
  54502. /**
  54503. * @brief Compares two type info objects.
  54504. * @param lhs A valid type info object.
  54505. * @param rhs A valid type info object.
  54506. * @return True if the first element is greater than the second, false
  54507. * otherwise.
  54508. */
  54509. [[nodiscard]] constexpr bool operator>(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT {
  54510. return rhs < lhs;
  54511. }
  54512. /**
  54513. * @brief Compares two type info objects.
  54514. * @param lhs A valid type info object.
  54515. * @param rhs A valid type info object.
  54516. * @return True if the first element is greater than or equal to the second,
  54517. * false otherwise.
  54518. */
  54519. [[nodiscard]] constexpr bool operator>=(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT {
  54520. return !(lhs < rhs);
  54521. }
  54522. /**
  54523. * @brief Returns the type info object associated to a given type.
  54524. *
  54525. * The returned element refers to an object with static storage duration.<br/>
  54526. * The type doesn't need to be a complete type. If the type is a reference, the
  54527. * result refers to the referenced type. In all cases, top-level cv-qualifiers
  54528. * are ignored.
  54529. *
  54530. * @tparam Type Type for which to generate a type info object.
  54531. * @return A reference to a properly initialized type info object.
  54532. */
  54533. template<typename Type>
  54534. [[nodiscard]] const type_info &type_id() ENTT_NOEXCEPT {
  54535. if constexpr(std::is_same_v<Type, std::remove_cv_t<std::remove_reference_t<Type>>>) {
  54536. static type_info instance{std::in_place_type<Type>};
  54537. return instance;
  54538. } else {
  54539. return type_id<std::remove_cv_t<std::remove_reference_t<Type>>>();
  54540. }
  54541. }
  54542. /*! @copydoc type_id */
  54543. template<typename Type>
  54544. [[nodiscard]] const type_info &type_id(Type &&) ENTT_NOEXCEPT {
  54545. return type_id<std::remove_cv_t<std::remove_reference_t<Type>>>();
  54546. }
  54547. } // namespace entt
  54548. #endif
  54549. // #include "../core/utility.hpp"
  54550. #ifndef ENTT_CORE_UTILITY_HPP
  54551. #define ENTT_CORE_UTILITY_HPP
  54552. #include <utility>
  54553. // #include "../config/config.h"
  54554. namespace entt {
  54555. /*! @brief Identity function object (waiting for C++20). */
  54556. struct identity {
  54557. /*! @brief Indicates that this is a transparent function object. */
  54558. using is_transparent = void;
  54559. /**
  54560. * @brief Returns its argument unchanged.
  54561. * @tparam Type Type of the argument.
  54562. * @param value The actual argument.
  54563. * @return The submitted value as-is.
  54564. */
  54565. template<class Type>
  54566. [[nodiscard]] constexpr Type &&operator()(Type &&value) const ENTT_NOEXCEPT {
  54567. return std::forward<Type>(value);
  54568. }
  54569. };
  54570. /**
  54571. * @brief Constant utility to disambiguate overloaded members of a class.
  54572. * @tparam Type Type of the desired overload.
  54573. * @tparam Class Type of class to which the member belongs.
  54574. * @param member A valid pointer to a member.
  54575. * @return Pointer to the member.
  54576. */
  54577. template<typename Type, typename Class>
  54578. [[nodiscard]] constexpr auto overload(Type Class::*member) ENTT_NOEXCEPT {
  54579. return member;
  54580. }
  54581. /**
  54582. * @brief Constant utility to disambiguate overloaded functions.
  54583. * @tparam Func Function type of the desired overload.
  54584. * @param func A valid pointer to a function.
  54585. * @return Pointer to the function.
  54586. */
  54587. template<typename Func>
  54588. [[nodiscard]] constexpr auto overload(Func *func) ENTT_NOEXCEPT {
  54589. return func;
  54590. }
  54591. /**
  54592. * @brief Helper type for visitors.
  54593. * @tparam Func Types of function objects.
  54594. */
  54595. template<class... Func>
  54596. struct overloaded: Func... {
  54597. using Func::operator()...;
  54598. };
  54599. /**
  54600. * @brief Deduction guide.
  54601. * @tparam Func Types of function objects.
  54602. */
  54603. template<class... Func>
  54604. overloaded(Func...) -> overloaded<Func...>;
  54605. /**
  54606. * @brief Basic implementation of a y-combinator.
  54607. * @tparam Func Type of a potentially recursive function.
  54608. */
  54609. template<class Func>
  54610. struct y_combinator {
  54611. /**
  54612. * @brief Constructs a y-combinator from a given function.
  54613. * @param recursive A potentially recursive function.
  54614. */
  54615. y_combinator(Func recursive)
  54616. : func{std::move(recursive)} {}
  54617. /**
  54618. * @brief Invokes a y-combinator and therefore its underlying function.
  54619. * @tparam Args Types of arguments to use to invoke the underlying function.
  54620. * @param args Parameters to use to invoke the underlying function.
  54621. * @return Return value of the underlying function, if any.
  54622. */
  54623. template<class... Args>
  54624. decltype(auto) operator()(Args &&...args) const {
  54625. return func(*this, std::forward<Args>(args)...);
  54626. }
  54627. /*! @copydoc operator()() */
  54628. template<class... Args>
  54629. decltype(auto) operator()(Args &&...args) {
  54630. return func(*this, std::forward<Args>(args)...);
  54631. }
  54632. private:
  54633. Func func;
  54634. };
  54635. } // namespace entt
  54636. #endif
  54637. // #include "fwd.hpp"
  54638. // #include "sigh.hpp"
  54639. #ifndef ENTT_SIGNAL_SIGH_HPP
  54640. #define ENTT_SIGNAL_SIGH_HPP
  54641. #include <algorithm>
  54642. #include <functional>
  54643. #include <type_traits>
  54644. #include <utility>
  54645. #include <vector>
  54646. // #include "../config/config.h"
  54647. // #include "delegate.hpp"
  54648. #ifndef ENTT_SIGNAL_DELEGATE_HPP
  54649. #define ENTT_SIGNAL_DELEGATE_HPP
  54650. #include <cstddef>
  54651. #include <functional>
  54652. #include <tuple>
  54653. #include <type_traits>
  54654. #include <utility>
  54655. // #include "../config/config.h"
  54656. // #include "../core/type_traits.hpp"
  54657. // #include "fwd.hpp"
  54658. namespace entt {
  54659. /**
  54660. * @cond TURN_OFF_DOXYGEN
  54661. * Internal details not to be documented.
  54662. */
  54663. namespace internal {
  54664. template<typename Ret, typename... Args>
  54665. auto function_pointer(Ret (*)(Args...)) -> Ret (*)(Args...);
  54666. template<typename Ret, typename Type, typename... Args, typename Other>
  54667. auto function_pointer(Ret (*)(Type, Args...), Other &&) -> Ret (*)(Args...);
  54668. template<typename Class, typename Ret, typename... Args, typename... Other>
  54669. auto function_pointer(Ret (Class::*)(Args...), Other &&...) -> Ret (*)(Args...);
  54670. template<typename Class, typename Ret, typename... Args, typename... Other>
  54671. auto function_pointer(Ret (Class::*)(Args...) const, Other &&...) -> Ret (*)(Args...);
  54672. template<typename Class, typename Type, typename... Other>
  54673. auto function_pointer(Type Class::*, Other &&...) -> Type (*)();
  54674. template<typename... Type>
  54675. using function_pointer_t = decltype(internal::function_pointer(std::declval<Type>()...));
  54676. template<typename... Class, typename Ret, typename... Args>
  54677. [[nodiscard]] constexpr auto index_sequence_for(Ret (*)(Args...)) {
  54678. return std::index_sequence_for<Class..., Args...>{};
  54679. }
  54680. } // namespace internal
  54681. /**
  54682. * Internal details not to be documented.
  54683. * @endcond
  54684. */
  54685. /*! @brief Used to wrap a function or a member of a specified type. */
  54686. template<auto>
  54687. struct connect_arg_t {};
  54688. /*! @brief Constant of type connect_arg_t used to disambiguate calls. */
  54689. template<auto Func>
  54690. inline constexpr connect_arg_t<Func> connect_arg{};
  54691. /**
  54692. * @brief Basic delegate implementation.
  54693. *
  54694. * Primary template isn't defined on purpose. All the specializations give a
  54695. * compile-time error unless the template parameter is a function type.
  54696. */
  54697. template<typename>
  54698. class delegate;
  54699. /**
  54700. * @brief Utility class to use to send around functions and members.
  54701. *
  54702. * Unmanaged delegate for function pointers and members. Users of this class are
  54703. * in charge of disconnecting instances before deleting them.
  54704. *
  54705. * A delegate can be used as a general purpose invoker without memory overhead
  54706. * for free functions possibly with payloads and bound or unbound members.
  54707. *
  54708. * @tparam Ret Return type of a function type.
  54709. * @tparam Args Types of arguments of a function type.
  54710. */
  54711. template<typename Ret, typename... Args>
  54712. class delegate<Ret(Args...)> {
  54713. template<auto Candidate, std::size_t... Index>
  54714. [[nodiscard]] auto wrap(std::index_sequence<Index...>) ENTT_NOEXCEPT {
  54715. return [](const void *, Args... args) -> Ret {
  54716. [[maybe_unused]] const auto arguments = std::forward_as_tuple(std::forward<Args>(args)...);
  54717. return static_cast<Ret>(std::invoke(Candidate, std::forward<type_list_element_t<Index, type_list<Args...>>>(std::get<Index>(arguments))...));
  54718. };
  54719. }
  54720. template<auto Candidate, typename Type, std::size_t... Index>
  54721. [[nodiscard]] auto wrap(Type &, std::index_sequence<Index...>) ENTT_NOEXCEPT {
  54722. return [](const void *payload, Args... args) -> Ret {
  54723. [[maybe_unused]] const auto arguments = std::forward_as_tuple(std::forward<Args>(args)...);
  54724. Type *curr = static_cast<Type *>(const_cast<constness_as_t<void, Type> *>(payload));
  54725. return static_cast<Ret>(std::invoke(Candidate, *curr, std::forward<type_list_element_t<Index, type_list<Args...>>>(std::get<Index>(arguments))...));
  54726. };
  54727. }
  54728. template<auto Candidate, typename Type, std::size_t... Index>
  54729. [[nodiscard]] auto wrap(Type *, std::index_sequence<Index...>) ENTT_NOEXCEPT {
  54730. return [](const void *payload, Args... args) -> Ret {
  54731. [[maybe_unused]] const auto arguments = std::forward_as_tuple(std::forward<Args>(args)...);
  54732. Type *curr = static_cast<Type *>(const_cast<constness_as_t<void, Type> *>(payload));
  54733. return static_cast<Ret>(std::invoke(Candidate, curr, std::forward<type_list_element_t<Index, type_list<Args...>>>(std::get<Index>(arguments))...));
  54734. };
  54735. }
  54736. public:
  54737. /*! @brief Function type of the contained target. */
  54738. using function_type = Ret(const void *, Args...);
  54739. /*! @brief Function type of the delegate. */
  54740. using type = Ret(Args...);
  54741. /*! @brief Return type of the delegate. */
  54742. using result_type = Ret;
  54743. /*! @brief Default constructor. */
  54744. delegate() ENTT_NOEXCEPT
  54745. : instance{nullptr},
  54746. fn{nullptr} {}
  54747. /**
  54748. * @brief Constructs a delegate and connects a free function or an unbound
  54749. * member.
  54750. * @tparam Candidate Function or member to connect to the delegate.
  54751. */
  54752. template<auto Candidate>
  54753. delegate(connect_arg_t<Candidate>) ENTT_NOEXCEPT {
  54754. connect<Candidate>();
  54755. }
  54756. /**
  54757. * @brief Constructs a delegate and connects a free function with payload or
  54758. * a bound member.
  54759. * @tparam Candidate Function or member to connect to the delegate.
  54760. * @tparam Type Type of class or type of payload.
  54761. * @param value_or_instance A valid object that fits the purpose.
  54762. */
  54763. template<auto Candidate, typename Type>
  54764. delegate(connect_arg_t<Candidate>, Type &&value_or_instance) ENTT_NOEXCEPT {
  54765. connect<Candidate>(std::forward<Type>(value_or_instance));
  54766. }
  54767. /**
  54768. * @brief Constructs a delegate and connects an user defined function with
  54769. * optional payload.
  54770. * @param function Function to connect to the delegate.
  54771. * @param payload User defined arbitrary data.
  54772. */
  54773. delegate(function_type *function, const void *payload = nullptr) ENTT_NOEXCEPT {
  54774. connect(function, payload);
  54775. }
  54776. /**
  54777. * @brief Connects a free function or an unbound member to a delegate.
  54778. * @tparam Candidate Function or member to connect to the delegate.
  54779. */
  54780. template<auto Candidate>
  54781. void connect() ENTT_NOEXCEPT {
  54782. instance = nullptr;
  54783. if constexpr(std::is_invocable_r_v<Ret, decltype(Candidate), Args...>) {
  54784. fn = [](const void *, Args... args) -> Ret {
  54785. return Ret(std::invoke(Candidate, std::forward<Args>(args)...));
  54786. };
  54787. } else if constexpr(std::is_member_pointer_v<decltype(Candidate)>) {
  54788. fn = wrap<Candidate>(internal::index_sequence_for<type_list_element_t<0, type_list<Args...>>>(internal::function_pointer_t<decltype(Candidate)>{}));
  54789. } else {
  54790. fn = wrap<Candidate>(internal::index_sequence_for(internal::function_pointer_t<decltype(Candidate)>{}));
  54791. }
  54792. }
  54793. /**
  54794. * @brief Connects a free function with payload or a bound member to a
  54795. * delegate.
  54796. *
  54797. * The delegate isn't responsible for the connected object or the payload.
  54798. * Users must always guarantee that the lifetime of the instance overcomes
  54799. * the one of the delegate.<br/>
  54800. * When used to connect a free function with payload, its signature must be
  54801. * such that the instance is the first argument before the ones used to
  54802. * define the delegate itself.
  54803. *
  54804. * @tparam Candidate Function or member to connect to the delegate.
  54805. * @tparam Type Type of class or type of payload.
  54806. * @param value_or_instance A valid reference that fits the purpose.
  54807. */
  54808. template<auto Candidate, typename Type>
  54809. void connect(Type &value_or_instance) ENTT_NOEXCEPT {
  54810. instance = &value_or_instance;
  54811. if constexpr(std::is_invocable_r_v<Ret, decltype(Candidate), Type &, Args...>) {
  54812. fn = [](const void *payload, Args... args) -> Ret {
  54813. Type *curr = static_cast<Type *>(const_cast<constness_as_t<void, Type> *>(payload));
  54814. return Ret(std::invoke(Candidate, *curr, std::forward<Args>(args)...));
  54815. };
  54816. } else {
  54817. fn = wrap<Candidate>(value_or_instance, internal::index_sequence_for(internal::function_pointer_t<decltype(Candidate), Type>{}));
  54818. }
  54819. }
  54820. /**
  54821. * @brief Connects a free function with payload or a bound member to a
  54822. * delegate.
  54823. *
  54824. * @sa connect(Type &)
  54825. *
  54826. * @tparam Candidate Function or member to connect to the delegate.
  54827. * @tparam Type Type of class or type of payload.
  54828. * @param value_or_instance A valid pointer that fits the purpose.
  54829. */
  54830. template<auto Candidate, typename Type>
  54831. void connect(Type *value_or_instance) ENTT_NOEXCEPT {
  54832. instance = value_or_instance;
  54833. if constexpr(std::is_invocable_r_v<Ret, decltype(Candidate), Type *, Args...>) {
  54834. fn = [](const void *payload, Args... args) -> Ret {
  54835. Type *curr = static_cast<Type *>(const_cast<constness_as_t<void, Type> *>(payload));
  54836. return Ret(std::invoke(Candidate, curr, std::forward<Args>(args)...));
  54837. };
  54838. } else {
  54839. fn = wrap<Candidate>(value_or_instance, internal::index_sequence_for(internal::function_pointer_t<decltype(Candidate), Type>{}));
  54840. }
  54841. }
  54842. /**
  54843. * @brief Connects an user defined function with optional payload to a
  54844. * delegate.
  54845. *
  54846. * The delegate isn't responsible for the connected object or the payload.
  54847. * Users must always guarantee that the lifetime of an instance overcomes
  54848. * the one of the delegate.<br/>
  54849. * The payload is returned as the first argument to the target function in
  54850. * all cases.
  54851. *
  54852. * @param function Function to connect to the delegate.
  54853. * @param payload User defined arbitrary data.
  54854. */
  54855. void connect(function_type *function, const void *payload = nullptr) ENTT_NOEXCEPT {
  54856. instance = payload;
  54857. fn = function;
  54858. }
  54859. /**
  54860. * @brief Resets a delegate.
  54861. *
  54862. * After a reset, a delegate cannot be invoked anymore.
  54863. */
  54864. void reset() ENTT_NOEXCEPT {
  54865. instance = nullptr;
  54866. fn = nullptr;
  54867. }
  54868. /**
  54869. * @brief Returns the instance or the payload linked to a delegate, if any.
  54870. * @return An opaque pointer to the underlying data.
  54871. */
  54872. [[nodiscard]] const void *data() const ENTT_NOEXCEPT {
  54873. return instance;
  54874. }
  54875. /**
  54876. * @brief Triggers a delegate.
  54877. *
  54878. * The delegate invokes the underlying function and returns the result.
  54879. *
  54880. * @warning
  54881. * Attempting to trigger an invalid delegate results in undefined
  54882. * behavior.
  54883. *
  54884. * @param args Arguments to use to invoke the underlying function.
  54885. * @return The value returned by the underlying function.
  54886. */
  54887. Ret operator()(Args... args) const {
  54888. ENTT_ASSERT(static_cast<bool>(*this), "Uninitialized delegate");
  54889. return fn(instance, std::forward<Args>(args)...);
  54890. }
  54891. /**
  54892. * @brief Checks whether a delegate actually stores a listener.
  54893. * @return False if the delegate is empty, true otherwise.
  54894. */
  54895. [[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
  54896. // no need to also test instance
  54897. return !(fn == nullptr);
  54898. }
  54899. /**
  54900. * @brief Compares the contents of two delegates.
  54901. * @param other Delegate with which to compare.
  54902. * @return False if the two contents differ, true otherwise.
  54903. */
  54904. [[nodiscard]] bool operator==(const delegate<Ret(Args...)> &other) const ENTT_NOEXCEPT {
  54905. return fn == other.fn && instance == other.instance;
  54906. }
  54907. private:
  54908. const void *instance;
  54909. function_type *fn;
  54910. };
  54911. /**
  54912. * @brief Compares the contents of two delegates.
  54913. * @tparam Ret Return type of a function type.
  54914. * @tparam Args Types of arguments of a function type.
  54915. * @param lhs A valid delegate object.
  54916. * @param rhs A valid delegate object.
  54917. * @return True if the two contents differ, false otherwise.
  54918. */
  54919. template<typename Ret, typename... Args>
  54920. [[nodiscard]] bool operator!=(const delegate<Ret(Args...)> &lhs, const delegate<Ret(Args...)> &rhs) ENTT_NOEXCEPT {
  54921. return !(lhs == rhs);
  54922. }
  54923. /**
  54924. * @brief Deduction guide.
  54925. * @tparam Candidate Function or member to connect to the delegate.
  54926. */
  54927. template<auto Candidate>
  54928. delegate(connect_arg_t<Candidate>) -> delegate<std::remove_pointer_t<internal::function_pointer_t<decltype(Candidate)>>>;
  54929. /**
  54930. * @brief Deduction guide.
  54931. * @tparam Candidate Function or member to connect to the delegate.
  54932. * @tparam Type Type of class or type of payload.
  54933. */
  54934. template<auto Candidate, typename Type>
  54935. delegate(connect_arg_t<Candidate>, Type &&) -> delegate<std::remove_pointer_t<internal::function_pointer_t<decltype(Candidate), Type>>>;
  54936. /**
  54937. * @brief Deduction guide.
  54938. * @tparam Ret Return type of a function type.
  54939. * @tparam Args Types of arguments of a function type.
  54940. */
  54941. template<typename Ret, typename... Args>
  54942. delegate(Ret (*)(const void *, Args...), const void * = nullptr) -> delegate<Ret(Args...)>;
  54943. } // namespace entt
  54944. #endif
  54945. // #include "fwd.hpp"
  54946. namespace entt {
  54947. /**
  54948. * @brief Sink class.
  54949. *
  54950. * Primary template isn't defined on purpose. All the specializations give a
  54951. * compile-time error unless the template parameter is a function type.
  54952. *
  54953. * @tparam Type A valid signal handler type.
  54954. */
  54955. template<typename Type>
  54956. class sink;
  54957. /**
  54958. * @brief Unmanaged signal handler.
  54959. *
  54960. * Primary template isn't defined on purpose. All the specializations give a
  54961. * compile-time error unless the template parameter is a function type.
  54962. *
  54963. * @tparam Type A valid function type.
  54964. * @tparam Allocator Type of allocator used to manage memory and elements.
  54965. */
  54966. template<typename Type, typename Allocator>
  54967. class sigh;
  54968. /**
  54969. * @brief Unmanaged signal handler.
  54970. *
  54971. * It works directly with references to classes and pointers to member functions
  54972. * as well as pointers to free functions. Users of this class are in charge of
  54973. * disconnecting instances before deleting them.
  54974. *
  54975. * This class serves mainly two purposes:
  54976. *
  54977. * * Creating signals to use later to notify a bunch of listeners.
  54978. * * Collecting results from a set of functions like in a voting system.
  54979. *
  54980. * @tparam Ret Return type of a function type.
  54981. * @tparam Args Types of arguments of a function type.
  54982. * @tparam Allocator Type of allocator used to manage memory and elements.
  54983. */
  54984. template<typename Ret, typename... Args, typename Allocator>
  54985. class sigh<Ret(Args...), Allocator> {
  54986. /*! @brief A sink is allowed to modify a signal. */
  54987. friend class sink<sigh<Ret(Args...), Allocator>>;
  54988. using alloc_traits = std::allocator_traits<Allocator>;
  54989. static_assert(std::is_same_v<typename alloc_traits::value_type, Ret (*)(Args...)>, "Invalid value type");
  54990. using container_type = std::vector<delegate<Ret(Args...)>, typename alloc_traits::template rebind_alloc<delegate<Ret(Args...)>>>;
  54991. public:
  54992. /*! @brief Allocator type. */
  54993. using allocator_type = Allocator;
  54994. /*! @brief Unsigned integer type. */
  54995. using size_type = std::size_t;
  54996. /*! @brief Sink type. */
  54997. using sink_type = sink<sigh<Ret(Args...), Allocator>>;
  54998. /*! @brief Default constructor. */
  54999. sigh()
  55000. : sigh{allocator_type{}} {}
  55001. /**
  55002. * @brief Constructs a signal handler with a given allocator.
  55003. * @param allocator The allocator to use.
  55004. */
  55005. explicit sigh(const allocator_type &allocator)
  55006. : calls{allocator} {}
  55007. /**
  55008. * @brief Copy constructor.
  55009. * @param other The instance to copy from.
  55010. */
  55011. sigh(const sigh &other)
  55012. : calls{other.calls} {}
  55013. /**
  55014. * @brief Allocator-extended copy constructor.
  55015. * @param other The instance to copy from.
  55016. * @param allocator The allocator to use.
  55017. */
  55018. sigh(const sigh &other, const allocator_type &allocator)
  55019. : calls{other.calls, allocator} {}
  55020. /**
  55021. * @brief Move constructor.
  55022. * @param other The instance to move from.
  55023. */
  55024. sigh(sigh &&other) ENTT_NOEXCEPT
  55025. : calls{std::move(other.calls)} {}
  55026. /**
  55027. * @brief Allocator-extended move constructor.
  55028. * @param other The instance to move from.
  55029. * @param allocator The allocator to use.
  55030. */
  55031. sigh(sigh &&other, const allocator_type &allocator) ENTT_NOEXCEPT
  55032. : calls{std::move(other.calls), allocator} {}
  55033. /**
  55034. * @brief Copy assignment operator.
  55035. * @param other The instance to copy from.
  55036. * @return This signal handler.
  55037. */
  55038. sigh &operator=(const sigh &other) {
  55039. calls = other.calls;
  55040. return *this;
  55041. }
  55042. /**
  55043. * @brief Move assignment operator.
  55044. * @param other The instance to move from.
  55045. * @return This signal handler.
  55046. */
  55047. sigh &operator=(sigh &&other) ENTT_NOEXCEPT {
  55048. calls = std::move(other.calls);
  55049. return *this;
  55050. }
  55051. /**
  55052. * @brief Exchanges the contents with those of a given signal handler.
  55053. * @param other Signal handler to exchange the content with.
  55054. */
  55055. void swap(sigh &other) {
  55056. using std::swap;
  55057. swap(calls, other.calls);
  55058. }
  55059. /**
  55060. * @brief Returns the associated allocator.
  55061. * @return The associated allocator.
  55062. */
  55063. [[nodiscard]] constexpr allocator_type get_allocator() const ENTT_NOEXCEPT {
  55064. return calls.get_allocator();
  55065. }
  55066. /**
  55067. * @brief Instance type when it comes to connecting member functions.
  55068. * @tparam Class Type of class to which the member function belongs.
  55069. */
  55070. template<typename Class>
  55071. using instance_type = Class *;
  55072. /**
  55073. * @brief Number of listeners connected to the signal.
  55074. * @return Number of listeners currently connected.
  55075. */
  55076. [[nodiscard]] size_type size() const ENTT_NOEXCEPT {
  55077. return calls.size();
  55078. }
  55079. /**
  55080. * @brief Returns false if at least a listener is connected to the signal.
  55081. * @return True if the signal has no listeners connected, false otherwise.
  55082. */
  55083. [[nodiscard]] bool empty() const ENTT_NOEXCEPT {
  55084. return calls.empty();
  55085. }
  55086. /**
  55087. * @brief Triggers a signal.
  55088. *
  55089. * All the listeners are notified. Order isn't guaranteed.
  55090. *
  55091. * @param args Arguments to use to invoke listeners.
  55092. */
  55093. void publish(Args... args) const {
  55094. for(auto &&call: std::as_const(calls)) {
  55095. call(args...);
  55096. }
  55097. }
  55098. /**
  55099. * @brief Collects return values from the listeners.
  55100. *
  55101. * The collector must expose a call operator with the following properties:
  55102. *
  55103. * * The return type is either `void` or such that it's convertible to
  55104. * `bool`. In the second case, a true value will stop the iteration.
  55105. * * The list of parameters is empty if `Ret` is `void`, otherwise it
  55106. * contains a single element such that `Ret` is convertible to it.
  55107. *
  55108. * @tparam Func Type of collector to use, if any.
  55109. * @param func A valid function object.
  55110. * @param args Arguments to use to invoke listeners.
  55111. */
  55112. template<typename Func>
  55113. void collect(Func func, Args... args) const {
  55114. for(auto &&call: calls) {
  55115. if constexpr(std::is_void_v<Ret>) {
  55116. if constexpr(std::is_invocable_r_v<bool, Func>) {
  55117. call(args...);
  55118. if(func()) { break; }
  55119. } else {
  55120. call(args...);
  55121. func();
  55122. }
  55123. } else {
  55124. if constexpr(std::is_invocable_r_v<bool, Func, Ret>) {
  55125. if(func(call(args...))) { break; }
  55126. } else {
  55127. func(call(args...));
  55128. }
  55129. }
  55130. }
  55131. }
  55132. private:
  55133. container_type calls;
  55134. };
  55135. /**
  55136. * @brief Connection class.
  55137. *
  55138. * Opaque object the aim of which is to allow users to release an already
  55139. * estabilished connection without having to keep a reference to the signal or
  55140. * the sink that generated it.
  55141. */
  55142. class connection {
  55143. /*! @brief A sink is allowed to create connection objects. */
  55144. template<typename>
  55145. friend class sink;
  55146. connection(delegate<void(void *)> fn, void *ref)
  55147. : disconnect{fn}, signal{ref} {}
  55148. public:
  55149. /*! @brief Default constructor. */
  55150. connection() = default;
  55151. /**
  55152. * @brief Checks whether a connection is properly initialized.
  55153. * @return True if the connection is properly initialized, false otherwise.
  55154. */
  55155. [[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
  55156. return static_cast<bool>(disconnect);
  55157. }
  55158. /*! @brief Breaks the connection. */
  55159. void release() {
  55160. if(disconnect) {
  55161. disconnect(signal);
  55162. disconnect.reset();
  55163. }
  55164. }
  55165. private:
  55166. delegate<void(void *)> disconnect;
  55167. void *signal{};
  55168. };
  55169. /**
  55170. * @brief Scoped connection class.
  55171. *
  55172. * Opaque object the aim of which is to allow users to release an already
  55173. * estabilished connection without having to keep a reference to the signal or
  55174. * the sink that generated it.<br/>
  55175. * A scoped connection automatically breaks the link between the two objects
  55176. * when it goes out of scope.
  55177. */
  55178. struct scoped_connection {
  55179. /*! @brief Default constructor. */
  55180. scoped_connection() = default;
  55181. /**
  55182. * @brief Constructs a scoped connection from a basic connection.
  55183. * @param other A valid connection object.
  55184. */
  55185. scoped_connection(const connection &other)
  55186. : conn{other} {}
  55187. /*! @brief Default copy constructor, deleted on purpose. */
  55188. scoped_connection(const scoped_connection &) = delete;
  55189. /**
  55190. * @brief Move constructor.
  55191. * @param other The scoped connection to move from.
  55192. */
  55193. scoped_connection(scoped_connection &&other) ENTT_NOEXCEPT
  55194. : conn{std::exchange(other.conn, {})} {}
  55195. /*! @brief Automatically breaks the link on destruction. */
  55196. ~scoped_connection() {
  55197. conn.release();
  55198. }
  55199. /**
  55200. * @brief Default copy assignment operator, deleted on purpose.
  55201. * @return This scoped connection.
  55202. */
  55203. scoped_connection &operator=(const scoped_connection &) = delete;
  55204. /**
  55205. * @brief Move assignment operator.
  55206. * @param other The scoped connection to move from.
  55207. * @return This scoped connection.
  55208. */
  55209. scoped_connection &operator=(scoped_connection &&other) ENTT_NOEXCEPT {
  55210. conn = std::exchange(other.conn, {});
  55211. return *this;
  55212. }
  55213. /**
  55214. * @brief Acquires a connection.
  55215. * @param other The connection object to acquire.
  55216. * @return This scoped connection.
  55217. */
  55218. scoped_connection &operator=(connection other) {
  55219. conn = std::move(other);
  55220. return *this;
  55221. }
  55222. /**
  55223. * @brief Checks whether a scoped connection is properly initialized.
  55224. * @return True if the connection is properly initialized, false otherwise.
  55225. */
  55226. [[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
  55227. return static_cast<bool>(conn);
  55228. }
  55229. /*! @brief Breaks the connection. */
  55230. void release() {
  55231. conn.release();
  55232. }
  55233. private:
  55234. connection conn;
  55235. };
  55236. /**
  55237. * @brief Sink class.
  55238. *
  55239. * A sink is used to connect listeners to signals and to disconnect them.<br/>
  55240. * The function type for a listener is the one of the signal to which it
  55241. * belongs.
  55242. *
  55243. * The clear separation between a signal and a sink permits to store the former
  55244. * as private data member without exposing the publish functionality to the
  55245. * users of the class.
  55246. *
  55247. * @warning
  55248. * Lifetime of a sink must not overcome that of the signal to which it refers.
  55249. * In any other case, attempting to use a sink results in undefined behavior.
  55250. *
  55251. * @tparam Ret Return type of a function type.
  55252. * @tparam Args Types of arguments of a function type.
  55253. * @tparam Allocator Type of allocator used to manage memory and elements.
  55254. */
  55255. template<typename Ret, typename... Args, typename Allocator>
  55256. class sink<sigh<Ret(Args...), Allocator>> {
  55257. using signal_type = sigh<Ret(Args...), Allocator>;
  55258. using difference_type = typename signal_type::container_type::difference_type;
  55259. template<auto Candidate, typename Type>
  55260. static void release(Type value_or_instance, void *signal) {
  55261. sink{*static_cast<signal_type *>(signal)}.disconnect<Candidate>(value_or_instance);
  55262. }
  55263. template<auto Candidate>
  55264. static void release(void *signal) {
  55265. sink{*static_cast<signal_type *>(signal)}.disconnect<Candidate>();
  55266. }
  55267. public:
  55268. /**
  55269. * @brief Constructs a sink that is allowed to modify a given signal.
  55270. * @param ref A valid reference to a signal object.
  55271. */
  55272. sink(sigh<Ret(Args...), Allocator> &ref) ENTT_NOEXCEPT
  55273. : offset{},
  55274. signal{&ref} {}
  55275. /**
  55276. * @brief Returns false if at least a listener is connected to the sink.
  55277. * @return True if the sink has no listeners connected, false otherwise.
  55278. */
  55279. [[nodiscard]] bool empty() const ENTT_NOEXCEPT {
  55280. return signal->calls.empty();
  55281. }
  55282. /**
  55283. * @brief Returns a sink that connects before a given free function or an
  55284. * unbound member.
  55285. * @tparam Function A valid free function pointer.
  55286. * @return A properly initialized sink object.
  55287. */
  55288. template<auto Function>
  55289. [[nodiscard]] sink before() {
  55290. delegate<Ret(Args...)> call{};
  55291. call.template connect<Function>();
  55292. const auto &calls = signal->calls;
  55293. const auto it = std::find(calls.cbegin(), calls.cend(), std::move(call));
  55294. sink other{*this};
  55295. other.offset = calls.cend() - it;
  55296. return other;
  55297. }
  55298. /**
  55299. * @brief Returns a sink that connects before a free function with payload
  55300. * or a bound member.
  55301. * @tparam Candidate Member or free function to look for.
  55302. * @tparam Type Type of class or type of payload.
  55303. * @param value_or_instance A valid object that fits the purpose.
  55304. * @return A properly initialized sink object.
  55305. */
  55306. template<auto Candidate, typename Type>
  55307. [[nodiscard]] sink before(Type &&value_or_instance) {
  55308. delegate<Ret(Args...)> call{};
  55309. call.template connect<Candidate>(value_or_instance);
  55310. const auto &calls = signal->calls;
  55311. const auto it = std::find(calls.cbegin(), calls.cend(), std::move(call));
  55312. sink other{*this};
  55313. other.offset = calls.cend() - it;
  55314. return other;
  55315. }
  55316. /**
  55317. * @brief Returns a sink that connects before a given instance or specific
  55318. * payload.
  55319. * @tparam Type Type of class or type of payload.
  55320. * @param value_or_instance A valid object that fits the purpose.
  55321. * @return A properly initialized sink object.
  55322. */
  55323. template<typename Type>
  55324. [[nodiscard]] sink before(Type &value_or_instance) {
  55325. return before(&value_or_instance);
  55326. }
  55327. /**
  55328. * @brief Returns a sink that connects before a given instance or specific
  55329. * payload.
  55330. * @tparam Type Type of class or type of payload.
  55331. * @param value_or_instance A valid pointer that fits the purpose.
  55332. * @return A properly initialized sink object.
  55333. */
  55334. template<typename Type>
  55335. [[nodiscard]] sink before(Type *value_or_instance) {
  55336. sink other{*this};
  55337. if(value_or_instance) {
  55338. const auto &calls = signal->calls;
  55339. const auto it = std::find_if(calls.cbegin(), calls.cend(), [value_or_instance](const auto &delegate) {
  55340. return delegate.data() == value_or_instance;
  55341. });
  55342. other.offset = calls.cend() - it;
  55343. }
  55344. return other;
  55345. }
  55346. /**
  55347. * @brief Returns a sink that connects before anything else.
  55348. * @return A properly initialized sink object.
  55349. */
  55350. [[nodiscard]] sink before() {
  55351. sink other{*this};
  55352. other.offset = signal->calls.size();
  55353. return other;
  55354. }
  55355. /**
  55356. * @brief Connects a free function or an unbound member to a signal.
  55357. *
  55358. * The signal handler performs checks to avoid multiple connections for the
  55359. * same function.
  55360. *
  55361. * @tparam Candidate Function or member to connect to the signal.
  55362. * @return A properly initialized connection object.
  55363. */
  55364. template<auto Candidate>
  55365. connection connect() {
  55366. disconnect<Candidate>();
  55367. delegate<Ret(Args...)> call{};
  55368. call.template connect<Candidate>();
  55369. signal->calls.insert(signal->calls.end() - offset, std::move(call));
  55370. delegate<void(void *)> conn{};
  55371. conn.template connect<&release<Candidate>>();
  55372. return {std::move(conn), signal};
  55373. }
  55374. /**
  55375. * @brief Connects a free function with payload or a bound member to a
  55376. * signal.
  55377. *
  55378. * The signal isn't responsible for the connected object or the payload.
  55379. * Users must always guarantee that the lifetime of the instance overcomes
  55380. * the one of the signal. On the other side, the signal handler performs
  55381. * checks to avoid multiple connections for the same function.<br/>
  55382. * When used to connect a free function with payload, its signature must be
  55383. * such that the instance is the first argument before the ones used to
  55384. * define the signal itself.
  55385. *
  55386. * @tparam Candidate Function or member to connect to the signal.
  55387. * @tparam Type Type of class or type of payload.
  55388. * @param value_or_instance A valid object that fits the purpose.
  55389. * @return A properly initialized connection object.
  55390. */
  55391. template<auto Candidate, typename Type>
  55392. connection connect(Type &&value_or_instance) {
  55393. disconnect<Candidate>(value_or_instance);
  55394. delegate<Ret(Args...)> call{};
  55395. call.template connect<Candidate>(value_or_instance);
  55396. signal->calls.insert(signal->calls.end() - offset, std::move(call));
  55397. delegate<void(void *)> conn{};
  55398. conn.template connect<&release<Candidate, Type>>(value_or_instance);
  55399. return {std::move(conn), signal};
  55400. }
  55401. /**
  55402. * @brief Disconnects a free function or an unbound member from a signal.
  55403. * @tparam Candidate Function or member to disconnect from the signal.
  55404. */
  55405. template<auto Candidate>
  55406. void disconnect() {
  55407. auto &calls = signal->calls;
  55408. delegate<Ret(Args...)> call{};
  55409. call.template connect<Candidate>();
  55410. calls.erase(std::remove(calls.begin(), calls.end(), std::move(call)), calls.end());
  55411. }
  55412. /**
  55413. * @brief Disconnects a free function with payload or a bound member from a
  55414. * signal.
  55415. * @tparam Candidate Function or member to disconnect from the signal.
  55416. * @tparam Type Type of class or type of payload.
  55417. * @param value_or_instance A valid object that fits the purpose.
  55418. */
  55419. template<auto Candidate, typename Type>
  55420. void disconnect(Type &&value_or_instance) {
  55421. auto &calls = signal->calls;
  55422. delegate<Ret(Args...)> call{};
  55423. call.template connect<Candidate>(value_or_instance);
  55424. calls.erase(std::remove(calls.begin(), calls.end(), std::move(call)), calls.end());
  55425. }
  55426. /**
  55427. * @brief Disconnects free functions with payload or bound members from a
  55428. * signal.
  55429. * @tparam Type Type of class or type of payload.
  55430. * @param value_or_instance A valid object that fits the purpose.
  55431. */
  55432. template<typename Type>
  55433. void disconnect(Type &value_or_instance) {
  55434. disconnect(&value_or_instance);
  55435. }
  55436. /**
  55437. * @brief Disconnects free functions with payload or bound members from a
  55438. * signal.
  55439. * @tparam Type Type of class or type of payload.
  55440. * @param value_or_instance A valid object that fits the purpose.
  55441. */
  55442. template<typename Type>
  55443. void disconnect(Type *value_or_instance) {
  55444. if(value_or_instance) {
  55445. auto &calls = signal->calls;
  55446. auto predicate = [value_or_instance](const auto &delegate) { return delegate.data() == value_or_instance; };
  55447. calls.erase(std::remove_if(calls.begin(), calls.end(), std::move(predicate)), calls.end());
  55448. }
  55449. }
  55450. /*! @brief Disconnects all the listeners from a signal. */
  55451. void disconnect() {
  55452. signal->calls.clear();
  55453. }
  55454. private:
  55455. difference_type offset;
  55456. signal_type *signal;
  55457. };
  55458. /**
  55459. * @brief Deduction guide.
  55460. *
  55461. * It allows to deduce the signal handler type of a sink directly from the
  55462. * signal it refers to.
  55463. *
  55464. * @tparam Ret Return type of a function type.
  55465. * @tparam Args Types of arguments of a function type.
  55466. * @tparam Allocator Type of allocator used to manage memory and elements.
  55467. */
  55468. template<typename Ret, typename... Args, typename Allocator>
  55469. sink(sigh<Ret(Args...), Allocator> &) -> sink<sigh<Ret(Args...), Allocator>>;
  55470. } // namespace entt
  55471. #endif
  55472. namespace entt {
  55473. /**
  55474. * @cond TURN_OFF_DOXYGEN
  55475. * Internal details not to be documented.
  55476. */
  55477. namespace internal {
  55478. struct basic_dispatcher_handler {
  55479. virtual ~basic_dispatcher_handler() = default;
  55480. virtual void publish() = 0;
  55481. virtual void disconnect(void *) = 0;
  55482. virtual void clear() ENTT_NOEXCEPT = 0;
  55483. virtual std::size_t size() const ENTT_NOEXCEPT = 0;
  55484. };
  55485. template<typename Event, typename Allocator>
  55486. class dispatcher_handler final: public basic_dispatcher_handler {
  55487. static_assert(std::is_same_v<Event, std::decay_t<Event>>, "Invalid event type");
  55488. using alloc_traits = std::allocator_traits<Allocator>;
  55489. using signal_type = sigh<void(Event &), typename alloc_traits::template rebind_alloc<void (*)(Event &)>>;
  55490. using container_type = std::vector<Event, typename alloc_traits::template rebind_alloc<Event>>;
  55491. public:
  55492. using allocator_type = Allocator;
  55493. dispatcher_handler(const allocator_type &allocator)
  55494. : signal{allocator},
  55495. events{allocator} {}
  55496. void publish() override {
  55497. const auto length = events.size();
  55498. for(std::size_t pos{}; pos < length; ++pos) {
  55499. signal.publish(events[pos]);
  55500. }
  55501. events.erase(events.cbegin(), events.cbegin() + length);
  55502. }
  55503. void disconnect(void *instance) override {
  55504. bucket().disconnect(instance);
  55505. }
  55506. void clear() ENTT_NOEXCEPT override {
  55507. events.clear();
  55508. }
  55509. [[nodiscard]] auto bucket() ENTT_NOEXCEPT {
  55510. using sink_type = typename sigh<void(Event &)>::sink_type;
  55511. return sink_type{signal};
  55512. }
  55513. void trigger(Event event) {
  55514. signal.publish(event);
  55515. }
  55516. template<typename... Args>
  55517. void enqueue(Args &&...args) {
  55518. if constexpr(std::is_aggregate_v<Event>) {
  55519. events.push_back(Event{std::forward<Args>(args)...});
  55520. } else {
  55521. events.emplace_back(std::forward<Args>(args)...);
  55522. }
  55523. }
  55524. std::size_t size() const ENTT_NOEXCEPT override {
  55525. return events.size();
  55526. }
  55527. private:
  55528. signal_type signal;
  55529. container_type events;
  55530. };
  55531. } // namespace internal
  55532. /**
  55533. * Internal details not to be documented.
  55534. * @endcond
  55535. */
  55536. /**
  55537. * @brief Basic dispatcher implementation.
  55538. *
  55539. * A dispatcher can be used either to trigger an immediate event or to enqueue
  55540. * events to be published all together once per tick.<br/>
  55541. * Listeners are provided in the form of member functions. For each event of
  55542. * type `Event`, listeners are such that they can be invoked with an argument of
  55543. * type `Event &`, no matter what the return type is.
  55544. *
  55545. * The dispatcher creates instances of the `sigh` class internally. Refer to the
  55546. * documentation of the latter for more details.
  55547. *
  55548. * @tparam Allocator Type of allocator used to manage memory and elements.
  55549. */
  55550. template<typename Allocator>
  55551. class basic_dispatcher {
  55552. template<typename Event>
  55553. using handler_type = internal::dispatcher_handler<Event, Allocator>;
  55554. using key_type = id_type;
  55555. // std::shared_ptr because of its type erased allocator which is pretty useful here
  55556. using mapped_type = std::shared_ptr<internal::basic_dispatcher_handler>;
  55557. using alloc_traits = std::allocator_traits<Allocator>;
  55558. using container_allocator = typename alloc_traits::template rebind_alloc<std::pair<const key_type, mapped_type>>;
  55559. using container_type = dense_map<id_type, mapped_type, identity, std::equal_to<id_type>, container_allocator>;
  55560. template<typename Event>
  55561. [[nodiscard]] handler_type<Event> &assure(const id_type id) {
  55562. auto &&ptr = pools.first()[id];
  55563. if(!ptr) {
  55564. const auto &allocator = pools.second();
  55565. ptr = std::allocate_shared<handler_type<Event>>(allocator, allocator);
  55566. }
  55567. return static_cast<handler_type<Event> &>(*ptr);
  55568. }
  55569. template<typename Event>
  55570. [[nodiscard]] const handler_type<Event> *assure(const id_type id) const {
  55571. auto &container = pools.first();
  55572. if(const auto it = container.find(id); it != container.end()) {
  55573. return static_cast<const handler_type<Event> *>(it->second.get());
  55574. }
  55575. return nullptr;
  55576. }
  55577. public:
  55578. /*! @brief Allocator type. */
  55579. using allocator_type = Allocator;
  55580. /*! @brief Unsigned integer type. */
  55581. using size_type = std::size_t;
  55582. /*! @brief Default constructor. */
  55583. basic_dispatcher()
  55584. : basic_dispatcher{allocator_type{}} {}
  55585. /**
  55586. * @brief Constructs a dispatcher with a given allocator.
  55587. * @param allocator The allocator to use.
  55588. */
  55589. explicit basic_dispatcher(const allocator_type &allocator)
  55590. : pools{allocator, allocator} {}
  55591. /**
  55592. * @brief Move constructor.
  55593. * @param other The instance to move from.
  55594. */
  55595. basic_dispatcher(basic_dispatcher &&other) ENTT_NOEXCEPT
  55596. : pools{std::move(other.pools)} {}
  55597. /**
  55598. * @brief Allocator-extended move constructor.
  55599. * @param other The instance to move from.
  55600. * @param allocator The allocator to use.
  55601. */
  55602. basic_dispatcher(basic_dispatcher &&other, const allocator_type &allocator) ENTT_NOEXCEPT
  55603. : pools{container_type{std::move(other.pools.first()), allocator}, allocator} {}
  55604. /**
  55605. * @brief Move assignment operator.
  55606. * @param other The instance to move from.
  55607. * @return This dispatcher.
  55608. */
  55609. basic_dispatcher &operator=(basic_dispatcher &&other) ENTT_NOEXCEPT {
  55610. pools = std::move(other.pools);
  55611. return *this;
  55612. }
  55613. /**
  55614. * @brief Exchanges the contents with those of a given dispatcher.
  55615. * @param other Dispatcher to exchange the content with.
  55616. */
  55617. void swap(basic_dispatcher &other) {
  55618. using std::swap;
  55619. swap(pools, other.pools);
  55620. }
  55621. /**
  55622. * @brief Returns the associated allocator.
  55623. * @return The associated allocator.
  55624. */
  55625. [[nodiscard]] constexpr allocator_type get_allocator() const ENTT_NOEXCEPT {
  55626. return pools.second();
  55627. }
  55628. /**
  55629. * @brief Returns the number of pending events for a given type.
  55630. * @tparam Event Type of event for which to return the count.
  55631. * @param id Name used to map the event queue within the dispatcher.
  55632. * @return The number of pending events for the given type.
  55633. */
  55634. template<typename Event>
  55635. size_type size(const id_type id = type_hash<Event>::value()) const ENTT_NOEXCEPT {
  55636. const auto *cpool = assure<Event>(id);
  55637. return cpool ? cpool->size() : 0u;
  55638. }
  55639. /**
  55640. * @brief Returns the total number of pending events.
  55641. * @return The total number of pending events.
  55642. */
  55643. size_type size() const ENTT_NOEXCEPT {
  55644. size_type count{};
  55645. for(auto &&cpool: pools.first()) {
  55646. count += cpool.second->size();
  55647. }
  55648. return count;
  55649. }
  55650. /**
  55651. * @brief Returns a sink object for the given event and queue.
  55652. *
  55653. * A sink is an opaque object used to connect listeners to events.
  55654. *
  55655. * The function type for a listener is _compatible_ with:
  55656. * @code{.cpp}
  55657. * void(Event &);
  55658. * @endcode
  55659. *
  55660. * The order of invocation of the listeners isn't guaranteed.
  55661. *
  55662. * @sa sink
  55663. *
  55664. * @tparam Event Type of event of which to get the sink.
  55665. * @param id Name used to map the event queue within the dispatcher.
  55666. * @return A temporary sink object.
  55667. */
  55668. template<typename Event>
  55669. [[nodiscard]] auto sink(const id_type id = type_hash<Event>::value()) {
  55670. return assure<Event>(id).bucket();
  55671. }
  55672. /**
  55673. * @brief Triggers an immediate event of a given type.
  55674. * @tparam Event Type of event to trigger.
  55675. * @param event An instance of the given type of event.
  55676. */
  55677. template<typename Event>
  55678. void trigger(Event &&event = {}) {
  55679. trigger(type_hash<std::decay_t<Event>>::value(), std::forward<Event>(event));
  55680. }
  55681. /**
  55682. * @brief Triggers an immediate event on a queue of a given type.
  55683. * @tparam Event Type of event to trigger.
  55684. * @param event An instance of the given type of event.
  55685. * @param id Name used to map the event queue within the dispatcher.
  55686. */
  55687. template<typename Event>
  55688. void trigger(const id_type id, Event &&event = {}) {
  55689. assure<std::decay_t<Event>>(id).trigger(std::forward<Event>(event));
  55690. }
  55691. /**
  55692. * @brief Enqueues an event of the given type.
  55693. * @tparam Event Type of event to enqueue.
  55694. * @tparam Args Types of arguments to use to construct the event.
  55695. * @param args Arguments to use to construct the event.
  55696. */
  55697. template<typename Event, typename... Args>
  55698. void enqueue(Args &&...args) {
  55699. enqueue_hint<Event>(type_hash<Event>::value(), std::forward<Args>(args)...);
  55700. }
  55701. /**
  55702. * @brief Enqueues an event of the given type.
  55703. * @tparam Event Type of event to enqueue.
  55704. * @param event An instance of the given type of event.
  55705. */
  55706. template<typename Event>
  55707. void enqueue(Event &&event) {
  55708. enqueue_hint(type_hash<std::decay_t<Event>>::value(), std::forward<Event>(event));
  55709. }
  55710. /**
  55711. * @brief Enqueues an event of the given type.
  55712. * @tparam Event Type of event to enqueue.
  55713. * @tparam Args Types of arguments to use to construct the event.
  55714. * @param id Name used to map the event queue within the dispatcher.
  55715. * @param args Arguments to use to construct the event.
  55716. */
  55717. template<typename Event, typename... Args>
  55718. void enqueue_hint(const id_type id, Args &&...args) {
  55719. assure<Event>(id).enqueue(std::forward<Args>(args)...);
  55720. }
  55721. /**
  55722. * @brief Enqueues an event of the given type.
  55723. * @tparam Event Type of event to enqueue.
  55724. * @param id Name used to map the event queue within the dispatcher.
  55725. * @param event An instance of the given type of event.
  55726. */
  55727. template<typename Event>
  55728. void enqueue_hint(const id_type id, Event &&event) {
  55729. assure<std::decay_t<Event>>(id).enqueue(std::forward<Event>(event));
  55730. }
  55731. /**
  55732. * @brief Utility function to disconnect everything related to a given value
  55733. * or instance from a dispatcher.
  55734. * @tparam Type Type of class or type of payload.
  55735. * @param value_or_instance A valid object that fits the purpose.
  55736. */
  55737. template<typename Type>
  55738. void disconnect(Type &value_or_instance) {
  55739. disconnect(&value_or_instance);
  55740. }
  55741. /**
  55742. * @brief Utility function to disconnect everything related to a given value
  55743. * or instance from a dispatcher.
  55744. * @tparam Type Type of class or type of payload.
  55745. * @param value_or_instance A valid object that fits the purpose.
  55746. */
  55747. template<typename Type>
  55748. void disconnect(Type *value_or_instance) {
  55749. for(auto &&cpool: pools.first()) {
  55750. cpool.second->disconnect(value_or_instance);
  55751. }
  55752. }
  55753. /**
  55754. * @brief Discards all the events stored so far in a given queue.
  55755. * @tparam Event Type of event to discard.
  55756. * @param id Name used to map the event queue within the dispatcher.
  55757. */
  55758. template<typename Event>
  55759. void clear(const id_type id = type_hash<Event>::value()) {
  55760. assure<Event>(id).clear();
  55761. }
  55762. /*! @brief Discards all the events queued so far. */
  55763. void clear() ENTT_NOEXCEPT {
  55764. for(auto &&cpool: pools.first()) {
  55765. cpool.second->clear();
  55766. }
  55767. }
  55768. /**
  55769. * @brief Delivers all the pending events of a given queue.
  55770. * @tparam Event Type of event to send.
  55771. * @param id Name used to map the event queue within the dispatcher.
  55772. */
  55773. template<typename Event>
  55774. void update(const id_type id = type_hash<Event>::value()) {
  55775. assure<Event>(id).publish();
  55776. }
  55777. /*! @brief Delivers all the pending events. */
  55778. void update() const {
  55779. for(auto &&cpool: pools.first()) {
  55780. cpool.second->publish();
  55781. }
  55782. }
  55783. private:
  55784. compressed_pair<container_type, allocator_type> pools;
  55785. };
  55786. } // namespace entt
  55787. #endif
  55788. // #include "signal/emitter.hpp"
  55789. #ifndef ENTT_SIGNAL_EMITTER_HPP
  55790. #define ENTT_SIGNAL_EMITTER_HPP
  55791. #include <algorithm>
  55792. #include <functional>
  55793. #include <iterator>
  55794. #include <list>
  55795. #include <memory>
  55796. #include <type_traits>
  55797. #include <utility>
  55798. // #include "../config/config.h"
  55799. // #include "../container/dense_map.hpp"
  55800. // #include "../core/fwd.hpp"
  55801. // #include "../core/type_info.hpp"
  55802. // #include "../core/utility.hpp"
  55803. // #include "fwd.hpp"
  55804. namespace entt {
  55805. /**
  55806. * @brief General purpose event emitter.
  55807. *
  55808. * The emitter class template follows the CRTP idiom. To create a custom emitter
  55809. * type, derived classes must inherit directly from the base class as:
  55810. *
  55811. * @code{.cpp}
  55812. * struct my_emitter: emitter<my_emitter> {
  55813. * // ...
  55814. * }
  55815. * @endcode
  55816. *
  55817. * Pools for the type of events are created internally on the fly. It's not
  55818. * required to specify in advance the full list of accepted types.<br/>
  55819. * Moreover, whenever an event is published, an emitter provides the listeners
  55820. * with a reference to itself along with a reference to the event. Therefore
  55821. * listeners have an handy way to work with it without incurring in the need of
  55822. * capturing a reference to the emitter.
  55823. *
  55824. * @tparam Derived Actual type of emitter that extends the class template.
  55825. */
  55826. template<typename Derived>
  55827. class emitter {
  55828. struct basic_pool {
  55829. virtual ~basic_pool() = default;
  55830. virtual bool empty() const ENTT_NOEXCEPT = 0;
  55831. virtual void clear() ENTT_NOEXCEPT = 0;
  55832. };
  55833. template<typename Event>
  55834. struct pool_handler final: basic_pool {
  55835. static_assert(std::is_same_v<Event, std::decay_t<Event>>, "Invalid event type");
  55836. using listener_type = std::function<void(Event &, Derived &)>;
  55837. using element_type = std::pair<bool, listener_type>;
  55838. using container_type = std::list<element_type>;
  55839. using connection_type = typename container_type::iterator;
  55840. [[nodiscard]] bool empty() const ENTT_NOEXCEPT override {
  55841. auto pred = [](auto &&element) { return element.first; };
  55842. return std::all_of(once_list.cbegin(), once_list.cend(), pred)
  55843. && std::all_of(on_list.cbegin(), on_list.cend(), pred);
  55844. }
  55845. void clear() ENTT_NOEXCEPT override {
  55846. if(publishing) {
  55847. for(auto &&element: once_list) {
  55848. element.first = true;
  55849. }
  55850. for(auto &&element: on_list) {
  55851. element.first = true;
  55852. }
  55853. } else {
  55854. once_list.clear();
  55855. on_list.clear();
  55856. }
  55857. }
  55858. connection_type once(listener_type listener) {
  55859. return once_list.emplace(once_list.cend(), false, std::move(listener));
  55860. }
  55861. connection_type on(listener_type listener) {
  55862. return on_list.emplace(on_list.cend(), false, std::move(listener));
  55863. }
  55864. void erase(connection_type conn) {
  55865. conn->first = true;
  55866. if(!publishing) {
  55867. auto pred = [](auto &&element) { return element.first; };
  55868. once_list.remove_if(pred);
  55869. on_list.remove_if(pred);
  55870. }
  55871. }
  55872. void publish(Event &event, Derived &ref) {
  55873. container_type swap_list;
  55874. once_list.swap(swap_list);
  55875. publishing = true;
  55876. for(auto &&element: on_list) {
  55877. element.first ? void() : element.second(event, ref);
  55878. }
  55879. for(auto &&element: swap_list) {
  55880. element.first ? void() : element.second(event, ref);
  55881. }
  55882. publishing = false;
  55883. on_list.remove_if([](auto &&element) { return element.first; });
  55884. }
  55885. private:
  55886. bool publishing{false};
  55887. container_type once_list{};
  55888. container_type on_list{};
  55889. };
  55890. template<typename Event>
  55891. [[nodiscard]] pool_handler<Event> *assure() {
  55892. if(auto &&ptr = pools[type_hash<Event>::value()]; !ptr) {
  55893. auto *cpool = new pool_handler<Event>{};
  55894. ptr.reset(cpool);
  55895. return cpool;
  55896. } else {
  55897. return static_cast<pool_handler<Event> *>(ptr.get());
  55898. }
  55899. }
  55900. template<typename Event>
  55901. [[nodiscard]] const pool_handler<Event> *assure() const {
  55902. const auto it = pools.find(type_hash<Event>::value());
  55903. return (it == pools.cend()) ? nullptr : static_cast<const pool_handler<Event> *>(it->second.get());
  55904. }
  55905. public:
  55906. /** @brief Type of listeners accepted for the given event. */
  55907. template<typename Event>
  55908. using listener = typename pool_handler<Event>::listener_type;
  55909. /**
  55910. * @brief Generic connection type for events.
  55911. *
  55912. * Type of the connection object returned by the event emitter whenever a
  55913. * listener for the given type is registered.<br/>
  55914. * It can be used to break connections still in use.
  55915. *
  55916. * @tparam Event Type of event for which the connection is created.
  55917. */
  55918. template<typename Event>
  55919. struct connection: private pool_handler<Event>::connection_type {
  55920. /** @brief Event emitters are friend classes of connections. */
  55921. friend class emitter;
  55922. /*! @brief Default constructor. */
  55923. connection() ENTT_NOEXCEPT = default;
  55924. /**
  55925. * @brief Creates a connection that wraps its underlying instance.
  55926. * @param conn A connection object to wrap.
  55927. */
  55928. connection(typename pool_handler<Event>::connection_type conn)
  55929. : pool_handler<Event>::connection_type{std::move(conn)} {}
  55930. };
  55931. /*! @brief Default constructor. */
  55932. emitter() = default;
  55933. /*! @brief Default destructor. */
  55934. virtual ~emitter() ENTT_NOEXCEPT {
  55935. static_assert(std::is_base_of_v<emitter<Derived>, Derived>, "Incorrect use of the class template");
  55936. }
  55937. /*! @brief Default move constructor. */
  55938. emitter(emitter &&) = default;
  55939. /*! @brief Default move assignment operator. @return This emitter. */
  55940. emitter &operator=(emitter &&) = default;
  55941. /**
  55942. * @brief Emits the given event.
  55943. *
  55944. * All the listeners registered for the specific event type are invoked with
  55945. * the given event. The event type must either have a proper constructor for
  55946. * the arguments provided or be an aggregate type.
  55947. *
  55948. * @tparam Event Type of event to publish.
  55949. * @tparam Args Types of arguments to use to construct the event.
  55950. * @param args Parameters to use to initialize the event.
  55951. */
  55952. template<typename Event, typename... Args>
  55953. void publish(Args &&...args) {
  55954. Event instance{std::forward<Args>(args)...};
  55955. assure<Event>()->publish(instance, *static_cast<Derived *>(this));
  55956. }
  55957. /**
  55958. * @brief Registers a long-lived listener with the event emitter.
  55959. *
  55960. * This method can be used to register a listener designed to be invoked
  55961. * more than once for the given event type.<br/>
  55962. * The connection returned by the method can be freely discarded. It's meant
  55963. * to be used later to disconnect the listener if required.
  55964. *
  55965. * The listener is as a callable object that can be moved and the type of
  55966. * which is _compatible_ with `void(Event &, Derived &)`.
  55967. *
  55968. * @note
  55969. * Whenever an event is emitted, the emitter provides the listener with a
  55970. * reference to the derived class. Listeners don't have to capture those
  55971. * instances for later uses.
  55972. *
  55973. * @tparam Event Type of event to which to connect the listener.
  55974. * @param instance The listener to register.
  55975. * @return Connection object that can be used to disconnect the listener.
  55976. */
  55977. template<typename Event>
  55978. connection<Event> on(listener<Event> instance) {
  55979. return assure<Event>()->on(std::move(instance));
  55980. }
  55981. /**
  55982. * @brief Registers a short-lived listener with the event emitter.
  55983. *
  55984. * This method can be used to register a listener designed to be invoked
  55985. * only once for the given event type.<br/>
  55986. * The connection returned by the method can be freely discarded. It's meant
  55987. * to be used later to disconnect the listener if required.
  55988. *
  55989. * The listener is as a callable object that can be moved and the type of
  55990. * which is _compatible_ with `void(Event &, Derived &)`.
  55991. *
  55992. * @note
  55993. * Whenever an event is emitted, the emitter provides the listener with a
  55994. * reference to the derived class. Listeners don't have to capture those
  55995. * instances for later uses.
  55996. *
  55997. * @tparam Event Type of event to which to connect the listener.
  55998. * @param instance The listener to register.
  55999. * @return Connection object that can be used to disconnect the listener.
  56000. */
  56001. template<typename Event>
  56002. connection<Event> once(listener<Event> instance) {
  56003. return assure<Event>()->once(std::move(instance));
  56004. }
  56005. /**
  56006. * @brief Disconnects a listener from the event emitter.
  56007. *
  56008. * Do not use twice the same connection to disconnect a listener, it results
  56009. * in undefined behavior. Once used, discard the connection object.
  56010. *
  56011. * @tparam Event Type of event of the connection.
  56012. * @param conn A valid connection.
  56013. */
  56014. template<typename Event>
  56015. void erase(connection<Event> conn) {
  56016. assure<Event>()->erase(std::move(conn));
  56017. }
  56018. /**
  56019. * @brief Disconnects all the listeners for the given event type.
  56020. *
  56021. * All the connections previously returned for the given event are
  56022. * invalidated. Using them results in undefined behavior.
  56023. *
  56024. * @tparam Event Type of event to reset.
  56025. */
  56026. template<typename Event>
  56027. void clear() {
  56028. assure<Event>()->clear();
  56029. }
  56030. /**
  56031. * @brief Disconnects all the listeners.
  56032. *
  56033. * All the connections previously returned are invalidated. Using them
  56034. * results in undefined behavior.
  56035. */
  56036. void clear() ENTT_NOEXCEPT {
  56037. for(auto &&cpool: pools) {
  56038. cpool.second->clear();
  56039. }
  56040. }
  56041. /**
  56042. * @brief Checks if there are listeners registered for the specific event.
  56043. * @tparam Event Type of event to test.
  56044. * @return True if there are no listeners registered, false otherwise.
  56045. */
  56046. template<typename Event>
  56047. [[nodiscard]] bool empty() const {
  56048. const auto *cpool = assure<Event>();
  56049. return !cpool || cpool->empty();
  56050. }
  56051. /**
  56052. * @brief Checks if there are listeners registered with the event emitter.
  56053. * @return True if there are no listeners registered, false otherwise.
  56054. */
  56055. [[nodiscard]] bool empty() const ENTT_NOEXCEPT {
  56056. return std::all_of(pools.cbegin(), pools.cend(), [](auto &&cpool) {
  56057. return cpool.second->empty();
  56058. });
  56059. }
  56060. private:
  56061. dense_map<id_type, std::unique_ptr<basic_pool>, identity> pools{};
  56062. };
  56063. } // namespace entt
  56064. #endif
  56065. // #include "signal/sigh.hpp"
  56066. #ifndef ENTT_SIGNAL_SIGH_HPP
  56067. #define ENTT_SIGNAL_SIGH_HPP
  56068. #include <algorithm>
  56069. #include <functional>
  56070. #include <type_traits>
  56071. #include <utility>
  56072. #include <vector>
  56073. // #include "../config/config.h"
  56074. // #include "delegate.hpp"
  56075. // #include "fwd.hpp"
  56076. namespace entt {
  56077. /**
  56078. * @brief Sink class.
  56079. *
  56080. * Primary template isn't defined on purpose. All the specializations give a
  56081. * compile-time error unless the template parameter is a function type.
  56082. *
  56083. * @tparam Type A valid signal handler type.
  56084. */
  56085. template<typename Type>
  56086. class sink;
  56087. /**
  56088. * @brief Unmanaged signal handler.
  56089. *
  56090. * Primary template isn't defined on purpose. All the specializations give a
  56091. * compile-time error unless the template parameter is a function type.
  56092. *
  56093. * @tparam Type A valid function type.
  56094. * @tparam Allocator Type of allocator used to manage memory and elements.
  56095. */
  56096. template<typename Type, typename Allocator>
  56097. class sigh;
  56098. /**
  56099. * @brief Unmanaged signal handler.
  56100. *
  56101. * It works directly with references to classes and pointers to member functions
  56102. * as well as pointers to free functions. Users of this class are in charge of
  56103. * disconnecting instances before deleting them.
  56104. *
  56105. * This class serves mainly two purposes:
  56106. *
  56107. * * Creating signals to use later to notify a bunch of listeners.
  56108. * * Collecting results from a set of functions like in a voting system.
  56109. *
  56110. * @tparam Ret Return type of a function type.
  56111. * @tparam Args Types of arguments of a function type.
  56112. * @tparam Allocator Type of allocator used to manage memory and elements.
  56113. */
  56114. template<typename Ret, typename... Args, typename Allocator>
  56115. class sigh<Ret(Args...), Allocator> {
  56116. /*! @brief A sink is allowed to modify a signal. */
  56117. friend class sink<sigh<Ret(Args...), Allocator>>;
  56118. using alloc_traits = std::allocator_traits<Allocator>;
  56119. static_assert(std::is_same_v<typename alloc_traits::value_type, Ret (*)(Args...)>, "Invalid value type");
  56120. using container_type = std::vector<delegate<Ret(Args...)>, typename alloc_traits::template rebind_alloc<delegate<Ret(Args...)>>>;
  56121. public:
  56122. /*! @brief Allocator type. */
  56123. using allocator_type = Allocator;
  56124. /*! @brief Unsigned integer type. */
  56125. using size_type = std::size_t;
  56126. /*! @brief Sink type. */
  56127. using sink_type = sink<sigh<Ret(Args...), Allocator>>;
  56128. /*! @brief Default constructor. */
  56129. sigh()
  56130. : sigh{allocator_type{}} {}
  56131. /**
  56132. * @brief Constructs a signal handler with a given allocator.
  56133. * @param allocator The allocator to use.
  56134. */
  56135. explicit sigh(const allocator_type &allocator)
  56136. : calls{allocator} {}
  56137. /**
  56138. * @brief Copy constructor.
  56139. * @param other The instance to copy from.
  56140. */
  56141. sigh(const sigh &other)
  56142. : calls{other.calls} {}
  56143. /**
  56144. * @brief Allocator-extended copy constructor.
  56145. * @param other The instance to copy from.
  56146. * @param allocator The allocator to use.
  56147. */
  56148. sigh(const sigh &other, const allocator_type &allocator)
  56149. : calls{other.calls, allocator} {}
  56150. /**
  56151. * @brief Move constructor.
  56152. * @param other The instance to move from.
  56153. */
  56154. sigh(sigh &&other) ENTT_NOEXCEPT
  56155. : calls{std::move(other.calls)} {}
  56156. /**
  56157. * @brief Allocator-extended move constructor.
  56158. * @param other The instance to move from.
  56159. * @param allocator The allocator to use.
  56160. */
  56161. sigh(sigh &&other, const allocator_type &allocator) ENTT_NOEXCEPT
  56162. : calls{std::move(other.calls), allocator} {}
  56163. /**
  56164. * @brief Copy assignment operator.
  56165. * @param other The instance to copy from.
  56166. * @return This signal handler.
  56167. */
  56168. sigh &operator=(const sigh &other) {
  56169. calls = other.calls;
  56170. return *this;
  56171. }
  56172. /**
  56173. * @brief Move assignment operator.
  56174. * @param other The instance to move from.
  56175. * @return This signal handler.
  56176. */
  56177. sigh &operator=(sigh &&other) ENTT_NOEXCEPT {
  56178. calls = std::move(other.calls);
  56179. return *this;
  56180. }
  56181. /**
  56182. * @brief Exchanges the contents with those of a given signal handler.
  56183. * @param other Signal handler to exchange the content with.
  56184. */
  56185. void swap(sigh &other) {
  56186. using std::swap;
  56187. swap(calls, other.calls);
  56188. }
  56189. /**
  56190. * @brief Returns the associated allocator.
  56191. * @return The associated allocator.
  56192. */
  56193. [[nodiscard]] constexpr allocator_type get_allocator() const ENTT_NOEXCEPT {
  56194. return calls.get_allocator();
  56195. }
  56196. /**
  56197. * @brief Instance type when it comes to connecting member functions.
  56198. * @tparam Class Type of class to which the member function belongs.
  56199. */
  56200. template<typename Class>
  56201. using instance_type = Class *;
  56202. /**
  56203. * @brief Number of listeners connected to the signal.
  56204. * @return Number of listeners currently connected.
  56205. */
  56206. [[nodiscard]] size_type size() const ENTT_NOEXCEPT {
  56207. return calls.size();
  56208. }
  56209. /**
  56210. * @brief Returns false if at least a listener is connected to the signal.
  56211. * @return True if the signal has no listeners connected, false otherwise.
  56212. */
  56213. [[nodiscard]] bool empty() const ENTT_NOEXCEPT {
  56214. return calls.empty();
  56215. }
  56216. /**
  56217. * @brief Triggers a signal.
  56218. *
  56219. * All the listeners are notified. Order isn't guaranteed.
  56220. *
  56221. * @param args Arguments to use to invoke listeners.
  56222. */
  56223. void publish(Args... args) const {
  56224. for(auto &&call: std::as_const(calls)) {
  56225. call(args...);
  56226. }
  56227. }
  56228. /**
  56229. * @brief Collects return values from the listeners.
  56230. *
  56231. * The collector must expose a call operator with the following properties:
  56232. *
  56233. * * The return type is either `void` or such that it's convertible to
  56234. * `bool`. In the second case, a true value will stop the iteration.
  56235. * * The list of parameters is empty if `Ret` is `void`, otherwise it
  56236. * contains a single element such that `Ret` is convertible to it.
  56237. *
  56238. * @tparam Func Type of collector to use, if any.
  56239. * @param func A valid function object.
  56240. * @param args Arguments to use to invoke listeners.
  56241. */
  56242. template<typename Func>
  56243. void collect(Func func, Args... args) const {
  56244. for(auto &&call: calls) {
  56245. if constexpr(std::is_void_v<Ret>) {
  56246. if constexpr(std::is_invocable_r_v<bool, Func>) {
  56247. call(args...);
  56248. if(func()) { break; }
  56249. } else {
  56250. call(args...);
  56251. func();
  56252. }
  56253. } else {
  56254. if constexpr(std::is_invocable_r_v<bool, Func, Ret>) {
  56255. if(func(call(args...))) { break; }
  56256. } else {
  56257. func(call(args...));
  56258. }
  56259. }
  56260. }
  56261. }
  56262. private:
  56263. container_type calls;
  56264. };
  56265. /**
  56266. * @brief Connection class.
  56267. *
  56268. * Opaque object the aim of which is to allow users to release an already
  56269. * estabilished connection without having to keep a reference to the signal or
  56270. * the sink that generated it.
  56271. */
  56272. class connection {
  56273. /*! @brief A sink is allowed to create connection objects. */
  56274. template<typename>
  56275. friend class sink;
  56276. connection(delegate<void(void *)> fn, void *ref)
  56277. : disconnect{fn}, signal{ref} {}
  56278. public:
  56279. /*! @brief Default constructor. */
  56280. connection() = default;
  56281. /**
  56282. * @brief Checks whether a connection is properly initialized.
  56283. * @return True if the connection is properly initialized, false otherwise.
  56284. */
  56285. [[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
  56286. return static_cast<bool>(disconnect);
  56287. }
  56288. /*! @brief Breaks the connection. */
  56289. void release() {
  56290. if(disconnect) {
  56291. disconnect(signal);
  56292. disconnect.reset();
  56293. }
  56294. }
  56295. private:
  56296. delegate<void(void *)> disconnect;
  56297. void *signal{};
  56298. };
  56299. /**
  56300. * @brief Scoped connection class.
  56301. *
  56302. * Opaque object the aim of which is to allow users to release an already
  56303. * estabilished connection without having to keep a reference to the signal or
  56304. * the sink that generated it.<br/>
  56305. * A scoped connection automatically breaks the link between the two objects
  56306. * when it goes out of scope.
  56307. */
  56308. struct scoped_connection {
  56309. /*! @brief Default constructor. */
  56310. scoped_connection() = default;
  56311. /**
  56312. * @brief Constructs a scoped connection from a basic connection.
  56313. * @param other A valid connection object.
  56314. */
  56315. scoped_connection(const connection &other)
  56316. : conn{other} {}
  56317. /*! @brief Default copy constructor, deleted on purpose. */
  56318. scoped_connection(const scoped_connection &) = delete;
  56319. /**
  56320. * @brief Move constructor.
  56321. * @param other The scoped connection to move from.
  56322. */
  56323. scoped_connection(scoped_connection &&other) ENTT_NOEXCEPT
  56324. : conn{std::exchange(other.conn, {})} {}
  56325. /*! @brief Automatically breaks the link on destruction. */
  56326. ~scoped_connection() {
  56327. conn.release();
  56328. }
  56329. /**
  56330. * @brief Default copy assignment operator, deleted on purpose.
  56331. * @return This scoped connection.
  56332. */
  56333. scoped_connection &operator=(const scoped_connection &) = delete;
  56334. /**
  56335. * @brief Move assignment operator.
  56336. * @param other The scoped connection to move from.
  56337. * @return This scoped connection.
  56338. */
  56339. scoped_connection &operator=(scoped_connection &&other) ENTT_NOEXCEPT {
  56340. conn = std::exchange(other.conn, {});
  56341. return *this;
  56342. }
  56343. /**
  56344. * @brief Acquires a connection.
  56345. * @param other The connection object to acquire.
  56346. * @return This scoped connection.
  56347. */
  56348. scoped_connection &operator=(connection other) {
  56349. conn = std::move(other);
  56350. return *this;
  56351. }
  56352. /**
  56353. * @brief Checks whether a scoped connection is properly initialized.
  56354. * @return True if the connection is properly initialized, false otherwise.
  56355. */
  56356. [[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
  56357. return static_cast<bool>(conn);
  56358. }
  56359. /*! @brief Breaks the connection. */
  56360. void release() {
  56361. conn.release();
  56362. }
  56363. private:
  56364. connection conn;
  56365. };
  56366. /**
  56367. * @brief Sink class.
  56368. *
  56369. * A sink is used to connect listeners to signals and to disconnect them.<br/>
  56370. * The function type for a listener is the one of the signal to which it
  56371. * belongs.
  56372. *
  56373. * The clear separation between a signal and a sink permits to store the former
  56374. * as private data member without exposing the publish functionality to the
  56375. * users of the class.
  56376. *
  56377. * @warning
  56378. * Lifetime of a sink must not overcome that of the signal to which it refers.
  56379. * In any other case, attempting to use a sink results in undefined behavior.
  56380. *
  56381. * @tparam Ret Return type of a function type.
  56382. * @tparam Args Types of arguments of a function type.
  56383. * @tparam Allocator Type of allocator used to manage memory and elements.
  56384. */
  56385. template<typename Ret, typename... Args, typename Allocator>
  56386. class sink<sigh<Ret(Args...), Allocator>> {
  56387. using signal_type = sigh<Ret(Args...), Allocator>;
  56388. using difference_type = typename signal_type::container_type::difference_type;
  56389. template<auto Candidate, typename Type>
  56390. static void release(Type value_or_instance, void *signal) {
  56391. sink{*static_cast<signal_type *>(signal)}.disconnect<Candidate>(value_or_instance);
  56392. }
  56393. template<auto Candidate>
  56394. static void release(void *signal) {
  56395. sink{*static_cast<signal_type *>(signal)}.disconnect<Candidate>();
  56396. }
  56397. public:
  56398. /**
  56399. * @brief Constructs a sink that is allowed to modify a given signal.
  56400. * @param ref A valid reference to a signal object.
  56401. */
  56402. sink(sigh<Ret(Args...), Allocator> &ref) ENTT_NOEXCEPT
  56403. : offset{},
  56404. signal{&ref} {}
  56405. /**
  56406. * @brief Returns false if at least a listener is connected to the sink.
  56407. * @return True if the sink has no listeners connected, false otherwise.
  56408. */
  56409. [[nodiscard]] bool empty() const ENTT_NOEXCEPT {
  56410. return signal->calls.empty();
  56411. }
  56412. /**
  56413. * @brief Returns a sink that connects before a given free function or an
  56414. * unbound member.
  56415. * @tparam Function A valid free function pointer.
  56416. * @return A properly initialized sink object.
  56417. */
  56418. template<auto Function>
  56419. [[nodiscard]] sink before() {
  56420. delegate<Ret(Args...)> call{};
  56421. call.template connect<Function>();
  56422. const auto &calls = signal->calls;
  56423. const auto it = std::find(calls.cbegin(), calls.cend(), std::move(call));
  56424. sink other{*this};
  56425. other.offset = calls.cend() - it;
  56426. return other;
  56427. }
  56428. /**
  56429. * @brief Returns a sink that connects before a free function with payload
  56430. * or a bound member.
  56431. * @tparam Candidate Member or free function to look for.
  56432. * @tparam Type Type of class or type of payload.
  56433. * @param value_or_instance A valid object that fits the purpose.
  56434. * @return A properly initialized sink object.
  56435. */
  56436. template<auto Candidate, typename Type>
  56437. [[nodiscard]] sink before(Type &&value_or_instance) {
  56438. delegate<Ret(Args...)> call{};
  56439. call.template connect<Candidate>(value_or_instance);
  56440. const auto &calls = signal->calls;
  56441. const auto it = std::find(calls.cbegin(), calls.cend(), std::move(call));
  56442. sink other{*this};
  56443. other.offset = calls.cend() - it;
  56444. return other;
  56445. }
  56446. /**
  56447. * @brief Returns a sink that connects before a given instance or specific
  56448. * payload.
  56449. * @tparam Type Type of class or type of payload.
  56450. * @param value_or_instance A valid object that fits the purpose.
  56451. * @return A properly initialized sink object.
  56452. */
  56453. template<typename Type>
  56454. [[nodiscard]] sink before(Type &value_or_instance) {
  56455. return before(&value_or_instance);
  56456. }
  56457. /**
  56458. * @brief Returns a sink that connects before a given instance or specific
  56459. * payload.
  56460. * @tparam Type Type of class or type of payload.
  56461. * @param value_or_instance A valid pointer that fits the purpose.
  56462. * @return A properly initialized sink object.
  56463. */
  56464. template<typename Type>
  56465. [[nodiscard]] sink before(Type *value_or_instance) {
  56466. sink other{*this};
  56467. if(value_or_instance) {
  56468. const auto &calls = signal->calls;
  56469. const auto it = std::find_if(calls.cbegin(), calls.cend(), [value_or_instance](const auto &delegate) {
  56470. return delegate.data() == value_or_instance;
  56471. });
  56472. other.offset = calls.cend() - it;
  56473. }
  56474. return other;
  56475. }
  56476. /**
  56477. * @brief Returns a sink that connects before anything else.
  56478. * @return A properly initialized sink object.
  56479. */
  56480. [[nodiscard]] sink before() {
  56481. sink other{*this};
  56482. other.offset = signal->calls.size();
  56483. return other;
  56484. }
  56485. /**
  56486. * @brief Connects a free function or an unbound member to a signal.
  56487. *
  56488. * The signal handler performs checks to avoid multiple connections for the
  56489. * same function.
  56490. *
  56491. * @tparam Candidate Function or member to connect to the signal.
  56492. * @return A properly initialized connection object.
  56493. */
  56494. template<auto Candidate>
  56495. connection connect() {
  56496. disconnect<Candidate>();
  56497. delegate<Ret(Args...)> call{};
  56498. call.template connect<Candidate>();
  56499. signal->calls.insert(signal->calls.end() - offset, std::move(call));
  56500. delegate<void(void *)> conn{};
  56501. conn.template connect<&release<Candidate>>();
  56502. return {std::move(conn), signal};
  56503. }
  56504. /**
  56505. * @brief Connects a free function with payload or a bound member to a
  56506. * signal.
  56507. *
  56508. * The signal isn't responsible for the connected object or the payload.
  56509. * Users must always guarantee that the lifetime of the instance overcomes
  56510. * the one of the signal. On the other side, the signal handler performs
  56511. * checks to avoid multiple connections for the same function.<br/>
  56512. * When used to connect a free function with payload, its signature must be
  56513. * such that the instance is the first argument before the ones used to
  56514. * define the signal itself.
  56515. *
  56516. * @tparam Candidate Function or member to connect to the signal.
  56517. * @tparam Type Type of class or type of payload.
  56518. * @param value_or_instance A valid object that fits the purpose.
  56519. * @return A properly initialized connection object.
  56520. */
  56521. template<auto Candidate, typename Type>
  56522. connection connect(Type &&value_or_instance) {
  56523. disconnect<Candidate>(value_or_instance);
  56524. delegate<Ret(Args...)> call{};
  56525. call.template connect<Candidate>(value_or_instance);
  56526. signal->calls.insert(signal->calls.end() - offset, std::move(call));
  56527. delegate<void(void *)> conn{};
  56528. conn.template connect<&release<Candidate, Type>>(value_or_instance);
  56529. return {std::move(conn), signal};
  56530. }
  56531. /**
  56532. * @brief Disconnects a free function or an unbound member from a signal.
  56533. * @tparam Candidate Function or member to disconnect from the signal.
  56534. */
  56535. template<auto Candidate>
  56536. void disconnect() {
  56537. auto &calls = signal->calls;
  56538. delegate<Ret(Args...)> call{};
  56539. call.template connect<Candidate>();
  56540. calls.erase(std::remove(calls.begin(), calls.end(), std::move(call)), calls.end());
  56541. }
  56542. /**
  56543. * @brief Disconnects a free function with payload or a bound member from a
  56544. * signal.
  56545. * @tparam Candidate Function or member to disconnect from the signal.
  56546. * @tparam Type Type of class or type of payload.
  56547. * @param value_or_instance A valid object that fits the purpose.
  56548. */
  56549. template<auto Candidate, typename Type>
  56550. void disconnect(Type &&value_or_instance) {
  56551. auto &calls = signal->calls;
  56552. delegate<Ret(Args...)> call{};
  56553. call.template connect<Candidate>(value_or_instance);
  56554. calls.erase(std::remove(calls.begin(), calls.end(), std::move(call)), calls.end());
  56555. }
  56556. /**
  56557. * @brief Disconnects free functions with payload or bound members from a
  56558. * signal.
  56559. * @tparam Type Type of class or type of payload.
  56560. * @param value_or_instance A valid object that fits the purpose.
  56561. */
  56562. template<typename Type>
  56563. void disconnect(Type &value_or_instance) {
  56564. disconnect(&value_or_instance);
  56565. }
  56566. /**
  56567. * @brief Disconnects free functions with payload or bound members from a
  56568. * signal.
  56569. * @tparam Type Type of class or type of payload.
  56570. * @param value_or_instance A valid object that fits the purpose.
  56571. */
  56572. template<typename Type>
  56573. void disconnect(Type *value_or_instance) {
  56574. if(value_or_instance) {
  56575. auto &calls = signal->calls;
  56576. auto predicate = [value_or_instance](const auto &delegate) { return delegate.data() == value_or_instance; };
  56577. calls.erase(std::remove_if(calls.begin(), calls.end(), std::move(predicate)), calls.end());
  56578. }
  56579. }
  56580. /*! @brief Disconnects all the listeners from a signal. */
  56581. void disconnect() {
  56582. signal->calls.clear();
  56583. }
  56584. private:
  56585. difference_type offset;
  56586. signal_type *signal;
  56587. };
  56588. /**
  56589. * @brief Deduction guide.
  56590. *
  56591. * It allows to deduce the signal handler type of a sink directly from the
  56592. * signal it refers to.
  56593. *
  56594. * @tparam Ret Return type of a function type.
  56595. * @tparam Args Types of arguments of a function type.
  56596. * @tparam Allocator Type of allocator used to manage memory and elements.
  56597. */
  56598. template<typename Ret, typename... Args, typename Allocator>
  56599. sink(sigh<Ret(Args...), Allocator> &) -> sink<sigh<Ret(Args...), Allocator>>;
  56600. } // namespace entt
  56601. #endif