object.d 132 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090
  1. /**
  2. * $(SCRIPT inhibitQuickIndex = 1;)
  3. * $(DIVC quickindex,
  4. * $(BOOKTABLE,
  5. * $(TR $(TH Category) $(TH Symbols))
  6. * $(TR $(TD Arrays) $(TD
  7. * $(MYREF assumeSafeAppend)
  8. * $(MYREF capacity)
  9. * $(MYREF idup)
  10. * $(MYREF reserve)
  11. * ))
  12. * $(TR $(TD Associative arrays) $(TD
  13. * $(MYREF byKey)
  14. * $(MYREF byKeyValue)
  15. * $(MYREF byValue)
  16. * $(MYREF clear)
  17. * $(MYREF get)
  18. * $(MYREF keys)
  19. * $(MYREF rehash)
  20. * $(MYREF require)
  21. * $(MYREF update)
  22. * $(MYREF values)
  23. * ))
  24. * $(TR $(TD General) $(TD
  25. * $(MYREF destroy)
  26. * $(MYREF dup)
  27. * $(MYREF hashOf)
  28. * $(MYREF opEquals)
  29. * ))
  30. * $(TR $(TD Types) $(TD
  31. * $(MYREF Error)
  32. * $(MYREF Exception)
  33. * $(MYREF noreturn)
  34. * $(MYREF Object)
  35. * $(MYREF Throwable)
  36. * ))
  37. * $(TR $(TD Type info) $(TD
  38. * $(MYREF Interface)
  39. * $(MYREF ModuleInfo)
  40. * $(MYREF OffsetTypeInfo)
  41. * $(MYREF RTInfoImpl)
  42. * $(MYREF rtinfoNoPointers)
  43. * $(MYREF TypeInfo)
  44. * $(MYREF TypeInfo_Class)
  45. * ))
  46. * ))
  47. *
  48. * Forms the symbols available to all D programs. Includes Object, which is
  49. * the root of the class object hierarchy. This module is implicitly
  50. * imported.
  51. *
  52. * Copyright: Copyright Digital Mars 2000 - 2011.
  53. * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
  54. * Authors: Walter Bright, Sean Kelly
  55. * Source: $(DRUNTIMESRC object.d)
  56. */
  57. module object;
  58. alias size_t = typeof(int.sizeof);
  59. alias ptrdiff_t = typeof(cast(void*)0 - cast(void*)0);
  60. alias sizediff_t = ptrdiff_t; // For backwards compatibility only.
  61. alias noreturn = typeof(*null); /// bottom type
  62. alias hash_t = size_t; // For backwards compatibility only.
  63. alias equals_t = bool; // For backwards compatibility only.
  64. alias string = immutable(char)[];
  65. alias wstring = immutable(wchar)[];
  66. alias dstring = immutable(dchar)[];
  67. version (D_ObjectiveC)
  68. {
  69. deprecated("explicitly import `selector` instead using: `import core.attribute : selector;`")
  70. public import core.attribute : selector;
  71. }
  72. version (Posix) public import core.attribute : gnuAbiTag;
  73. // Some ABIs use a complex varargs implementation requiring TypeInfo.argTypes().
  74. version (GNU)
  75. {
  76. // No TypeInfo-based core.vararg.va_arg().
  77. }
  78. else version (X86_64)
  79. {
  80. version (DigitalMars) version = WithArgTypes;
  81. else version (Windows) { /* no need for Win64 ABI */ }
  82. else version = WithArgTypes;
  83. }
  84. else version (AArch64)
  85. {
  86. // Apple uses a trivial varargs implementation
  87. version (OSX) {}
  88. else version (iOS) {}
  89. else version (TVOS) {}
  90. else version (WatchOS) {}
  91. else version = WithArgTypes;
  92. }
  93. /**
  94. * All D class objects inherit from Object.
  95. */
  96. class Object
  97. {
  98. /**
  99. * Convert Object to a human readable string.
  100. */
  101. string toString()
  102. {
  103. return typeid(this).name;
  104. }
  105. @system unittest
  106. {
  107. enum unittest_sym_name = __traits(identifier, __traits(parent, (){}));
  108. enum fqn_unittest = "object.Object." ~ unittest_sym_name; // object.__unittest_LX_CY
  109. class C {}
  110. Object obj = new Object;
  111. C c = new C;
  112. assert(obj.toString() == "object.Object");
  113. assert(c.toString() == fqn_unittest ~ ".C");
  114. }
  115. /**
  116. * Compute hash function for Object.
  117. */
  118. size_t toHash() @trusted nothrow
  119. {
  120. // BUG: this prevents a compacting GC from working, needs to be fixed
  121. size_t addr = cast(size_t) cast(void*) this;
  122. // The bottom log2((void*).alignof) bits of the address will always
  123. // be 0. Moreover it is likely that each Object is allocated with a
  124. // separate call to malloc. The alignment of malloc differs from
  125. // platform to platform, but rather than having special cases for
  126. // each platform it is safe to use a shift of 4. To minimize
  127. // collisions in the low bits it is more important for the shift to
  128. // not be too small than for the shift to not be too big.
  129. return addr ^ (addr >>> 4);
  130. }
  131. /**
  132. * Compare with another Object obj.
  133. * Returns:
  134. * $(TABLE
  135. * $(TR $(TD this < obj) $(TD < 0))
  136. * $(TR $(TD this == obj) $(TD 0))
  137. * $(TR $(TD this > obj) $(TD > 0))
  138. * )
  139. */
  140. int opCmp(Object o)
  141. {
  142. // BUG: this prevents a compacting GC from working, needs to be fixed
  143. //return cast(int)cast(void*)this - cast(int)cast(void*)o;
  144. throw new Exception("need opCmp for class " ~ typeid(this).name);
  145. //return this !is o;
  146. }
  147. @system unittest
  148. {
  149. Object obj = new Object;
  150. bool gotCaught;
  151. try
  152. {
  153. obj.opCmp(new Object);
  154. }
  155. catch (Exception e)
  156. {
  157. gotCaught = true;
  158. assert(e.msg == "need opCmp for class object.Object");
  159. }
  160. assert(gotCaught);
  161. }
  162. /**
  163. * Test whether $(D this) is equal to $(D o).
  164. * The default implementation only compares by identity (using the $(D is) operator).
  165. * Generally, overrides and overloads for $(D opEquals) should attempt to compare objects by their contents.
  166. * A class will most likely want to add an overload that takes your specific type as the argument
  167. * and does the content comparison. Then you can override this and forward it to your specific
  168. * typed overload with a cast. Remember to check for `null` on the typed overload.
  169. *
  170. * Examples:
  171. * ---
  172. * class Child {
  173. * int contents;
  174. * // the typed overload first. It can use all the attribute you want
  175. * bool opEquals(const Child c) const @safe pure nothrow @nogc
  176. * {
  177. * if (c is null)
  178. * return false;
  179. * return this.contents == c.contents;
  180. * }
  181. *
  182. * // and now the generic override forwards with a cast
  183. * override bool opEquals(Object o)
  184. * {
  185. * return this.opEquals(cast(Child) o);
  186. * }
  187. * }
  188. * ---
  189. */
  190. bool opEquals(Object o)
  191. {
  192. return this is o;
  193. }
  194. interface Monitor
  195. {
  196. void lock();
  197. void unlock();
  198. }
  199. /**
  200. * Create instance of class specified by the fully qualified name
  201. * classname.
  202. * The class must either have no constructors or have
  203. * a default constructor.
  204. * Returns:
  205. * null if failed
  206. * Example:
  207. * ---
  208. * module foo.bar;
  209. *
  210. * class C
  211. * {
  212. * this() { x = 10; }
  213. * int x;
  214. * }
  215. *
  216. * void main()
  217. * {
  218. * auto c = cast(C)Object.factory("foo.bar.C");
  219. * assert(c !is null && c.x == 10);
  220. * }
  221. * ---
  222. */
  223. static Object factory(string classname)
  224. {
  225. auto ci = TypeInfo_Class.find(classname);
  226. if (ci)
  227. {
  228. return ci.create();
  229. }
  230. return null;
  231. }
  232. @system unittest
  233. {
  234. Object valid_obj = Object.factory("object.Object");
  235. Object invalid_obj = Object.factory("object.__this_class_doesnt_exist__");
  236. assert(valid_obj !is null);
  237. assert(invalid_obj is null);
  238. }
  239. }
  240. /++
  241. Implementation for class opEquals override. Calls the class-defined methods after a null check.
  242. Please note this is not nogc right now, even if your implementation is, because of
  243. the typeinfo name string compare. This is because of dmd's dll implementation. However,
  244. it can infer to @safe if your class' opEquals is.
  245. +/
  246. bool opEquals(LHS, RHS)(LHS lhs, RHS rhs) if (is(LHS : const Object) && is(RHS : const Object))
  247. {
  248. static if (__traits(compiles, lhs.opEquals(rhs)) && __traits(compiles, rhs.opEquals(lhs)))
  249. {
  250. // If aliased to the same object or both null => equal
  251. if (lhs is rhs) return true;
  252. // If either is null => non-equal
  253. if (lhs is null || rhs is null) return false;
  254. if (!lhs.opEquals(rhs)) return false;
  255. // If same exact type => one call to method opEquals
  256. if (typeid(lhs) is typeid(rhs) ||
  257. !__ctfe && typeid(lhs).opEquals(typeid(rhs)))
  258. /* CTFE doesn't like typeid much. 'is' works, but opEquals doesn't
  259. (issue 7147). But CTFE also guarantees that equal TypeInfos are
  260. always identical. So, no opEquals needed during CTFE. */
  261. {
  262. return true;
  263. }
  264. // General case => symmetric calls to method opEquals
  265. return rhs.opEquals(lhs);
  266. }
  267. else
  268. {
  269. // this is a compatibility hack for the old const cast behavior
  270. // if none of the new overloads compile, we'll go back plain Object,
  271. // including casting away const. It does this through the pointer
  272. // to bypass any opCast that may be present on the original class.
  273. return .opEquals!(Object, Object)(*cast(Object*) &lhs, *cast(Object*) &rhs);
  274. }
  275. }
  276. /// If aliased to the same object or both null => equal
  277. @system unittest // this one is not @safe because it goes through the Object base method
  278. {
  279. class F { int flag; this(int flag) { this.flag = flag; } }
  280. F f;
  281. assert(f == f); // both null
  282. f = new F(1);
  283. assert(f == f); // both aliased to the same object
  284. }
  285. /// If either is null => non-equal
  286. @system unittest
  287. {
  288. class F { int flag; this(int flag) { this.flag = flag; } }
  289. F f;
  290. assert(!(new F(0) == f));
  291. assert(!(f == new F(0)));
  292. }
  293. /// If same exact type => one call to method opEquals
  294. /// This test passes `@safe` because it defines a new opEquals with `@safe`
  295. @safe unittest
  296. {
  297. class F
  298. {
  299. int flag;
  300. this(int flag)
  301. {
  302. this.flag = flag;
  303. }
  304. bool opEquals(const F o) const @safe nothrow pure
  305. {
  306. return flag == o.flag;
  307. }
  308. }
  309. F f;
  310. assert(new F(0) == new F(0));
  311. assert(!(new F(0) == new F(1)));
  312. }
  313. /// General case => symmetric calls to method opEquals
  314. @safe unittest
  315. {
  316. int fEquals, gEquals;
  317. class Base
  318. {
  319. int flag;
  320. this(int flag)
  321. {
  322. this.flag = flag;
  323. }
  324. }
  325. class F : Base
  326. {
  327. this(int flag) { super(flag); }
  328. bool opEquals(const Base o) @safe
  329. {
  330. fEquals++;
  331. return flag == o.flag;
  332. }
  333. }
  334. class G : Base
  335. {
  336. this(int flag) { super(flag); }
  337. bool opEquals(const Base o) @safe
  338. {
  339. gEquals++;
  340. return flag == o.flag;
  341. }
  342. }
  343. assert(new F(1) == new G(1));
  344. assert(fEquals == 1);
  345. assert(gEquals == 1);
  346. }
  347. /++
  348. This test shows an example for a comprehensive inheritance equality chain too.
  349. +/
  350. unittest
  351. {
  352. static class Base
  353. {
  354. int member;
  355. this(int member) pure @safe nothrow @nogc
  356. {
  357. this.member = member;
  358. }
  359. override bool opEquals(Object rhs) const
  360. {
  361. return this.opEquals(cast(Base) rhs);
  362. }
  363. bool opEquals(const Base rhs) const @nogc pure nothrow @safe
  364. {
  365. if (rhs is null)
  366. return false;
  367. return this.member == rhs.member;
  368. }
  369. }
  370. // works through the direct class with attributes enabled, except for pure and nogc in the current TypeInfo implementation
  371. bool testThroughBase() nothrow @safe
  372. {
  373. Base b1 = new Base(0);
  374. Base b2 = new Base(0);
  375. assert(b1 == b2);
  376. Base b3 = new Base(1);
  377. assert(b1 != b3);
  378. return true;
  379. }
  380. static assert(testThroughBase());
  381. // also works through the base class interface thanks to the override, but no more attributes
  382. bool testThroughObject()
  383. {
  384. Object o1 = new Base(0);
  385. Object o2 = new Base(0);
  386. assert(o1 == o2);
  387. Object o3 = new Base(1);
  388. assert(o1 != o3);
  389. return true;
  390. }
  391. static assert(testThroughObject());
  392. // Each time you make a child, you want to override all old opEquals
  393. // and add a new overload for the new child.
  394. static class Child : Base
  395. {
  396. int member2;
  397. this(int member, int member2) pure @safe nothrow @nogc
  398. {
  399. super(member);
  400. this.member2 = member2;
  401. }
  402. // override the whole chain so it works consistently though any base
  403. override bool opEquals(Object rhs) const
  404. {
  405. return this.opEquals(cast(Child) rhs);
  406. }
  407. override bool opEquals(const Base rhs) const
  408. {
  409. return this.opEquals(cast(const Child) rhs);
  410. }
  411. // and then add the new overload, if necessary, to handle new members
  412. bool opEquals(const Child rhs) const @nogc pure nothrow @safe
  413. {
  414. if (rhs is null)
  415. return false;
  416. // can call back to the devirtualized base test with implicit conversion
  417. // then compare the new member too. or we could have just compared the base
  418. // member directly here as well.
  419. return Base.opEquals(rhs) && this.member2 == rhs.member2;
  420. }
  421. // a mixin template, of course, could automate this.
  422. }
  423. bool testThroughChild()
  424. {
  425. Child a = new Child(0, 0);
  426. Child b = new Child(0, 1);
  427. assert(a != b);
  428. Base ba = a;
  429. Base bb = b;
  430. assert(ba != bb);
  431. Object oa = a;
  432. Object ob = b;
  433. assert(oa != ob);
  434. return true;
  435. }
  436. static assert(testThroughChild());
  437. }
  438. // To cover const Object opEquals
  439. @system unittest
  440. {
  441. const Object obj1 = new Object;
  442. const Object obj2 = new Object;
  443. assert(obj1 == obj1);
  444. assert(obj1 != obj2);
  445. }
  446. private extern(C) void _d_setSameMutex(shared Object ownee, shared Object owner) nothrow;
  447. void setSameMutex(shared Object ownee, shared Object owner)
  448. {
  449. _d_setSameMutex(ownee, owner);
  450. }
  451. @system unittest
  452. {
  453. shared Object obj1 = new Object;
  454. synchronized class C
  455. {
  456. void bar() {}
  457. }
  458. shared C obj2 = new shared(C);
  459. obj2.bar();
  460. assert(obj1.__monitor != obj2.__monitor);
  461. assert(obj1.__monitor is null);
  462. setSameMutex(obj1, obj2);
  463. assert(obj1.__monitor == obj2.__monitor);
  464. assert(obj1.__monitor !is null);
  465. }
  466. /**
  467. * Information about an interface.
  468. * When an object is accessed via an interface, an Interface* appears as the
  469. * first entry in its vtbl.
  470. */
  471. struct Interface
  472. {
  473. /// Class info returned by `typeid` for this interface (not for containing class)
  474. TypeInfo_Class classinfo;
  475. void*[] vtbl;
  476. size_t offset; /// offset to Interface 'this' from Object 'this'
  477. }
  478. /**
  479. * Array of pairs giving the offset and type information for each
  480. * member in an aggregate.
  481. */
  482. struct OffsetTypeInfo
  483. {
  484. size_t offset; /// Offset of member from start of object
  485. TypeInfo ti; /// TypeInfo for this member
  486. }
  487. /**
  488. * Runtime type information about a type.
  489. * Can be retrieved for any type using a
  490. * $(GLINK2 expression,TypeidExpression, TypeidExpression).
  491. */
  492. class TypeInfo
  493. {
  494. override string toString() const @safe nothrow
  495. {
  496. return typeid(this).name;
  497. }
  498. override size_t toHash() @trusted const nothrow
  499. {
  500. return hashOf(this.toString());
  501. }
  502. override int opCmp(Object rhs)
  503. {
  504. if (this is rhs)
  505. return 0;
  506. auto ti = cast(TypeInfo) rhs;
  507. if (ti is null)
  508. return 1;
  509. return __cmp(this.toString(), ti.toString());
  510. }
  511. @system unittest
  512. {
  513. assert(typeid(void) <= typeid(void));
  514. assert(typeid(void).opCmp(null));
  515. assert(!typeid(void).opCmp(typeid(void)));
  516. }
  517. override bool opEquals(Object o)
  518. {
  519. return opEquals(cast(TypeInfo) o);
  520. }
  521. bool opEquals(const TypeInfo ti) @safe nothrow const
  522. {
  523. /* TypeInfo instances are singletons, but duplicates can exist
  524. * across DLL's. Therefore, comparing for a name match is
  525. * sufficient.
  526. */
  527. if (this is ti)
  528. return true;
  529. return ti && this.toString() == ti.toString();
  530. }
  531. @system unittest
  532. {
  533. auto anotherObj = new Object();
  534. assert(typeid(void).opEquals(typeid(void)));
  535. assert(typeid(void) != anotherObj); // calling .opEquals here directly is a type mismatch
  536. }
  537. /**
  538. * Computes a hash of the instance of a type.
  539. * Params:
  540. * p = pointer to start of instance of the type
  541. * Returns:
  542. * the hash
  543. * Bugs:
  544. * fix https://issues.dlang.org/show_bug.cgi?id=12516 e.g. by changing this to a truly safe interface.
  545. */
  546. size_t getHash(scope const void* p) @trusted nothrow const
  547. {
  548. return hashOf(p);
  549. }
  550. /// Compares two instances for equality.
  551. bool equals(in void* p1, in void* p2) const { return p1 == p2; }
  552. /// Compares two instances for &lt;, ==, or &gt;.
  553. int compare(in void* p1, in void* p2) const { return _xopCmp(p1, p2); }
  554. /// Returns size of the type.
  555. @property size_t tsize() nothrow pure const @safe @nogc { return 0; }
  556. /// Swaps two instances of the type.
  557. void swap(void* p1, void* p2) const
  558. {
  559. size_t remaining = tsize;
  560. // If the type might contain pointers perform the swap in pointer-sized
  561. // chunks in case a garbage collection pass interrupts this function.
  562. if ((cast(size_t) p1 | cast(size_t) p2) % (void*).alignof == 0)
  563. {
  564. while (remaining >= (void*).sizeof)
  565. {
  566. void* tmp = *cast(void**) p1;
  567. *cast(void**) p1 = *cast(void**) p2;
  568. *cast(void**) p2 = tmp;
  569. p1 += (void*).sizeof;
  570. p2 += (void*).sizeof;
  571. remaining -= (void*).sizeof;
  572. }
  573. }
  574. for (size_t i = 0; i < remaining; i++)
  575. {
  576. byte t = (cast(byte *)p1)[i];
  577. (cast(byte*)p1)[i] = (cast(byte*)p2)[i];
  578. (cast(byte*)p2)[i] = t;
  579. }
  580. }
  581. @system unittest
  582. {
  583. class _TypeInfo_Dummy : TypeInfo
  584. {
  585. override const(void)[] initializer() const { return []; }
  586. @property override size_t tsize() nothrow pure const @safe @nogc { return tsize_val; }
  587. size_t tsize_val;
  588. }
  589. auto dummy = new _TypeInfo_Dummy();
  590. cast(void)dummy.initializer(); // For coverage completeness
  591. int a = 2, b = -2;
  592. dummy.swap(&a, &b);
  593. // does nothing because tsize is 0
  594. assert(a == 2);
  595. assert(b == -2);
  596. dummy.tsize_val = int.sizeof;
  597. dummy.swap(&a, &b);
  598. assert(a == -2);
  599. assert(b == 2);
  600. void* ptr_a = null, ptr_b = cast(void*)1;
  601. dummy.tsize_val = (void*).sizeof;
  602. dummy.swap(&ptr_a, &ptr_b);
  603. assert(ptr_a is cast(void*)1);
  604. assert(ptr_b is null);
  605. }
  606. /** Get TypeInfo for 'next' type, as defined by what kind of type this is,
  607. null if none. */
  608. @property inout(TypeInfo) next() nothrow pure inout @nogc { return null; }
  609. /**
  610. * Return default initializer. If the type should be initialized to all
  611. * zeros, an array with a null ptr and a length equal to the type size will
  612. * be returned. For static arrays, this returns the default initializer for
  613. * a single element of the array, use `tsize` to get the correct size.
  614. */
  615. abstract const(void)[] initializer() nothrow pure const @safe @nogc;
  616. /** Get flags for type: 1 means GC should scan for pointers,
  617. 2 means arg of this type is passed in SIMD register(s) if available */
  618. @property uint flags() nothrow pure const @safe @nogc { return 0; }
  619. /// Get type information on the contents of the type; null if not available
  620. const(OffsetTypeInfo)[] offTi() const { return null; }
  621. /// Run the destructor on the object and all its sub-objects
  622. void destroy(void* p) const {}
  623. /// Run the postblit on the object and all its sub-objects
  624. void postblit(void* p) const {}
  625. /// Return alignment of type
  626. @property size_t talign() nothrow pure const @safe @nogc { return tsize; }
  627. /** Return internal info on arguments fitting into 8byte.
  628. * See X86-64 ABI 3.2.3
  629. */
  630. version (WithArgTypes) int argTypes(out TypeInfo arg1, out TypeInfo arg2) @safe nothrow
  631. {
  632. arg1 = this;
  633. return 0;
  634. }
  635. /** Return info used by the garbage collector to do precise collection.
  636. */
  637. @property immutable(void)* rtInfo() nothrow pure const @safe @nogc { return rtinfoHasPointers; } // better safe than sorry
  638. }
  639. @system unittest
  640. {
  641. class _TypeInfo_Dummy : TypeInfo
  642. {
  643. override const(void)[] initializer() const { return []; }
  644. }
  645. auto dummy = new _TypeInfo_Dummy();
  646. cast(void)dummy.initializer(); // For coverage completeness
  647. assert(dummy.rtInfo() is rtinfoHasPointers);
  648. assert(typeid(void).rtInfo() is rtinfoNoPointers);
  649. assert(dummy.tsize() == 0);
  650. bool gotCaught;
  651. try
  652. {
  653. dummy.compare(null, null);
  654. } catch (Error e)
  655. {
  656. gotCaught = true;
  657. assert(e.msg == "TypeInfo.compare is not implemented");
  658. }
  659. assert(gotCaught);
  660. assert(dummy.equals(null, null));
  661. assert(!dummy.equals(cast(void*)1, null));
  662. }
  663. @system unittest
  664. {
  665. assert(typeid(void).next() is null);
  666. assert(typeid(void).offTi() is null);
  667. assert(typeid(void).tsize() == 1);
  668. version (WithArgTypes)
  669. {
  670. TypeInfo ti1;
  671. TypeInfo ti2;
  672. assert(typeid(void).argTypes(ti1, ti2) == 0);
  673. assert(typeid(void) is ti1);
  674. assert(ti1 !is null);
  675. assert(ti2 is null);
  676. }
  677. }
  678. @system unittest
  679. {
  680. class _ZypeInfo_Dummy : TypeInfo
  681. {
  682. override const(void)[] initializer() const { return []; }
  683. }
  684. auto dummy2 = new _ZypeInfo_Dummy();
  685. cast(void)dummy2.initializer(); // For coverage completeness
  686. assert(typeid(void) > dummy2);
  687. assert(dummy2 < typeid(void));
  688. }
  689. @safe unittest
  690. {
  691. enum unittest_sym_name = __traits(identifier, __traits(parent, (){}));
  692. enum fqn_unittest = "object." ~ unittest_sym_name; // object.__unittest_LX_CY
  693. class _TypeInfo_Dummy : TypeInfo
  694. {
  695. override const(void)[] initializer() const { return []; }
  696. }
  697. auto dummy = new _TypeInfo_Dummy();
  698. cast(void)dummy.initializer(); // For coverage completeness
  699. assert(dummy.toString() == fqn_unittest ~ "._TypeInfo_Dummy");
  700. assert(dummy.toHash() == hashOf(dummy.toString()));
  701. assert(dummy.getHash(null) == 0);
  702. }
  703. class TypeInfo_Enum : TypeInfo
  704. {
  705. override string toString() const pure { return name; }
  706. override bool opEquals(Object o)
  707. {
  708. if (this is o)
  709. return true;
  710. auto c = cast(const TypeInfo_Enum)o;
  711. return c && this.name == c.name &&
  712. this.base == c.base;
  713. }
  714. @system unittest
  715. {
  716. enum E { A, B, C }
  717. enum EE { A, B, C }
  718. assert(typeid(E).opEquals(typeid(E)));
  719. assert(!typeid(E).opEquals(typeid(EE)));
  720. }
  721. override size_t getHash(scope const void* p) const { return base.getHash(p); }
  722. @system unittest
  723. {
  724. enum E { A, B, C }
  725. E e1 = E.A;
  726. E e2 = E.B;
  727. assert(typeid(E).getHash(&e1) == hashOf(E.A));
  728. assert(typeid(E).getHash(&e2) == hashOf(E.B));
  729. enum ES : string { A = "foo", B = "bar" }
  730. ES es1 = ES.A;
  731. ES es2 = ES.B;
  732. assert(typeid(ES).getHash(&es1) == hashOf("foo"));
  733. assert(typeid(ES).getHash(&es2) == hashOf("bar"));
  734. }
  735. override bool equals(in void* p1, in void* p2) const { return base.equals(p1, p2); }
  736. @system unittest
  737. {
  738. enum E { A, B, C }
  739. E e1 = E.A;
  740. E e2 = E.B;
  741. assert(typeid(E).equals(&e1, &e1));
  742. assert(!typeid(E).equals(&e1, &e2));
  743. }
  744. override int compare(in void* p1, in void* p2) const { return base.compare(p1, p2); }
  745. @system unittest
  746. {
  747. enum E { A, B, C }
  748. E e1 = E.A;
  749. E e2 = E.B;
  750. assert(typeid(E).compare(&e1, &e1) == 0);
  751. assert(typeid(E).compare(&e1, &e2) < 0);
  752. assert(typeid(E).compare(&e2, &e1) > 0);
  753. }
  754. override @property size_t tsize() nothrow pure const { return base.tsize; }
  755. @safe unittest
  756. {
  757. enum E { A, B, C }
  758. enum ES : string { A = "a", B = "b", C = "c"}
  759. assert(typeid(E).tsize == E.sizeof);
  760. assert(typeid(ES).tsize == ES.sizeof);
  761. assert(typeid(E).tsize != ES.sizeof);
  762. }
  763. override void swap(void* p1, void* p2) const { return base.swap(p1, p2); }
  764. @system unittest
  765. {
  766. enum E { A, B, C }
  767. E e1 = E.A;
  768. E e2 = E.B;
  769. typeid(E).swap(&e1, &e2);
  770. assert(e1 == E.B);
  771. assert(e2 == E.A);
  772. }
  773. override @property inout(TypeInfo) next() nothrow pure inout { return base.next; }
  774. @system unittest
  775. {
  776. enum E { A, B, C }
  777. assert(typeid(E).next is null);
  778. }
  779. override @property uint flags() nothrow pure const { return base.flags; }
  780. @safe unittest
  781. {
  782. enum E { A, B, C }
  783. assert(typeid(E).flags == 0);
  784. }
  785. override const(OffsetTypeInfo)[] offTi() const { return base.offTi; }
  786. @system unittest
  787. {
  788. enum E { A, B, C }
  789. assert(typeid(E).offTi is null);
  790. }
  791. override void destroy(void* p) const { return base.destroy(p); }
  792. override void postblit(void* p) const { return base.postblit(p); }
  793. override const(void)[] initializer() const
  794. {
  795. return m_init.length ? m_init : base.initializer();
  796. }
  797. override @property size_t talign() nothrow pure const { return base.talign; }
  798. version (WithArgTypes) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
  799. {
  800. return base.argTypes(arg1, arg2);
  801. }
  802. override @property immutable(void)* rtInfo() const { return base.rtInfo; }
  803. TypeInfo base;
  804. string name;
  805. void[] m_init;
  806. }
  807. @safe unittest
  808. {
  809. enum unittest_sym_name = __traits(identifier, __traits(parent, (){}));
  810. enum fqn_unittest = "object." ~ unittest_sym_name; // object.__unittest_LX_CY
  811. enum E { A, B, C }
  812. enum EE { A, B, C }
  813. assert(typeid(E).toString() == fqn_unittest ~ ".E");
  814. }
  815. @safe unittest // issue 12233
  816. {
  817. static assert(is(typeof(TypeInfo.init) == TypeInfo));
  818. assert(TypeInfo.init is null);
  819. }
  820. // Please make sure to keep this in sync with TypeInfo_P (src/rt/typeinfo/ti_ptr.d)
  821. class TypeInfo_Pointer : TypeInfo
  822. {
  823. override string toString() const { return m_next.toString() ~ "*"; }
  824. override bool opEquals(Object o)
  825. {
  826. if (this is o)
  827. return true;
  828. auto c = cast(const TypeInfo_Pointer)o;
  829. return c && this.m_next == c.m_next;
  830. }
  831. override size_t getHash(scope const void* p) @trusted const
  832. {
  833. size_t addr = cast(size_t) *cast(const void**)p;
  834. return addr ^ (addr >> 4);
  835. }
  836. override bool equals(in void* p1, in void* p2) const
  837. {
  838. return *cast(void**)p1 == *cast(void**)p2;
  839. }
  840. override int compare(in void* p1, in void* p2) const
  841. {
  842. const v1 = *cast(void**) p1, v2 = *cast(void**) p2;
  843. return (v1 > v2) - (v1 < v2);
  844. }
  845. override @property size_t tsize() nothrow pure const
  846. {
  847. return (void*).sizeof;
  848. }
  849. override const(void)[] initializer() const @trusted
  850. {
  851. return (cast(void *)null)[0 .. (void*).sizeof];
  852. }
  853. override void swap(void* p1, void* p2) const
  854. {
  855. void* tmp = *cast(void**)p1;
  856. *cast(void**)p1 = *cast(void**)p2;
  857. *cast(void**)p2 = tmp;
  858. }
  859. override @property inout(TypeInfo) next() nothrow pure inout { return m_next; }
  860. override @property uint flags() nothrow pure const { return 1; }
  861. TypeInfo m_next;
  862. }
  863. class TypeInfo_Array : TypeInfo
  864. {
  865. override string toString() const { return value.toString() ~ "[]"; }
  866. override bool opEquals(Object o)
  867. {
  868. if (this is o)
  869. return true;
  870. auto c = cast(const TypeInfo_Array)o;
  871. return c && this.value == c.value;
  872. }
  873. override size_t getHash(scope const void* p) @trusted const
  874. {
  875. void[] a = *cast(void[]*)p;
  876. return getArrayHash(value, a.ptr, a.length);
  877. }
  878. override bool equals(in void* p1, in void* p2) const
  879. {
  880. void[] a1 = *cast(void[]*)p1;
  881. void[] a2 = *cast(void[]*)p2;
  882. if (a1.length != a2.length)
  883. return false;
  884. size_t sz = value.tsize;
  885. for (size_t i = 0; i < a1.length; i++)
  886. {
  887. if (!value.equals(a1.ptr + i * sz, a2.ptr + i * sz))
  888. return false;
  889. }
  890. return true;
  891. }
  892. override int compare(in void* p1, in void* p2) const
  893. {
  894. void[] a1 = *cast(void[]*)p1;
  895. void[] a2 = *cast(void[]*)p2;
  896. size_t sz = value.tsize;
  897. size_t len = a1.length;
  898. if (a2.length < len)
  899. len = a2.length;
  900. for (size_t u = 0; u < len; u++)
  901. {
  902. immutable int result = value.compare(a1.ptr + u * sz, a2.ptr + u * sz);
  903. if (result)
  904. return result;
  905. }
  906. return (a1.length > a2.length) - (a1.length < a2.length);
  907. }
  908. override @property size_t tsize() nothrow pure const
  909. {
  910. return (void[]).sizeof;
  911. }
  912. override const(void)[] initializer() const @trusted
  913. {
  914. return (cast(void *)null)[0 .. (void[]).sizeof];
  915. }
  916. override void swap(void* p1, void* p2) const
  917. {
  918. void[] tmp = *cast(void[]*)p1;
  919. *cast(void[]*)p1 = *cast(void[]*)p2;
  920. *cast(void[]*)p2 = tmp;
  921. }
  922. TypeInfo value;
  923. override @property inout(TypeInfo) next() nothrow pure inout
  924. {
  925. return value;
  926. }
  927. override @property uint flags() nothrow pure const { return 1; }
  928. override @property size_t talign() nothrow pure const
  929. {
  930. return (void[]).alignof;
  931. }
  932. version (WithArgTypes) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
  933. {
  934. arg1 = typeid(size_t);
  935. arg2 = typeid(void*);
  936. return 0;
  937. }
  938. override @property immutable(void)* rtInfo() nothrow pure const @safe { return RTInfo!(void[]); }
  939. }
  940. class TypeInfo_StaticArray : TypeInfo
  941. {
  942. override string toString() const
  943. {
  944. import core.internal.string : unsignedToTempString;
  945. char[20] tmpBuff = void;
  946. const lenString = unsignedToTempString(len, tmpBuff);
  947. return (() @trusted => cast(string) (value.toString() ~ "[" ~ lenString ~ "]"))();
  948. }
  949. override bool opEquals(Object o)
  950. {
  951. if (this is o)
  952. return true;
  953. auto c = cast(const TypeInfo_StaticArray)o;
  954. return c && this.len == c.len &&
  955. this.value == c.value;
  956. }
  957. override size_t getHash(scope const void* p) @trusted const
  958. {
  959. return getArrayHash(value, p, len);
  960. }
  961. override bool equals(in void* p1, in void* p2) const
  962. {
  963. size_t sz = value.tsize;
  964. for (size_t u = 0; u < len; u++)
  965. {
  966. if (!value.equals(p1 + u * sz, p2 + u * sz))
  967. return false;
  968. }
  969. return true;
  970. }
  971. override int compare(in void* p1, in void* p2) const
  972. {
  973. size_t sz = value.tsize;
  974. for (size_t u = 0; u < len; u++)
  975. {
  976. immutable int result = value.compare(p1 + u * sz, p2 + u * sz);
  977. if (result)
  978. return result;
  979. }
  980. return 0;
  981. }
  982. override @property size_t tsize() nothrow pure const
  983. {
  984. return len * value.tsize;
  985. }
  986. override void swap(void* p1, void* p2) const
  987. {
  988. import core.stdc.string : memcpy;
  989. size_t remaining = value.tsize * len;
  990. void[size_t.sizeof * 4] buffer = void;
  991. while (remaining > buffer.length)
  992. {
  993. memcpy(buffer.ptr, p1, buffer.length);
  994. memcpy(p1, p2, buffer.length);
  995. memcpy(p2, buffer.ptr, buffer.length);
  996. p1 += buffer.length;
  997. p2 += buffer.length;
  998. remaining -= buffer.length;
  999. }
  1000. memcpy(buffer.ptr, p1, remaining);
  1001. memcpy(p1, p2, remaining);
  1002. memcpy(p2, buffer.ptr, remaining);
  1003. }
  1004. override const(void)[] initializer() nothrow pure const
  1005. {
  1006. return value.initializer();
  1007. }
  1008. override @property inout(TypeInfo) next() nothrow pure inout { return value; }
  1009. override @property uint flags() nothrow pure const { return value.flags; }
  1010. override void destroy(void* p) const
  1011. {
  1012. immutable sz = value.tsize;
  1013. p += sz * len;
  1014. foreach (i; 0 .. len)
  1015. {
  1016. p -= sz;
  1017. value.destroy(p);
  1018. }
  1019. }
  1020. override void postblit(void* p) const
  1021. {
  1022. immutable sz = value.tsize;
  1023. foreach (i; 0 .. len)
  1024. {
  1025. value.postblit(p);
  1026. p += sz;
  1027. }
  1028. }
  1029. TypeInfo value;
  1030. size_t len;
  1031. override @property size_t talign() nothrow pure const
  1032. {
  1033. return value.talign;
  1034. }
  1035. version (WithArgTypes) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
  1036. {
  1037. arg1 = typeid(void*);
  1038. return 0;
  1039. }
  1040. // just return the rtInfo of the element, we have no generic type T to run RTInfo!T on
  1041. override @property immutable(void)* rtInfo() nothrow pure const @safe { return value.rtInfo(); }
  1042. }
  1043. // https://issues.dlang.org/show_bug.cgi?id=21315
  1044. @system unittest
  1045. {
  1046. int[16] a, b;
  1047. foreach (int i; 0 .. 16)
  1048. {
  1049. a[i] = i;
  1050. b[i] = ~i;
  1051. }
  1052. typeid(int[16]).swap(&a, &b);
  1053. foreach (int i; 0 .. 16)
  1054. {
  1055. assert(a[i] == ~i);
  1056. assert(b[i] == i);
  1057. }
  1058. }
  1059. class TypeInfo_AssociativeArray : TypeInfo
  1060. {
  1061. override string toString() const
  1062. {
  1063. return value.toString() ~ "[" ~ key.toString() ~ "]";
  1064. }
  1065. override bool opEquals(Object o)
  1066. {
  1067. if (this is o)
  1068. return true;
  1069. auto c = cast(const TypeInfo_AssociativeArray)o;
  1070. return c && this.key == c.key &&
  1071. this.value == c.value;
  1072. }
  1073. override bool equals(in void* p1, in void* p2) @trusted const
  1074. {
  1075. return !!_aaEqual(this, *cast(const AA*) p1, *cast(const AA*) p2);
  1076. }
  1077. override hash_t getHash(scope const void* p) nothrow @trusted const
  1078. {
  1079. return _aaGetHash(cast(AA*)p, this);
  1080. }
  1081. // BUG: need to add the rest of the functions
  1082. override @property size_t tsize() nothrow pure const
  1083. {
  1084. return (char[int]).sizeof;
  1085. }
  1086. override const(void)[] initializer() const @trusted
  1087. {
  1088. return (cast(void *)null)[0 .. (char[int]).sizeof];
  1089. }
  1090. override @property inout(TypeInfo) next() nothrow pure inout { return value; }
  1091. override @property uint flags() nothrow pure const { return 1; }
  1092. TypeInfo value;
  1093. TypeInfo key;
  1094. override @property size_t talign() nothrow pure const
  1095. {
  1096. return (char[int]).alignof;
  1097. }
  1098. version (WithArgTypes) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
  1099. {
  1100. arg1 = typeid(void*);
  1101. return 0;
  1102. }
  1103. }
  1104. class TypeInfo_Vector : TypeInfo
  1105. {
  1106. override string toString() const { return "__vector(" ~ base.toString() ~ ")"; }
  1107. override bool opEquals(Object o)
  1108. {
  1109. if (this is o)
  1110. return true;
  1111. auto c = cast(const TypeInfo_Vector)o;
  1112. return c && this.base == c.base;
  1113. }
  1114. override size_t getHash(scope const void* p) const { return base.getHash(p); }
  1115. override bool equals(in void* p1, in void* p2) const { return base.equals(p1, p2); }
  1116. override int compare(in void* p1, in void* p2) const { return base.compare(p1, p2); }
  1117. override @property size_t tsize() nothrow pure const { return base.tsize; }
  1118. override void swap(void* p1, void* p2) const { return base.swap(p1, p2); }
  1119. override @property inout(TypeInfo) next() nothrow pure inout { return base.next; }
  1120. override @property uint flags() nothrow pure const { return 2; /* passed in SIMD register */ }
  1121. override const(void)[] initializer() nothrow pure const
  1122. {
  1123. return base.initializer();
  1124. }
  1125. override @property size_t talign() nothrow pure const { return 16; }
  1126. version (WithArgTypes) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
  1127. {
  1128. return base.argTypes(arg1, arg2);
  1129. }
  1130. TypeInfo base;
  1131. }
  1132. class TypeInfo_Function : TypeInfo
  1133. {
  1134. override string toString() const pure @trusted
  1135. {
  1136. import core.demangle : demangleType;
  1137. alias SafeDemangleFunctionType = char[] function (const(char)[] buf, char[] dst = null) @safe nothrow pure;
  1138. SafeDemangleFunctionType demangle = cast(SafeDemangleFunctionType) &demangleType;
  1139. return cast(string) demangle(deco);
  1140. }
  1141. override bool opEquals(Object o)
  1142. {
  1143. if (this is o)
  1144. return true;
  1145. auto c = cast(const TypeInfo_Function)o;
  1146. return c && this.deco == c.deco;
  1147. }
  1148. // BUG: need to add the rest of the functions
  1149. override @property size_t tsize() nothrow pure const
  1150. {
  1151. return 0; // no size for functions
  1152. }
  1153. override const(void)[] initializer() const @safe
  1154. {
  1155. return null;
  1156. }
  1157. override @property immutable(void)* rtInfo() nothrow pure const @safe { return rtinfoNoPointers; }
  1158. TypeInfo next;
  1159. /**
  1160. * Mangled function type string
  1161. */
  1162. string deco;
  1163. }
  1164. @safe unittest
  1165. {
  1166. abstract class C
  1167. {
  1168. void func();
  1169. void func(int a);
  1170. int func(int a, int b);
  1171. }
  1172. alias functionTypes = typeof(__traits(getVirtualFunctions, C, "func"));
  1173. assert(typeid(functionTypes[0]).toString() == "void function()");
  1174. assert(typeid(functionTypes[1]).toString() == "void function(int)");
  1175. assert(typeid(functionTypes[2]).toString() == "int function(int, int)");
  1176. }
  1177. @system unittest
  1178. {
  1179. abstract class C
  1180. {
  1181. void func();
  1182. void func(int a);
  1183. }
  1184. alias functionTypes = typeof(__traits(getVirtualFunctions, C, "func"));
  1185. Object obj = typeid(functionTypes[0]);
  1186. assert(obj.opEquals(typeid(functionTypes[0])));
  1187. assert(typeid(functionTypes[0]) == typeid(functionTypes[0]));
  1188. assert(typeid(functionTypes[0]) != typeid(functionTypes[1]));
  1189. assert(typeid(functionTypes[0]).tsize() == 0);
  1190. assert(typeid(functionTypes[0]).initializer() is null);
  1191. assert(typeid(functionTypes[0]).rtInfo() is null);
  1192. }
  1193. class TypeInfo_Delegate : TypeInfo
  1194. {
  1195. override string toString() const pure @trusted
  1196. {
  1197. import core.demangle : demangleType;
  1198. alias SafeDemangleFunctionType = char[] function (const(char)[] buf, char[] dst = null) @safe nothrow pure;
  1199. SafeDemangleFunctionType demangle = cast(SafeDemangleFunctionType) &demangleType;
  1200. return cast(string) demangle(deco);
  1201. }
  1202. @safe unittest
  1203. {
  1204. double sqr(double x) { return x * x; }
  1205. sqr(double.init); // for coverage completeness
  1206. auto delegate_str = "double delegate(double) pure nothrow @nogc @safe";
  1207. assert(typeid(typeof(&sqr)).toString() == delegate_str);
  1208. assert(delegate_str.hashOf() == typeid(typeof(&sqr)).hashOf());
  1209. assert(typeid(typeof(&sqr)).toHash() == typeid(typeof(&sqr)).hashOf());
  1210. int g;
  1211. alias delegate_type = typeof((int a, int b) => a + b + g);
  1212. delegate_str = "int delegate(int, int) pure nothrow @nogc @safe";
  1213. assert(typeid(delegate_type).toString() == delegate_str);
  1214. assert(delegate_str.hashOf() == typeid(delegate_type).hashOf());
  1215. assert(typeid(delegate_type).toHash() == typeid(delegate_type).hashOf());
  1216. }
  1217. override bool opEquals(Object o)
  1218. {
  1219. if (this is o)
  1220. return true;
  1221. auto c = cast(const TypeInfo_Delegate)o;
  1222. return c && this.deco == c.deco;
  1223. }
  1224. @system unittest
  1225. {
  1226. double sqr(double x) { return x * x; }
  1227. int dbl(int x) { return x + x; }
  1228. sqr(double.init); // for coverage completeness
  1229. dbl(int.init); // for coverage completeness
  1230. Object obj = typeid(typeof(&sqr));
  1231. assert(obj.opEquals(typeid(typeof(&sqr))));
  1232. assert(typeid(typeof(&sqr)) == typeid(typeof(&sqr)));
  1233. assert(typeid(typeof(&dbl)) != typeid(typeof(&sqr)));
  1234. }
  1235. override size_t getHash(scope const void* p) @trusted const
  1236. {
  1237. return hashOf(*cast(void delegate()*)p);
  1238. }
  1239. override bool equals(in void* p1, in void* p2) const
  1240. {
  1241. auto dg1 = *cast(void delegate()*)p1;
  1242. auto dg2 = *cast(void delegate()*)p2;
  1243. return dg1 == dg2;
  1244. }
  1245. override int compare(in void* p1, in void* p2) const
  1246. {
  1247. auto dg1 = *cast(void delegate()*)p1;
  1248. auto dg2 = *cast(void delegate()*)p2;
  1249. if (dg1 < dg2)
  1250. return -1;
  1251. else if (dg1 > dg2)
  1252. return 1;
  1253. else
  1254. return 0;
  1255. }
  1256. override @property size_t tsize() nothrow pure const
  1257. {
  1258. alias dg = int delegate();
  1259. return dg.sizeof;
  1260. }
  1261. override const(void)[] initializer() const @trusted
  1262. {
  1263. return (cast(void *)null)[0 .. (int delegate()).sizeof];
  1264. }
  1265. override @property uint flags() nothrow pure const { return 1; }
  1266. TypeInfo next;
  1267. string deco;
  1268. override @property size_t talign() nothrow pure const
  1269. {
  1270. alias dg = int delegate();
  1271. return dg.alignof;
  1272. }
  1273. version (WithArgTypes) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
  1274. {
  1275. arg1 = typeid(void*);
  1276. arg2 = typeid(void*);
  1277. return 0;
  1278. }
  1279. override @property immutable(void)* rtInfo() nothrow pure const @safe { return RTInfo!(int delegate()); }
  1280. }
  1281. private extern (C) Object _d_newclass(const TypeInfo_Class ci);
  1282. private extern (C) int _d_isbaseof(scope TypeInfo_Class child,
  1283. scope const TypeInfo_Class parent) @nogc nothrow pure @safe; // rt.cast_
  1284. /**
  1285. * Runtime type information about a class.
  1286. * Can be retrieved from an object instance by using the
  1287. * $(DDSUBLINK spec/expression,typeid_expressions,typeid expression).
  1288. */
  1289. class TypeInfo_Class : TypeInfo
  1290. {
  1291. override string toString() const pure { return name; }
  1292. override bool opEquals(const TypeInfo o) const
  1293. {
  1294. if (this is o)
  1295. return true;
  1296. auto c = cast(const TypeInfo_Class)o;
  1297. return c && this.name == c.name;
  1298. }
  1299. override size_t getHash(scope const void* p) @trusted const
  1300. {
  1301. auto o = *cast(Object*)p;
  1302. return o ? o.toHash() : 0;
  1303. }
  1304. override bool equals(in void* p1, in void* p2) const
  1305. {
  1306. Object o1 = *cast(Object*)p1;
  1307. Object o2 = *cast(Object*)p2;
  1308. return (o1 is o2) || (o1 && o1.opEquals(o2));
  1309. }
  1310. override int compare(in void* p1, in void* p2) const
  1311. {
  1312. Object o1 = *cast(Object*)p1;
  1313. Object o2 = *cast(Object*)p2;
  1314. int c = 0;
  1315. // Regard null references as always being "less than"
  1316. if (o1 !is o2)
  1317. {
  1318. if (o1)
  1319. {
  1320. if (!o2)
  1321. c = 1;
  1322. else
  1323. c = o1.opCmp(o2);
  1324. }
  1325. else
  1326. c = -1;
  1327. }
  1328. return c;
  1329. }
  1330. override @property size_t tsize() nothrow pure const
  1331. {
  1332. return Object.sizeof;
  1333. }
  1334. override const(void)[] initializer() nothrow pure const @safe
  1335. {
  1336. return m_init;
  1337. }
  1338. override @property uint flags() nothrow pure const { return 1; }
  1339. override @property const(OffsetTypeInfo)[] offTi() nothrow pure const
  1340. {
  1341. return m_offTi;
  1342. }
  1343. final @property auto info() @safe @nogc nothrow pure const return { return this; }
  1344. final @property auto typeinfo() @safe @nogc nothrow pure const return { return this; }
  1345. byte[] m_init; /** class static initializer
  1346. * (init.length gives size in bytes of class)
  1347. */
  1348. string name; /// class name
  1349. void*[] vtbl; /// virtual function pointer table
  1350. Interface[] interfaces; /// interfaces this class implements
  1351. TypeInfo_Class base; /// base class
  1352. void* destructor;
  1353. void function(Object) classInvariant;
  1354. enum ClassFlags : uint
  1355. {
  1356. isCOMclass = 0x1,
  1357. noPointers = 0x2,
  1358. hasOffTi = 0x4,
  1359. hasCtor = 0x8,
  1360. hasGetMembers = 0x10,
  1361. hasTypeInfo = 0x20,
  1362. isAbstract = 0x40,
  1363. isCPPclass = 0x80,
  1364. hasDtor = 0x100,
  1365. }
  1366. ClassFlags m_flags;
  1367. void* deallocator;
  1368. OffsetTypeInfo[] m_offTi;
  1369. void function(Object) defaultConstructor; // default Constructor
  1370. immutable(void)* m_RTInfo; // data for precise GC
  1371. override @property immutable(void)* rtInfo() const { return m_RTInfo; }
  1372. /**
  1373. * Search all modules for TypeInfo_Class corresponding to classname.
  1374. * Returns: null if not found
  1375. */
  1376. static const(TypeInfo_Class) find(const scope char[] classname)
  1377. {
  1378. foreach (m; ModuleInfo)
  1379. {
  1380. if (m)
  1381. {
  1382. //writefln("module %s, %d", m.name, m.localClasses.length);
  1383. foreach (c; m.localClasses)
  1384. {
  1385. if (c is null)
  1386. continue;
  1387. //writefln("\tclass %s", c.name);
  1388. if (c.name == classname)
  1389. return c;
  1390. }
  1391. }
  1392. }
  1393. return null;
  1394. }
  1395. /**
  1396. * Create instance of Object represented by 'this'.
  1397. */
  1398. Object create() const
  1399. {
  1400. if (m_flags & 8 && !defaultConstructor)
  1401. return null;
  1402. if (m_flags & 64) // abstract
  1403. return null;
  1404. Object o = _d_newclass(this);
  1405. if (m_flags & 8 && defaultConstructor)
  1406. {
  1407. defaultConstructor(o);
  1408. }
  1409. return o;
  1410. }
  1411. /**
  1412. * Returns true if the class described by `child` derives from or is
  1413. * the class described by this `TypeInfo_Class`. Always returns false
  1414. * if the argument is null.
  1415. *
  1416. * Params:
  1417. * child = TypeInfo for some class
  1418. * Returns:
  1419. * true if the class described by `child` derives from or is the
  1420. * class described by this `TypeInfo_Class`.
  1421. */
  1422. final bool isBaseOf(scope const TypeInfo_Class child) const @nogc nothrow pure @trusted
  1423. {
  1424. if (m_init.length)
  1425. {
  1426. // If this TypeInfo_Class represents an actual class we only need
  1427. // to check the child and its direct ancestors.
  1428. for (auto ti = cast() child; ti !is null; ti = ti.base)
  1429. if (ti is this)
  1430. return true;
  1431. return false;
  1432. }
  1433. else
  1434. {
  1435. // If this TypeInfo_Class is the .info field of a TypeInfo_Interface
  1436. // we also need to recursively check the child's interfaces.
  1437. return child !is null && _d_isbaseof(cast() child, this);
  1438. }
  1439. }
  1440. }
  1441. alias ClassInfo = TypeInfo_Class;
  1442. @safe unittest
  1443. {
  1444. // Bugzilla 14401
  1445. static class X
  1446. {
  1447. int a;
  1448. }
  1449. assert(typeid(X).initializer is typeid(X).m_init);
  1450. assert(typeid(X).initializer.length == typeid(const(X)).initializer.length);
  1451. assert(typeid(X).initializer.length == typeid(shared(X)).initializer.length);
  1452. assert(typeid(X).initializer.length == typeid(immutable(X)).initializer.length);
  1453. }
  1454. class TypeInfo_Interface : TypeInfo
  1455. {
  1456. override string toString() const pure { return info.name; }
  1457. override bool opEquals(Object o)
  1458. {
  1459. if (this is o)
  1460. return true;
  1461. auto c = cast(const TypeInfo_Interface)o;
  1462. return c && this.info.name == typeid(c).name;
  1463. }
  1464. override size_t getHash(scope const void* p) @trusted const
  1465. {
  1466. if (!*cast(void**)p)
  1467. {
  1468. return 0;
  1469. }
  1470. Interface* pi = **cast(Interface ***)*cast(void**)p;
  1471. Object o = cast(Object)(*cast(void**)p - pi.offset);
  1472. assert(o);
  1473. return o.toHash();
  1474. }
  1475. override bool equals(in void* p1, in void* p2) const
  1476. {
  1477. Interface* pi = **cast(Interface ***)*cast(void**)p1;
  1478. Object o1 = cast(Object)(*cast(void**)p1 - pi.offset);
  1479. pi = **cast(Interface ***)*cast(void**)p2;
  1480. Object o2 = cast(Object)(*cast(void**)p2 - pi.offset);
  1481. return o1 == o2 || (o1 && o1.opCmp(o2) == 0);
  1482. }
  1483. override int compare(in void* p1, in void* p2) const
  1484. {
  1485. Interface* pi = **cast(Interface ***)*cast(void**)p1;
  1486. Object o1 = cast(Object)(*cast(void**)p1 - pi.offset);
  1487. pi = **cast(Interface ***)*cast(void**)p2;
  1488. Object o2 = cast(Object)(*cast(void**)p2 - pi.offset);
  1489. int c = 0;
  1490. // Regard null references as always being "less than"
  1491. if (o1 != o2)
  1492. {
  1493. if (o1)
  1494. {
  1495. if (!o2)
  1496. c = 1;
  1497. else
  1498. c = o1.opCmp(o2);
  1499. }
  1500. else
  1501. c = -1;
  1502. }
  1503. return c;
  1504. }
  1505. override @property size_t tsize() nothrow pure const
  1506. {
  1507. return Object.sizeof;
  1508. }
  1509. override const(void)[] initializer() const @trusted
  1510. {
  1511. return (cast(void *)null)[0 .. Object.sizeof];
  1512. }
  1513. override @property uint flags() nothrow pure const { return 1; }
  1514. TypeInfo_Class info;
  1515. /**
  1516. * Returns true if the class described by `child` derives from the
  1517. * interface described by this `TypeInfo_Interface`. Always returns
  1518. * false if the argument is null.
  1519. *
  1520. * Params:
  1521. * child = TypeInfo for some class
  1522. * Returns:
  1523. * true if the class described by `child` derives from the
  1524. * interface described by this `TypeInfo_Interface`.
  1525. */
  1526. final bool isBaseOf(scope const TypeInfo_Class child) const @nogc nothrow pure @trusted
  1527. {
  1528. return child !is null && _d_isbaseof(cast() child, this.info);
  1529. }
  1530. /**
  1531. * Returns true if the interface described by `child` derives from
  1532. * or is the interface described by this `TypeInfo_Interface`.
  1533. * Always returns false if the argument is null.
  1534. *
  1535. * Params:
  1536. * child = TypeInfo for some interface
  1537. * Returns:
  1538. * true if the interface described by `child` derives from or is
  1539. * the interface described by this `TypeInfo_Interface`.
  1540. */
  1541. final bool isBaseOf(scope const TypeInfo_Interface child) const @nogc nothrow pure @trusted
  1542. {
  1543. return child !is null && _d_isbaseof(cast() child.info, this.info);
  1544. }
  1545. }
  1546. @safe unittest
  1547. {
  1548. enum unittest_sym_name = __traits(identifier, __traits(parent, (){}));
  1549. enum fqn_unittest = "object." ~ unittest_sym_name; // object.__unittest_LX_CY
  1550. interface I {}
  1551. assert(fqn_unittest ~ ".I" == typeid(I).info.name);
  1552. assert((fqn_unittest ~ ".I").hashOf() == typeid(I).hashOf());
  1553. assert(typeid(I).toHash() == typeid(I).hashOf());
  1554. }
  1555. class TypeInfo_Struct : TypeInfo
  1556. {
  1557. override string toString() const { return name; }
  1558. override size_t toHash() const
  1559. {
  1560. return hashOf(this.mangledName);
  1561. }
  1562. override bool opEquals(Object o)
  1563. {
  1564. if (this is o)
  1565. return true;
  1566. auto s = cast(const TypeInfo_Struct)o;
  1567. return s && this.mangledName == s.mangledName;
  1568. }
  1569. override size_t getHash(scope const void* p) @trusted pure nothrow const
  1570. {
  1571. assert(p);
  1572. if (xtoHash)
  1573. {
  1574. return (*xtoHash)(p);
  1575. }
  1576. else
  1577. {
  1578. return hashOf(p[0 .. initializer().length]);
  1579. }
  1580. }
  1581. override bool equals(in void* p1, in void* p2) @trusted pure nothrow const
  1582. {
  1583. import core.stdc.string : memcmp;
  1584. if (!p1 || !p2)
  1585. return false;
  1586. else if (xopEquals)
  1587. {
  1588. const dg = _memberFunc(p1, xopEquals);
  1589. return dg.xopEquals(p2);
  1590. }
  1591. else if (p1 == p2)
  1592. return true;
  1593. else
  1594. // BUG: relies on the GC not moving objects
  1595. return memcmp(p1, p2, initializer().length) == 0;
  1596. }
  1597. override int compare(in void* p1, in void* p2) @trusted pure nothrow const
  1598. {
  1599. import core.stdc.string : memcmp;
  1600. // Regard null references as always being "less than"
  1601. if (p1 != p2)
  1602. {
  1603. if (p1)
  1604. {
  1605. if (!p2)
  1606. return true;
  1607. else if (xopCmp)
  1608. {
  1609. const dg = _memberFunc(p1, xopCmp);
  1610. return dg.xopCmp(p2);
  1611. }
  1612. else
  1613. // BUG: relies on the GC not moving objects
  1614. return memcmp(p1, p2, initializer().length);
  1615. }
  1616. else
  1617. return -1;
  1618. }
  1619. return 0;
  1620. }
  1621. override @property size_t tsize() nothrow pure const
  1622. {
  1623. return initializer().length;
  1624. }
  1625. override const(void)[] initializer() nothrow pure const @safe
  1626. {
  1627. return m_init;
  1628. }
  1629. override @property uint flags() nothrow pure const { return m_flags; }
  1630. override @property size_t talign() nothrow pure const { return m_align; }
  1631. final override void destroy(void* p) const
  1632. {
  1633. if (xdtor)
  1634. {
  1635. if (m_flags & StructFlags.isDynamicType)
  1636. (*xdtorti)(p, this);
  1637. else
  1638. (*xdtor)(p);
  1639. }
  1640. }
  1641. override void postblit(void* p) const
  1642. {
  1643. if (xpostblit)
  1644. (*xpostblit)(p);
  1645. }
  1646. string mangledName;
  1647. final @property string name() nothrow const @trusted
  1648. {
  1649. import core.demangle : demangleType;
  1650. if (mangledName is null) // e.g., opaque structs
  1651. return null;
  1652. const key = cast(const void*) this; // faster lookup than TypeInfo_Struct, at the cost of potential duplicates per binary
  1653. static string[typeof(key)] demangledNamesCache; // per thread
  1654. // not nothrow:
  1655. //return demangledNamesCache.require(key, cast(string) demangleType(mangledName));
  1656. if (auto pDemangled = key in demangledNamesCache)
  1657. return *pDemangled;
  1658. const demangled = cast(string) demangleType(mangledName);
  1659. demangledNamesCache[key] = demangled;
  1660. return demangled;
  1661. }
  1662. void[] m_init; // initializer; m_init.ptr == null if 0 initialize
  1663. @safe pure nothrow
  1664. {
  1665. size_t function(in void*) xtoHash;
  1666. bool function(in void*, in void*) xopEquals;
  1667. int function(in void*, in void*) xopCmp;
  1668. string function(in void*) xtoString;
  1669. enum StructFlags : uint
  1670. {
  1671. hasPointers = 0x1,
  1672. isDynamicType = 0x2, // built at runtime, needs type info in xdtor
  1673. }
  1674. StructFlags m_flags;
  1675. }
  1676. union
  1677. {
  1678. void function(void*) xdtor;
  1679. void function(void*, const TypeInfo_Struct ti) xdtorti;
  1680. }
  1681. void function(void*) xpostblit;
  1682. uint m_align;
  1683. override @property immutable(void)* rtInfo() nothrow pure const @safe { return m_RTInfo; }
  1684. version (WithArgTypes)
  1685. {
  1686. override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
  1687. {
  1688. arg1 = m_arg1;
  1689. arg2 = m_arg2;
  1690. return 0;
  1691. }
  1692. TypeInfo m_arg1;
  1693. TypeInfo m_arg2;
  1694. }
  1695. immutable(void)* m_RTInfo; // data for precise GC
  1696. // The xopEquals and xopCmp members are function pointers to member
  1697. // functions, which is not guaranteed to share the same ABI, as it is not
  1698. // known whether the `this` parameter is the first or second argument.
  1699. // This wrapper is to convert it to a delegate which will always pass the
  1700. // `this` parameter in the correct way.
  1701. private struct _memberFunc
  1702. {
  1703. union
  1704. {
  1705. struct // delegate
  1706. {
  1707. const void* ptr;
  1708. const void* funcptr;
  1709. }
  1710. @safe pure nothrow
  1711. {
  1712. bool delegate(in void*) xopEquals;
  1713. int delegate(in void*) xopCmp;
  1714. }
  1715. }
  1716. }
  1717. }
  1718. @system unittest
  1719. {
  1720. struct S
  1721. {
  1722. bool opEquals(ref const S rhs) const
  1723. {
  1724. return false;
  1725. }
  1726. }
  1727. S s;
  1728. assert(!typeid(S).equals(&s, &s));
  1729. }
  1730. class TypeInfo_Tuple : TypeInfo
  1731. {
  1732. TypeInfo[] elements;
  1733. override string toString() const
  1734. {
  1735. string s = "(";
  1736. foreach (i, element; elements)
  1737. {
  1738. if (i)
  1739. s ~= ',';
  1740. s ~= element.toString();
  1741. }
  1742. s ~= ")";
  1743. return s;
  1744. }
  1745. override bool opEquals(Object o)
  1746. {
  1747. if (this is o)
  1748. return true;
  1749. auto t = cast(const TypeInfo_Tuple)o;
  1750. if (t && elements.length == t.elements.length)
  1751. {
  1752. for (size_t i = 0; i < elements.length; i++)
  1753. {
  1754. if (elements[i] != t.elements[i])
  1755. return false;
  1756. }
  1757. return true;
  1758. }
  1759. return false;
  1760. }
  1761. override size_t getHash(scope const void* p) const
  1762. {
  1763. assert(0);
  1764. }
  1765. override bool equals(in void* p1, in void* p2) const
  1766. {
  1767. assert(0);
  1768. }
  1769. override int compare(in void* p1, in void* p2) const
  1770. {
  1771. assert(0);
  1772. }
  1773. override @property size_t tsize() nothrow pure const
  1774. {
  1775. assert(0);
  1776. }
  1777. override const(void)[] initializer() const @trusted
  1778. {
  1779. assert(0);
  1780. }
  1781. override void swap(void* p1, void* p2) const
  1782. {
  1783. assert(0);
  1784. }
  1785. override void destroy(void* p) const
  1786. {
  1787. assert(0);
  1788. }
  1789. override void postblit(void* p) const
  1790. {
  1791. assert(0);
  1792. }
  1793. override @property size_t talign() nothrow pure const
  1794. {
  1795. assert(0);
  1796. }
  1797. version (WithArgTypes) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
  1798. {
  1799. assert(0);
  1800. }
  1801. }
  1802. class TypeInfo_Const : TypeInfo
  1803. {
  1804. override string toString() const
  1805. {
  1806. return cast(string) ("const(" ~ base.toString() ~ ")");
  1807. }
  1808. //override bool opEquals(Object o) { return base.opEquals(o); }
  1809. override bool opEquals(Object o)
  1810. {
  1811. if (this is o)
  1812. return true;
  1813. if (typeid(this) != typeid(o))
  1814. return false;
  1815. auto t = cast(TypeInfo_Const)o;
  1816. return base.opEquals(t.base);
  1817. }
  1818. override size_t getHash(scope const void *p) const { return base.getHash(p); }
  1819. override bool equals(in void *p1, in void *p2) const { return base.equals(p1, p2); }
  1820. override int compare(in void *p1, in void *p2) const { return base.compare(p1, p2); }
  1821. override @property size_t tsize() nothrow pure const { return base.tsize; }
  1822. override void swap(void *p1, void *p2) const { return base.swap(p1, p2); }
  1823. override @property inout(TypeInfo) next() nothrow pure inout { return base.next; }
  1824. override @property uint flags() nothrow pure const { return base.flags; }
  1825. override const(void)[] initializer() nothrow pure const
  1826. {
  1827. return base.initializer();
  1828. }
  1829. override @property size_t talign() nothrow pure const { return base.talign; }
  1830. version (WithArgTypes) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
  1831. {
  1832. return base.argTypes(arg1, arg2);
  1833. }
  1834. TypeInfo base;
  1835. }
  1836. class TypeInfo_Invariant : TypeInfo_Const
  1837. {
  1838. override string toString() const
  1839. {
  1840. return cast(string) ("immutable(" ~ base.toString() ~ ")");
  1841. }
  1842. }
  1843. class TypeInfo_Shared : TypeInfo_Const
  1844. {
  1845. override string toString() const
  1846. {
  1847. return cast(string) ("shared(" ~ base.toString() ~ ")");
  1848. }
  1849. }
  1850. class TypeInfo_Inout : TypeInfo_Const
  1851. {
  1852. override string toString() const
  1853. {
  1854. return cast(string) ("inout(" ~ base.toString() ~ ")");
  1855. }
  1856. }
  1857. // Contents of Moduleinfo._flags
  1858. enum
  1859. {
  1860. MIctorstart = 0x1, // we've started constructing it
  1861. MIctordone = 0x2, // finished construction
  1862. MIstandalone = 0x4, // module ctor does not depend on other module
  1863. // ctors being done first
  1864. MItlsctor = 8,
  1865. MItlsdtor = 0x10,
  1866. MIctor = 0x20,
  1867. MIdtor = 0x40,
  1868. MIxgetMembers = 0x80,
  1869. MIictor = 0x100,
  1870. MIunitTest = 0x200,
  1871. MIimportedModules = 0x400,
  1872. MIlocalClasses = 0x800,
  1873. MIname = 0x1000,
  1874. }
  1875. /*****************************************
  1876. * An instance of ModuleInfo is generated into the object file for each compiled module.
  1877. *
  1878. * It provides access to various aspects of the module.
  1879. * It is not generated for betterC.
  1880. */
  1881. struct ModuleInfo
  1882. {
  1883. uint _flags; // MIxxxx
  1884. uint _index; // index into _moduleinfo_array[]
  1885. version (all)
  1886. {
  1887. deprecated("ModuleInfo cannot be copy-assigned because it is a variable-sized struct.")
  1888. void opAssign(const scope ModuleInfo m) { _flags = m._flags; _index = m._index; }
  1889. }
  1890. else
  1891. {
  1892. @disable this();
  1893. }
  1894. const:
  1895. private void* addrOf(int flag) return nothrow pure @nogc
  1896. in
  1897. {
  1898. assert(flag >= MItlsctor && flag <= MIname);
  1899. assert(!(flag & (flag - 1)) && !(flag & ~(flag - 1) << 1));
  1900. }
  1901. do
  1902. {
  1903. import core.stdc.string : strlen;
  1904. void* p = cast(void*)&this + ModuleInfo.sizeof;
  1905. if (flags & MItlsctor)
  1906. {
  1907. if (flag == MItlsctor) return p;
  1908. p += typeof(tlsctor).sizeof;
  1909. }
  1910. if (flags & MItlsdtor)
  1911. {
  1912. if (flag == MItlsdtor) return p;
  1913. p += typeof(tlsdtor).sizeof;
  1914. }
  1915. if (flags & MIctor)
  1916. {
  1917. if (flag == MIctor) return p;
  1918. p += typeof(ctor).sizeof;
  1919. }
  1920. if (flags & MIdtor)
  1921. {
  1922. if (flag == MIdtor) return p;
  1923. p += typeof(dtor).sizeof;
  1924. }
  1925. if (flags & MIxgetMembers)
  1926. {
  1927. if (flag == MIxgetMembers) return p;
  1928. p += typeof(xgetMembers).sizeof;
  1929. }
  1930. if (flags & MIictor)
  1931. {
  1932. if (flag == MIictor) return p;
  1933. p += typeof(ictor).sizeof;
  1934. }
  1935. if (flags & MIunitTest)
  1936. {
  1937. if (flag == MIunitTest) return p;
  1938. p += typeof(unitTest).sizeof;
  1939. }
  1940. if (flags & MIimportedModules)
  1941. {
  1942. if (flag == MIimportedModules) return p;
  1943. p += size_t.sizeof + *cast(size_t*)p * typeof(importedModules[0]).sizeof;
  1944. }
  1945. if (flags & MIlocalClasses)
  1946. {
  1947. if (flag == MIlocalClasses) return p;
  1948. p += size_t.sizeof + *cast(size_t*)p * typeof(localClasses[0]).sizeof;
  1949. }
  1950. if (true || flags & MIname) // always available for now
  1951. {
  1952. if (flag == MIname) return p;
  1953. p += strlen(cast(immutable char*)p);
  1954. }
  1955. assert(0);
  1956. }
  1957. @property uint index() nothrow pure @nogc { return _index; }
  1958. @property uint flags() nothrow pure @nogc { return _flags; }
  1959. /************************
  1960. * Returns:
  1961. * module constructor for thread locals, `null` if there isn't one
  1962. */
  1963. @property void function() tlsctor() nothrow pure @nogc
  1964. {
  1965. return flags & MItlsctor ? *cast(typeof(return)*)addrOf(MItlsctor) : null;
  1966. }
  1967. /************************
  1968. * Returns:
  1969. * module destructor for thread locals, `null` if there isn't one
  1970. */
  1971. @property void function() tlsdtor() nothrow pure @nogc
  1972. {
  1973. return flags & MItlsdtor ? *cast(typeof(return)*)addrOf(MItlsdtor) : null;
  1974. }
  1975. /*****************************
  1976. * Returns:
  1977. * address of a module's `const(MemberInfo)[] getMembers(string)` function, `null` if there isn't one
  1978. */
  1979. @property void* xgetMembers() nothrow pure @nogc
  1980. {
  1981. return flags & MIxgetMembers ? *cast(typeof(return)*)addrOf(MIxgetMembers) : null;
  1982. }
  1983. /************************
  1984. * Returns:
  1985. * module constructor, `null` if there isn't one
  1986. */
  1987. @property void function() ctor() nothrow pure @nogc
  1988. {
  1989. return flags & MIctor ? *cast(typeof(return)*)addrOf(MIctor) : null;
  1990. }
  1991. /************************
  1992. * Returns:
  1993. * module destructor, `null` if there isn't one
  1994. */
  1995. @property void function() dtor() nothrow pure @nogc
  1996. {
  1997. return flags & MIdtor ? *cast(typeof(return)*)addrOf(MIdtor) : null;
  1998. }
  1999. /************************
  2000. * Returns:
  2001. * module order independent constructor, `null` if there isn't one
  2002. */
  2003. @property void function() ictor() nothrow pure @nogc
  2004. {
  2005. return flags & MIictor ? *cast(typeof(return)*)addrOf(MIictor) : null;
  2006. }
  2007. /*************
  2008. * Returns:
  2009. * address of function that runs the module's unittests, `null` if there isn't one
  2010. */
  2011. @property void function() unitTest() nothrow pure @nogc
  2012. {
  2013. return flags & MIunitTest ? *cast(typeof(return)*)addrOf(MIunitTest) : null;
  2014. }
  2015. /****************
  2016. * Returns:
  2017. * array of pointers to the ModuleInfo's of modules imported by this one
  2018. */
  2019. @property immutable(ModuleInfo*)[] importedModules() return nothrow pure @nogc
  2020. {
  2021. if (flags & MIimportedModules)
  2022. {
  2023. auto p = cast(size_t*)addrOf(MIimportedModules);
  2024. return (cast(immutable(ModuleInfo*)*)(p + 1))[0 .. *p];
  2025. }
  2026. return null;
  2027. }
  2028. /****************
  2029. * Returns:
  2030. * array of TypeInfo_Class references for classes defined in this module
  2031. */
  2032. @property TypeInfo_Class[] localClasses() return nothrow pure @nogc
  2033. {
  2034. if (flags & MIlocalClasses)
  2035. {
  2036. auto p = cast(size_t*)addrOf(MIlocalClasses);
  2037. return (cast(TypeInfo_Class*)(p + 1))[0 .. *p];
  2038. }
  2039. return null;
  2040. }
  2041. /********************
  2042. * Returns:
  2043. * name of module, `null` if no name
  2044. */
  2045. @property string name() return nothrow pure @nogc
  2046. {
  2047. import core.stdc.string : strlen;
  2048. auto p = cast(immutable char*) addrOf(MIname);
  2049. return p[0 .. strlen(p)];
  2050. }
  2051. static int opApply(scope int delegate(ModuleInfo*) dg)
  2052. {
  2053. import core.internal.traits : externDFunc;
  2054. alias moduleinfos_apply = externDFunc!("rt.minfo.moduleinfos_apply",
  2055. int function(scope int delegate(immutable(ModuleInfo*))));
  2056. // Bugzilla 13084 - enforcing immutable ModuleInfo would break client code
  2057. return moduleinfos_apply(
  2058. (immutable(ModuleInfo*)m) => dg(cast(ModuleInfo*)m));
  2059. }
  2060. }
  2061. @system unittest
  2062. {
  2063. ModuleInfo* m1;
  2064. foreach (m; ModuleInfo)
  2065. {
  2066. m1 = m;
  2067. }
  2068. }
  2069. ///////////////////////////////////////////////////////////////////////////////
  2070. // Throwable
  2071. ///////////////////////////////////////////////////////////////////////////////
  2072. /**
  2073. * The base class of all thrown objects.
  2074. *
  2075. * All thrown objects must inherit from Throwable. Class $(D Exception), which
  2076. * derives from this class, represents the category of thrown objects that are
  2077. * safe to catch and handle. In principle, one should not catch Throwable
  2078. * objects that are not derived from $(D Exception), as they represent
  2079. * unrecoverable runtime errors. Certain runtime guarantees may fail to hold
  2080. * when these errors are thrown, making it unsafe to continue execution after
  2081. * catching them.
  2082. */
  2083. class Throwable : Object
  2084. {
  2085. interface TraceInfo
  2086. {
  2087. int opApply(scope int delegate(ref const(char[]))) const;
  2088. int opApply(scope int delegate(ref size_t, ref const(char[]))) const;
  2089. string toString() const;
  2090. }
  2091. string msg; /// A message describing the error.
  2092. /**
  2093. * The _file name of the D source code corresponding with
  2094. * where the error was thrown from.
  2095. */
  2096. string file;
  2097. /**
  2098. * The _line number of the D source code corresponding with
  2099. * where the error was thrown from.
  2100. */
  2101. size_t line;
  2102. /**
  2103. * The stack trace of where the error happened. This is an opaque object
  2104. * that can either be converted to $(D string), or iterated over with $(D
  2105. * foreach) to extract the items in the stack trace (as strings).
  2106. */
  2107. TraceInfo info;
  2108. /**
  2109. * A reference to the _next error in the list. This is used when a new
  2110. * $(D Throwable) is thrown from inside a $(D catch) block. The originally
  2111. * caught $(D Exception) will be chained to the new $(D Throwable) via this
  2112. * field.
  2113. */
  2114. private Throwable nextInChain;
  2115. private uint _refcount; // 0 : allocated by GC
  2116. // 1 : allocated by _d_newThrowable()
  2117. // 2.. : reference count + 1
  2118. /**
  2119. * Returns:
  2120. * A reference to the _next error in the list. This is used when a new
  2121. * $(D Throwable) is thrown from inside a $(D catch) block. The originally
  2122. * caught $(D Exception) will be chained to the new $(D Throwable) via this
  2123. * field.
  2124. */
  2125. @property inout(Throwable) next() @safe inout return scope pure nothrow @nogc { return nextInChain; }
  2126. /**
  2127. * Replace next in chain with `tail`.
  2128. * Use `chainTogether` instead if at all possible.
  2129. */
  2130. @property void next(Throwable tail) @safe scope pure nothrow @nogc
  2131. {
  2132. if (tail && tail._refcount)
  2133. ++tail._refcount; // increment the replacement *first*
  2134. auto n = nextInChain;
  2135. nextInChain = null; // sever the tail before deleting it
  2136. if (n && n._refcount)
  2137. _d_delThrowable(n); // now delete the old tail
  2138. nextInChain = tail; // and set the new tail
  2139. }
  2140. /**
  2141. * Returns:
  2142. * mutable reference to the reference count, which is
  2143. * 0 - allocated by the GC, 1 - allocated by _d_newThrowable(),
  2144. * and >=2 which is the reference count + 1
  2145. * Note:
  2146. * Marked as `@system` to discourage casual use of it.
  2147. */
  2148. @system @nogc final pure nothrow ref uint refcount() return { return _refcount; }
  2149. /**
  2150. * Loop over the chain of Throwables.
  2151. */
  2152. int opApply(scope int delegate(Throwable) dg)
  2153. {
  2154. int result = 0;
  2155. for (Throwable t = this; t; t = t.nextInChain)
  2156. {
  2157. result = dg(t);
  2158. if (result)
  2159. break;
  2160. }
  2161. return result;
  2162. }
  2163. /**
  2164. * Append `e2` to chain of exceptions that starts with `e1`.
  2165. * Params:
  2166. * e1 = start of chain (can be null)
  2167. * e2 = second part of chain (can be null)
  2168. * Returns:
  2169. * Throwable that is at the start of the chain; null if both `e1` and `e2` are null
  2170. */
  2171. static @__future @system @nogc pure nothrow Throwable chainTogether(return scope Throwable e1, return scope Throwable e2)
  2172. {
  2173. if (!e1)
  2174. return e2;
  2175. if (!e2)
  2176. return e1;
  2177. if (e2.refcount())
  2178. ++e2.refcount();
  2179. for (auto e = e1; 1; e = e.nextInChain)
  2180. {
  2181. if (!e.nextInChain)
  2182. {
  2183. e.nextInChain = e2;
  2184. break;
  2185. }
  2186. }
  2187. return e1;
  2188. }
  2189. @nogc @safe pure nothrow this(string msg, Throwable nextInChain = null)
  2190. {
  2191. this.msg = msg;
  2192. this.nextInChain = nextInChain;
  2193. if (nextInChain && nextInChain._refcount)
  2194. ++nextInChain._refcount;
  2195. //this.info = _d_traceContext();
  2196. }
  2197. @nogc @safe pure nothrow this(string msg, string file, size_t line, Throwable nextInChain = null)
  2198. {
  2199. this(msg, nextInChain);
  2200. this.file = file;
  2201. this.line = line;
  2202. //this.info = _d_traceContext();
  2203. }
  2204. @trusted nothrow ~this()
  2205. {
  2206. if (nextInChain && nextInChain._refcount)
  2207. _d_delThrowable(nextInChain);
  2208. }
  2209. /**
  2210. * Overrides $(D Object.toString) and returns the error message.
  2211. * Internally this forwards to the $(D toString) overload that
  2212. * takes a $(D_PARAM sink) delegate.
  2213. */
  2214. override string toString()
  2215. {
  2216. string s;
  2217. toString((in buf) { s ~= buf; });
  2218. return s;
  2219. }
  2220. /**
  2221. * The Throwable hierarchy uses a toString overload that takes a
  2222. * $(D_PARAM _sink) delegate to avoid GC allocations, which cannot be
  2223. * performed in certain error situations. Override this $(D
  2224. * toString) method to customize the error message.
  2225. */
  2226. void toString(scope void delegate(in char[]) sink) const
  2227. {
  2228. import core.internal.string : unsignedToTempString;
  2229. char[20] tmpBuff = void;
  2230. sink(typeid(this).name);
  2231. sink("@"); sink(file);
  2232. sink("("); sink(unsignedToTempString(line, tmpBuff)); sink(")");
  2233. if (msg.length)
  2234. {
  2235. sink(": "); sink(msg);
  2236. }
  2237. if (info)
  2238. {
  2239. try
  2240. {
  2241. sink("\n----------------");
  2242. foreach (t; info)
  2243. {
  2244. sink("\n"); sink(t);
  2245. }
  2246. }
  2247. catch (Throwable)
  2248. {
  2249. // ignore more errors
  2250. }
  2251. }
  2252. }
  2253. /**
  2254. * Get the message describing the error.
  2255. *
  2256. * This getter is an alternative way to access the Exception's message,
  2257. * with the added advantage of being override-able in subclasses.
  2258. * Subclasses are hence free to do their own memory managements without
  2259. * being tied to the requirement of providing a `string` in a field.
  2260. *
  2261. * The default behavior is to return the `Throwable.msg` field.
  2262. *
  2263. * Returns:
  2264. * A message representing the cause of the `Throwable`
  2265. */
  2266. @__future const(char)[] message() const @safe nothrow
  2267. {
  2268. return this.msg;
  2269. }
  2270. }
  2271. /**
  2272. * The base class of all errors that are safe to catch and handle.
  2273. *
  2274. * In principle, only thrown objects derived from this class are safe to catch
  2275. * inside a $(D catch) block. Thrown objects not derived from Exception
  2276. * represent runtime errors that should not be caught, as certain runtime
  2277. * guarantees may not hold, making it unsafe to continue program execution.
  2278. */
  2279. class Exception : Throwable
  2280. {
  2281. /**
  2282. * Creates a new instance of Exception. The nextInChain parameter is used
  2283. * internally and should always be $(D null) when passed by user code.
  2284. * This constructor does not automatically throw the newly-created
  2285. * Exception; the $(D throw) statement should be used for that purpose.
  2286. */
  2287. @nogc @safe pure nothrow this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable nextInChain = null)
  2288. {
  2289. super(msg, file, line, nextInChain);
  2290. }
  2291. @nogc @safe pure nothrow this(string msg, Throwable nextInChain, string file = __FILE__, size_t line = __LINE__)
  2292. {
  2293. super(msg, file, line, nextInChain);
  2294. }
  2295. }
  2296. ///
  2297. @safe unittest
  2298. {
  2299. bool gotCaught;
  2300. try
  2301. {
  2302. throw new Exception("msg");
  2303. }
  2304. catch (Exception e)
  2305. {
  2306. gotCaught = true;
  2307. assert(e.msg == "msg");
  2308. }
  2309. assert(gotCaught);
  2310. }
  2311. @system unittest
  2312. {
  2313. {
  2314. auto e = new Exception("msg");
  2315. assert(e.file == __FILE__);
  2316. assert(e.line == __LINE__ - 2);
  2317. assert(e.nextInChain is null);
  2318. assert(e.msg == "msg");
  2319. }
  2320. {
  2321. auto e = new Exception("msg", new Exception("It's an Exception!"), "hello", 42);
  2322. assert(e.file == "hello");
  2323. assert(e.line == 42);
  2324. assert(e.nextInChain !is null);
  2325. assert(e.msg == "msg");
  2326. }
  2327. {
  2328. auto e = new Exception("msg", "hello", 42, new Exception("It's an Exception!"));
  2329. assert(e.file == "hello");
  2330. assert(e.line == 42);
  2331. assert(e.nextInChain !is null);
  2332. assert(e.msg == "msg");
  2333. }
  2334. {
  2335. auto e = new Exception("message");
  2336. assert(e.message == "message");
  2337. }
  2338. }
  2339. /**
  2340. * The base class of all unrecoverable runtime errors.
  2341. *
  2342. * This represents the category of $(D Throwable) objects that are $(B not)
  2343. * safe to catch and handle. In principle, one should not catch Error
  2344. * objects, as they represent unrecoverable runtime errors.
  2345. * Certain runtime guarantees may fail to hold when these errors are
  2346. * thrown, making it unsafe to continue execution after catching them.
  2347. */
  2348. class Error : Throwable
  2349. {
  2350. /**
  2351. * Creates a new instance of Error. The nextInChain parameter is used
  2352. * internally and should always be $(D null) when passed by user code.
  2353. * This constructor does not automatically throw the newly-created
  2354. * Error; the $(D throw) statement should be used for that purpose.
  2355. */
  2356. @nogc @safe pure nothrow this(string msg, Throwable nextInChain = null)
  2357. {
  2358. super(msg, nextInChain);
  2359. bypassedException = null;
  2360. }
  2361. @nogc @safe pure nothrow this(string msg, string file, size_t line, Throwable nextInChain = null)
  2362. {
  2363. super(msg, file, line, nextInChain);
  2364. bypassedException = null;
  2365. }
  2366. /** The first $(D Exception) which was bypassed when this Error was thrown,
  2367. or $(D null) if no $(D Exception)s were pending. */
  2368. Throwable bypassedException;
  2369. }
  2370. ///
  2371. @system unittest
  2372. {
  2373. bool gotCaught;
  2374. try
  2375. {
  2376. throw new Error("msg");
  2377. }
  2378. catch (Error e)
  2379. {
  2380. gotCaught = true;
  2381. assert(e.msg == "msg");
  2382. }
  2383. assert(gotCaught);
  2384. }
  2385. @safe unittest
  2386. {
  2387. {
  2388. auto e = new Error("msg");
  2389. assert(e.file is null);
  2390. assert(e.line == 0);
  2391. assert(e.nextInChain is null);
  2392. assert(e.msg == "msg");
  2393. assert(e.bypassedException is null);
  2394. }
  2395. {
  2396. auto e = new Error("msg", new Exception("It's an Exception!"));
  2397. assert(e.file is null);
  2398. assert(e.line == 0);
  2399. assert(e.nextInChain !is null);
  2400. assert(e.msg == "msg");
  2401. assert(e.bypassedException is null);
  2402. }
  2403. {
  2404. auto e = new Error("msg", "hello", 42, new Exception("It's an Exception!"));
  2405. assert(e.file == "hello");
  2406. assert(e.line == 42);
  2407. assert(e.nextInChain !is null);
  2408. assert(e.msg == "msg");
  2409. assert(e.bypassedException is null);
  2410. }
  2411. }
  2412. extern (C)
  2413. {
  2414. // from druntime/src/rt/aaA.d
  2415. private struct AA { void* impl; }
  2416. // size_t _aaLen(in AA aa) pure nothrow @nogc;
  2417. private void* _aaGetY(AA* paa, const TypeInfo_AssociativeArray ti, const size_t valsz, const scope void* pkey) pure nothrow;
  2418. private void* _aaGetX(AA* paa, const TypeInfo_AssociativeArray ti, const size_t valsz, const scope void* pkey, out bool found) pure nothrow;
  2419. // inout(void)* _aaGetRvalueX(inout AA aa, in TypeInfo keyti, in size_t valsz, in void* pkey);
  2420. inout(void[]) _aaValues(inout AA aa, const size_t keysz, const size_t valsz, const TypeInfo tiValueArray) pure nothrow;
  2421. inout(void[]) _aaKeys(inout AA aa, const size_t keysz, const TypeInfo tiKeyArray) pure nothrow;
  2422. void* _aaRehash(AA* paa, const scope TypeInfo keyti) pure nothrow;
  2423. void _aaClear(AA aa) pure nothrow;
  2424. // alias _dg_t = extern(D) int delegate(void*);
  2425. // int _aaApply(AA aa, size_t keysize, _dg_t dg);
  2426. // alias _dg2_t = extern(D) int delegate(void*, void*);
  2427. // int _aaApply2(AA aa, size_t keysize, _dg2_t dg);
  2428. private struct AARange { AA impl; size_t idx; }
  2429. AARange _aaRange(AA aa) pure nothrow @nogc @safe;
  2430. bool _aaRangeEmpty(AARange r) pure nothrow @nogc @safe;
  2431. void* _aaRangeFrontKey(AARange r) pure nothrow @nogc @safe;
  2432. void* _aaRangeFrontValue(AARange r) pure nothrow @nogc @safe;
  2433. void _aaRangePopFront(ref AARange r) pure nothrow @nogc @safe;
  2434. int _aaEqual(scope const TypeInfo tiRaw, scope const AA aa1, scope const AA aa2);
  2435. hash_t _aaGetHash(scope const AA* aa, scope const TypeInfo tiRaw) nothrow;
  2436. /*
  2437. _d_assocarrayliteralTX marked as pure, because aaLiteral can be called from pure code.
  2438. This is a typesystem hole, however this is existing hole.
  2439. Early compiler didn't check purity of toHash or postblit functions, if key is a UDT thus
  2440. copiler allowed to create AA literal with keys, which have impure unsafe toHash methods.
  2441. */
  2442. void* _d_assocarrayliteralTX(const TypeInfo_AssociativeArray ti, void[] keys, void[] values) pure;
  2443. }
  2444. void* aaLiteral(Key, Value)(Key[] keys, Value[] values) @trusted pure
  2445. {
  2446. return _d_assocarrayliteralTX(typeid(Value[Key]), *cast(void[]*)&keys, *cast(void[]*)&values);
  2447. }
  2448. alias AssociativeArray(Key, Value) = Value[Key];
  2449. /***********************************
  2450. * Removes all remaining keys and values from an associative array.
  2451. * Params:
  2452. * aa = The associative array.
  2453. */
  2454. void clear(Value, Key)(Value[Key] aa)
  2455. {
  2456. _aaClear(*cast(AA *) &aa);
  2457. }
  2458. /** ditto */
  2459. void clear(Value, Key)(Value[Key]* aa)
  2460. {
  2461. _aaClear(*cast(AA *) aa);
  2462. }
  2463. ///
  2464. @system unittest
  2465. {
  2466. auto aa = ["k1": 2];
  2467. aa.clear;
  2468. assert("k1" !in aa);
  2469. }
  2470. // Issue 20559
  2471. @system unittest
  2472. {
  2473. static class Foo
  2474. {
  2475. int[string] aa;
  2476. alias aa this;
  2477. }
  2478. auto v = new Foo();
  2479. v["Hello World"] = 42;
  2480. v.clear;
  2481. assert("Hello World" !in v);
  2482. // Test for T*
  2483. static assert(!__traits(compiles, (&v).clear));
  2484. static assert( __traits(compiles, (*(&v)).clear));
  2485. }
  2486. /***********************************
  2487. * Reorganizes the associative array in place so that lookups are more
  2488. * efficient.
  2489. * Params:
  2490. * aa = The associative array.
  2491. * Returns:
  2492. * The rehashed associative array.
  2493. */
  2494. T rehash(T : Value[Key], Value, Key)(T aa)
  2495. {
  2496. _aaRehash(cast(AA*)&aa, typeid(Value[Key]));
  2497. return aa;
  2498. }
  2499. /** ditto */
  2500. T rehash(T : Value[Key], Value, Key)(T* aa)
  2501. {
  2502. _aaRehash(cast(AA*)aa, typeid(Value[Key]));
  2503. return *aa;
  2504. }
  2505. /** ditto */
  2506. T rehash(T : shared Value[Key], Value, Key)(T aa)
  2507. {
  2508. _aaRehash(cast(AA*)&aa, typeid(Value[Key]));
  2509. return aa;
  2510. }
  2511. /** ditto */
  2512. T rehash(T : shared Value[Key], Value, Key)(T* aa)
  2513. {
  2514. _aaRehash(cast(AA*)aa, typeid(Value[Key]));
  2515. return *aa;
  2516. }
  2517. /***********************************
  2518. * Creates a new associative array of the same size and copies the contents of
  2519. * the associative array into it.
  2520. * Params:
  2521. * aa = The associative array.
  2522. */
  2523. V[K] dup(T : V[K], K, V)(T aa)
  2524. {
  2525. //pragma(msg, "K = ", K, ", V = ", V);
  2526. // Bug10720 - check whether V is copyable
  2527. static assert(is(typeof({ V v = aa[K.init]; })),
  2528. "cannot call " ~ T.stringof ~ ".dup because " ~ V.stringof ~ " is not copyable");
  2529. V[K] result;
  2530. //foreach (k, ref v; aa)
  2531. // result[k] = v; // Bug13701 - won't work if V is not mutable
  2532. ref V duplicateElem(ref K k, ref const V v) @trusted pure nothrow
  2533. {
  2534. import core.stdc.string : memcpy;
  2535. void* pv = _aaGetY(cast(AA*)&result, typeid(V[K]), V.sizeof, &k);
  2536. memcpy(pv, &v, V.sizeof);
  2537. return *cast(V*)pv;
  2538. }
  2539. foreach (k, ref v; aa)
  2540. {
  2541. static if (!__traits(hasPostblit, V))
  2542. duplicateElem(k, v);
  2543. else static if (__traits(isStaticArray, V))
  2544. _doPostblit(duplicateElem(k, v)[]);
  2545. else static if (!is(typeof(v.__xpostblit())) && is(immutable V == immutable UV, UV))
  2546. (() @trusted => *cast(UV*) &duplicateElem(k, v))().__xpostblit();
  2547. else
  2548. duplicateElem(k, v).__xpostblit();
  2549. }
  2550. return result;
  2551. }
  2552. /** ditto */
  2553. V[K] dup(T : V[K], K, V)(T* aa)
  2554. {
  2555. return (*aa).dup;
  2556. }
  2557. ///
  2558. @safe unittest
  2559. {
  2560. auto aa = ["k1": 2];
  2561. auto a2 = aa.dup;
  2562. aa["k2"] = 3;
  2563. assert("k2" !in a2);
  2564. }
  2565. // this should never be made public.
  2566. private AARange _aaToRange(T: V[K], K, V)(ref T aa) pure nothrow @nogc @safe
  2567. {
  2568. // ensure we are dealing with a genuine AA.
  2569. static if (is(const(V[K]) == const(T)))
  2570. alias realAA = aa;
  2571. else
  2572. const(V[K]) realAA = aa;
  2573. return _aaRange(() @trusted { return *cast(AA*)&realAA; } ());
  2574. }
  2575. /***********************************
  2576. * Returns a $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives)
  2577. * which will iterate over the keys of the associative array. The keys are
  2578. * returned by reference.
  2579. *
  2580. * If structural changes are made to the array (removing or adding keys), all
  2581. * ranges previously obtained through this function are invalidated. The
  2582. * following example program will dereference a null pointer:
  2583. *
  2584. *---
  2585. * import std.stdio : writeln;
  2586. *
  2587. * auto dict = ["k1": 1, "k2": 2];
  2588. * auto keyRange = dict.byKey;
  2589. * dict.clear;
  2590. * writeln(keyRange.front); // Segmentation fault
  2591. *---
  2592. *
  2593. * Params:
  2594. * aa = The associative array.
  2595. * Returns:
  2596. * A forward range referencing the keys of the associative array.
  2597. */
  2598. auto byKey(T : V[K], K, V)(T aa) pure nothrow @nogc @safe
  2599. {
  2600. import core.internal.traits : substInout;
  2601. static struct Result
  2602. {
  2603. AARange r;
  2604. pure nothrow @nogc:
  2605. @property bool empty() @safe { return _aaRangeEmpty(r); }
  2606. @property ref front() @trusted
  2607. {
  2608. return *cast(substInout!K*) _aaRangeFrontKey(r);
  2609. }
  2610. void popFront() @safe { _aaRangePopFront(r); }
  2611. @property Result save() { return this; }
  2612. }
  2613. return Result(_aaToRange(aa));
  2614. }
  2615. /** ditto */
  2616. auto byKey(T : V[K], K, V)(T* aa) pure nothrow @nogc
  2617. {
  2618. return (*aa).byKey();
  2619. }
  2620. ///
  2621. @safe unittest
  2622. {
  2623. auto dict = [1: "v1", 2: "v2"];
  2624. int sum;
  2625. foreach (v; dict.byKey)
  2626. sum += v;
  2627. assert(sum == 3);
  2628. }
  2629. /***********************************
  2630. * Returns a $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives)
  2631. * which will iterate over the values of the associative array. The values are
  2632. * returned by reference.
  2633. *
  2634. * If structural changes are made to the array (removing or adding keys), all
  2635. * ranges previously obtained through this function are invalidated. The
  2636. * following example program will dereference a null pointer:
  2637. *
  2638. *---
  2639. * import std.stdio : writeln;
  2640. *
  2641. * auto dict = ["k1": 1, "k2": 2];
  2642. * auto valueRange = dict.byValue;
  2643. * dict.clear;
  2644. * writeln(valueRange.front); // Segmentation fault
  2645. *---
  2646. *
  2647. * Params:
  2648. * aa = The associative array.
  2649. * Returns:
  2650. * A forward range referencing the values of the associative array.
  2651. */
  2652. auto byValue(T : V[K], K, V)(T aa) pure nothrow @nogc @safe
  2653. {
  2654. import core.internal.traits : substInout;
  2655. static struct Result
  2656. {
  2657. AARange r;
  2658. pure nothrow @nogc:
  2659. @property bool empty() @safe { return _aaRangeEmpty(r); }
  2660. @property ref front() @trusted
  2661. {
  2662. return *cast(substInout!V*) _aaRangeFrontValue(r);
  2663. }
  2664. void popFront() @safe { _aaRangePopFront(r); }
  2665. @property Result save() { return this; }
  2666. }
  2667. return Result(_aaToRange(aa));
  2668. }
  2669. /** ditto */
  2670. auto byValue(T : V[K], K, V)(T* aa) pure nothrow @nogc
  2671. {
  2672. return (*aa).byValue();
  2673. }
  2674. ///
  2675. @safe unittest
  2676. {
  2677. auto dict = ["k1": 1, "k2": 2];
  2678. int sum;
  2679. foreach (v; dict.byValue)
  2680. sum += v;
  2681. assert(sum == 3);
  2682. }
  2683. /***********************************
  2684. * Returns a $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives)
  2685. * which will iterate over the key-value pairs of the associative array. The
  2686. * returned pairs are represented by an opaque type with `.key` and `.value`
  2687. * properties for accessing references to the key and value of the pair,
  2688. * respectively.
  2689. *
  2690. * If structural changes are made to the array (removing or adding keys), all
  2691. * ranges previously obtained through this function are invalidated. The
  2692. * following example program will dereference a null pointer:
  2693. *
  2694. *---
  2695. * import std.stdio : writeln;
  2696. *
  2697. * auto dict = ["k1": 1, "k2": 2];
  2698. * auto kvRange = dict.byKeyValue;
  2699. * dict.clear;
  2700. * writeln(kvRange.front.key, ": ", kvRange.front.value); // Segmentation fault
  2701. *---
  2702. *
  2703. * Note that this is a low-level interface to iterating over the associative
  2704. * array and is not compatible withth the
  2705. * $(LINK2 $(ROOT_DIR)phobos/std_typecons.html#.Tuple,`Tuple`) type in Phobos.
  2706. * For compatibility with `Tuple`, use
  2707. * $(LINK2 $(ROOT_DIR)phobos/std_array.html#.byPair,std.array.byPair) instead.
  2708. *
  2709. * Params:
  2710. * aa = The associative array.
  2711. * Returns:
  2712. * A forward range referencing the pairs of the associative array.
  2713. */
  2714. auto byKeyValue(T : V[K], K, V)(T aa) pure nothrow @nogc @safe
  2715. {
  2716. import core.internal.traits : substInout;
  2717. static struct Result
  2718. {
  2719. AARange r;
  2720. pure nothrow @nogc:
  2721. @property bool empty() @safe { return _aaRangeEmpty(r); }
  2722. @property auto front()
  2723. {
  2724. static struct Pair
  2725. {
  2726. // We save the pointers here so that the Pair we return
  2727. // won't mutate when Result.popFront is called afterwards.
  2728. private void* keyp;
  2729. private void* valp;
  2730. @property ref key() inout @trusted
  2731. {
  2732. return *cast(substInout!K*) keyp;
  2733. }
  2734. @property ref value() inout @trusted
  2735. {
  2736. return *cast(substInout!V*) valp;
  2737. }
  2738. }
  2739. return Pair(_aaRangeFrontKey(r),
  2740. _aaRangeFrontValue(r));
  2741. }
  2742. void popFront() @safe { return _aaRangePopFront(r); }
  2743. @property Result save() { return this; }
  2744. }
  2745. return Result(_aaToRange(aa));
  2746. }
  2747. /** ditto */
  2748. auto byKeyValue(T : V[K], K, V)(T* aa) pure nothrow @nogc
  2749. {
  2750. return (*aa).byKeyValue();
  2751. }
  2752. ///
  2753. @safe unittest
  2754. {
  2755. auto dict = ["k1": 1, "k2": 2];
  2756. int sum;
  2757. foreach (e; dict.byKeyValue)
  2758. {
  2759. assert(e.key[1] == e.value + '0');
  2760. sum += e.value;
  2761. }
  2762. assert(sum == 3);
  2763. }
  2764. /***********************************
  2765. * Returns a newly allocated dynamic array containing a copy of the keys from
  2766. * the associative array.
  2767. * Params:
  2768. * aa = The associative array.
  2769. * Returns:
  2770. * A dynamic array containing a copy of the keys.
  2771. */
  2772. Key[] keys(T : Value[Key], Value, Key)(T aa) @property
  2773. {
  2774. // ensure we are dealing with a genuine AA.
  2775. static if (is(const(Value[Key]) == const(T)))
  2776. alias realAA = aa;
  2777. else
  2778. const(Value[Key]) realAA = aa;
  2779. auto res = () @trusted {
  2780. auto a = cast(void[])_aaKeys(*cast(inout(AA)*)&realAA, Key.sizeof, typeid(Key[]));
  2781. return *cast(Key[]*)&a;
  2782. }();
  2783. static if (__traits(hasPostblit, Key))
  2784. _doPostblit(res);
  2785. return res;
  2786. }
  2787. /** ditto */
  2788. Key[] keys(T : Value[Key], Value, Key)(T *aa) @property
  2789. {
  2790. return (*aa).keys;
  2791. }
  2792. ///
  2793. @safe unittest
  2794. {
  2795. auto aa = [1: "v1", 2: "v2"];
  2796. int sum;
  2797. foreach (k; aa.keys)
  2798. sum += k;
  2799. assert(sum == 3);
  2800. }
  2801. @safe unittest
  2802. {
  2803. static struct S
  2804. {
  2805. string str;
  2806. void[][string] dict;
  2807. alias dict this;
  2808. }
  2809. auto s = S("a");
  2810. assert(s.keys.length == 0);
  2811. }
  2812. @safe unittest
  2813. {
  2814. @safe static struct Key
  2815. {
  2816. string str;
  2817. this(this) @safe {}
  2818. }
  2819. string[Key] aa;
  2820. static assert(__traits(compiles, {
  2821. void test() @safe {
  2822. const _ = aa.keys;
  2823. }
  2824. }));
  2825. }
  2826. @safe unittest
  2827. {
  2828. static struct Key
  2829. {
  2830. string str;
  2831. this(this) @system {}
  2832. }
  2833. string[Key] aa;
  2834. static assert(!__traits(compiles, {
  2835. void test() @safe {
  2836. const _ = aa.keys;
  2837. }
  2838. }));
  2839. }
  2840. /***********************************
  2841. * Returns a newly allocated dynamic array containing a copy of the values from
  2842. * the associative array.
  2843. * Params:
  2844. * aa = The associative array.
  2845. * Returns:
  2846. * A dynamic array containing a copy of the values.
  2847. */
  2848. Value[] values(T : Value[Key], Value, Key)(T aa) @property
  2849. {
  2850. // ensure we are dealing with a genuine AA.
  2851. static if (is(const(Value[Key]) == const(T)))
  2852. alias realAA = aa;
  2853. else
  2854. const(Value[Key]) realAA = aa;
  2855. auto res = () @trusted {
  2856. auto a = cast(void[])_aaValues(*cast(inout(AA)*)&realAA, Key.sizeof, Value.sizeof, typeid(Value[]));
  2857. return *cast(Value[]*)&a;
  2858. }();
  2859. static if (__traits(hasPostblit, Value))
  2860. _doPostblit(res);
  2861. return res;
  2862. }
  2863. /** ditto */
  2864. Value[] values(T : Value[Key], Value, Key)(T *aa) @property
  2865. {
  2866. return (*aa).values;
  2867. }
  2868. ///
  2869. @safe unittest
  2870. {
  2871. auto aa = ["k1": 1, "k2": 2];
  2872. int sum;
  2873. foreach (e; aa.values)
  2874. sum += e;
  2875. assert(sum == 3);
  2876. }
  2877. @safe unittest
  2878. {
  2879. static struct S
  2880. {
  2881. string str;
  2882. void[][string] dict;
  2883. alias dict this;
  2884. }
  2885. auto s = S("a");
  2886. assert(s.values.length == 0);
  2887. }
  2888. @safe unittest
  2889. {
  2890. @safe static struct Value
  2891. {
  2892. string str;
  2893. this(this) @safe {}
  2894. }
  2895. Value[string] aa;
  2896. static assert(__traits(compiles, {
  2897. void test() @safe {
  2898. const _ = aa.values;
  2899. }
  2900. }));
  2901. }
  2902. @safe unittest
  2903. {
  2904. static struct Value
  2905. {
  2906. string str;
  2907. this(this) @system {}
  2908. }
  2909. Value[string] aa;
  2910. static assert(!__traits(compiles, {
  2911. void test() @safe {
  2912. const _ = aa.values;
  2913. }
  2914. }));
  2915. }
  2916. /***********************************
  2917. * Looks up key; if it exists returns corresponding value else evaluates and
  2918. * returns defaultValue.
  2919. * Params:
  2920. * aa = The associative array.
  2921. * key = The key.
  2922. * defaultValue = The default value.
  2923. * Returns:
  2924. * The value.
  2925. */
  2926. inout(V) get(K, V)(inout(V[K]) aa, K key, lazy inout(V) defaultValue)
  2927. {
  2928. auto p = key in aa;
  2929. return p ? *p : defaultValue;
  2930. }
  2931. /** ditto */
  2932. inout(V) get(K, V)(inout(V[K])* aa, K key, lazy inout(V) defaultValue)
  2933. {
  2934. return (*aa).get(key, defaultValue);
  2935. }
  2936. ///
  2937. @safe unittest
  2938. {
  2939. auto aa = ["k1": 1];
  2940. assert(aa.get("k1", 0) == 1);
  2941. assert(aa.get("k2", 0) == 0);
  2942. }
  2943. /***********************************
  2944. * Looks up key; if it exists returns corresponding value else evaluates
  2945. * value, adds it to the associative array and returns it.
  2946. * Params:
  2947. * aa = The associative array.
  2948. * key = The key.
  2949. * value = The required value.
  2950. * Returns:
  2951. * The value.
  2952. */
  2953. ref V require(K, V)(ref V[K] aa, K key, lazy V value = V.init)
  2954. {
  2955. bool found;
  2956. // if key is @safe-ly copyable, `require` can infer @safe
  2957. static if (isSafeCopyable!K)
  2958. {
  2959. auto p = () @trusted
  2960. {
  2961. return cast(V*) _aaGetX(cast(AA*) &aa, typeid(V[K]), V.sizeof, &key, found);
  2962. } ();
  2963. }
  2964. else
  2965. {
  2966. auto p = cast(V*) _aaGetX(cast(AA*) &aa, typeid(V[K]), V.sizeof, &key, found);
  2967. }
  2968. if (found)
  2969. return *p;
  2970. else
  2971. {
  2972. *p = value; // Not `return (*p = value)` since if `=` is overloaded
  2973. return *p; // this might not return a ref to the left-hand side.
  2974. }
  2975. }
  2976. ///
  2977. @safe unittest
  2978. {
  2979. auto aa = ["k1": 1];
  2980. assert(aa.require("k1", 0) == 1);
  2981. assert(aa.require("k2", 0) == 0);
  2982. assert(aa["k2"] == 0);
  2983. }
  2984. // Tests whether T can be @safe-ly copied. Use a union to exclude destructor from the test.
  2985. private enum bool isSafeCopyable(T) = is(typeof(() @safe { union U { T x; } T *x; auto u = U(*x); }));
  2986. /***********************************
  2987. * Looks up key; if it exists applies the update callable else evaluates the
  2988. * create callable and adds it to the associative array
  2989. * Params:
  2990. * aa = The associative array.
  2991. * key = The key.
  2992. * create = The callable to apply on create.
  2993. * update = The callable to apply on update.
  2994. */
  2995. void update(K, V, C, U)(ref V[K] aa, K key, scope C create, scope U update)
  2996. if (is(typeof(create()) : V) && (is(typeof(update(aa[K.init])) : V) || is(typeof(update(aa[K.init])) == void)))
  2997. {
  2998. bool found;
  2999. // if key is @safe-ly copyable, `update` may infer @safe
  3000. static if (isSafeCopyable!K)
  3001. {
  3002. auto p = () @trusted
  3003. {
  3004. return cast(V*) _aaGetX(cast(AA*) &aa, typeid(V[K]), V.sizeof, &key, found);
  3005. } ();
  3006. }
  3007. else
  3008. {
  3009. auto p = cast(V*) _aaGetX(cast(AA*) &aa, typeid(V[K]), V.sizeof, &key, found);
  3010. }
  3011. if (!found)
  3012. *p = create();
  3013. else
  3014. {
  3015. static if (is(typeof(update(*p)) == void))
  3016. update(*p);
  3017. else
  3018. *p = update(*p);
  3019. }
  3020. }
  3021. ///
  3022. @system unittest
  3023. {
  3024. auto aa = ["k1": 1];
  3025. aa.update("k1", {
  3026. return -1; // create (won't be executed)
  3027. }, (ref int v) {
  3028. v += 1; // update
  3029. });
  3030. assert(aa["k1"] == 2);
  3031. aa.update("k2", {
  3032. return 0; // create
  3033. }, (ref int v) {
  3034. v = -1; // update (won't be executed)
  3035. });
  3036. assert(aa["k2"] == 0);
  3037. }
  3038. @safe unittest
  3039. {
  3040. static struct S
  3041. {
  3042. int x;
  3043. @nogc nothrow pure:
  3044. this(this) @system {}
  3045. @safe const:
  3046. // stubs
  3047. bool opEquals(S rhs) { assert(0); }
  3048. size_t toHash() { assert(0); }
  3049. }
  3050. int[string] aai;
  3051. static assert(is(typeof(() @safe { aai.require("a", 1234); })));
  3052. static assert(is(typeof(() @safe { aai.update("a", { return 1234; }, (ref int x) { x++; return x; }); })));
  3053. S[string] aas;
  3054. static assert(is(typeof(() { aas.require("a", S(1234)); })));
  3055. static assert(is(typeof(() { aas.update("a", { return S(1234); }, (ref S s) { s.x++; return s; }); })));
  3056. static assert(!is(typeof(() @safe { aas.update("a", { return S(1234); }, (ref S s) { s.x++; return s; }); })));
  3057. int[S] aais;
  3058. static assert(is(typeof(() { aais.require(S(1234), 1234); })));
  3059. static assert(is(typeof(() { aais.update(S(1234), { return 1234; }, (ref int x) { x++; return x; }); })));
  3060. static assert(!is(typeof(() @safe { aais.require(S(1234), 1234); })));
  3061. static assert(!is(typeof(() @safe { aais.update(S(1234), { return 1234; }, (ref int x) { x++; return x; }); })));
  3062. }
  3063. @safe unittest
  3064. {
  3065. struct S0
  3066. {
  3067. int opCall(ref int v)
  3068. {
  3069. return v + 1;
  3070. }
  3071. }
  3072. struct S1
  3073. {
  3074. int opCall()()
  3075. {
  3076. return -2;
  3077. }
  3078. T opCall(T)(ref T v)
  3079. {
  3080. return v + 1;
  3081. }
  3082. }
  3083. int[string] a = ["2" : 1];
  3084. a.update("2", () => -1, S0.init);
  3085. assert(a["2"] == 2);
  3086. a.update("0", () => -1, S0.init);
  3087. assert(a["0"] == -1);
  3088. a.update("2", S1.init, S1.init);
  3089. assert(a["2"] == 3);
  3090. a.update("1", S1.init, S1.init);
  3091. assert(a["1"] == -2);
  3092. }
  3093. @system unittest
  3094. {
  3095. int[string] aa;
  3096. foreach (n; 0 .. 2)
  3097. aa.update("k1", {
  3098. return 7;
  3099. }, (ref int v) {
  3100. return v + 3;
  3101. });
  3102. assert(aa["k1"] == 10);
  3103. }
  3104. version (CoreDdoc)
  3105. {
  3106. // This lets DDoc produce better documentation.
  3107. /**
  3108. Calculates the hash value of `arg` with an optional `seed` initial value.
  3109. The result might not be equal to `typeid(T).getHash(&arg)`.
  3110. Params:
  3111. arg = argument to calculate the hash value of
  3112. seed = optional `seed` value (may be used for hash chaining)
  3113. Return: calculated hash value of `arg`
  3114. */
  3115. size_t hashOf(T)(auto ref T arg, size_t seed)
  3116. {
  3117. static import core.internal.hash;
  3118. return core.internal.hash.hashOf(arg, seed);
  3119. }
  3120. /// ditto
  3121. size_t hashOf(T)(auto ref T arg)
  3122. {
  3123. static import core.internal.hash;
  3124. return core.internal.hash.hashOf(arg);
  3125. }
  3126. @safe unittest
  3127. {
  3128. auto h1 = "my.string".hashOf;
  3129. assert(h1 == "my.string".hashOf);
  3130. }
  3131. }
  3132. else
  3133. {
  3134. public import core.internal.hash : hashOf;
  3135. }
  3136. ///
  3137. @system unittest
  3138. {
  3139. class MyObject
  3140. {
  3141. size_t myMegaHash() const @safe pure nothrow
  3142. {
  3143. return 42;
  3144. }
  3145. }
  3146. struct Test
  3147. {
  3148. int a;
  3149. string b;
  3150. MyObject c;
  3151. size_t toHash() const pure nothrow
  3152. {
  3153. size_t hash = a.hashOf();
  3154. hash = b.hashOf(hash);
  3155. size_t h1 = c.myMegaHash();
  3156. hash = h1.hashOf(hash); //Mix two hash values
  3157. return hash;
  3158. }
  3159. }
  3160. }
  3161. bool _xopEquals(in void*, in void*)
  3162. {
  3163. throw new Error("TypeInfo.equals is not implemented");
  3164. }
  3165. bool _xopCmp(in void*, in void*)
  3166. {
  3167. throw new Error("TypeInfo.compare is not implemented");
  3168. }
  3169. /******************************************
  3170. * Create RTInfo for type T
  3171. */
  3172. template RTInfoImpl(size_t[] pointerBitmap)
  3173. {
  3174. immutable size_t[pointerBitmap.length] RTInfoImpl = pointerBitmap[];
  3175. }
  3176. template NoPointersBitmapPayload(size_t N)
  3177. {
  3178. enum size_t[N] NoPointersBitmapPayload = 0;
  3179. }
  3180. template RTInfo(T)
  3181. {
  3182. enum pointerBitmap = __traits(getPointerBitmap, T);
  3183. static if (pointerBitmap[1 .. $] == NoPointersBitmapPayload!(pointerBitmap.length - 1))
  3184. enum RTInfo = rtinfoNoPointers;
  3185. else
  3186. enum RTInfo = RTInfoImpl!(pointerBitmap).ptr;
  3187. }
  3188. /**
  3189. * shortcuts for the precise GC, also generated by the compiler
  3190. * used instead of the actual pointer bitmap
  3191. */
  3192. enum immutable(void)* rtinfoNoPointers = null;
  3193. enum immutable(void)* rtinfoHasPointers = cast(void*)1;
  3194. // Helper functions
  3195. private inout(TypeInfo) getElement(return scope inout TypeInfo value) @trusted pure nothrow
  3196. {
  3197. TypeInfo element = cast() value;
  3198. for (;;)
  3199. {
  3200. if (auto qualified = cast(TypeInfo_Const) element)
  3201. element = qualified.base;
  3202. else if (auto redefined = cast(TypeInfo_Enum) element)
  3203. element = redefined.base;
  3204. else if (auto staticArray = cast(TypeInfo_StaticArray) element)
  3205. element = staticArray.value;
  3206. else if (auto vector = cast(TypeInfo_Vector) element)
  3207. element = vector.base;
  3208. else
  3209. break;
  3210. }
  3211. return cast(inout) element;
  3212. }
  3213. private size_t getArrayHash(const scope TypeInfo element, const scope void* ptr, const size_t count) @trusted nothrow
  3214. {
  3215. if (!count)
  3216. return 0;
  3217. const size_t elementSize = element.tsize;
  3218. if (!elementSize)
  3219. return 0;
  3220. static bool hasCustomToHash(const scope TypeInfo value) @trusted pure nothrow
  3221. {
  3222. const element = getElement(value);
  3223. if (const struct_ = cast(const TypeInfo_Struct) element)
  3224. return !!struct_.xtoHash;
  3225. return cast(const TypeInfo_Array) element
  3226. || cast(const TypeInfo_AssociativeArray) element
  3227. || cast(const ClassInfo) element
  3228. || cast(const TypeInfo_Interface) element;
  3229. }
  3230. if (!hasCustomToHash(element))
  3231. return hashOf(ptr[0 .. elementSize * count]);
  3232. size_t hash = 0;
  3233. foreach (size_t i; 0 .. count)
  3234. hash = hashOf(element.getHash(ptr + i * elementSize), hash);
  3235. return hash;
  3236. }
  3237. /// Provide the .dup array property.
  3238. @property auto dup(T)(T[] a)
  3239. if (!is(const(T) : T))
  3240. {
  3241. import core.internal.traits : Unconst;
  3242. static assert(is(T : Unconst!T), "Cannot implicitly convert type "~T.stringof~
  3243. " to "~Unconst!T.stringof~" in dup.");
  3244. return _dup!(T, Unconst!T)(a);
  3245. }
  3246. ///
  3247. @safe unittest
  3248. {
  3249. auto arr = [1, 2];
  3250. auto arr2 = arr.dup;
  3251. arr[0] = 0;
  3252. assert(arr == [0, 2]);
  3253. assert(arr2 == [1, 2]);
  3254. }
  3255. /// ditto
  3256. // const overload to support implicit conversion to immutable (unique result, see DIP29)
  3257. @property T[] dup(T)(const(T)[] a)
  3258. if (is(const(T) : T))
  3259. {
  3260. return _dup!(const(T), T)(a);
  3261. }
  3262. /// Provide the .idup array property.
  3263. @property immutable(T)[] idup(T)(T[] a)
  3264. {
  3265. static assert(is(T : immutable(T)), "Cannot implicitly convert type "~T.stringof~
  3266. " to immutable in idup.");
  3267. return _dup!(T, immutable(T))(a);
  3268. }
  3269. /// ditto
  3270. @property immutable(T)[] idup(T:void)(const(T)[] a)
  3271. {
  3272. return a.dup;
  3273. }
  3274. ///
  3275. @safe unittest
  3276. {
  3277. char[] arr = ['a', 'b', 'c'];
  3278. string s = arr.idup;
  3279. arr[0] = '.';
  3280. assert(s == "abc");
  3281. }
  3282. private U[] _dup(T, U)(scope T[] a) pure nothrow @trusted if (__traits(isPOD, T))
  3283. {
  3284. if (__ctfe)
  3285. return _dupCtfe!(T, U)(a);
  3286. import core.stdc.string : memcpy;
  3287. auto arr = _d_newarrayU(typeid(T[]), a.length);
  3288. memcpy(arr.ptr, cast(const(void)*) a.ptr, T.sizeof * a.length);
  3289. return *cast(U[]*) &arr;
  3290. }
  3291. private U[] _dupCtfe(T, U)(scope T[] a)
  3292. {
  3293. static if (is(T : void))
  3294. assert(0, "Cannot dup a void[] array at compile time.");
  3295. else
  3296. {
  3297. U[] res;
  3298. foreach (ref e; a)
  3299. res ~= e;
  3300. return res;
  3301. }
  3302. }
  3303. private U[] _dup(T, U)(T[] a) if (!__traits(isPOD, T))
  3304. {
  3305. // note: copyEmplace is `@system` inside a `@trusted` block, so the __ctfe branch
  3306. // has the extra duty to infer _dup `@system` when the copy-constructor is `@system`.
  3307. if (__ctfe)
  3308. return _dupCtfe!(T, U)(a);
  3309. import core.lifetime: copyEmplace;
  3310. U[] res = () @trusted {
  3311. auto arr = cast(U*) _d_newarrayU(typeid(T[]), a.length);
  3312. size_t i;
  3313. scope (failure)
  3314. {
  3315. import core.internal.lifetime: emplaceInitializer;
  3316. // Initialize all remaining elements to not destruct garbage
  3317. foreach (j; i .. a.length)
  3318. emplaceInitializer(cast() arr[j]);
  3319. }
  3320. for (; i < a.length; i++)
  3321. {
  3322. copyEmplace(a.ptr[i], arr[i]);
  3323. }
  3324. return cast(U[])(arr[0..a.length]);
  3325. } ();
  3326. return res;
  3327. }
  3328. // https://issues.dlang.org/show_bug.cgi?id=22107
  3329. @safe unittest
  3330. {
  3331. static int i;
  3332. @safe struct S
  3333. {
  3334. this(this) { i++; }
  3335. }
  3336. void fun(scope S[] values...) @safe
  3337. {
  3338. values.dup;
  3339. }
  3340. }
  3341. // HACK: This is a lie. `_d_arraysetcapacity` is neither `nothrow` nor `pure`, but this lie is
  3342. // necessary for now to prevent breaking code.
  3343. private extern (C) size_t _d_arraysetcapacity(const TypeInfo ti, size_t newcapacity, void[]* arrptr) pure nothrow;
  3344. /**
  3345. (Property) Gets the current _capacity of a slice. The _capacity is the size
  3346. that the slice can grow to before the underlying array must be
  3347. reallocated or extended.
  3348. If an append must reallocate a slice with no possibility of extension, then
  3349. `0` is returned. This happens when the slice references a static array, or
  3350. if another slice references elements past the end of the current slice.
  3351. Note: The _capacity of a slice may be impacted by operations on other slices.
  3352. */
  3353. @property size_t capacity(T)(T[] arr) pure nothrow @trusted
  3354. {
  3355. return _d_arraysetcapacity(typeid(T[]), 0, cast(void[]*)&arr);
  3356. }
  3357. ///
  3358. @safe unittest
  3359. {
  3360. //Static array slice: no capacity
  3361. int[4] sarray = [1, 2, 3, 4];
  3362. int[] slice = sarray[];
  3363. assert(sarray.capacity == 0);
  3364. //Appending to slice will reallocate to a new array
  3365. slice ~= 5;
  3366. assert(slice.capacity >= 5);
  3367. //Dynamic array slices
  3368. int[] a = [1, 2, 3, 4];
  3369. int[] b = a[1 .. $];
  3370. int[] c = a[1 .. $ - 1];
  3371. debug(SENTINEL) {} else // non-zero capacity very much depends on the array and GC implementation
  3372. {
  3373. assert(a.capacity != 0);
  3374. assert(a.capacity == b.capacity + 1); //both a and b share the same tail
  3375. }
  3376. assert(c.capacity == 0); //an append to c must relocate c.
  3377. }
  3378. /**
  3379. Reserves capacity for a slice. The capacity is the size
  3380. that the slice can grow to before the underlying array must be
  3381. reallocated or extended.
  3382. Returns: The new capacity of the array (which may be larger than
  3383. the requested capacity).
  3384. */
  3385. size_t reserve(T)(ref T[] arr, size_t newcapacity) pure nothrow @trusted
  3386. {
  3387. if (__ctfe)
  3388. return newcapacity;
  3389. else
  3390. return _d_arraysetcapacity(typeid(T[]), newcapacity, cast(void[]*)&arr);
  3391. }
  3392. ///
  3393. @safe unittest
  3394. {
  3395. //Static array slice: no capacity. Reserve relocates.
  3396. int[4] sarray = [1, 2, 3, 4];
  3397. int[] slice = sarray[];
  3398. auto u = slice.reserve(8);
  3399. assert(u >= 8);
  3400. assert(&sarray[0] !is &slice[0]);
  3401. assert(slice.capacity == u);
  3402. //Dynamic array slices
  3403. int[] a = [1, 2, 3, 4];
  3404. a.reserve(8); //prepare a for appending 4 more items
  3405. auto p = &a[0];
  3406. u = a.capacity;
  3407. a ~= [5, 6, 7, 8];
  3408. assert(p == &a[0]); //a should not have been reallocated
  3409. assert(u == a.capacity); //a should not have been extended
  3410. }
  3411. // https://issues.dlang.org/show_bug.cgi?id=12330, reserve() at CTFE time
  3412. @safe unittest
  3413. {
  3414. int[] foo() {
  3415. int[] result;
  3416. auto a = result.reserve = 5;
  3417. assert(a == 5);
  3418. return result;
  3419. }
  3420. enum r = foo();
  3421. }
  3422. // Issue 6646: should be possible to use array.reserve from SafeD.
  3423. @safe unittest
  3424. {
  3425. int[] a;
  3426. a.reserve(10);
  3427. }
  3428. // HACK: This is a lie. `_d_arrayshrinkfit` is not `nothrow`, but this lie is necessary
  3429. // for now to prevent breaking code.
  3430. private extern (C) void _d_arrayshrinkfit(const TypeInfo ti, void[] arr) nothrow;
  3431. /**
  3432. Assume that it is safe to append to this array. Appends made to this array
  3433. after calling this function may append in place, even if the array was a
  3434. slice of a larger array to begin with.
  3435. Use this only when it is certain there are no elements in use beyond the
  3436. array in the memory block. If there are, those elements will be
  3437. overwritten by appending to this array.
  3438. Warning: Calling this function, and then using references to data located after the
  3439. given array results in undefined behavior.
  3440. Returns:
  3441. The input is returned.
  3442. */
  3443. auto ref inout(T[]) assumeSafeAppend(T)(auto ref inout(T[]) arr) nothrow @system
  3444. {
  3445. _d_arrayshrinkfit(typeid(T[]), *(cast(void[]*)&arr));
  3446. return arr;
  3447. }
  3448. ///
  3449. @system unittest
  3450. {
  3451. int[] a = [1, 2, 3, 4];
  3452. // Without assumeSafeAppend. Appending relocates.
  3453. int[] b = a [0 .. 3];
  3454. b ~= 5;
  3455. assert(a.ptr != b.ptr);
  3456. debug(SENTINEL) {} else
  3457. {
  3458. // With assumeSafeAppend. Appending overwrites.
  3459. int[] c = a [0 .. 3];
  3460. c.assumeSafeAppend() ~= 5;
  3461. assert(a.ptr == c.ptr);
  3462. }
  3463. }
  3464. @system unittest
  3465. {
  3466. int[] arr;
  3467. auto newcap = arr.reserve(2000);
  3468. assert(newcap >= 2000);
  3469. assert(newcap == arr.capacity);
  3470. auto ptr = arr.ptr;
  3471. foreach (i; 0..2000)
  3472. arr ~= i;
  3473. assert(ptr == arr.ptr);
  3474. arr = arr[0..1];
  3475. arr.assumeSafeAppend();
  3476. arr ~= 5;
  3477. assert(ptr == arr.ptr);
  3478. }
  3479. @system unittest
  3480. {
  3481. int[] arr = [1, 2, 3];
  3482. void foo(ref int[] i)
  3483. {
  3484. i ~= 5;
  3485. }
  3486. arr = arr[0 .. 2];
  3487. foo(assumeSafeAppend(arr)); //pass by ref
  3488. assert(arr[]==[1, 2, 5]);
  3489. arr = arr[0 .. 1].assumeSafeAppend(); //pass by value
  3490. }
  3491. // https://issues.dlang.org/show_bug.cgi?id=10574
  3492. @system unittest
  3493. {
  3494. int[] a;
  3495. immutable(int[]) b;
  3496. auto a2 = &assumeSafeAppend(a);
  3497. auto b2 = &assumeSafeAppend(b);
  3498. auto a3 = assumeSafeAppend(a[]);
  3499. auto b3 = assumeSafeAppend(b[]);
  3500. assert(is(typeof(*a2) == int[]));
  3501. assert(is(typeof(*b2) == immutable(int[])));
  3502. assert(is(typeof(a3) == int[]));
  3503. assert(is(typeof(b3) == immutable(int[])));
  3504. }
  3505. private extern (C) void[] _d_newarrayU(const scope TypeInfo ti, size_t length) pure nothrow;
  3506. private void _doPostblit(T)(T[] arr)
  3507. {
  3508. // infer static postblit type, run postblit if any
  3509. static if (__traits(hasPostblit, T))
  3510. {
  3511. static if (__traits(isStaticArray, T) && is(T : E[], E))
  3512. _doPostblit(cast(E[]) arr);
  3513. else static if (!is(typeof(arr[0].__xpostblit())) && is(immutable T == immutable U, U))
  3514. foreach (ref elem; (() @trusted => cast(U[]) arr)())
  3515. elem.__xpostblit();
  3516. else
  3517. foreach (ref elem; arr)
  3518. elem.__xpostblit();
  3519. }
  3520. }
  3521. @safe unittest
  3522. {
  3523. static struct S1 { int* p; }
  3524. static struct S2 { @disable this(); }
  3525. static struct S3 { @disable this(this); }
  3526. int dg1() pure nothrow @safe
  3527. {
  3528. {
  3529. char[] m;
  3530. string i;
  3531. m = m.dup;
  3532. i = i.idup;
  3533. m = i.dup;
  3534. i = m.idup;
  3535. }
  3536. {
  3537. S1[] m;
  3538. immutable(S1)[] i;
  3539. m = m.dup;
  3540. i = i.idup;
  3541. static assert(!is(typeof(m.idup)));
  3542. static assert(!is(typeof(i.dup)));
  3543. }
  3544. {
  3545. S3[] m;
  3546. immutable(S3)[] i;
  3547. static assert(!is(typeof(m.dup)));
  3548. static assert(!is(typeof(i.idup)));
  3549. }
  3550. {
  3551. shared(S1)[] m;
  3552. m = m.dup;
  3553. static assert(!is(typeof(m.idup)));
  3554. }
  3555. {
  3556. int[] a = (inout(int)) { inout(const(int))[] a; return a.dup; }(0);
  3557. }
  3558. return 1;
  3559. }
  3560. int dg2() pure nothrow @safe
  3561. {
  3562. {
  3563. S2[] m = [S2.init, S2.init];
  3564. immutable(S2)[] i = [S2.init, S2.init];
  3565. m = m.dup;
  3566. m = i.dup;
  3567. i = m.idup;
  3568. i = i.idup;
  3569. }
  3570. return 2;
  3571. }
  3572. enum a = dg1();
  3573. enum b = dg2();
  3574. assert(dg1() == a);
  3575. assert(dg2() == b);
  3576. }
  3577. @system unittest
  3578. {
  3579. static struct Sunpure { this(this) @safe nothrow {} }
  3580. static struct Sthrow { this(this) @safe pure {} }
  3581. static struct Sunsafe { this(this) @system pure nothrow {} }
  3582. static struct Snocopy { @disable this(this); }
  3583. [].dup!Sunpure;
  3584. [].dup!Sthrow;
  3585. cast(void) [].dup!Sunsafe;
  3586. static assert(!__traits(compiles, () pure { [].dup!Sunpure; }));
  3587. static assert(!__traits(compiles, () nothrow { [].dup!Sthrow; }));
  3588. static assert(!__traits(compiles, () @safe { [].dup!Sunsafe; }));
  3589. static assert(!__traits(compiles, () { [].dup!Snocopy; }));
  3590. [].idup!Sunpure;
  3591. [].idup!Sthrow;
  3592. [].idup!Sunsafe;
  3593. static assert(!__traits(compiles, () pure { [].idup!Sunpure; }));
  3594. static assert(!__traits(compiles, () nothrow { [].idup!Sthrow; }));
  3595. static assert(!__traits(compiles, () @safe { [].idup!Sunsafe; }));
  3596. static assert(!__traits(compiles, () { [].idup!Snocopy; }));
  3597. }
  3598. @safe unittest
  3599. {
  3600. // test that the copy-constructor is called with .dup
  3601. static struct ArrElem
  3602. {
  3603. int a;
  3604. this(int a)
  3605. {
  3606. this.a = a;
  3607. }
  3608. this(ref const ArrElem)
  3609. {
  3610. a = 2;
  3611. }
  3612. this(ref ArrElem) immutable
  3613. {
  3614. a = 3;
  3615. }
  3616. }
  3617. auto arr = [ArrElem(1), ArrElem(1)];
  3618. ArrElem[] b = arr.dup;
  3619. assert(b[0].a == 2 && b[1].a == 2);
  3620. immutable ArrElem[] c = arr.idup;
  3621. assert(c[0].a == 3 && c[1].a == 3);
  3622. }
  3623. @system unittest
  3624. {
  3625. static struct Sunpure { this(ref const typeof(this)) @safe nothrow {} }
  3626. static struct Sthrow { this(ref const typeof(this)) @safe pure {} }
  3627. static struct Sunsafe { this(ref const typeof(this)) @system pure nothrow {} }
  3628. [].dup!Sunpure;
  3629. [].dup!Sthrow;
  3630. cast(void) [].dup!Sunsafe;
  3631. static assert(!__traits(compiles, () pure { [].dup!Sunpure; }));
  3632. static assert(!__traits(compiles, () nothrow { [].dup!Sthrow; }));
  3633. static assert(!__traits(compiles, () @safe { [].dup!Sunsafe; }));
  3634. // for idup to work on structs that have copy constructors, it is necessary
  3635. // that the struct defines a copy constructor that creates immutable objects
  3636. static struct ISunpure { this(ref const typeof(this)) immutable @safe nothrow {} }
  3637. static struct ISthrow { this(ref const typeof(this)) immutable @safe pure {} }
  3638. static struct ISunsafe { this(ref const typeof(this)) immutable @system pure nothrow {} }
  3639. [].idup!ISunpure;
  3640. [].idup!ISthrow;
  3641. [].idup!ISunsafe;
  3642. static assert(!__traits(compiles, () pure { [].idup!ISunpure; }));
  3643. static assert(!__traits(compiles, () nothrow { [].idup!ISthrow; }));
  3644. static assert(!__traits(compiles, () @safe { [].idup!ISunsafe; }));
  3645. }
  3646. @safe unittest
  3647. {
  3648. static int*[] pureFoo() pure { return null; }
  3649. { char[] s; immutable x = s.dup; }
  3650. { immutable x = (cast(int*[])null).dup; }
  3651. { immutable x = pureFoo(); }
  3652. { immutable x = pureFoo().dup; }
  3653. }
  3654. @safe unittest
  3655. {
  3656. auto a = [1, 2, 3];
  3657. auto b = a.dup;
  3658. debug(SENTINEL) {} else
  3659. assert(b.capacity >= 3);
  3660. }
  3661. @system unittest
  3662. {
  3663. // Bugzilla 12580
  3664. void[] m = [0];
  3665. shared(void)[] s = [cast(shared)1];
  3666. immutable(void)[] i = [cast(immutable)2];
  3667. s = s.dup;
  3668. static assert(is(typeof(s.dup) == shared(void)[]));
  3669. m = i.dup;
  3670. i = m.dup;
  3671. i = i.idup;
  3672. i = m.idup;
  3673. i = s.idup;
  3674. i = s.dup;
  3675. static assert(!__traits(compiles, m = s.dup));
  3676. }
  3677. @safe unittest
  3678. {
  3679. // Bugzilla 13809
  3680. static struct S
  3681. {
  3682. this(this) {}
  3683. ~this() {}
  3684. }
  3685. S[] arr;
  3686. auto a = arr.dup;
  3687. }
  3688. @system unittest
  3689. {
  3690. // Bugzilla 16504
  3691. static struct S
  3692. {
  3693. __gshared int* gp;
  3694. int* p;
  3695. // postblit and hence .dup could escape
  3696. this(this) { gp = p; }
  3697. }
  3698. int p;
  3699. scope S[1] arr = [S(&p)];
  3700. auto a = arr.dup; // dup does escape
  3701. }
  3702. // https://issues.dlang.org/show_bug.cgi?id=21983
  3703. // dup/idup destroys partially constructed arrays on failure
  3704. @safe unittest
  3705. {
  3706. static struct SImpl(bool postblit)
  3707. {
  3708. int num;
  3709. long l = 0xDEADBEEF;
  3710. static if (postblit)
  3711. {
  3712. this(this)
  3713. {
  3714. if (this.num == 3)
  3715. throw new Exception("");
  3716. }
  3717. }
  3718. else
  3719. {
  3720. this(scope ref const SImpl other)
  3721. {
  3722. if (other.num == 3)
  3723. throw new Exception("");
  3724. this.num = other.num;
  3725. this.l = other.l;
  3726. }
  3727. }
  3728. ~this() @trusted
  3729. {
  3730. if (l != 0xDEADBEEF)
  3731. {
  3732. import core.stdc.stdio;
  3733. printf("Unexpected value: %lld\n", l);
  3734. fflush(stdout);
  3735. assert(false);
  3736. }
  3737. }
  3738. }
  3739. alias Postblit = SImpl!true;
  3740. alias Copy = SImpl!false;
  3741. static int test(S)()
  3742. {
  3743. S[4] arr = [ S(1), S(2), S(3), S(4) ];
  3744. try
  3745. {
  3746. arr.dup();
  3747. assert(false);
  3748. }
  3749. catch (Exception)
  3750. {
  3751. return 1;
  3752. }
  3753. }
  3754. static assert(test!Postblit());
  3755. assert(test!Postblit());
  3756. static assert(test!Copy());
  3757. assert(test!Copy());
  3758. }
  3759. /**
  3760. Destroys the given object and optionally resets to initial state. It's used to
  3761. _destroy an object, calling its destructor or finalizer so it no longer
  3762. references any other objects. It does $(I not) initiate a GC cycle or free
  3763. any GC memory.
  3764. If `initialize` is supplied `false`, the object is considered invalid after
  3765. destruction, and should not be referenced.
  3766. */
  3767. void destroy(bool initialize = true, T)(ref T obj) if (is(T == struct))
  3768. {
  3769. import core.internal.destruction : destructRecurse;
  3770. destructRecurse(obj);
  3771. static if (initialize)
  3772. {
  3773. import core.internal.lifetime : emplaceInitializer;
  3774. emplaceInitializer(obj); // emplace T.init
  3775. }
  3776. }
  3777. @safe unittest
  3778. {
  3779. struct A { string s = "A"; }
  3780. A a = {s: "B"};
  3781. assert(a.s == "B");
  3782. a.destroy;
  3783. assert(a.s == "A");
  3784. }
  3785. nothrow @safe @nogc unittest
  3786. {
  3787. {
  3788. struct A { string s = "A"; }
  3789. A a;
  3790. a.s = "asd";
  3791. destroy!false(a);
  3792. assert(a.s == "asd");
  3793. destroy(a);
  3794. assert(a.s == "A");
  3795. }
  3796. {
  3797. static int destroyed = 0;
  3798. struct C
  3799. {
  3800. string s = "C";
  3801. ~this() nothrow @safe @nogc
  3802. {
  3803. destroyed ++;
  3804. }
  3805. }
  3806. struct B
  3807. {
  3808. C c;
  3809. string s = "B";
  3810. ~this() nothrow @safe @nogc
  3811. {
  3812. destroyed ++;
  3813. }
  3814. }
  3815. B a;
  3816. a.s = "asd";
  3817. a.c.s = "jkl";
  3818. destroy!false(a);
  3819. assert(destroyed == 2);
  3820. assert(a.s == "asd");
  3821. assert(a.c.s == "jkl" );
  3822. destroy(a);
  3823. assert(destroyed == 4);
  3824. assert(a.s == "B");
  3825. assert(a.c.s == "C" );
  3826. }
  3827. }
  3828. private extern (C) void rt_finalize(void *data, bool det=true) nothrow;
  3829. /// ditto
  3830. void destroy(bool initialize = true, T)(T obj) if (is(T == class))
  3831. {
  3832. static if (__traits(getLinkage, T) == "C++")
  3833. {
  3834. static if (__traits(hasMember, T, "__xdtor"))
  3835. obj.__xdtor();
  3836. static if (initialize)
  3837. {
  3838. const initializer = __traits(initSymbol, T);
  3839. (cast(void*)obj)[0 .. initializer.length] = initializer[];
  3840. }
  3841. }
  3842. else
  3843. {
  3844. // Bypass overloaded opCast
  3845. auto ptr = (() @trusted => *cast(void**) &obj)();
  3846. rt_finalize(ptr);
  3847. }
  3848. }
  3849. /// ditto
  3850. void destroy(bool initialize = true, T)(T obj) if (is(T == interface))
  3851. {
  3852. static assert(__traits(getLinkage, T) == "D", "Invalid call to destroy() on extern(" ~ __traits(getLinkage, T) ~ ") interface");
  3853. destroy!initialize(cast(Object)obj);
  3854. }
  3855. /// Reference type demonstration
  3856. @system unittest
  3857. {
  3858. class C
  3859. {
  3860. struct Agg
  3861. {
  3862. static int dtorCount;
  3863. int x = 10;
  3864. ~this() { dtorCount++; }
  3865. }
  3866. static int dtorCount;
  3867. string s = "S";
  3868. Agg a;
  3869. ~this() { dtorCount++; }
  3870. }
  3871. C c = new C();
  3872. assert(c.dtorCount == 0); // destructor not yet called
  3873. assert(c.s == "S"); // initial state `c.s` is `"S"`
  3874. assert(c.a.dtorCount == 0); // destructor not yet called
  3875. assert(c.a.x == 10); // initial state `c.a.x` is `10`
  3876. c.s = "T";
  3877. c.a.x = 30;
  3878. assert(c.s == "T"); // `c.s` is `"T"`
  3879. destroy(c);
  3880. assert(c.dtorCount == 1); // `c`'s destructor was called
  3881. assert(c.s == "S"); // `c.s` is back to its inital state, `"S"`
  3882. assert(c.a.dtorCount == 1); // `c.a`'s destructor was called
  3883. assert(c.a.x == 10); // `c.a.x` is back to its inital state, `10`
  3884. // check C++ classes work too!
  3885. extern (C++) class CPP
  3886. {
  3887. struct Agg
  3888. {
  3889. __gshared int dtorCount;
  3890. int x = 10;
  3891. ~this() { dtorCount++; }
  3892. }
  3893. __gshared int dtorCount;
  3894. string s = "S";
  3895. Agg a;
  3896. ~this() { dtorCount++; }
  3897. }
  3898. CPP cpp = new CPP();
  3899. assert(cpp.dtorCount == 0); // destructor not yet called
  3900. assert(cpp.s == "S"); // initial state `cpp.s` is `"S"`
  3901. assert(cpp.a.dtorCount == 0); // destructor not yet called
  3902. assert(cpp.a.x == 10); // initial state `cpp.a.x` is `10`
  3903. cpp.s = "T";
  3904. cpp.a.x = 30;
  3905. assert(cpp.s == "T"); // `cpp.s` is `"T"`
  3906. destroy!false(cpp); // destroy without initialization
  3907. assert(cpp.dtorCount == 1); // `cpp`'s destructor was called
  3908. assert(cpp.s == "T"); // `cpp.s` is not initialized
  3909. assert(cpp.a.dtorCount == 1); // `cpp.a`'s destructor was called
  3910. assert(cpp.a.x == 30); // `cpp.a.x` is not initialized
  3911. destroy(cpp);
  3912. assert(cpp.dtorCount == 2); // `cpp`'s destructor was called again
  3913. assert(cpp.s == "S"); // `cpp.s` is back to its inital state, `"S"`
  3914. assert(cpp.a.dtorCount == 2); // `cpp.a`'s destructor was called again
  3915. assert(cpp.a.x == 10); // `cpp.a.x` is back to its inital state, `10`
  3916. }
  3917. /// Value type demonstration
  3918. @safe unittest
  3919. {
  3920. int i;
  3921. assert(i == 0); // `i`'s initial state is `0`
  3922. i = 1;
  3923. assert(i == 1); // `i` changed to `1`
  3924. destroy!false(i);
  3925. assert(i == 1); // `i` was not initialized
  3926. destroy(i);
  3927. assert(i == 0); // `i` is back to its initial state `0`
  3928. }
  3929. @system unittest
  3930. {
  3931. extern(C++)
  3932. static class C
  3933. {
  3934. void* ptr;
  3935. this() {}
  3936. }
  3937. destroy!false(new C());
  3938. destroy!true(new C());
  3939. }
  3940. @system unittest
  3941. {
  3942. // class with an `alias this`
  3943. class A
  3944. {
  3945. static int dtorCount;
  3946. ~this()
  3947. {
  3948. dtorCount++;
  3949. }
  3950. }
  3951. class B
  3952. {
  3953. A a;
  3954. alias a this;
  3955. this()
  3956. {
  3957. a = new A;
  3958. }
  3959. static int dtorCount;
  3960. ~this()
  3961. {
  3962. dtorCount++;
  3963. }
  3964. }
  3965. auto b = new B;
  3966. assert(A.dtorCount == 0);
  3967. assert(B.dtorCount == 0);
  3968. destroy(b);
  3969. assert(A.dtorCount == 0);
  3970. assert(B.dtorCount == 1);
  3971. auto a = new A;
  3972. destroy(a);
  3973. assert(A.dtorCount == 1);
  3974. }
  3975. @system unittest
  3976. {
  3977. interface I { }
  3978. {
  3979. class A: I { string s = "A"; this() {} }
  3980. auto a = new A, b = new A;
  3981. a.s = b.s = "asd";
  3982. destroy(a);
  3983. assert(a.s == "A");
  3984. I i = b;
  3985. destroy(i);
  3986. assert(b.s == "A");
  3987. }
  3988. {
  3989. static bool destroyed = false;
  3990. class B: I
  3991. {
  3992. string s = "B";
  3993. this() {}
  3994. ~this()
  3995. {
  3996. destroyed = true;
  3997. }
  3998. }
  3999. auto a = new B, b = new B;
  4000. a.s = b.s = "asd";
  4001. destroy(a);
  4002. assert(destroyed);
  4003. assert(a.s == "B");
  4004. destroyed = false;
  4005. I i = b;
  4006. destroy(i);
  4007. assert(destroyed);
  4008. assert(b.s == "B");
  4009. }
  4010. // this test is invalid now that the default ctor is not run after clearing
  4011. version (none)
  4012. {
  4013. class C
  4014. {
  4015. string s;
  4016. this()
  4017. {
  4018. s = "C";
  4019. }
  4020. }
  4021. auto a = new C;
  4022. a.s = "asd";
  4023. destroy(a);
  4024. assert(a.s == "C");
  4025. }
  4026. }
  4027. nothrow @safe @nogc unittest
  4028. {
  4029. {
  4030. struct A { string s = "A"; }
  4031. A a;
  4032. a.s = "asd";
  4033. destroy!false(a);
  4034. assert(a.s == "asd");
  4035. destroy(a);
  4036. assert(a.s == "A");
  4037. }
  4038. {
  4039. static int destroyed = 0;
  4040. struct C
  4041. {
  4042. string s = "C";
  4043. ~this() nothrow @safe @nogc
  4044. {
  4045. destroyed ++;
  4046. }
  4047. }
  4048. struct B
  4049. {
  4050. C c;
  4051. string s = "B";
  4052. ~this() nothrow @safe @nogc
  4053. {
  4054. destroyed ++;
  4055. }
  4056. }
  4057. B a;
  4058. a.s = "asd";
  4059. a.c.s = "jkl";
  4060. destroy!false(a);
  4061. assert(destroyed == 2);
  4062. assert(a.s == "asd");
  4063. assert(a.c.s == "jkl" );
  4064. destroy(a);
  4065. assert(destroyed == 4);
  4066. assert(a.s == "B");
  4067. assert(a.c.s == "C" );
  4068. }
  4069. }
  4070. nothrow unittest
  4071. {
  4072. // Bugzilla 20049: Test to ensure proper behavior of `nothrow` destructors
  4073. class C
  4074. {
  4075. static int dtorCount = 0;
  4076. this() nothrow {}
  4077. ~this() nothrow { dtorCount++; }
  4078. }
  4079. auto c = new C;
  4080. destroy(c);
  4081. assert(C.dtorCount == 1);
  4082. }
  4083. // https://issues.dlang.org/show_bug.cgi?id=22832
  4084. nothrow unittest
  4085. {
  4086. static struct A {}
  4087. static class B
  4088. {
  4089. A opCast(T : A)() { return A(); }
  4090. }
  4091. destroy(B.init);
  4092. }
  4093. /// ditto
  4094. void destroy(bool initialize = true, T)(ref T obj)
  4095. if (__traits(isStaticArray, T))
  4096. {
  4097. foreach_reverse (ref e; obj[])
  4098. destroy!initialize(e);
  4099. }
  4100. @safe unittest
  4101. {
  4102. int[2] a;
  4103. a[0] = 1;
  4104. a[1] = 2;
  4105. destroy!false(a);
  4106. assert(a == [ 1, 2 ]);
  4107. destroy(a);
  4108. assert(a == [ 0, 0 ]);
  4109. }
  4110. @safe unittest
  4111. {
  4112. static struct vec2f {
  4113. float[2] values;
  4114. alias values this;
  4115. }
  4116. vec2f v;
  4117. destroy!(true, vec2f)(v);
  4118. }
  4119. @system unittest
  4120. {
  4121. // Bugzilla 15009
  4122. static string op;
  4123. static struct S
  4124. {
  4125. int x;
  4126. this(int x) { op ~= "C" ~ cast(char)('0'+x); this.x = x; }
  4127. this(this) { op ~= "P" ~ cast(char)('0'+x); }
  4128. ~this() { op ~= "D" ~ cast(char)('0'+x); }
  4129. }
  4130. {
  4131. S[2] a1 = [S(1), S(2)];
  4132. op = "";
  4133. }
  4134. assert(op == "D2D1"); // built-in scope destruction
  4135. {
  4136. S[2] a1 = [S(1), S(2)];
  4137. op = "";
  4138. destroy(a1);
  4139. assert(op == "D2D1"); // consistent with built-in behavior
  4140. }
  4141. {
  4142. S[2][2] a2 = [[S(1), S(2)], [S(3), S(4)]];
  4143. op = "";
  4144. }
  4145. assert(op == "D4D3D2D1");
  4146. {
  4147. S[2][2] a2 = [[S(1), S(2)], [S(3), S(4)]];
  4148. op = "";
  4149. destroy(a2);
  4150. assert(op == "D4D3D2D1", op);
  4151. }
  4152. }
  4153. // https://issues.dlang.org/show_bug.cgi?id=19218
  4154. @system unittest
  4155. {
  4156. static struct S
  4157. {
  4158. static dtorCount = 0;
  4159. ~this() { ++dtorCount; }
  4160. }
  4161. static interface I
  4162. {
  4163. ref S[3] getArray();
  4164. alias getArray this;
  4165. }
  4166. static class C : I
  4167. {
  4168. static dtorCount = 0;
  4169. ~this() { ++dtorCount; }
  4170. S[3] a;
  4171. alias a this;
  4172. ref S[3] getArray() { return a; }
  4173. }
  4174. C c = new C();
  4175. destroy(c);
  4176. assert(S.dtorCount == 3);
  4177. assert(C.dtorCount == 1);
  4178. I i = new C();
  4179. destroy(i);
  4180. assert(S.dtorCount == 6);
  4181. assert(C.dtorCount == 2);
  4182. }
  4183. /// ditto
  4184. void destroy(bool initialize = true, T)(ref T obj)
  4185. if (!is(T == struct) && !is(T == interface) && !is(T == class) && !__traits(isStaticArray, T))
  4186. {
  4187. static if (initialize)
  4188. obj = T.init;
  4189. }
  4190. @safe unittest
  4191. {
  4192. {
  4193. int a = 42;
  4194. destroy!false(a);
  4195. assert(a == 42);
  4196. destroy(a);
  4197. assert(a == 0);
  4198. }
  4199. {
  4200. float a = 42;
  4201. destroy!false(a);
  4202. assert(a == 42);
  4203. destroy(a);
  4204. assert(a != a); // isnan
  4205. }
  4206. }
  4207. @safe unittest
  4208. {
  4209. // Bugzilla 14746
  4210. static struct HasDtor
  4211. {
  4212. ~this() { assert(0); }
  4213. }
  4214. static struct Owner
  4215. {
  4216. HasDtor* ptr;
  4217. alias ptr this;
  4218. }
  4219. Owner o;
  4220. assert(o.ptr is null);
  4221. destroy(o); // must not reach in HasDtor.__dtor()
  4222. }
  4223. /* ************************************************************************
  4224. COMPILER SUPPORT
  4225. The compiler lowers certain expressions to instantiations of the following
  4226. templates. They must be implicitly imported, which is why they are here
  4227. in this file. They must also be `public` as they must be visible from the
  4228. scope in which they are instantiated. They are explicitly undocumented as
  4229. they are only intended to be instantiated by the compiler, not the user.
  4230. **************************************************************************/
  4231. public import core.internal.entrypoint : _d_cmain;
  4232. public import core.internal.array.appending : _d_arrayappendTImpl;
  4233. public import core.internal.array.appending : _d_arrayappendcTXImpl;
  4234. public import core.internal.array.comparison : __cmp;
  4235. public import core.internal.array.equality : __equals;
  4236. public import core.internal.array.casting: __ArrayCast;
  4237. public import core.internal.array.concatenation : _d_arraycatnTXImpl;
  4238. public import core.internal.array.construction : _d_arrayctor;
  4239. public import core.internal.array.construction : _d_arraysetctor;
  4240. public import core.internal.array.capacity: _d_arraysetlengthTImpl;
  4241. public import core.internal.dassert: _d_assert_fail;
  4242. public import core.internal.destruction: __ArrayDtor;
  4243. public import core.internal.moving: __move_post_blt;
  4244. public import core.internal.postblit: __ArrayPostblit;
  4245. public import core.internal.switch_: __switch;
  4246. public import core.internal.switch_: __switch_error;
  4247. public import core.lifetime : _d_delstructImpl;
  4248. public import core.lifetime : _d_newThrowable;
  4249. public @trusted @nogc nothrow pure extern (C) void _d_delThrowable(scope Throwable);
  4250. // Compare class and interface objects for ordering.
  4251. int __cmp(C1, C2)(C1 lhs, C2 rhs)
  4252. if ((is(C1 : const(Object)) || (is(C1 == interface) && (__traits(getLinkage, C1) == "D"))) &&
  4253. (is(C2 : const(Object)) || (is(C2 == interface) && (__traits(getLinkage, C2) == "D"))))
  4254. {
  4255. static if (is(C1 == typeof(null)) && is(C2 == typeof(null)))
  4256. {
  4257. return 0;
  4258. }
  4259. else static if (is(C1 == typeof(null)))
  4260. {
  4261. // Regard null references as always being "less than"
  4262. return -1;
  4263. }
  4264. else static if (is(C2 == typeof(null)))
  4265. {
  4266. return 1;
  4267. }
  4268. else
  4269. {
  4270. if (lhs is rhs)
  4271. return 0;
  4272. if (lhs is null)
  4273. return -1;
  4274. if (rhs is null)
  4275. return 1;
  4276. return lhs.opCmp(rhs);
  4277. }
  4278. }
  4279. // objects
  4280. @safe unittest
  4281. {
  4282. class C
  4283. {
  4284. int i;
  4285. this(int i) { this.i = i; }
  4286. override int opCmp(Object c) const @safe
  4287. {
  4288. return i - (cast(C)c).i;
  4289. }
  4290. }
  4291. auto c1 = new C(1);
  4292. auto c2 = new C(2);
  4293. assert(__cmp(c1, null) > 0);
  4294. assert(__cmp(null, c1) < 0);
  4295. assert(__cmp(c1, c1) == 0);
  4296. assert(__cmp(c1, c2) < 0);
  4297. assert(__cmp(c2, c1) > 0);
  4298. assert(__cmp([c1, c1][], [c2, c2][]) < 0);
  4299. assert(__cmp([c2, c2], [c1, c1]) > 0);
  4300. }
  4301. // structs
  4302. @safe unittest
  4303. {
  4304. struct C
  4305. {
  4306. ubyte i;
  4307. this(ubyte i) { this.i = i; }
  4308. }
  4309. auto c1 = C(1);
  4310. auto c2 = C(2);
  4311. assert(__cmp([c1, c1][], [c2, c2][]) < 0);
  4312. assert(__cmp([c2, c2], [c1, c1]) > 0);
  4313. assert(__cmp([c2, c2], [c2, c1]) > 0);
  4314. }
  4315. @safe unittest
  4316. {
  4317. auto a = "hello"c;
  4318. assert(a > "hel");
  4319. assert(a >= "hel");
  4320. assert(a < "helloo");
  4321. assert(a <= "helloo");
  4322. assert(a > "betty");
  4323. assert(a >= "betty");
  4324. assert(a == "hello");
  4325. assert(a <= "hello");
  4326. assert(a >= "hello");
  4327. assert(a < "я");
  4328. }
  4329. // Used in Exception Handling LSDA tables to 'wrap' C++ type info
  4330. // so it can be distinguished from D TypeInfo
  4331. class __cpp_type_info_ptr
  4332. {
  4333. void* ptr; // opaque pointer to C++ RTTI type info
  4334. }
  4335. // Compiler hook into the runtime implementation of array (vector) operations.
  4336. template _arrayOp(Args...)
  4337. {
  4338. import core.internal.array.operations;
  4339. alias _arrayOp = arrayOp!Args;
  4340. }
  4341. public import core.builtins : __ctfeWrite;
  4342. /**
  4343. Provides an "inline import", i.e. an `import` that is only available for a
  4344. limited lookup. For example:
  4345. ---
  4346. void fun(imported!"std.stdio".File input)
  4347. {
  4348. ... use File from std.stdio normally ...
  4349. }
  4350. ---
  4351. There is no need to import `std.stdio` at top level, so `fun` carries its own
  4352. dependencies. The same approach can be used for template constraints:
  4353. ---
  4354. void fun(T)(imported!"std.stdio".File input, T value)
  4355. if (imported!"std.traits".isIntegral!T)
  4356. {
  4357. ...
  4358. }
  4359. ---
  4360. An inline import may be used in conjunction with the `with` statement as well.
  4361. Inside the scope controlled by `with`, all symbols in the imported module are
  4362. made available:
  4363. ---
  4364. void fun()
  4365. {
  4366. with (imported!"std.datetime")
  4367. with (imported!"std.stdio")
  4368. {
  4369. Clock.currTime.writeln;
  4370. }
  4371. }
  4372. ---
  4373. The advantages of inline imports over top-level uses of the `import` declaration
  4374. are the following:
  4375. $(UL
  4376. $(LI The `imported` template specifies dependencies at declaration level, not at
  4377. module level. This allows reasoning about the dependency cost of declarations in
  4378. separation instead of aggregated at module level.)
  4379. $(LI Declarations using `imported` are easier to move around because they don't
  4380. require top-level context, making for simpler and quicker refactorings.)
  4381. $(LI Declarations using `imported` scale better with templates. This is because
  4382. templates that are not instantiated do not have their parameters and constraints
  4383. instantiated, so additional modules are not imported without necessity. This
  4384. makes the cost of unused templates negligible. Dependencies are pulled on a need
  4385. basis depending on the declarations used by client code.)
  4386. )
  4387. The use of `imported` also has drawbacks:
  4388. $(UL
  4389. $(LI If most declarations in a module need the same imports, then factoring them
  4390. at top level, outside the declarations, is simpler than repeating them.)
  4391. $(LI Traditional dependency-tracking tools such as make and other build systems
  4392. assume file-level dependencies and need special tooling (such as rdmd) in order
  4393. to work efficiently.)
  4394. $(LI Dependencies at the top of a module are easier to inspect quickly than
  4395. dependencies spread throughout the module.)
  4396. )
  4397. See_Also: The $(HTTP forum.dlang.org/post/tzqzmqhankrkbrfsrmbo@forum.dlang.org,
  4398. forum discussion) that led to the creation of the `imported` facility. Credit is
  4399. due to Daniel Nielsen and Dominikus Dittes Scherkl.
  4400. */
  4401. template imported(string moduleName)
  4402. {
  4403. mixin("import imported = " ~ moduleName ~ ";");
  4404. }