doctest.h 316 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138
  1. // ====================================================================== lgtm [cpp/missing-header-guard]
  2. // == DO NOT MODIFY THIS FILE BY HAND - IT IS AUTO GENERATED BY CMAKE! ==
  3. // ======================================================================
  4. //
  5. // doctest.h - the lightest feature-rich C++ single-header testing framework for unit tests and TDD
  6. //
  7. // Copyright (c) 2016-2023 Viktor Kirilov
  8. //
  9. // Distributed under the MIT Software License
  10. // See accompanying file LICENSE.txt or copy at
  11. // https://opensource.org/licenses/MIT
  12. //
  13. // The documentation can be found at the library's page:
  14. // https://github.com/doctest/doctest/blob/master/doc/markdown/readme.md
  15. //
  16. // =================================================================================================
  17. // =================================================================================================
  18. // =================================================================================================
  19. //
  20. // The library is heavily influenced by Catch - https://github.com/catchorg/Catch2
  21. // which uses the Boost Software License - Version 1.0
  22. // see here - https://github.com/catchorg/Catch2/blob/master/LICENSE.txt
  23. //
  24. // The concept of subcases (sections in Catch) and expression decomposition are from there.
  25. // Some parts of the code are taken directly:
  26. // - stringification - the detection of "ostream& operator<<(ostream&, const T&)" and StringMaker<>
  27. // - the Approx() helper class for floating point comparison
  28. // - colors in the console
  29. // - breaking into a debugger
  30. // - signal / SEH handling
  31. // - timer
  32. // - XmlWriter class - thanks to Phil Nash for allowing the direct reuse (AKA copy/paste)
  33. //
  34. // The expression decomposing templates are taken from lest - https://github.com/martinmoene/lest
  35. // which uses the Boost Software License - Version 1.0
  36. // see here - https://github.com/martinmoene/lest/blob/master/LICENSE.txt
  37. //
  38. // =================================================================================================
  39. // =================================================================================================
  40. // =================================================================================================
  41. #ifndef DOCTEST_LIBRARY_INCLUDED
  42. #define DOCTEST_LIBRARY_INCLUDED
  43. // =================================================================================================
  44. // == VERSION ======================================================================================
  45. // =================================================================================================
  46. #define DOCTEST_VERSION_MAJOR 2
  47. #define DOCTEST_VERSION_MINOR 4
  48. #define DOCTEST_VERSION_PATCH 12
  49. // util we need here
  50. #define DOCTEST_TOSTR_IMPL(x) #x
  51. #define DOCTEST_TOSTR(x) DOCTEST_TOSTR_IMPL(x)
  52. #define DOCTEST_VERSION_STR \
  53. DOCTEST_TOSTR(DOCTEST_VERSION_MAJOR) "." \
  54. DOCTEST_TOSTR(DOCTEST_VERSION_MINOR) "." \
  55. DOCTEST_TOSTR(DOCTEST_VERSION_PATCH)
  56. #define DOCTEST_VERSION \
  57. (DOCTEST_VERSION_MAJOR * 10000 + DOCTEST_VERSION_MINOR * 100 + DOCTEST_VERSION_PATCH)
  58. // =================================================================================================
  59. // == COMPILER VERSION =============================================================================
  60. // =================================================================================================
  61. // ideas for the version stuff are taken from here: https://github.com/cxxstuff/cxx_detect
  62. #ifdef _MSC_VER
  63. #define DOCTEST_CPLUSPLUS _MSVC_LANG
  64. #else
  65. #define DOCTEST_CPLUSPLUS __cplusplus
  66. #endif
  67. #define DOCTEST_COMPILER(MAJOR, MINOR, PATCH) ((MAJOR)*10000000 + (MINOR)*100000 + (PATCH))
  68. // GCC/Clang and GCC/MSVC are mutually exclusive, but Clang/MSVC are not because of clang-cl...
  69. #if defined(_MSC_VER) && defined(_MSC_FULL_VER)
  70. #if _MSC_VER == _MSC_FULL_VER / 10000
  71. #define DOCTEST_MSVC DOCTEST_COMPILER(_MSC_VER / 100, _MSC_VER % 100, _MSC_FULL_VER % 10000)
  72. #else // MSVC
  73. #define DOCTEST_MSVC \
  74. DOCTEST_COMPILER(_MSC_VER / 100, (_MSC_FULL_VER / 100000) % 100, _MSC_FULL_VER % 100000)
  75. #endif // MSVC
  76. #endif // MSVC
  77. #if defined(__clang__) && defined(__clang_minor__) && defined(__clang_patchlevel__)
  78. #define DOCTEST_CLANG DOCTEST_COMPILER(__clang_major__, __clang_minor__, __clang_patchlevel__)
  79. #elif defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) && \
  80. !defined(__INTEL_COMPILER)
  81. #define DOCTEST_GCC DOCTEST_COMPILER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
  82. #endif // GCC
  83. #if defined(__INTEL_COMPILER)
  84. #define DOCTEST_ICC DOCTEST_COMPILER(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0)
  85. #endif // ICC
  86. #ifndef DOCTEST_MSVC
  87. #define DOCTEST_MSVC 0
  88. #endif // DOCTEST_MSVC
  89. #ifndef DOCTEST_CLANG
  90. #define DOCTEST_CLANG 0
  91. #endif // DOCTEST_CLANG
  92. #ifndef DOCTEST_GCC
  93. #define DOCTEST_GCC 0
  94. #endif // DOCTEST_GCC
  95. #ifndef DOCTEST_ICC
  96. #define DOCTEST_ICC 0
  97. #endif // DOCTEST_ICC
  98. // =================================================================================================
  99. // == COMPILER WARNINGS HELPERS ====================================================================
  100. // =================================================================================================
  101. #if DOCTEST_CLANG && !DOCTEST_ICC
  102. #define DOCTEST_PRAGMA_TO_STR(x) _Pragma(#x)
  103. #define DOCTEST_CLANG_SUPPRESS_WARNING_PUSH _Pragma("clang diagnostic push")
  104. #define DOCTEST_CLANG_SUPPRESS_WARNING(w) DOCTEST_PRAGMA_TO_STR(clang diagnostic ignored w)
  105. #define DOCTEST_CLANG_SUPPRESS_WARNING_POP _Pragma("clang diagnostic pop")
  106. #define DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH(w) \
  107. DOCTEST_CLANG_SUPPRESS_WARNING_PUSH DOCTEST_CLANG_SUPPRESS_WARNING(w)
  108. #else // DOCTEST_CLANG
  109. #define DOCTEST_CLANG_SUPPRESS_WARNING_PUSH
  110. #define DOCTEST_CLANG_SUPPRESS_WARNING(w)
  111. #define DOCTEST_CLANG_SUPPRESS_WARNING_POP
  112. #define DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH(w)
  113. #endif // DOCTEST_CLANG
  114. #if DOCTEST_GCC
  115. #define DOCTEST_PRAGMA_TO_STR(x) _Pragma(#x)
  116. #define DOCTEST_GCC_SUPPRESS_WARNING_PUSH _Pragma("GCC diagnostic push")
  117. #define DOCTEST_GCC_SUPPRESS_WARNING(w) DOCTEST_PRAGMA_TO_STR(GCC diagnostic ignored w)
  118. #define DOCTEST_GCC_SUPPRESS_WARNING_POP _Pragma("GCC diagnostic pop")
  119. #define DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH(w) \
  120. DOCTEST_GCC_SUPPRESS_WARNING_PUSH DOCTEST_GCC_SUPPRESS_WARNING(w)
  121. #else // DOCTEST_GCC
  122. #define DOCTEST_GCC_SUPPRESS_WARNING_PUSH
  123. #define DOCTEST_GCC_SUPPRESS_WARNING(w)
  124. #define DOCTEST_GCC_SUPPRESS_WARNING_POP
  125. #define DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH(w)
  126. #endif // DOCTEST_GCC
  127. #if DOCTEST_MSVC
  128. #define DOCTEST_MSVC_SUPPRESS_WARNING_PUSH __pragma(warning(push))
  129. #define DOCTEST_MSVC_SUPPRESS_WARNING(w) __pragma(warning(disable : w))
  130. #define DOCTEST_MSVC_SUPPRESS_WARNING_POP __pragma(warning(pop))
  131. #define DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(w) \
  132. DOCTEST_MSVC_SUPPRESS_WARNING_PUSH DOCTEST_MSVC_SUPPRESS_WARNING(w)
  133. #else // DOCTEST_MSVC
  134. #define DOCTEST_MSVC_SUPPRESS_WARNING_PUSH
  135. #define DOCTEST_MSVC_SUPPRESS_WARNING(w)
  136. #define DOCTEST_MSVC_SUPPRESS_WARNING_POP
  137. #define DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(w)
  138. #endif // DOCTEST_MSVC
  139. // =================================================================================================
  140. // == COMPILER WARNINGS ============================================================================
  141. // =================================================================================================
  142. // both the header and the implementation suppress all of these,
  143. // so it only makes sense to aggregate them like so
  144. #define DOCTEST_SUPPRESS_COMMON_WARNINGS_PUSH \
  145. DOCTEST_CLANG_SUPPRESS_WARNING_PUSH \
  146. DOCTEST_CLANG_SUPPRESS_WARNING("-Wunknown-pragmas") \
  147. DOCTEST_CLANG_SUPPRESS_WARNING("-Wweak-vtables") \
  148. DOCTEST_CLANG_SUPPRESS_WARNING("-Wpadded") \
  149. DOCTEST_CLANG_SUPPRESS_WARNING("-Wmissing-prototypes") \
  150. DOCTEST_CLANG_SUPPRESS_WARNING("-Wc++98-compat") \
  151. DOCTEST_CLANG_SUPPRESS_WARNING("-Wc++98-compat-pedantic") \
  152. \
  153. DOCTEST_GCC_SUPPRESS_WARNING_PUSH \
  154. DOCTEST_GCC_SUPPRESS_WARNING("-Wunknown-pragmas") \
  155. DOCTEST_GCC_SUPPRESS_WARNING("-Wpragmas") \
  156. DOCTEST_GCC_SUPPRESS_WARNING("-Weffc++") \
  157. DOCTEST_GCC_SUPPRESS_WARNING("-Wstrict-overflow") \
  158. DOCTEST_GCC_SUPPRESS_WARNING("-Wstrict-aliasing") \
  159. DOCTEST_GCC_SUPPRESS_WARNING("-Wmissing-declarations") \
  160. DOCTEST_GCC_SUPPRESS_WARNING("-Wuseless-cast") \
  161. DOCTEST_GCC_SUPPRESS_WARNING("-Wnoexcept") \
  162. \
  163. DOCTEST_MSVC_SUPPRESS_WARNING_PUSH \
  164. /* these 4 also disabled globally via cmake: */ \
  165. DOCTEST_MSVC_SUPPRESS_WARNING(4514) /* unreferenced inline function has been removed */ \
  166. DOCTEST_MSVC_SUPPRESS_WARNING(4571) /* SEH related */ \
  167. DOCTEST_MSVC_SUPPRESS_WARNING(4710) /* function not inlined */ \
  168. DOCTEST_MSVC_SUPPRESS_WARNING(4711) /* function selected for inline expansion*/ \
  169. /* common ones */ \
  170. DOCTEST_MSVC_SUPPRESS_WARNING(4616) /* invalid compiler warning */ \
  171. DOCTEST_MSVC_SUPPRESS_WARNING(4619) /* invalid compiler warning */ \
  172. DOCTEST_MSVC_SUPPRESS_WARNING(4996) /* The compiler encountered a deprecated declaration */ \
  173. DOCTEST_MSVC_SUPPRESS_WARNING(4706) /* assignment within conditional expression */ \
  174. DOCTEST_MSVC_SUPPRESS_WARNING(4512) /* 'class' : assignment operator could not be generated */ \
  175. DOCTEST_MSVC_SUPPRESS_WARNING(4127) /* conditional expression is constant */ \
  176. DOCTEST_MSVC_SUPPRESS_WARNING(4820) /* padding */ \
  177. DOCTEST_MSVC_SUPPRESS_WARNING(4625) /* copy constructor was implicitly deleted */ \
  178. DOCTEST_MSVC_SUPPRESS_WARNING(4626) /* assignment operator was implicitly deleted */ \
  179. DOCTEST_MSVC_SUPPRESS_WARNING(5027) /* move assignment operator implicitly deleted */ \
  180. DOCTEST_MSVC_SUPPRESS_WARNING(5026) /* move constructor was implicitly deleted */ \
  181. DOCTEST_MSVC_SUPPRESS_WARNING(4640) /* construction of local static object not thread-safe */ \
  182. DOCTEST_MSVC_SUPPRESS_WARNING(5045) /* Spectre mitigation for memory load */ \
  183. DOCTEST_MSVC_SUPPRESS_WARNING(5264) /* 'variable-name': 'const' variable is not used */ \
  184. /* static analysis */ \
  185. DOCTEST_MSVC_SUPPRESS_WARNING(26439) /* Function may not throw. Declare it 'noexcept' */ \
  186. DOCTEST_MSVC_SUPPRESS_WARNING(26495) /* Always initialize a member variable */ \
  187. DOCTEST_MSVC_SUPPRESS_WARNING(26451) /* Arithmetic overflow ... */ \
  188. DOCTEST_MSVC_SUPPRESS_WARNING(26444) /* Avoid unnamed objects with custom ctor and dtor... */ \
  189. DOCTEST_MSVC_SUPPRESS_WARNING(26812) /* Prefer 'enum class' over 'enum' */
  190. #define DOCTEST_SUPPRESS_COMMON_WARNINGS_POP \
  191. DOCTEST_CLANG_SUPPRESS_WARNING_POP \
  192. DOCTEST_GCC_SUPPRESS_WARNING_POP \
  193. DOCTEST_MSVC_SUPPRESS_WARNING_POP
  194. DOCTEST_SUPPRESS_COMMON_WARNINGS_PUSH
  195. DOCTEST_CLANG_SUPPRESS_WARNING_PUSH
  196. DOCTEST_CLANG_SUPPRESS_WARNING("-Wnon-virtual-dtor")
  197. DOCTEST_CLANG_SUPPRESS_WARNING("-Wdeprecated")
  198. DOCTEST_GCC_SUPPRESS_WARNING_PUSH
  199. DOCTEST_GCC_SUPPRESS_WARNING("-Wctor-dtor-privacy")
  200. DOCTEST_GCC_SUPPRESS_WARNING("-Wnon-virtual-dtor")
  201. DOCTEST_GCC_SUPPRESS_WARNING("-Wsign-promo")
  202. DOCTEST_MSVC_SUPPRESS_WARNING_PUSH
  203. DOCTEST_MSVC_SUPPRESS_WARNING(4623) // default constructor was implicitly defined as deleted
  204. #define DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_BEGIN \
  205. DOCTEST_MSVC_SUPPRESS_WARNING_PUSH \
  206. DOCTEST_MSVC_SUPPRESS_WARNING(4548) /* before comma no effect; expected side - effect */ \
  207. DOCTEST_MSVC_SUPPRESS_WARNING(4265) /* virtual functions, but destructor is not virtual */ \
  208. DOCTEST_MSVC_SUPPRESS_WARNING(4986) /* exception specification does not match previous */ \
  209. DOCTEST_MSVC_SUPPRESS_WARNING(4350) /* 'member1' called instead of 'member2' */ \
  210. DOCTEST_MSVC_SUPPRESS_WARNING(4668) /* not defined as a preprocessor macro */ \
  211. DOCTEST_MSVC_SUPPRESS_WARNING(4365) /* signed/unsigned mismatch */ \
  212. DOCTEST_MSVC_SUPPRESS_WARNING(4774) /* format string not a string literal */ \
  213. DOCTEST_MSVC_SUPPRESS_WARNING(4820) /* padding */ \
  214. DOCTEST_MSVC_SUPPRESS_WARNING(4625) /* copy constructor was implicitly deleted */ \
  215. DOCTEST_MSVC_SUPPRESS_WARNING(4626) /* assignment operator was implicitly deleted */ \
  216. DOCTEST_MSVC_SUPPRESS_WARNING(5027) /* move assignment operator implicitly deleted */ \
  217. DOCTEST_MSVC_SUPPRESS_WARNING(5026) /* move constructor was implicitly deleted */ \
  218. DOCTEST_MSVC_SUPPRESS_WARNING(4623) /* default constructor was implicitly deleted */ \
  219. DOCTEST_MSVC_SUPPRESS_WARNING(5039) /* pointer to pot. throwing function passed to extern C */ \
  220. DOCTEST_MSVC_SUPPRESS_WARNING(5045) /* Spectre mitigation for memory load */ \
  221. DOCTEST_MSVC_SUPPRESS_WARNING(5105) /* macro producing 'defined' has undefined behavior */ \
  222. DOCTEST_MSVC_SUPPRESS_WARNING(4738) /* storing float result in memory, loss of performance */ \
  223. DOCTEST_MSVC_SUPPRESS_WARNING(5262) /* implicit fall-through */
  224. #define DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_END DOCTEST_MSVC_SUPPRESS_WARNING_POP
  225. // =================================================================================================
  226. // == FEATURE DETECTION ============================================================================
  227. // =================================================================================================
  228. // general compiler feature support table: https://en.cppreference.com/w/cpp/compiler_support
  229. // MSVC C++11 feature support table: https://msdn.microsoft.com/en-us/library/hh567368.aspx
  230. // GCC C++11 feature support table: https://gcc.gnu.org/projects/cxx-status.html
  231. // MSVC version table:
  232. // https://en.wikipedia.org/wiki/Microsoft_Visual_C%2B%2B#Internal_version_numbering
  233. // MSVC++ 14.3 (17) _MSC_VER == 1930 (Visual Studio 2022)
  234. // MSVC++ 14.2 (16) _MSC_VER == 1920 (Visual Studio 2019)
  235. // MSVC++ 14.1 (15) _MSC_VER == 1910 (Visual Studio 2017)
  236. // MSVC++ 14.0 _MSC_VER == 1900 (Visual Studio 2015)
  237. // MSVC++ 12.0 _MSC_VER == 1800 (Visual Studio 2013)
  238. // MSVC++ 11.0 _MSC_VER == 1700 (Visual Studio 2012)
  239. // MSVC++ 10.0 _MSC_VER == 1600 (Visual Studio 2010)
  240. // MSVC++ 9.0 _MSC_VER == 1500 (Visual Studio 2008)
  241. // MSVC++ 8.0 _MSC_VER == 1400 (Visual Studio 2005)
  242. // Universal Windows Platform support
  243. #if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
  244. #define DOCTEST_CONFIG_NO_WINDOWS_SEH
  245. #endif // WINAPI_FAMILY
  246. #if DOCTEST_MSVC && !defined(DOCTEST_CONFIG_WINDOWS_SEH)
  247. #define DOCTEST_CONFIG_WINDOWS_SEH
  248. #endif // MSVC
  249. #if defined(DOCTEST_CONFIG_NO_WINDOWS_SEH) && defined(DOCTEST_CONFIG_WINDOWS_SEH)
  250. #undef DOCTEST_CONFIG_WINDOWS_SEH
  251. #endif // DOCTEST_CONFIG_NO_WINDOWS_SEH
  252. #if !defined(_WIN32) && !defined(__QNX__) && !defined(DOCTEST_CONFIG_POSIX_SIGNALS) && \
  253. !defined(__EMSCRIPTEN__) && !defined(__wasi__)
  254. #define DOCTEST_CONFIG_POSIX_SIGNALS
  255. #endif // _WIN32
  256. #if defined(DOCTEST_CONFIG_NO_POSIX_SIGNALS) && defined(DOCTEST_CONFIG_POSIX_SIGNALS)
  257. #undef DOCTEST_CONFIG_POSIX_SIGNALS
  258. #endif // DOCTEST_CONFIG_NO_POSIX_SIGNALS
  259. #ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
  260. #if !defined(__cpp_exceptions) && !defined(__EXCEPTIONS) && !defined(_CPPUNWIND) \
  261. || defined(__wasi__)
  262. #define DOCTEST_CONFIG_NO_EXCEPTIONS
  263. #endif // no exceptions
  264. #endif // DOCTEST_CONFIG_NO_EXCEPTIONS
  265. #ifdef DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS
  266. #ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
  267. #define DOCTEST_CONFIG_NO_EXCEPTIONS
  268. #endif // DOCTEST_CONFIG_NO_EXCEPTIONS
  269. #endif // DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS
  270. #if defined(DOCTEST_CONFIG_NO_EXCEPTIONS) && !defined(DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS)
  271. #define DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS
  272. #endif // DOCTEST_CONFIG_NO_EXCEPTIONS && !DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS
  273. #ifdef __wasi__
  274. #define DOCTEST_CONFIG_NO_MULTITHREADING
  275. #endif
  276. #if defined(DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN) && !defined(DOCTEST_CONFIG_IMPLEMENT)
  277. #define DOCTEST_CONFIG_IMPLEMENT
  278. #endif // DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
  279. #if defined(_WIN32) || defined(__CYGWIN__)
  280. #if DOCTEST_MSVC
  281. #define DOCTEST_SYMBOL_EXPORT __declspec(dllexport)
  282. #define DOCTEST_SYMBOL_IMPORT __declspec(dllimport)
  283. #else // MSVC
  284. #define DOCTEST_SYMBOL_EXPORT __attribute__((dllexport))
  285. #define DOCTEST_SYMBOL_IMPORT __attribute__((dllimport))
  286. #endif // MSVC
  287. #else // _WIN32
  288. #define DOCTEST_SYMBOL_EXPORT __attribute__((visibility("default")))
  289. #define DOCTEST_SYMBOL_IMPORT
  290. #endif // _WIN32
  291. #ifdef DOCTEST_CONFIG_IMPLEMENTATION_IN_DLL
  292. #ifdef DOCTEST_CONFIG_IMPLEMENT
  293. #define DOCTEST_INTERFACE DOCTEST_SYMBOL_EXPORT
  294. #else // DOCTEST_CONFIG_IMPLEMENT
  295. #define DOCTEST_INTERFACE DOCTEST_SYMBOL_IMPORT
  296. #endif // DOCTEST_CONFIG_IMPLEMENT
  297. #else // DOCTEST_CONFIG_IMPLEMENTATION_IN_DLL
  298. #define DOCTEST_INTERFACE
  299. #endif // DOCTEST_CONFIG_IMPLEMENTATION_IN_DLL
  300. // needed for extern template instantiations
  301. // see https://github.com/fmtlib/fmt/issues/2228
  302. #if DOCTEST_MSVC
  303. #define DOCTEST_INTERFACE_DECL
  304. #define DOCTEST_INTERFACE_DEF DOCTEST_INTERFACE
  305. #else // DOCTEST_MSVC
  306. #define DOCTEST_INTERFACE_DECL DOCTEST_INTERFACE
  307. #define DOCTEST_INTERFACE_DEF
  308. #endif // DOCTEST_MSVC
  309. #define DOCTEST_EMPTY
  310. #if DOCTEST_MSVC
  311. #define DOCTEST_NOINLINE __declspec(noinline)
  312. #define DOCTEST_UNUSED
  313. #define DOCTEST_ALIGNMENT(x)
  314. #elif DOCTEST_CLANG && DOCTEST_CLANG < DOCTEST_COMPILER(3, 5, 0)
  315. #define DOCTEST_NOINLINE
  316. #define DOCTEST_UNUSED
  317. #define DOCTEST_ALIGNMENT(x)
  318. #else
  319. #define DOCTEST_NOINLINE __attribute__((noinline))
  320. #define DOCTEST_UNUSED __attribute__((unused))
  321. #define DOCTEST_ALIGNMENT(x) __attribute__((aligned(x)))
  322. #endif
  323. #ifdef DOCTEST_CONFIG_NO_CONTRADICTING_INLINE
  324. #define DOCTEST_INLINE_NOINLINE inline
  325. #else
  326. #define DOCTEST_INLINE_NOINLINE inline DOCTEST_NOINLINE
  327. #endif
  328. #ifndef DOCTEST_NORETURN
  329. #if DOCTEST_MSVC && (DOCTEST_MSVC < DOCTEST_COMPILER(19, 0, 0))
  330. #define DOCTEST_NORETURN
  331. #else // DOCTEST_MSVC
  332. #define DOCTEST_NORETURN [[noreturn]]
  333. #endif // DOCTEST_MSVC
  334. #endif // DOCTEST_NORETURN
  335. #ifndef DOCTEST_NOEXCEPT
  336. #if DOCTEST_MSVC && (DOCTEST_MSVC < DOCTEST_COMPILER(19, 0, 0))
  337. #define DOCTEST_NOEXCEPT
  338. #else // DOCTEST_MSVC
  339. #define DOCTEST_NOEXCEPT noexcept
  340. #endif // DOCTEST_MSVC
  341. #endif // DOCTEST_NOEXCEPT
  342. #ifndef DOCTEST_CONSTEXPR
  343. #if DOCTEST_MSVC && (DOCTEST_MSVC < DOCTEST_COMPILER(19, 0, 0))
  344. #define DOCTEST_CONSTEXPR const
  345. #define DOCTEST_CONSTEXPR_FUNC inline
  346. #else // DOCTEST_MSVC
  347. #define DOCTEST_CONSTEXPR constexpr
  348. #define DOCTEST_CONSTEXPR_FUNC constexpr
  349. #endif // DOCTEST_MSVC
  350. #endif // DOCTEST_CONSTEXPR
  351. #ifndef DOCTEST_NO_SANITIZE_INTEGER
  352. #if DOCTEST_CLANG >= DOCTEST_COMPILER(3, 7, 0)
  353. #define DOCTEST_NO_SANITIZE_INTEGER __attribute__((no_sanitize("integer")))
  354. #else
  355. #define DOCTEST_NO_SANITIZE_INTEGER
  356. #endif
  357. #endif // DOCTEST_NO_SANITIZE_INTEGER
  358. // =================================================================================================
  359. // == FEATURE DETECTION END ========================================================================
  360. // =================================================================================================
  361. #define DOCTEST_DECLARE_INTERFACE(name) \
  362. virtual ~name(); \
  363. name() = default; \
  364. name(const name&) = delete; \
  365. name(name&&) = delete; \
  366. name& operator=(const name&) = delete; \
  367. name& operator=(name&&) = delete;
  368. #define DOCTEST_DEFINE_INTERFACE(name) \
  369. name::~name() = default;
  370. // internal macros for string concatenation and anonymous variable name generation
  371. #define DOCTEST_CAT_IMPL(s1, s2) s1##s2
  372. #define DOCTEST_CAT(s1, s2) DOCTEST_CAT_IMPL(s1, s2)
  373. #ifdef __COUNTER__ // not standard and may be missing for some compilers
  374. #define DOCTEST_ANONYMOUS(x) DOCTEST_CAT(x, __COUNTER__)
  375. #else // __COUNTER__
  376. #define DOCTEST_ANONYMOUS(x) DOCTEST_CAT(x, __LINE__)
  377. #endif // __COUNTER__
  378. #ifndef DOCTEST_CONFIG_ASSERTION_PARAMETERS_BY_VALUE
  379. #define DOCTEST_REF_WRAP(x) x&
  380. #else // DOCTEST_CONFIG_ASSERTION_PARAMETERS_BY_VALUE
  381. #define DOCTEST_REF_WRAP(x) x
  382. #endif // DOCTEST_CONFIG_ASSERTION_PARAMETERS_BY_VALUE
  383. // not using __APPLE__ because... this is how Catch does it
  384. #ifdef __MAC_OS_X_VERSION_MIN_REQUIRED
  385. #define DOCTEST_PLATFORM_MAC
  386. #elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
  387. #define DOCTEST_PLATFORM_IPHONE
  388. #elif defined(_WIN32)
  389. #define DOCTEST_PLATFORM_WINDOWS
  390. #elif defined(__wasi__)
  391. #define DOCTEST_PLATFORM_WASI
  392. #else // DOCTEST_PLATFORM
  393. #define DOCTEST_PLATFORM_LINUX
  394. #endif // DOCTEST_PLATFORM
  395. namespace doctest { namespace detail {
  396. static DOCTEST_CONSTEXPR int consume(const int*, int) noexcept { return 0; }
  397. }}
  398. #define DOCTEST_GLOBAL_NO_WARNINGS(var, ...) \
  399. DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wglobal-constructors") \
  400. static const int var = doctest::detail::consume(&var, __VA_ARGS__); \
  401. DOCTEST_CLANG_SUPPRESS_WARNING_POP
  402. #ifndef DOCTEST_BREAK_INTO_DEBUGGER
  403. // should probably take a look at https://github.com/scottt/debugbreak
  404. #ifdef DOCTEST_PLATFORM_LINUX
  405. #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64))
  406. // Break at the location of the failing check if possible
  407. #define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("int $3\n" : :) // NOLINT(hicpp-no-assembler)
  408. #else
  409. #include <signal.h>
  410. #define DOCTEST_BREAK_INTO_DEBUGGER() raise(SIGTRAP)
  411. #endif
  412. #elif defined(DOCTEST_PLATFORM_MAC)
  413. #if defined(__x86_64) || defined(__x86_64__) || defined(__amd64__) || defined(__i386)
  414. #define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("int $3\n" : :) // NOLINT(hicpp-no-assembler)
  415. #elif defined(__ppc__) || defined(__ppc64__)
  416. // https://www.cocoawithlove.com/2008/03/break-into-debugger.html
  417. #define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n": : : "memory","r0","r3","r4") // NOLINT(hicpp-no-assembler)
  418. #else
  419. #define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("brk #0"); // NOLINT(hicpp-no-assembler)
  420. #endif
  421. #elif DOCTEST_MSVC
  422. #define DOCTEST_BREAK_INTO_DEBUGGER() __debugbreak()
  423. #elif defined(__MINGW32__)
  424. DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wredundant-decls")
  425. extern "C" __declspec(dllimport) void __stdcall DebugBreak();
  426. DOCTEST_GCC_SUPPRESS_WARNING_POP
  427. #define DOCTEST_BREAK_INTO_DEBUGGER() ::DebugBreak()
  428. #else // linux
  429. #define DOCTEST_BREAK_INTO_DEBUGGER() (static_cast<void>(0))
  430. #endif // linux
  431. #endif // DOCTEST_BREAK_INTO_DEBUGGER
  432. // this is kept here for backwards compatibility since the config option was changed
  433. #ifdef DOCTEST_CONFIG_USE_IOSFWD
  434. #ifndef DOCTEST_CONFIG_USE_STD_HEADERS
  435. #define DOCTEST_CONFIG_USE_STD_HEADERS
  436. #endif
  437. #endif // DOCTEST_CONFIG_USE_IOSFWD
  438. // for clang - always include <version> or <ciso646> (which drags some std stuff)
  439. // because we want to check if we are using libc++ with the _LIBCPP_VERSION macro in
  440. // which case we don't want to forward declare stuff from std - for reference:
  441. // https://github.com/doctest/doctest/issues/126
  442. // https://github.com/doctest/doctest/issues/356
  443. #if DOCTEST_CLANG
  444. #if DOCTEST_CPLUSPLUS >= 201703L && __has_include(<version>)
  445. #include <version>
  446. #else
  447. #include <ciso646>
  448. #endif
  449. #endif // clang
  450. #ifdef _LIBCPP_VERSION
  451. #ifndef DOCTEST_CONFIG_USE_STD_HEADERS
  452. #define DOCTEST_CONFIG_USE_STD_HEADERS
  453. #endif
  454. #endif // _LIBCPP_VERSION
  455. #ifdef DOCTEST_CONFIG_USE_STD_HEADERS
  456. #ifndef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
  457. #define DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
  458. #endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
  459. DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_BEGIN
  460. #include <cstddef>
  461. #include <ostream>
  462. #include <istream>
  463. DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_END
  464. #else // DOCTEST_CONFIG_USE_STD_HEADERS
  465. // Forward declaring 'X' in namespace std is not permitted by the C++ Standard.
  466. DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4643)
  467. namespace std { // NOLINT(cert-dcl58-cpp)
  468. typedef decltype(nullptr) nullptr_t; // NOLINT(modernize-use-using)
  469. typedef decltype(sizeof(void*)) size_t; // NOLINT(modernize-use-using)
  470. template <class charT>
  471. struct char_traits;
  472. template <>
  473. struct char_traits<char>;
  474. template <class charT, class traits>
  475. class basic_ostream; // NOLINT(fuchsia-virtual-inheritance)
  476. typedef basic_ostream<char, char_traits<char>> ostream; // NOLINT(modernize-use-using)
  477. template<class traits>
  478. // NOLINTNEXTLINE
  479. basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>&, const char*);
  480. template <class charT, class traits>
  481. class basic_istream;
  482. typedef basic_istream<char, char_traits<char>> istream; // NOLINT(modernize-use-using)
  483. template <class... Types>
  484. class tuple;
  485. #if DOCTEST_MSVC >= DOCTEST_COMPILER(19, 20, 0)
  486. // see this issue on why this is needed: https://github.com/doctest/doctest/issues/183
  487. template <class Ty>
  488. class allocator;
  489. template <class Elem, class Traits, class Alloc>
  490. class basic_string;
  491. using string = basic_string<char, char_traits<char>, allocator<char>>;
  492. #endif // VS 2019
  493. } // namespace std
  494. DOCTEST_MSVC_SUPPRESS_WARNING_POP
  495. #endif // DOCTEST_CONFIG_USE_STD_HEADERS
  496. #ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
  497. #include <type_traits>
  498. #endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
  499. namespace doctest {
  500. using std::size_t;
  501. DOCTEST_INTERFACE extern bool is_running_in_test;
  502. #ifndef DOCTEST_CONFIG_STRING_SIZE_TYPE
  503. #define DOCTEST_CONFIG_STRING_SIZE_TYPE unsigned
  504. #endif
  505. // A 24 byte string class (can be as small as 17 for x64 and 13 for x86) that can hold strings with length
  506. // of up to 23 chars on the stack before going on the heap - the last byte of the buffer is used for:
  507. // - "is small" bit - the highest bit - if "0" then it is small - otherwise its "1" (128)
  508. // - if small - capacity left before going on the heap - using the lowest 5 bits
  509. // - if small - 2 bits are left unused - the second and third highest ones
  510. // - if small - acts as a null terminator if strlen() is 23 (24 including the null terminator)
  511. // and the "is small" bit remains "0" ("as well as the capacity left") so its OK
  512. // Idea taken from this lecture about the string implementation of facebook/folly - fbstring
  513. // https://www.youtube.com/watch?v=kPR8h4-qZdk
  514. // TODO:
  515. // - optimizations - like not deleting memory unnecessarily in operator= and etc.
  516. // - resize/reserve/clear
  517. // - replace
  518. // - back/front
  519. // - iterator stuff
  520. // - find & friends
  521. // - push_back/pop_back
  522. // - assign/insert/erase
  523. // - relational operators as free functions - taking const char* as one of the params
  524. class DOCTEST_INTERFACE String
  525. {
  526. public:
  527. using size_type = DOCTEST_CONFIG_STRING_SIZE_TYPE;
  528. private:
  529. static DOCTEST_CONSTEXPR size_type len = 24; //!OCLINT avoid private static members
  530. static DOCTEST_CONSTEXPR size_type last = len - 1; //!OCLINT avoid private static members
  531. struct view // len should be more than sizeof(view) - because of the final byte for flags
  532. {
  533. char* ptr;
  534. size_type size;
  535. size_type capacity;
  536. };
  537. union
  538. {
  539. char buf[len]; // NOLINT(*-avoid-c-arrays)
  540. view data;
  541. };
  542. char* allocate(size_type sz);
  543. bool isOnStack() const noexcept { return (buf[last] & 128) == 0; }
  544. void setOnHeap() noexcept;
  545. void setLast(size_type in = last) noexcept;
  546. void setSize(size_type sz) noexcept;
  547. void copy(const String& other);
  548. public:
  549. static DOCTEST_CONSTEXPR size_type npos = static_cast<size_type>(-1);
  550. String() noexcept;
  551. ~String();
  552. // cppcheck-suppress noExplicitConstructor
  553. String(const char* in);
  554. String(const char* in, size_type in_size);
  555. String(std::istream& in, size_type in_size);
  556. String(const String& other);
  557. String& operator=(const String& other);
  558. String& operator+=(const String& other);
  559. String(String&& other) noexcept;
  560. String& operator=(String&& other) noexcept;
  561. char operator[](size_type i) const;
  562. char& operator[](size_type i);
  563. // the only functions I'm willing to leave in the interface - available for inlining
  564. const char* c_str() const { return const_cast<String*>(this)->c_str(); } // NOLINT
  565. char* c_str() {
  566. if (isOnStack()) {
  567. return reinterpret_cast<char*>(buf);
  568. }
  569. return data.ptr;
  570. }
  571. size_type size() const;
  572. size_type capacity() const;
  573. String substr(size_type pos, size_type cnt = npos) &&;
  574. String substr(size_type pos, size_type cnt = npos) const &;
  575. size_type find(char ch, size_type pos = 0) const;
  576. size_type rfind(char ch, size_type pos = npos) const;
  577. int compare(const char* other, bool no_case = false) const;
  578. int compare(const String& other, bool no_case = false) const;
  579. friend DOCTEST_INTERFACE std::ostream& operator<<(std::ostream& s, const String& in);
  580. };
  581. DOCTEST_INTERFACE String operator+(const String& lhs, const String& rhs);
  582. DOCTEST_INTERFACE bool operator==(const String& lhs, const String& rhs);
  583. DOCTEST_INTERFACE bool operator!=(const String& lhs, const String& rhs);
  584. DOCTEST_INTERFACE bool operator<(const String& lhs, const String& rhs);
  585. DOCTEST_INTERFACE bool operator>(const String& lhs, const String& rhs);
  586. DOCTEST_INTERFACE bool operator<=(const String& lhs, const String& rhs);
  587. DOCTEST_INTERFACE bool operator>=(const String& lhs, const String& rhs);
  588. class DOCTEST_INTERFACE Contains {
  589. public:
  590. explicit Contains(const String& string);
  591. bool checkWith(const String& other) const;
  592. String string;
  593. };
  594. DOCTEST_INTERFACE String toString(const Contains& in);
  595. DOCTEST_INTERFACE bool operator==(const String& lhs, const Contains& rhs);
  596. DOCTEST_INTERFACE bool operator==(const Contains& lhs, const String& rhs);
  597. DOCTEST_INTERFACE bool operator!=(const String& lhs, const Contains& rhs);
  598. DOCTEST_INTERFACE bool operator!=(const Contains& lhs, const String& rhs);
  599. namespace Color {
  600. enum Enum
  601. {
  602. None = 0,
  603. White,
  604. Red,
  605. Green,
  606. Blue,
  607. Cyan,
  608. Yellow,
  609. Grey,
  610. Bright = 0x10,
  611. BrightRed = Bright | Red,
  612. BrightGreen = Bright | Green,
  613. LightGrey = Bright | Grey,
  614. BrightWhite = Bright | White
  615. };
  616. DOCTEST_INTERFACE std::ostream& operator<<(std::ostream& s, Color::Enum code);
  617. } // namespace Color
  618. namespace assertType {
  619. enum Enum
  620. {
  621. // macro traits
  622. is_warn = 1,
  623. is_check = 2 * is_warn,
  624. is_require = 2 * is_check,
  625. is_normal = 2 * is_require,
  626. is_throws = 2 * is_normal,
  627. is_throws_as = 2 * is_throws,
  628. is_throws_with = 2 * is_throws_as,
  629. is_nothrow = 2 * is_throws_with,
  630. is_false = 2 * is_nothrow,
  631. is_unary = 2 * is_false, // not checked anywhere - used just to distinguish the types
  632. is_eq = 2 * is_unary,
  633. is_ne = 2 * is_eq,
  634. is_lt = 2 * is_ne,
  635. is_gt = 2 * is_lt,
  636. is_ge = 2 * is_gt,
  637. is_le = 2 * is_ge,
  638. // macro types
  639. DT_WARN = is_normal | is_warn,
  640. DT_CHECK = is_normal | is_check,
  641. DT_REQUIRE = is_normal | is_require,
  642. DT_WARN_FALSE = is_normal | is_false | is_warn,
  643. DT_CHECK_FALSE = is_normal | is_false | is_check,
  644. DT_REQUIRE_FALSE = is_normal | is_false | is_require,
  645. DT_WARN_THROWS = is_throws | is_warn,
  646. DT_CHECK_THROWS = is_throws | is_check,
  647. DT_REQUIRE_THROWS = is_throws | is_require,
  648. DT_WARN_THROWS_AS = is_throws_as | is_warn,
  649. DT_CHECK_THROWS_AS = is_throws_as | is_check,
  650. DT_REQUIRE_THROWS_AS = is_throws_as | is_require,
  651. DT_WARN_THROWS_WITH = is_throws_with | is_warn,
  652. DT_CHECK_THROWS_WITH = is_throws_with | is_check,
  653. DT_REQUIRE_THROWS_WITH = is_throws_with | is_require,
  654. DT_WARN_THROWS_WITH_AS = is_throws_with | is_throws_as | is_warn,
  655. DT_CHECK_THROWS_WITH_AS = is_throws_with | is_throws_as | is_check,
  656. DT_REQUIRE_THROWS_WITH_AS = is_throws_with | is_throws_as | is_require,
  657. DT_WARN_NOTHROW = is_nothrow | is_warn,
  658. DT_CHECK_NOTHROW = is_nothrow | is_check,
  659. DT_REQUIRE_NOTHROW = is_nothrow | is_require,
  660. DT_WARN_EQ = is_normal | is_eq | is_warn,
  661. DT_CHECK_EQ = is_normal | is_eq | is_check,
  662. DT_REQUIRE_EQ = is_normal | is_eq | is_require,
  663. DT_WARN_NE = is_normal | is_ne | is_warn,
  664. DT_CHECK_NE = is_normal | is_ne | is_check,
  665. DT_REQUIRE_NE = is_normal | is_ne | is_require,
  666. DT_WARN_GT = is_normal | is_gt | is_warn,
  667. DT_CHECK_GT = is_normal | is_gt | is_check,
  668. DT_REQUIRE_GT = is_normal | is_gt | is_require,
  669. DT_WARN_LT = is_normal | is_lt | is_warn,
  670. DT_CHECK_LT = is_normal | is_lt | is_check,
  671. DT_REQUIRE_LT = is_normal | is_lt | is_require,
  672. DT_WARN_GE = is_normal | is_ge | is_warn,
  673. DT_CHECK_GE = is_normal | is_ge | is_check,
  674. DT_REQUIRE_GE = is_normal | is_ge | is_require,
  675. DT_WARN_LE = is_normal | is_le | is_warn,
  676. DT_CHECK_LE = is_normal | is_le | is_check,
  677. DT_REQUIRE_LE = is_normal | is_le | is_require,
  678. DT_WARN_UNARY = is_normal | is_unary | is_warn,
  679. DT_CHECK_UNARY = is_normal | is_unary | is_check,
  680. DT_REQUIRE_UNARY = is_normal | is_unary | is_require,
  681. DT_WARN_UNARY_FALSE = is_normal | is_false | is_unary | is_warn,
  682. DT_CHECK_UNARY_FALSE = is_normal | is_false | is_unary | is_check,
  683. DT_REQUIRE_UNARY_FALSE = is_normal | is_false | is_unary | is_require,
  684. };
  685. } // namespace assertType
  686. DOCTEST_INTERFACE const char* assertString(assertType::Enum at);
  687. DOCTEST_INTERFACE const char* failureString(assertType::Enum at);
  688. DOCTEST_INTERFACE const char* skipPathFromFilename(const char* file);
  689. struct DOCTEST_INTERFACE TestCaseData
  690. {
  691. String m_file; // the file in which the test was registered (using String - see #350)
  692. unsigned m_line; // the line where the test was registered
  693. const char* m_name; // name of the test case
  694. const char* m_test_suite; // the test suite in which the test was added
  695. const char* m_description;
  696. bool m_skip;
  697. bool m_no_breaks;
  698. bool m_no_output;
  699. bool m_may_fail;
  700. bool m_should_fail;
  701. int m_expected_failures;
  702. double m_timeout;
  703. };
  704. struct DOCTEST_INTERFACE AssertData
  705. {
  706. // common - for all asserts
  707. const TestCaseData* m_test_case;
  708. assertType::Enum m_at;
  709. const char* m_file;
  710. int m_line;
  711. const char* m_expr;
  712. bool m_failed;
  713. // exception-related - for all asserts
  714. bool m_threw;
  715. String m_exception;
  716. // for normal asserts
  717. String m_decomp;
  718. // for specific exception-related asserts
  719. bool m_threw_as;
  720. const char* m_exception_type;
  721. class DOCTEST_INTERFACE StringContains {
  722. private:
  723. Contains content;
  724. bool isContains;
  725. public:
  726. StringContains(const String& str) : content(str), isContains(false) { }
  727. StringContains(Contains cntn) : content(static_cast<Contains&&>(cntn)), isContains(true) { }
  728. bool check(const String& str) { return isContains ? (content == str) : (content.string == str); }
  729. operator const String&() const { return content.string; }
  730. const char* c_str() const { return content.string.c_str(); }
  731. } m_exception_string;
  732. AssertData(assertType::Enum at, const char* file, int line, const char* expr,
  733. const char* exception_type, const StringContains& exception_string);
  734. };
  735. struct DOCTEST_INTERFACE MessageData
  736. {
  737. String m_string;
  738. const char* m_file;
  739. int m_line;
  740. assertType::Enum m_severity;
  741. };
  742. struct DOCTEST_INTERFACE SubcaseSignature
  743. {
  744. String m_name;
  745. const char* m_file;
  746. int m_line;
  747. bool operator==(const SubcaseSignature& other) const;
  748. bool operator<(const SubcaseSignature& other) const;
  749. };
  750. struct DOCTEST_INTERFACE IContextScope
  751. {
  752. DOCTEST_DECLARE_INTERFACE(IContextScope)
  753. virtual void stringify(std::ostream*) const = 0;
  754. };
  755. namespace detail {
  756. struct DOCTEST_INTERFACE TestCase;
  757. } // namespace detail
  758. struct ContextOptions //!OCLINT too many fields
  759. {
  760. std::ostream* cout = nullptr; // stdout stream
  761. String binary_name; // the test binary name
  762. const detail::TestCase* currentTest = nullptr;
  763. // == parameters from the command line
  764. String out; // output filename
  765. String order_by; // how tests should be ordered
  766. unsigned rand_seed; // the seed for rand ordering
  767. unsigned first; // the first (matching) test to be executed
  768. unsigned last; // the last (matching) test to be executed
  769. int abort_after; // stop tests after this many failed assertions
  770. int subcase_filter_levels; // apply the subcase filters for the first N levels
  771. bool success; // include successful assertions in output
  772. bool case_sensitive; // if filtering should be case sensitive
  773. bool exit; // if the program should be exited after the tests are ran/whatever
  774. bool duration; // print the time duration of each test case
  775. bool minimal; // minimal console output (only test failures)
  776. bool quiet; // no console output
  777. bool no_throw; // to skip exceptions-related assertion macros
  778. bool no_exitcode; // if the framework should return 0 as the exitcode
  779. bool no_run; // to not run the tests at all (can be done with an "*" exclude)
  780. bool no_intro; // to not print the intro of the framework
  781. bool no_version; // to not print the version of the framework
  782. bool no_colors; // if output to the console should be colorized
  783. bool force_colors; // forces the use of colors even when a tty cannot be detected
  784. bool no_breaks; // to not break into the debugger
  785. bool no_skip; // don't skip test cases which are marked to be skipped
  786. bool gnu_file_line; // if line numbers should be surrounded with :x: and not (x):
  787. bool no_path_in_filenames; // if the path to files should be removed from the output
  788. String strip_file_prefixes;// remove the longest matching one of these prefixes from any file paths in the output
  789. bool no_line_numbers; // if source code line numbers should be omitted from the output
  790. bool no_debug_output; // no output in the debug console when a debugger is attached
  791. bool no_skipped_summary; // don't print "skipped" in the summary !!! UNDOCUMENTED !!!
  792. bool no_time_in_output; // omit any time/timestamps from output !!! UNDOCUMENTED !!!
  793. bool help; // to print the help
  794. bool version; // to print the version
  795. bool count; // if only the count of matching tests is to be retrieved
  796. bool list_test_cases; // to list all tests matching the filters
  797. bool list_test_suites; // to list all suites matching the filters
  798. bool list_reporters; // lists all registered reporters
  799. };
  800. namespace detail {
  801. namespace types {
  802. #ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
  803. using namespace std;
  804. #else
  805. template <bool COND, typename T = void>
  806. struct enable_if { };
  807. template <typename T>
  808. struct enable_if<true, T> { using type = T; };
  809. struct true_type { static DOCTEST_CONSTEXPR bool value = true; };
  810. struct false_type { static DOCTEST_CONSTEXPR bool value = false; };
  811. template <typename T> struct remove_reference { using type = T; };
  812. template <typename T> struct remove_reference<T&> { using type = T; };
  813. template <typename T> struct remove_reference<T&&> { using type = T; };
  814. template <typename T> struct is_rvalue_reference : false_type { };
  815. template <typename T> struct is_rvalue_reference<T&&> : true_type { };
  816. template<typename T> struct remove_const { using type = T; };
  817. template <typename T> struct remove_const<const T> { using type = T; };
  818. // Compiler intrinsics
  819. template <typename T> struct is_enum { static DOCTEST_CONSTEXPR bool value = __is_enum(T); };
  820. template <typename T> struct underlying_type { using type = __underlying_type(T); };
  821. template <typename T> struct is_pointer : false_type { };
  822. template <typename T> struct is_pointer<T*> : true_type { };
  823. template <typename T> struct is_array : false_type { };
  824. // NOLINTNEXTLINE(*-avoid-c-arrays)
  825. template <typename T, size_t SIZE> struct is_array<T[SIZE]> : true_type { };
  826. #endif
  827. }
  828. // <utility>
  829. template <typename T>
  830. T&& declval();
  831. template <class T>
  832. DOCTEST_CONSTEXPR_FUNC T&& forward(typename types::remove_reference<T>::type& t) DOCTEST_NOEXCEPT {
  833. return static_cast<T&&>(t);
  834. }
  835. template <class T>
  836. DOCTEST_CONSTEXPR_FUNC T&& forward(typename types::remove_reference<T>::type&& t) DOCTEST_NOEXCEPT {
  837. return static_cast<T&&>(t);
  838. }
  839. template <typename T>
  840. struct deferred_false : types::false_type { };
  841. // MSVS 2015 :(
  842. #if !DOCTEST_CLANG && defined(_MSC_VER) && _MSC_VER <= 1900
  843. template <typename T, typename = void>
  844. struct has_global_insertion_operator : types::false_type { };
  845. template <typename T>
  846. struct has_global_insertion_operator<T, decltype(::operator<<(declval<std::ostream&>(), declval<const T&>()), void())> : types::true_type { };
  847. template <typename T, typename = void>
  848. struct has_insertion_operator { static DOCTEST_CONSTEXPR bool value = has_global_insertion_operator<T>::value; };
  849. template <typename T, bool global>
  850. struct insert_hack;
  851. template <typename T>
  852. struct insert_hack<T, true> {
  853. static void insert(std::ostream& os, const T& t) { ::operator<<(os, t); }
  854. };
  855. template <typename T>
  856. struct insert_hack<T, false> {
  857. static void insert(std::ostream& os, const T& t) { operator<<(os, t); }
  858. };
  859. template <typename T>
  860. using insert_hack_t = insert_hack<T, has_global_insertion_operator<T>::value>;
  861. #else
  862. template <typename T, typename = void>
  863. struct has_insertion_operator : types::false_type { };
  864. #endif
  865. template <typename T>
  866. struct has_insertion_operator<T, decltype(operator<<(declval<std::ostream&>(), declval<const T&>()), void())> : types::true_type { };
  867. template <typename T>
  868. struct should_stringify_as_underlying_type {
  869. static DOCTEST_CONSTEXPR bool value = detail::types::is_enum<T>::value && !doctest::detail::has_insertion_operator<T>::value;
  870. };
  871. DOCTEST_INTERFACE std::ostream* tlssPush();
  872. DOCTEST_INTERFACE String tlssPop();
  873. template <bool C>
  874. struct StringMakerBase {
  875. template <typename T>
  876. static String convert(const DOCTEST_REF_WRAP(T)) {
  877. #ifdef DOCTEST_CONFIG_REQUIRE_STRINGIFICATION_FOR_ALL_USED_TYPES
  878. static_assert(deferred_false<T>::value, "No stringification detected for type T. See string conversion manual");
  879. #endif
  880. return "{?}";
  881. }
  882. };
  883. template <typename T>
  884. struct filldata;
  885. template <typename T>
  886. void filloss(std::ostream* stream, const T& in) {
  887. filldata<T>::fill(stream, in);
  888. }
  889. template <typename T, size_t N>
  890. void filloss(std::ostream* stream, const T (&in)[N]) { // NOLINT(*-avoid-c-arrays)
  891. // T[N], T(&)[N], T(&&)[N] have same behaviour.
  892. // Hence remove reference.
  893. filloss<typename types::remove_reference<decltype(in)>::type>(stream, in);
  894. }
  895. template <typename T>
  896. String toStream(const T& in) {
  897. std::ostream* stream = tlssPush();
  898. filloss(stream, in);
  899. return tlssPop();
  900. }
  901. template <>
  902. struct StringMakerBase<true> {
  903. template <typename T>
  904. static String convert(const DOCTEST_REF_WRAP(T) in) {
  905. return toStream(in);
  906. }
  907. };
  908. } // namespace detail
  909. template <typename T>
  910. struct StringMaker : public detail::StringMakerBase<
  911. detail::has_insertion_operator<T>::value || detail::types::is_pointer<T>::value || detail::types::is_array<T>::value>
  912. {};
  913. #ifndef DOCTEST_STRINGIFY
  914. #ifdef DOCTEST_CONFIG_DOUBLE_STRINGIFY
  915. #define DOCTEST_STRINGIFY(...) toString(toString(__VA_ARGS__))
  916. #else
  917. #define DOCTEST_STRINGIFY(...) toString(__VA_ARGS__)
  918. #endif
  919. #endif
  920. template <typename T>
  921. String toString() {
  922. #if DOCTEST_CLANG == 0 && DOCTEST_GCC == 0 && DOCTEST_ICC == 0
  923. String ret = __FUNCSIG__; // class doctest::String __cdecl doctest::toString<TYPE>(void)
  924. String::size_type beginPos = ret.find('<');
  925. return ret.substr(beginPos + 1, ret.size() - beginPos - static_cast<String::size_type>(sizeof(">(void)")));
  926. #else
  927. String ret = __PRETTY_FUNCTION__; // doctest::String toString() [with T = TYPE]
  928. String::size_type begin = ret.find('=') + 2;
  929. return ret.substr(begin, ret.size() - begin - 1);
  930. #endif
  931. }
  932. template <typename T, typename detail::types::enable_if<!detail::should_stringify_as_underlying_type<T>::value, bool>::type = true>
  933. String toString(const DOCTEST_REF_WRAP(T) value) {
  934. return StringMaker<T>::convert(value);
  935. }
  936. #ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
  937. DOCTEST_INTERFACE String toString(const char* in);
  938. #endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
  939. #if DOCTEST_MSVC >= DOCTEST_COMPILER(19, 20, 0)
  940. // see this issue on why this is needed: https://github.com/doctest/doctest/issues/183
  941. DOCTEST_INTERFACE String toString(const std::string& in);
  942. #endif // VS 2019
  943. DOCTEST_INTERFACE String toString(String in);
  944. DOCTEST_INTERFACE String toString(std::nullptr_t);
  945. DOCTEST_INTERFACE String toString(bool in);
  946. DOCTEST_INTERFACE String toString(float in);
  947. DOCTEST_INTERFACE String toString(double in);
  948. DOCTEST_INTERFACE String toString(double long in);
  949. DOCTEST_INTERFACE String toString(char in);
  950. DOCTEST_INTERFACE String toString(char signed in);
  951. DOCTEST_INTERFACE String toString(char unsigned in);
  952. DOCTEST_INTERFACE String toString(short in);
  953. DOCTEST_INTERFACE String toString(short unsigned in);
  954. DOCTEST_INTERFACE String toString(signed in);
  955. DOCTEST_INTERFACE String toString(unsigned in);
  956. DOCTEST_INTERFACE String toString(long in);
  957. DOCTEST_INTERFACE String toString(long unsigned in);
  958. DOCTEST_INTERFACE String toString(long long in);
  959. DOCTEST_INTERFACE String toString(long long unsigned in);
  960. template <typename T, typename detail::types::enable_if<detail::should_stringify_as_underlying_type<T>::value, bool>::type = true>
  961. String toString(const DOCTEST_REF_WRAP(T) value) {
  962. using UT = typename detail::types::underlying_type<T>::type;
  963. return (DOCTEST_STRINGIFY(static_cast<UT>(value)));
  964. }
  965. namespace detail {
  966. template <typename T>
  967. struct filldata
  968. {
  969. static void fill(std::ostream* stream, const T& in) {
  970. #if defined(_MSC_VER) && _MSC_VER <= 1900
  971. insert_hack_t<T>::insert(*stream, in);
  972. #else
  973. operator<<(*stream, in);
  974. #endif
  975. }
  976. };
  977. DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4866)
  978. // NOLINTBEGIN(*-avoid-c-arrays)
  979. template <typename T, size_t N>
  980. struct filldata<T[N]> {
  981. static void fill(std::ostream* stream, const T(&in)[N]) {
  982. *stream << "[";
  983. for (size_t i = 0; i < N; i++) {
  984. if (i != 0) { *stream << ", "; }
  985. *stream << (DOCTEST_STRINGIFY(in[i]));
  986. }
  987. *stream << "]";
  988. }
  989. };
  990. // NOLINTEND(*-avoid-c-arrays)
  991. DOCTEST_MSVC_SUPPRESS_WARNING_POP
  992. // Specialized since we don't want the terminating null byte!
  993. // NOLINTBEGIN(*-avoid-c-arrays)
  994. template <size_t N>
  995. struct filldata<const char[N]> {
  996. static void fill(std::ostream* stream, const char (&in)[N]) {
  997. *stream << String(in, in[N - 1] ? N : N - 1);
  998. } // NOLINT(clang-analyzer-cplusplus.NewDeleteLeaks)
  999. };
  1000. // NOLINTEND(*-avoid-c-arrays)
  1001. template <>
  1002. struct filldata<const void*> {
  1003. static void fill(std::ostream* stream, const void* in);
  1004. };
  1005. template <typename T>
  1006. struct filldata<T*> {
  1007. DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4180)
  1008. static void fill(std::ostream* stream, const T* in) {
  1009. DOCTEST_MSVC_SUPPRESS_WARNING_POP
  1010. DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wmicrosoft-cast")
  1011. filldata<const void*>::fill(stream,
  1012. #if DOCTEST_GCC == 0 || DOCTEST_GCC >= DOCTEST_COMPILER(4, 9, 0)
  1013. reinterpret_cast<const void*>(in)
  1014. #else
  1015. *reinterpret_cast<const void* const*>(&in)
  1016. #endif
  1017. );
  1018. DOCTEST_CLANG_SUPPRESS_WARNING_POP
  1019. }
  1020. };
  1021. }
  1022. struct DOCTEST_INTERFACE Approx
  1023. {
  1024. Approx(double value);
  1025. Approx operator()(double value) const;
  1026. #ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
  1027. template <typename T>
  1028. explicit Approx(const T& value,
  1029. typename detail::types::enable_if<std::is_constructible<double, T>::value>::type* =
  1030. static_cast<T*>(nullptr)) {
  1031. *this = static_cast<double>(value);
  1032. }
  1033. #endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
  1034. Approx& epsilon(double newEpsilon);
  1035. #ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
  1036. template <typename T>
  1037. typename std::enable_if<std::is_constructible<double, T>::value, Approx&>::type epsilon(
  1038. const T& newEpsilon) {
  1039. m_epsilon = static_cast<double>(newEpsilon);
  1040. return *this;
  1041. }
  1042. #endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
  1043. Approx& scale(double newScale);
  1044. #ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
  1045. template <typename T>
  1046. typename std::enable_if<std::is_constructible<double, T>::value, Approx&>::type scale(
  1047. const T& newScale) {
  1048. m_scale = static_cast<double>(newScale);
  1049. return *this;
  1050. }
  1051. #endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
  1052. // clang-format off
  1053. DOCTEST_INTERFACE friend bool operator==(double lhs, const Approx & rhs);
  1054. DOCTEST_INTERFACE friend bool operator==(const Approx & lhs, double rhs);
  1055. DOCTEST_INTERFACE friend bool operator!=(double lhs, const Approx & rhs);
  1056. DOCTEST_INTERFACE friend bool operator!=(const Approx & lhs, double rhs);
  1057. DOCTEST_INTERFACE friend bool operator<=(double lhs, const Approx & rhs);
  1058. DOCTEST_INTERFACE friend bool operator<=(const Approx & lhs, double rhs);
  1059. DOCTEST_INTERFACE friend bool operator>=(double lhs, const Approx & rhs);
  1060. DOCTEST_INTERFACE friend bool operator>=(const Approx & lhs, double rhs);
  1061. DOCTEST_INTERFACE friend bool operator< (double lhs, const Approx & rhs);
  1062. DOCTEST_INTERFACE friend bool operator< (const Approx & lhs, double rhs);
  1063. DOCTEST_INTERFACE friend bool operator> (double lhs, const Approx & rhs);
  1064. DOCTEST_INTERFACE friend bool operator> (const Approx & lhs, double rhs);
  1065. #ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
  1066. #define DOCTEST_APPROX_PREFIX \
  1067. template <typename T> friend typename std::enable_if<std::is_constructible<double, T>::value, bool>::type
  1068. DOCTEST_APPROX_PREFIX operator==(const T& lhs, const Approx& rhs) { return operator==(static_cast<double>(lhs), rhs); }
  1069. DOCTEST_APPROX_PREFIX operator==(const Approx& lhs, const T& rhs) { return operator==(rhs, lhs); }
  1070. DOCTEST_APPROX_PREFIX operator!=(const T& lhs, const Approx& rhs) { return !operator==(lhs, rhs); }
  1071. DOCTEST_APPROX_PREFIX operator!=(const Approx& lhs, const T& rhs) { return !operator==(rhs, lhs); }
  1072. DOCTEST_APPROX_PREFIX operator<=(const T& lhs, const Approx& rhs) { return static_cast<double>(lhs) < rhs.m_value || lhs == rhs; }
  1073. DOCTEST_APPROX_PREFIX operator<=(const Approx& lhs, const T& rhs) { return lhs.m_value < static_cast<double>(rhs) || lhs == rhs; }
  1074. DOCTEST_APPROX_PREFIX operator>=(const T& lhs, const Approx& rhs) { return static_cast<double>(lhs) > rhs.m_value || lhs == rhs; }
  1075. DOCTEST_APPROX_PREFIX operator>=(const Approx& lhs, const T& rhs) { return lhs.m_value > static_cast<double>(rhs) || lhs == rhs; }
  1076. DOCTEST_APPROX_PREFIX operator< (const T& lhs, const Approx& rhs) { return static_cast<double>(lhs) < rhs.m_value && lhs != rhs; }
  1077. DOCTEST_APPROX_PREFIX operator< (const Approx& lhs, const T& rhs) { return lhs.m_value < static_cast<double>(rhs) && lhs != rhs; }
  1078. DOCTEST_APPROX_PREFIX operator> (const T& lhs, const Approx& rhs) { return static_cast<double>(lhs) > rhs.m_value && lhs != rhs; }
  1079. DOCTEST_APPROX_PREFIX operator> (const Approx& lhs, const T& rhs) { return lhs.m_value > static_cast<double>(rhs) && lhs != rhs; }
  1080. #undef DOCTEST_APPROX_PREFIX
  1081. #endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
  1082. // clang-format on
  1083. double m_epsilon;
  1084. double m_scale;
  1085. double m_value;
  1086. };
  1087. DOCTEST_INTERFACE String toString(const Approx& in);
  1088. DOCTEST_INTERFACE const ContextOptions* getContextOptions();
  1089. template <typename F>
  1090. struct DOCTEST_INTERFACE_DECL IsNaN
  1091. {
  1092. F value; bool flipped;
  1093. IsNaN(F f, bool flip = false) : value(f), flipped(flip) { }
  1094. IsNaN<F> operator!() const { return { value, !flipped }; }
  1095. operator bool() const;
  1096. };
  1097. #ifndef __MINGW32__
  1098. extern template struct DOCTEST_INTERFACE_DECL IsNaN<float>;
  1099. extern template struct DOCTEST_INTERFACE_DECL IsNaN<double>;
  1100. extern template struct DOCTEST_INTERFACE_DECL IsNaN<long double>;
  1101. #endif
  1102. DOCTEST_INTERFACE String toString(IsNaN<float> in);
  1103. DOCTEST_INTERFACE String toString(IsNaN<double> in);
  1104. DOCTEST_INTERFACE String toString(IsNaN<double long> in);
  1105. #ifndef DOCTEST_CONFIG_DISABLE
  1106. namespace detail {
  1107. // clang-format off
  1108. #ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
  1109. template<class T> struct decay_array { using type = T; };
  1110. template<class T, unsigned N> struct decay_array<T[N]> { using type = T*; };
  1111. template<class T> struct decay_array<T[]> { using type = T*; };
  1112. template<class T> struct not_char_pointer { static DOCTEST_CONSTEXPR int value = 1; };
  1113. template<> struct not_char_pointer<char*> { static DOCTEST_CONSTEXPR int value = 0; };
  1114. template<> struct not_char_pointer<const char*> { static DOCTEST_CONSTEXPR int value = 0; };
  1115. template<class T> struct can_use_op : public not_char_pointer<typename decay_array<T>::type> {};
  1116. #endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
  1117. // clang-format on
  1118. struct DOCTEST_INTERFACE TestFailureException
  1119. {
  1120. };
  1121. DOCTEST_INTERFACE bool checkIfShouldThrow(assertType::Enum at);
  1122. #ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
  1123. DOCTEST_NORETURN
  1124. #endif // DOCTEST_CONFIG_NO_EXCEPTIONS
  1125. DOCTEST_INTERFACE void throwException();
  1126. struct DOCTEST_INTERFACE Subcase
  1127. {
  1128. SubcaseSignature m_signature;
  1129. bool m_entered = false;
  1130. Subcase(const String& name, const char* file, int line);
  1131. Subcase(const Subcase&) = delete;
  1132. Subcase(Subcase&&) = delete;
  1133. Subcase& operator=(const Subcase&) = delete;
  1134. Subcase& operator=(Subcase&&) = delete;
  1135. ~Subcase();
  1136. operator bool() const;
  1137. private:
  1138. bool checkFilters();
  1139. };
  1140. template <typename L, typename R>
  1141. String stringifyBinaryExpr(const DOCTEST_REF_WRAP(L) lhs, const char* op,
  1142. const DOCTEST_REF_WRAP(R) rhs) {
  1143. return (DOCTEST_STRINGIFY(lhs)) + op + (DOCTEST_STRINGIFY(rhs));
  1144. }
  1145. #if DOCTEST_CLANG && DOCTEST_CLANG < DOCTEST_COMPILER(3, 6, 0)
  1146. DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wunused-comparison")
  1147. #endif
  1148. // This will check if there is any way it could find a operator like member or friend and uses it.
  1149. // If not it doesn't find the operator or if the operator at global scope is defined after
  1150. // this template, the template won't be instantiated due to SFINAE. Once the template is not
  1151. // instantiated it can look for global operator using normal conversions.
  1152. #ifdef __NVCC__
  1153. #define SFINAE_OP(ret,op) ret
  1154. #else
  1155. #define SFINAE_OP(ret,op) decltype((void)(doctest::detail::declval<L>() op doctest::detail::declval<R>()),ret{})
  1156. #endif
  1157. #define DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(op, op_str, op_macro) \
  1158. template <typename R> \
  1159. DOCTEST_NOINLINE SFINAE_OP(Result,op) operator op(R&& rhs) { \
  1160. bool res = op_macro(doctest::detail::forward<const L>(lhs), doctest::detail::forward<R>(rhs)); \
  1161. if(m_at & assertType::is_false) \
  1162. res = !res; \
  1163. if(!res || doctest::getContextOptions()->success) \
  1164. return Result(res, stringifyBinaryExpr(lhs, op_str, rhs)); \
  1165. return Result(res); \
  1166. }
  1167. // more checks could be added - like in Catch:
  1168. // https://github.com/catchorg/Catch2/pull/1480/files
  1169. // https://github.com/catchorg/Catch2/pull/1481/files
  1170. #define DOCTEST_FORBIT_EXPRESSION(rt, op) \
  1171. template <typename R> \
  1172. rt& operator op(const R&) { \
  1173. static_assert(deferred_false<R>::value, \
  1174. "Expression Too Complex Please Rewrite As Binary Comparison!"); \
  1175. return *this; \
  1176. }
  1177. struct DOCTEST_INTERFACE Result // NOLINT(*-member-init)
  1178. {
  1179. bool m_passed;
  1180. String m_decomp;
  1181. Result() = default; // TODO: Why do we need this? (To remove NOLINT)
  1182. Result(bool passed, const String& decomposition = String());
  1183. // forbidding some expressions based on this table: https://en.cppreference.com/w/cpp/language/operator_precedence
  1184. DOCTEST_FORBIT_EXPRESSION(Result, &)
  1185. DOCTEST_FORBIT_EXPRESSION(Result, ^)
  1186. DOCTEST_FORBIT_EXPRESSION(Result, |)
  1187. DOCTEST_FORBIT_EXPRESSION(Result, &&)
  1188. DOCTEST_FORBIT_EXPRESSION(Result, ||)
  1189. DOCTEST_FORBIT_EXPRESSION(Result, ==)
  1190. DOCTEST_FORBIT_EXPRESSION(Result, !=)
  1191. DOCTEST_FORBIT_EXPRESSION(Result, <)
  1192. DOCTEST_FORBIT_EXPRESSION(Result, >)
  1193. DOCTEST_FORBIT_EXPRESSION(Result, <=)
  1194. DOCTEST_FORBIT_EXPRESSION(Result, >=)
  1195. DOCTEST_FORBIT_EXPRESSION(Result, =)
  1196. DOCTEST_FORBIT_EXPRESSION(Result, +=)
  1197. DOCTEST_FORBIT_EXPRESSION(Result, -=)
  1198. DOCTEST_FORBIT_EXPRESSION(Result, *=)
  1199. DOCTEST_FORBIT_EXPRESSION(Result, /=)
  1200. DOCTEST_FORBIT_EXPRESSION(Result, %=)
  1201. DOCTEST_FORBIT_EXPRESSION(Result, <<=)
  1202. DOCTEST_FORBIT_EXPRESSION(Result, >>=)
  1203. DOCTEST_FORBIT_EXPRESSION(Result, &=)
  1204. DOCTEST_FORBIT_EXPRESSION(Result, ^=)
  1205. DOCTEST_FORBIT_EXPRESSION(Result, |=)
  1206. };
  1207. #ifndef DOCTEST_CONFIG_NO_COMPARISON_WARNING_SUPPRESSION
  1208. DOCTEST_CLANG_SUPPRESS_WARNING_PUSH
  1209. DOCTEST_CLANG_SUPPRESS_WARNING("-Wsign-conversion")
  1210. DOCTEST_CLANG_SUPPRESS_WARNING("-Wsign-compare")
  1211. //DOCTEST_CLANG_SUPPRESS_WARNING("-Wdouble-promotion")
  1212. //DOCTEST_CLANG_SUPPRESS_WARNING("-Wconversion")
  1213. //DOCTEST_CLANG_SUPPRESS_WARNING("-Wfloat-equal")
  1214. DOCTEST_GCC_SUPPRESS_WARNING_PUSH
  1215. DOCTEST_GCC_SUPPRESS_WARNING("-Wsign-conversion")
  1216. DOCTEST_GCC_SUPPRESS_WARNING("-Wsign-compare")
  1217. //DOCTEST_GCC_SUPPRESS_WARNING("-Wdouble-promotion")
  1218. //DOCTEST_GCC_SUPPRESS_WARNING("-Wconversion")
  1219. //DOCTEST_GCC_SUPPRESS_WARNING("-Wfloat-equal")
  1220. DOCTEST_MSVC_SUPPRESS_WARNING_PUSH
  1221. // https://stackoverflow.com/questions/39479163 what's the difference between 4018 and 4389
  1222. DOCTEST_MSVC_SUPPRESS_WARNING(4388) // signed/unsigned mismatch
  1223. DOCTEST_MSVC_SUPPRESS_WARNING(4389) // 'operator' : signed/unsigned mismatch
  1224. DOCTEST_MSVC_SUPPRESS_WARNING(4018) // 'expression' : signed/unsigned mismatch
  1225. //DOCTEST_MSVC_SUPPRESS_WARNING(4805) // 'operation' : unsafe mix of type 'type' and type 'type' in operation
  1226. #endif // DOCTEST_CONFIG_NO_COMPARISON_WARNING_SUPPRESSION
  1227. // clang-format off
  1228. #ifndef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
  1229. #define DOCTEST_COMPARISON_RETURN_TYPE bool
  1230. #else // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
  1231. #define DOCTEST_COMPARISON_RETURN_TYPE typename types::enable_if<can_use_op<L>::value || can_use_op<R>::value, bool>::type
  1232. inline bool eq(const char* lhs, const char* rhs) { return String(lhs) == String(rhs); }
  1233. inline bool ne(const char* lhs, const char* rhs) { return String(lhs) != String(rhs); }
  1234. inline bool lt(const char* lhs, const char* rhs) { return String(lhs) < String(rhs); }
  1235. inline bool gt(const char* lhs, const char* rhs) { return String(lhs) > String(rhs); }
  1236. inline bool le(const char* lhs, const char* rhs) { return String(lhs) <= String(rhs); }
  1237. inline bool ge(const char* lhs, const char* rhs) { return String(lhs) >= String(rhs); }
  1238. #endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
  1239. // clang-format on
  1240. #define DOCTEST_RELATIONAL_OP(name, op) \
  1241. template <typename L, typename R> \
  1242. DOCTEST_COMPARISON_RETURN_TYPE name(const DOCTEST_REF_WRAP(L) lhs, \
  1243. const DOCTEST_REF_WRAP(R) rhs) { \
  1244. return lhs op rhs; \
  1245. }
  1246. DOCTEST_RELATIONAL_OP(eq, ==)
  1247. DOCTEST_RELATIONAL_OP(ne, !=)
  1248. DOCTEST_RELATIONAL_OP(lt, <)
  1249. DOCTEST_RELATIONAL_OP(gt, >)
  1250. DOCTEST_RELATIONAL_OP(le, <=)
  1251. DOCTEST_RELATIONAL_OP(ge, >=)
  1252. #ifndef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
  1253. #define DOCTEST_CMP_EQ(l, r) l == r
  1254. #define DOCTEST_CMP_NE(l, r) l != r
  1255. #define DOCTEST_CMP_GT(l, r) l > r
  1256. #define DOCTEST_CMP_LT(l, r) l < r
  1257. #define DOCTEST_CMP_GE(l, r) l >= r
  1258. #define DOCTEST_CMP_LE(l, r) l <= r
  1259. #else // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
  1260. #define DOCTEST_CMP_EQ(l, r) eq(l, r)
  1261. #define DOCTEST_CMP_NE(l, r) ne(l, r)
  1262. #define DOCTEST_CMP_GT(l, r) gt(l, r)
  1263. #define DOCTEST_CMP_LT(l, r) lt(l, r)
  1264. #define DOCTEST_CMP_GE(l, r) ge(l, r)
  1265. #define DOCTEST_CMP_LE(l, r) le(l, r)
  1266. #endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
  1267. template <typename L>
  1268. // cppcheck-suppress copyCtorAndEqOperator
  1269. struct Expression_lhs
  1270. {
  1271. L lhs;
  1272. assertType::Enum m_at;
  1273. explicit Expression_lhs(L&& in, assertType::Enum at)
  1274. : lhs(static_cast<L&&>(in))
  1275. , m_at(at) {}
  1276. DOCTEST_NOINLINE operator Result() {
  1277. // this is needed only for MSVC 2015
  1278. DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4800) // 'int': forcing value to bool
  1279. bool res = static_cast<bool>(lhs);
  1280. DOCTEST_MSVC_SUPPRESS_WARNING_POP
  1281. if(m_at & assertType::is_false) { //!OCLINT bitwise operator in conditional
  1282. res = !res;
  1283. }
  1284. if(!res || getContextOptions()->success) {
  1285. return { res, (DOCTEST_STRINGIFY(lhs)) };
  1286. }
  1287. return { res };
  1288. }
  1289. /* This is required for user-defined conversions from Expression_lhs to L */
  1290. operator L() const { return lhs; }
  1291. // clang-format off
  1292. DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(==, " == ", DOCTEST_CMP_EQ) //!OCLINT bitwise operator in conditional
  1293. DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(!=, " != ", DOCTEST_CMP_NE) //!OCLINT bitwise operator in conditional
  1294. DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(>, " > ", DOCTEST_CMP_GT) //!OCLINT bitwise operator in conditional
  1295. DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(<, " < ", DOCTEST_CMP_LT) //!OCLINT bitwise operator in conditional
  1296. DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(>=, " >= ", DOCTEST_CMP_GE) //!OCLINT bitwise operator in conditional
  1297. DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(<=, " <= ", DOCTEST_CMP_LE) //!OCLINT bitwise operator in conditional
  1298. // clang-format on
  1299. // forbidding some expressions based on this table: https://en.cppreference.com/w/cpp/language/operator_precedence
  1300. DOCTEST_FORBIT_EXPRESSION(Expression_lhs, &)
  1301. DOCTEST_FORBIT_EXPRESSION(Expression_lhs, ^)
  1302. DOCTEST_FORBIT_EXPRESSION(Expression_lhs, |)
  1303. DOCTEST_FORBIT_EXPRESSION(Expression_lhs, &&)
  1304. DOCTEST_FORBIT_EXPRESSION(Expression_lhs, ||)
  1305. DOCTEST_FORBIT_EXPRESSION(Expression_lhs, =)
  1306. DOCTEST_FORBIT_EXPRESSION(Expression_lhs, +=)
  1307. DOCTEST_FORBIT_EXPRESSION(Expression_lhs, -=)
  1308. DOCTEST_FORBIT_EXPRESSION(Expression_lhs, *=)
  1309. DOCTEST_FORBIT_EXPRESSION(Expression_lhs, /=)
  1310. DOCTEST_FORBIT_EXPRESSION(Expression_lhs, %=)
  1311. DOCTEST_FORBIT_EXPRESSION(Expression_lhs, <<=)
  1312. DOCTEST_FORBIT_EXPRESSION(Expression_lhs, >>=)
  1313. DOCTEST_FORBIT_EXPRESSION(Expression_lhs, &=)
  1314. DOCTEST_FORBIT_EXPRESSION(Expression_lhs, ^=)
  1315. DOCTEST_FORBIT_EXPRESSION(Expression_lhs, |=)
  1316. // these 2 are unfortunate because they should be allowed - they have higher precedence over the comparisons, but the
  1317. // ExpressionDecomposer class uses the left shift operator to capture the left operand of the binary expression...
  1318. DOCTEST_FORBIT_EXPRESSION(Expression_lhs, <<)
  1319. DOCTEST_FORBIT_EXPRESSION(Expression_lhs, >>)
  1320. };
  1321. #ifndef DOCTEST_CONFIG_NO_COMPARISON_WARNING_SUPPRESSION
  1322. DOCTEST_CLANG_SUPPRESS_WARNING_POP
  1323. DOCTEST_MSVC_SUPPRESS_WARNING_POP
  1324. DOCTEST_GCC_SUPPRESS_WARNING_POP
  1325. #endif // DOCTEST_CONFIG_NO_COMPARISON_WARNING_SUPPRESSION
  1326. #if DOCTEST_CLANG && DOCTEST_CLANG < DOCTEST_COMPILER(3, 6, 0)
  1327. DOCTEST_CLANG_SUPPRESS_WARNING_POP
  1328. #endif
  1329. struct DOCTEST_INTERFACE ExpressionDecomposer
  1330. {
  1331. assertType::Enum m_at;
  1332. ExpressionDecomposer(assertType::Enum at);
  1333. // The right operator for capturing expressions is "<=" instead of "<<" (based on the operator precedence table)
  1334. // but then there will be warnings from GCC about "-Wparentheses" and since "_Pragma()" is problematic this will stay for now...
  1335. // https://github.com/catchorg/Catch2/issues/870
  1336. // https://github.com/catchorg/Catch2/issues/565
  1337. template <typename L>
  1338. Expression_lhs<const L&&> operator<<(const L&& operand) { //bitfields bind to universal ref but not const rvalue ref
  1339. return Expression_lhs<const L&&>(static_cast<const L&&>(operand), m_at);
  1340. }
  1341. template <typename L,typename types::enable_if<!doctest::detail::types::is_rvalue_reference<L>::value,void >::type* = nullptr>
  1342. Expression_lhs<const L&> operator<<(const L &operand) {
  1343. return Expression_lhs<const L&>(operand, m_at);
  1344. }
  1345. };
  1346. struct DOCTEST_INTERFACE TestSuite
  1347. {
  1348. const char* m_test_suite = nullptr;
  1349. const char* m_description = nullptr;
  1350. bool m_skip = false;
  1351. bool m_no_breaks = false;
  1352. bool m_no_output = false;
  1353. bool m_may_fail = false;
  1354. bool m_should_fail = false;
  1355. int m_expected_failures = 0;
  1356. double m_timeout = 0;
  1357. TestSuite& operator*(const char* in);
  1358. template <typename T>
  1359. TestSuite& operator*(const T& in) {
  1360. in.fill(*this);
  1361. return *this;
  1362. }
  1363. };
  1364. using funcType = void (*)();
  1365. struct DOCTEST_INTERFACE TestCase : public TestCaseData
  1366. {
  1367. funcType m_test; // a function pointer to the test case
  1368. String m_type; // for templated test cases - gets appended to the real name
  1369. int m_template_id; // an ID used to distinguish between the different versions of a templated test case
  1370. String m_full_name; // contains the name (only for templated test cases!) + the template type
  1371. TestCase(funcType test, const char* file, unsigned line, const TestSuite& test_suite,
  1372. const String& type = String(), int template_id = -1);
  1373. TestCase(const TestCase& other);
  1374. TestCase(TestCase&&) = delete;
  1375. DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(26434) // hides a non-virtual function
  1376. TestCase& operator=(const TestCase& other);
  1377. DOCTEST_MSVC_SUPPRESS_WARNING_POP
  1378. TestCase& operator=(TestCase&&) = delete;
  1379. TestCase& operator*(const char* in);
  1380. template <typename T>
  1381. TestCase& operator*(const T& in) {
  1382. in.fill(*this);
  1383. return *this;
  1384. }
  1385. bool operator<(const TestCase& other) const;
  1386. ~TestCase() = default;
  1387. };
  1388. // forward declarations of functions used by the macros
  1389. DOCTEST_INTERFACE int regTest(const TestCase& tc);
  1390. DOCTEST_INTERFACE int setTestSuite(const TestSuite& ts);
  1391. DOCTEST_INTERFACE bool isDebuggerActive();
  1392. template<typename T>
  1393. int instantiationHelper(const T&) { return 0; }
  1394. namespace binaryAssertComparison {
  1395. enum Enum
  1396. {
  1397. eq = 0,
  1398. ne,
  1399. gt,
  1400. lt,
  1401. ge,
  1402. le
  1403. };
  1404. } // namespace binaryAssertComparison
  1405. // clang-format off
  1406. template <int, class L, class R> struct RelationalComparator { bool operator()(const DOCTEST_REF_WRAP(L), const DOCTEST_REF_WRAP(R) ) const { return false; } };
  1407. #define DOCTEST_BINARY_RELATIONAL_OP(n, op) \
  1408. template <class L, class R> struct RelationalComparator<n, L, R> { bool operator()(const DOCTEST_REF_WRAP(L) lhs, const DOCTEST_REF_WRAP(R) rhs) const { return op(lhs, rhs); } };
  1409. // clang-format on
  1410. DOCTEST_BINARY_RELATIONAL_OP(0, doctest::detail::eq)
  1411. DOCTEST_BINARY_RELATIONAL_OP(1, doctest::detail::ne)
  1412. DOCTEST_BINARY_RELATIONAL_OP(2, doctest::detail::gt)
  1413. DOCTEST_BINARY_RELATIONAL_OP(3, doctest::detail::lt)
  1414. DOCTEST_BINARY_RELATIONAL_OP(4, doctest::detail::ge)
  1415. DOCTEST_BINARY_RELATIONAL_OP(5, doctest::detail::le)
  1416. struct DOCTEST_INTERFACE ResultBuilder : public AssertData
  1417. {
  1418. ResultBuilder(assertType::Enum at, const char* file, int line, const char* expr,
  1419. const char* exception_type = "", const String& exception_string = "");
  1420. ResultBuilder(assertType::Enum at, const char* file, int line, const char* expr,
  1421. const char* exception_type, const Contains& exception_string);
  1422. void setResult(const Result& res);
  1423. template <int comparison, typename L, typename R>
  1424. DOCTEST_NOINLINE bool binary_assert(const DOCTEST_REF_WRAP(L) lhs,
  1425. const DOCTEST_REF_WRAP(R) rhs) {
  1426. m_failed = !RelationalComparator<comparison, L, R>()(lhs, rhs);
  1427. if (m_failed || getContextOptions()->success) {
  1428. m_decomp = stringifyBinaryExpr(lhs, ", ", rhs);
  1429. }
  1430. return !m_failed;
  1431. }
  1432. template <typename L>
  1433. DOCTEST_NOINLINE bool unary_assert(const DOCTEST_REF_WRAP(L) val) {
  1434. m_failed = !val;
  1435. if (m_at & assertType::is_false) { //!OCLINT bitwise operator in conditional
  1436. m_failed = !m_failed;
  1437. }
  1438. if (m_failed || getContextOptions()->success) {
  1439. m_decomp = (DOCTEST_STRINGIFY(val));
  1440. }
  1441. return !m_failed;
  1442. }
  1443. void translateException();
  1444. bool log();
  1445. void react() const;
  1446. };
  1447. namespace assertAction {
  1448. enum Enum
  1449. {
  1450. nothing = 0,
  1451. dbgbreak = 1,
  1452. shouldthrow = 2
  1453. };
  1454. } // namespace assertAction
  1455. DOCTEST_INTERFACE void failed_out_of_a_testing_context(const AssertData& ad);
  1456. DOCTEST_INTERFACE bool decomp_assert(assertType::Enum at, const char* file, int line,
  1457. const char* expr, const Result& result);
  1458. #define DOCTEST_ASSERT_OUT_OF_TESTS(decomp) \
  1459. do { \
  1460. if(!is_running_in_test) { \
  1461. if(failed) { \
  1462. ResultBuilder rb(at, file, line, expr); \
  1463. rb.m_failed = failed; \
  1464. rb.m_decomp = decomp; \
  1465. failed_out_of_a_testing_context(rb); \
  1466. if(isDebuggerActive() && !getContextOptions()->no_breaks) \
  1467. DOCTEST_BREAK_INTO_DEBUGGER(); \
  1468. if(checkIfShouldThrow(at)) \
  1469. throwException(); \
  1470. } \
  1471. return !failed; \
  1472. } \
  1473. } while(false)
  1474. #define DOCTEST_ASSERT_IN_TESTS(decomp) \
  1475. ResultBuilder rb(at, file, line, expr); \
  1476. rb.m_failed = failed; \
  1477. if(rb.m_failed || getContextOptions()->success) \
  1478. rb.m_decomp = decomp; \
  1479. if(rb.log()) \
  1480. DOCTEST_BREAK_INTO_DEBUGGER(); \
  1481. if(rb.m_failed && checkIfShouldThrow(at)) \
  1482. throwException()
  1483. template <int comparison, typename L, typename R>
  1484. DOCTEST_NOINLINE bool binary_assert(assertType::Enum at, const char* file, int line,
  1485. const char* expr, const DOCTEST_REF_WRAP(L) lhs,
  1486. const DOCTEST_REF_WRAP(R) rhs) {
  1487. bool failed = !RelationalComparator<comparison, L, R>()(lhs, rhs);
  1488. // ###################################################################################
  1489. // IF THE DEBUGGER BREAKS HERE - GO 1 LEVEL UP IN THE CALLSTACK FOR THE FAILING ASSERT
  1490. // THIS IS THE EFFECT OF HAVING 'DOCTEST_CONFIG_SUPER_FAST_ASSERTS' DEFINED
  1491. // ###################################################################################
  1492. DOCTEST_ASSERT_OUT_OF_TESTS(stringifyBinaryExpr(lhs, ", ", rhs));
  1493. DOCTEST_ASSERT_IN_TESTS(stringifyBinaryExpr(lhs, ", ", rhs));
  1494. return !failed;
  1495. }
  1496. template <typename L>
  1497. DOCTEST_NOINLINE bool unary_assert(assertType::Enum at, const char* file, int line,
  1498. const char* expr, const DOCTEST_REF_WRAP(L) val) {
  1499. bool failed = !val;
  1500. if(at & assertType::is_false) //!OCLINT bitwise operator in conditional
  1501. failed = !failed;
  1502. // ###################################################################################
  1503. // IF THE DEBUGGER BREAKS HERE - GO 1 LEVEL UP IN THE CALLSTACK FOR THE FAILING ASSERT
  1504. // THIS IS THE EFFECT OF HAVING 'DOCTEST_CONFIG_SUPER_FAST_ASSERTS' DEFINED
  1505. // ###################################################################################
  1506. DOCTEST_ASSERT_OUT_OF_TESTS((DOCTEST_STRINGIFY(val)));
  1507. DOCTEST_ASSERT_IN_TESTS((DOCTEST_STRINGIFY(val)));
  1508. return !failed;
  1509. }
  1510. struct DOCTEST_INTERFACE IExceptionTranslator
  1511. {
  1512. DOCTEST_DECLARE_INTERFACE(IExceptionTranslator)
  1513. virtual bool translate(String&) const = 0;
  1514. };
  1515. template <typename T>
  1516. class ExceptionTranslator : public IExceptionTranslator //!OCLINT destructor of virtual class
  1517. {
  1518. public:
  1519. explicit ExceptionTranslator(String (*translateFunction)(T))
  1520. : m_translateFunction(translateFunction) {}
  1521. bool translate(String& res) const override {
  1522. #ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
  1523. try {
  1524. throw; // lgtm [cpp/rethrow-no-exception]
  1525. // cppcheck-suppress catchExceptionByValue
  1526. } catch(const T& ex) {
  1527. res = m_translateFunction(ex); //!OCLINT parameter reassignment
  1528. return true;
  1529. } catch(...) {} //!OCLINT - empty catch statement
  1530. #endif // DOCTEST_CONFIG_NO_EXCEPTIONS
  1531. static_cast<void>(res); // to silence -Wunused-parameter
  1532. return false;
  1533. }
  1534. private:
  1535. String (*m_translateFunction)(T);
  1536. };
  1537. DOCTEST_INTERFACE void registerExceptionTranslatorImpl(const IExceptionTranslator* et);
  1538. // ContextScope base class used to allow implementing methods of ContextScope
  1539. // that don't depend on the template parameter in doctest.cpp.
  1540. struct DOCTEST_INTERFACE ContextScopeBase : public IContextScope {
  1541. ContextScopeBase(const ContextScopeBase&) = delete;
  1542. ContextScopeBase& operator=(const ContextScopeBase&) = delete;
  1543. ContextScopeBase& operator=(ContextScopeBase&&) = delete;
  1544. ~ContextScopeBase() override = default;
  1545. protected:
  1546. ContextScopeBase();
  1547. ContextScopeBase(ContextScopeBase&& other) noexcept;
  1548. void destroy();
  1549. bool need_to_destroy{true};
  1550. };
  1551. template <typename L> class ContextScope : public ContextScopeBase
  1552. {
  1553. L lambda_;
  1554. public:
  1555. explicit ContextScope(const L &lambda) : lambda_(lambda) {}
  1556. explicit ContextScope(L&& lambda) : lambda_(static_cast<L&&>(lambda)) { }
  1557. ContextScope(const ContextScope&) = delete;
  1558. ContextScope(ContextScope&&) noexcept = default;
  1559. ContextScope& operator=(const ContextScope&) = delete;
  1560. ContextScope& operator=(ContextScope&&) = delete;
  1561. void stringify(std::ostream* s) const override { lambda_(s); }
  1562. ~ContextScope() override {
  1563. if (need_to_destroy) {
  1564. destroy();
  1565. }
  1566. }
  1567. };
  1568. struct DOCTEST_INTERFACE MessageBuilder : public MessageData
  1569. {
  1570. std::ostream* m_stream;
  1571. bool logged = false;
  1572. MessageBuilder(const char* file, int line, assertType::Enum severity);
  1573. MessageBuilder(const MessageBuilder&) = delete;
  1574. MessageBuilder(MessageBuilder&&) = delete;
  1575. MessageBuilder& operator=(const MessageBuilder&) = delete;
  1576. MessageBuilder& operator=(MessageBuilder&&) = delete;
  1577. ~MessageBuilder();
  1578. // the preferred way of chaining parameters for stringification
  1579. DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4866)
  1580. template <typename T>
  1581. MessageBuilder& operator,(const T& in) {
  1582. *m_stream << (DOCTEST_STRINGIFY(in));
  1583. return *this;
  1584. }
  1585. DOCTEST_MSVC_SUPPRESS_WARNING_POP
  1586. // kept here just for backwards-compatibility - the comma operator should be preferred now
  1587. template <typename T>
  1588. MessageBuilder& operator<<(const T& in) { return this->operator,(in); }
  1589. // the `,` operator has the lowest operator precedence - if `<<` is used by the user then
  1590. // the `,` operator will be called last which is not what we want and thus the `*` operator
  1591. // is used first (has higher operator precedence compared to `<<`) so that we guarantee that
  1592. // an operator of the MessageBuilder class is called first before the rest of the parameters
  1593. template <typename T>
  1594. MessageBuilder& operator*(const T& in) { return this->operator,(in); }
  1595. bool log();
  1596. void react();
  1597. };
  1598. template <typename L>
  1599. ContextScope<L> MakeContextScope(const L &lambda) {
  1600. return ContextScope<L>(lambda);
  1601. }
  1602. } // namespace detail
  1603. #define DOCTEST_DEFINE_DECORATOR(name, type, def) \
  1604. struct name \
  1605. { \
  1606. type data; \
  1607. name(type in = def) \
  1608. : data(in) {} \
  1609. void fill(detail::TestCase& state) const { state.DOCTEST_CAT(m_, name) = data; } \
  1610. void fill(detail::TestSuite& state) const { state.DOCTEST_CAT(m_, name) = data; } \
  1611. }
  1612. DOCTEST_DEFINE_DECORATOR(test_suite, const char*, "");
  1613. DOCTEST_DEFINE_DECORATOR(description, const char*, "");
  1614. DOCTEST_DEFINE_DECORATOR(skip, bool, true);
  1615. DOCTEST_DEFINE_DECORATOR(no_breaks, bool, true);
  1616. DOCTEST_DEFINE_DECORATOR(no_output, bool, true);
  1617. DOCTEST_DEFINE_DECORATOR(timeout, double, 0);
  1618. DOCTEST_DEFINE_DECORATOR(may_fail, bool, true);
  1619. DOCTEST_DEFINE_DECORATOR(should_fail, bool, true);
  1620. DOCTEST_DEFINE_DECORATOR(expected_failures, int, 0);
  1621. template <typename T>
  1622. int registerExceptionTranslator(String (*translateFunction)(T)) {
  1623. DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wexit-time-destructors")
  1624. static detail::ExceptionTranslator<T> exceptionTranslator(translateFunction);
  1625. DOCTEST_CLANG_SUPPRESS_WARNING_POP
  1626. detail::registerExceptionTranslatorImpl(&exceptionTranslator);
  1627. return 0;
  1628. }
  1629. } // namespace doctest
  1630. // in a separate namespace outside of doctest because the DOCTEST_TEST_SUITE macro
  1631. // introduces an anonymous namespace in which getCurrentTestSuite gets overridden
  1632. namespace doctest_detail_test_suite_ns {
  1633. DOCTEST_INTERFACE doctest::detail::TestSuite& getCurrentTestSuite();
  1634. } // namespace doctest_detail_test_suite_ns
  1635. namespace doctest {
  1636. #else // DOCTEST_CONFIG_DISABLE
  1637. template <typename T>
  1638. int registerExceptionTranslator(String (*)(T)) {
  1639. return 0;
  1640. }
  1641. #endif // DOCTEST_CONFIG_DISABLE
  1642. namespace detail {
  1643. using assert_handler = void (*)(const AssertData&);
  1644. struct ContextState;
  1645. } // namespace detail
  1646. class DOCTEST_INTERFACE Context
  1647. {
  1648. detail::ContextState* p;
  1649. void parseArgs(int argc, const char* const* argv, bool withDefaults = false);
  1650. public:
  1651. explicit Context(int argc = 0, const char* const* argv = nullptr);
  1652. Context(const Context&) = delete;
  1653. Context(Context&&) = delete;
  1654. Context& operator=(const Context&) = delete;
  1655. Context& operator=(Context&&) = delete;
  1656. ~Context(); // NOLINT(performance-trivially-destructible)
  1657. void applyCommandLine(int argc, const char* const* argv);
  1658. void addFilter(const char* filter, const char* value);
  1659. void clearFilters();
  1660. void setOption(const char* option, bool value);
  1661. void setOption(const char* option, int value);
  1662. void setOption(const char* option, const char* value);
  1663. bool shouldExit();
  1664. void setAsDefaultForAssertsOutOfTestCases();
  1665. void setAssertHandler(detail::assert_handler ah);
  1666. void setCout(std::ostream* out);
  1667. int run();
  1668. };
  1669. namespace TestCaseFailureReason {
  1670. enum Enum
  1671. {
  1672. None = 0,
  1673. AssertFailure = 1, // an assertion has failed in the test case
  1674. Exception = 2, // test case threw an exception
  1675. Crash = 4, // a crash...
  1676. TooManyFailedAsserts = 8, // the abort-after option
  1677. Timeout = 16, // see the timeout decorator
  1678. ShouldHaveFailedButDidnt = 32, // see the should_fail decorator
  1679. ShouldHaveFailedAndDid = 64, // see the should_fail decorator
  1680. DidntFailExactlyNumTimes = 128, // see the expected_failures decorator
  1681. FailedExactlyNumTimes = 256, // see the expected_failures decorator
  1682. CouldHaveFailedAndDid = 512 // see the may_fail decorator
  1683. };
  1684. } // namespace TestCaseFailureReason
  1685. struct DOCTEST_INTERFACE CurrentTestCaseStats
  1686. {
  1687. int numAssertsCurrentTest;
  1688. int numAssertsFailedCurrentTest;
  1689. double seconds;
  1690. int failure_flags; // use TestCaseFailureReason::Enum
  1691. bool testCaseSuccess;
  1692. };
  1693. struct DOCTEST_INTERFACE TestCaseException
  1694. {
  1695. String error_string;
  1696. bool is_crash;
  1697. };
  1698. struct DOCTEST_INTERFACE TestRunStats
  1699. {
  1700. unsigned numTestCases;
  1701. unsigned numTestCasesPassingFilters;
  1702. unsigned numTestSuitesPassingFilters;
  1703. unsigned numTestCasesFailed;
  1704. int numAsserts;
  1705. int numAssertsFailed;
  1706. };
  1707. struct QueryData
  1708. {
  1709. const TestRunStats* run_stats = nullptr;
  1710. const TestCaseData** data = nullptr;
  1711. unsigned num_data = 0;
  1712. };
  1713. struct DOCTEST_INTERFACE IReporter
  1714. {
  1715. // The constructor has to accept "const ContextOptions&" as a single argument
  1716. // which has most of the options for the run + a pointer to the stdout stream
  1717. // Reporter(const ContextOptions& in)
  1718. // called when a query should be reported (listing test cases, printing the version, etc.)
  1719. virtual void report_query(const QueryData&) = 0;
  1720. // called when the whole test run starts
  1721. virtual void test_run_start() = 0;
  1722. // called when the whole test run ends (caching a pointer to the input doesn't make sense here)
  1723. virtual void test_run_end(const TestRunStats&) = 0;
  1724. // called when a test case is started (safe to cache a pointer to the input)
  1725. virtual void test_case_start(const TestCaseData&) = 0;
  1726. // called when a test case is reentered because of unfinished subcases (safe to cache a pointer to the input)
  1727. virtual void test_case_reenter(const TestCaseData&) = 0;
  1728. // called when a test case has ended
  1729. virtual void test_case_end(const CurrentTestCaseStats&) = 0;
  1730. // called when an exception is thrown from the test case (or it crashes)
  1731. virtual void test_case_exception(const TestCaseException&) = 0;
  1732. // called whenever a subcase is entered (don't cache pointers to the input)
  1733. virtual void subcase_start(const SubcaseSignature&) = 0;
  1734. // called whenever a subcase is exited (don't cache pointers to the input)
  1735. virtual void subcase_end() = 0;
  1736. // called for each assert (don't cache pointers to the input)
  1737. virtual void log_assert(const AssertData&) = 0;
  1738. // called for each message (don't cache pointers to the input)
  1739. virtual void log_message(const MessageData&) = 0;
  1740. // called when a test case is skipped either because it doesn't pass the filters, has a skip decorator
  1741. // or isn't in the execution range (between first and last) (safe to cache a pointer to the input)
  1742. virtual void test_case_skipped(const TestCaseData&) = 0;
  1743. DOCTEST_DECLARE_INTERFACE(IReporter)
  1744. // can obtain all currently active contexts and stringify them if one wishes to do so
  1745. static int get_num_active_contexts();
  1746. static const IContextScope* const* get_active_contexts();
  1747. // can iterate through contexts which have been stringified automatically in their destructors when an exception has been thrown
  1748. static int get_num_stringified_contexts();
  1749. static const String* get_stringified_contexts();
  1750. };
  1751. namespace detail {
  1752. using reporterCreatorFunc = IReporter* (*)(const ContextOptions&);
  1753. DOCTEST_INTERFACE void registerReporterImpl(const char* name, int prio, reporterCreatorFunc c, bool isReporter);
  1754. template <typename Reporter>
  1755. IReporter* reporterCreator(const ContextOptions& o) {
  1756. return new Reporter(o);
  1757. }
  1758. } // namespace detail
  1759. template <typename Reporter>
  1760. int registerReporter(const char* name, int priority, bool isReporter) {
  1761. detail::registerReporterImpl(name, priority, detail::reporterCreator<Reporter>, isReporter);
  1762. return 0;
  1763. }
  1764. } // namespace doctest
  1765. #ifdef DOCTEST_CONFIG_ASSERTS_RETURN_VALUES
  1766. #define DOCTEST_FUNC_EMPTY [] { return false; }()
  1767. #else
  1768. #define DOCTEST_FUNC_EMPTY (void)0
  1769. #endif
  1770. // if registering is not disabled
  1771. #ifndef DOCTEST_CONFIG_DISABLE
  1772. #ifdef DOCTEST_CONFIG_ASSERTS_RETURN_VALUES
  1773. #define DOCTEST_FUNC_SCOPE_BEGIN [&]
  1774. #define DOCTEST_FUNC_SCOPE_END ()
  1775. #define DOCTEST_FUNC_SCOPE_RET(v) return v
  1776. #else
  1777. #define DOCTEST_FUNC_SCOPE_BEGIN do
  1778. #define DOCTEST_FUNC_SCOPE_END while(false)
  1779. #define DOCTEST_FUNC_SCOPE_RET(v) (void)0
  1780. #endif
  1781. // common code in asserts - for convenience
  1782. #define DOCTEST_ASSERT_LOG_REACT_RETURN(b) \
  1783. if(b.log()) DOCTEST_BREAK_INTO_DEBUGGER(); \
  1784. b.react(); \
  1785. DOCTEST_FUNC_SCOPE_RET(!b.m_failed)
  1786. #ifdef DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS
  1787. #define DOCTEST_WRAP_IN_TRY(x) x;
  1788. #else // DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS
  1789. #define DOCTEST_WRAP_IN_TRY(x) \
  1790. try { \
  1791. x; \
  1792. } catch(...) { DOCTEST_RB.translateException(); }
  1793. #endif // DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS
  1794. #ifdef DOCTEST_CONFIG_VOID_CAST_EXPRESSIONS
  1795. #define DOCTEST_CAST_TO_VOID(...) \
  1796. DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wuseless-cast") \
  1797. static_cast<void>(__VA_ARGS__); \
  1798. DOCTEST_GCC_SUPPRESS_WARNING_POP
  1799. #else // DOCTEST_CONFIG_VOID_CAST_EXPRESSIONS
  1800. #define DOCTEST_CAST_TO_VOID(...) __VA_ARGS__;
  1801. #endif // DOCTEST_CONFIG_VOID_CAST_EXPRESSIONS
  1802. // registers the test by initializing a dummy var with a function
  1803. #define DOCTEST_REGISTER_FUNCTION(global_prefix, f, decorators) \
  1804. global_prefix DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(DOCTEST_ANON_VAR_), /* NOLINT */ \
  1805. doctest::detail::regTest( \
  1806. doctest::detail::TestCase( \
  1807. f, __FILE__, __LINE__, \
  1808. doctest_detail_test_suite_ns::getCurrentTestSuite()) * \
  1809. decorators))
  1810. #define DOCTEST_IMPLEMENT_FIXTURE(der, base, func, decorators) \
  1811. namespace { /* NOLINT */ \
  1812. struct der : public base \
  1813. { \
  1814. void f(); \
  1815. }; \
  1816. static DOCTEST_INLINE_NOINLINE void func() { \
  1817. der v; \
  1818. v.f(); \
  1819. } \
  1820. DOCTEST_REGISTER_FUNCTION(DOCTEST_EMPTY, func, decorators) \
  1821. } \
  1822. DOCTEST_INLINE_NOINLINE void der::f() // NOLINT(misc-definitions-in-headers)
  1823. #define DOCTEST_CREATE_AND_REGISTER_FUNCTION(f, decorators) \
  1824. static void f(); \
  1825. DOCTEST_REGISTER_FUNCTION(DOCTEST_EMPTY, f, decorators) \
  1826. static void f()
  1827. #define DOCTEST_CREATE_AND_REGISTER_FUNCTION_IN_CLASS(f, proxy, decorators) \
  1828. static doctest::detail::funcType proxy() { return f; } \
  1829. DOCTEST_REGISTER_FUNCTION(inline, proxy(), decorators) \
  1830. static void f()
  1831. // for registering tests
  1832. #define DOCTEST_TEST_CASE(decorators) \
  1833. DOCTEST_CREATE_AND_REGISTER_FUNCTION(DOCTEST_ANONYMOUS(DOCTEST_ANON_FUNC_), decorators)
  1834. // for registering tests in classes - requires C++17 for inline variables!
  1835. #if DOCTEST_CPLUSPLUS >= 201703L
  1836. #define DOCTEST_TEST_CASE_CLASS(decorators) \
  1837. DOCTEST_CREATE_AND_REGISTER_FUNCTION_IN_CLASS(DOCTEST_ANONYMOUS(DOCTEST_ANON_FUNC_), \
  1838. DOCTEST_ANONYMOUS(DOCTEST_ANON_PROXY_), \
  1839. decorators)
  1840. #else // DOCTEST_TEST_CASE_CLASS
  1841. #define DOCTEST_TEST_CASE_CLASS(...) \
  1842. TEST_CASES_CAN_BE_REGISTERED_IN_CLASSES_ONLY_IN_CPP17_MODE_OR_WITH_VS_2017_OR_NEWER
  1843. #endif // DOCTEST_TEST_CASE_CLASS
  1844. // for registering tests with a fixture
  1845. #define DOCTEST_TEST_CASE_FIXTURE(c, decorators) \
  1846. DOCTEST_IMPLEMENT_FIXTURE(DOCTEST_ANONYMOUS(DOCTEST_ANON_CLASS_), c, \
  1847. DOCTEST_ANONYMOUS(DOCTEST_ANON_FUNC_), decorators)
  1848. // for converting types to strings without the <typeinfo> header and demangling
  1849. #define DOCTEST_TYPE_TO_STRING_AS(str, ...) \
  1850. namespace doctest { \
  1851. template <> \
  1852. inline String toString<__VA_ARGS__>() { \
  1853. return str; \
  1854. } \
  1855. } \
  1856. static_assert(true, "")
  1857. #define DOCTEST_TYPE_TO_STRING(...) DOCTEST_TYPE_TO_STRING_AS(#__VA_ARGS__, __VA_ARGS__)
  1858. #define DOCTEST_TEST_CASE_TEMPLATE_DEFINE_IMPL(dec, T, iter, func) \
  1859. template <typename T> \
  1860. static void func(); \
  1861. namespace { /* NOLINT */ \
  1862. template <typename Tuple> \
  1863. struct iter; \
  1864. template <typename Type, typename... Rest> \
  1865. struct iter<std::tuple<Type, Rest...>> \
  1866. { \
  1867. iter(const char* file, unsigned line, int index) { \
  1868. doctest::detail::regTest(doctest::detail::TestCase(func<Type>, file, line, \
  1869. doctest_detail_test_suite_ns::getCurrentTestSuite(), \
  1870. doctest::toString<Type>(), \
  1871. int(line) * 1000 + index) \
  1872. * dec); \
  1873. iter<std::tuple<Rest...>>(file, line, index + 1); \
  1874. } \
  1875. }; \
  1876. template <> \
  1877. struct iter<std::tuple<>> \
  1878. { \
  1879. iter(const char*, unsigned, int) {} \
  1880. }; \
  1881. } \
  1882. template <typename T> \
  1883. static void func()
  1884. #define DOCTEST_TEST_CASE_TEMPLATE_DEFINE(dec, T, id) \
  1885. DOCTEST_TEST_CASE_TEMPLATE_DEFINE_IMPL(dec, T, DOCTEST_CAT(id, ITERATOR), \
  1886. DOCTEST_ANONYMOUS(DOCTEST_ANON_TMP_))
  1887. #define DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE_IMPL(id, anon, ...) \
  1888. DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_CAT(anon, DUMMY), /* NOLINT(cert-err58-cpp, fuchsia-statically-constructed-objects) */ \
  1889. doctest::detail::instantiationHelper( \
  1890. DOCTEST_CAT(id, ITERATOR)<__VA_ARGS__>(__FILE__, __LINE__, 0)))
  1891. #define DOCTEST_TEST_CASE_TEMPLATE_INVOKE(id, ...) \
  1892. DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE_IMPL(id, DOCTEST_ANONYMOUS(DOCTEST_ANON_TMP_), std::tuple<__VA_ARGS__>) \
  1893. static_assert(true, "")
  1894. #define DOCTEST_TEST_CASE_TEMPLATE_APPLY(id, ...) \
  1895. DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE_IMPL(id, DOCTEST_ANONYMOUS(DOCTEST_ANON_TMP_), __VA_ARGS__) \
  1896. static_assert(true, "")
  1897. #define DOCTEST_TEST_CASE_TEMPLATE_IMPL(dec, T, anon, ...) \
  1898. DOCTEST_TEST_CASE_TEMPLATE_DEFINE_IMPL(dec, T, DOCTEST_CAT(anon, ITERATOR), anon); \
  1899. DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE_IMPL(anon, anon, std::tuple<__VA_ARGS__>) \
  1900. template <typename T> \
  1901. static void anon()
  1902. #define DOCTEST_TEST_CASE_TEMPLATE(dec, T, ...) \
  1903. DOCTEST_TEST_CASE_TEMPLATE_IMPL(dec, T, DOCTEST_ANONYMOUS(DOCTEST_ANON_TMP_), __VA_ARGS__)
  1904. // for subcases
  1905. #define DOCTEST_SUBCASE(name) \
  1906. if(const doctest::detail::Subcase & DOCTEST_ANONYMOUS(DOCTEST_ANON_SUBCASE_) DOCTEST_UNUSED = \
  1907. doctest::detail::Subcase(name, __FILE__, __LINE__))
  1908. // for grouping tests in test suites by using code blocks
  1909. #define DOCTEST_TEST_SUITE_IMPL(decorators, ns_name) \
  1910. namespace ns_name { namespace doctest_detail_test_suite_ns { \
  1911. static DOCTEST_NOINLINE doctest::detail::TestSuite& getCurrentTestSuite() noexcept { \
  1912. DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4640) \
  1913. DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wexit-time-destructors") \
  1914. DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wmissing-field-initializers") \
  1915. static doctest::detail::TestSuite data{}; \
  1916. static bool inited = false; \
  1917. DOCTEST_MSVC_SUPPRESS_WARNING_POP \
  1918. DOCTEST_CLANG_SUPPRESS_WARNING_POP \
  1919. DOCTEST_GCC_SUPPRESS_WARNING_POP \
  1920. if(!inited) { \
  1921. data* decorators; \
  1922. inited = true; \
  1923. } \
  1924. return data; \
  1925. } \
  1926. } \
  1927. } \
  1928. namespace ns_name
  1929. #define DOCTEST_TEST_SUITE(decorators) \
  1930. DOCTEST_TEST_SUITE_IMPL(decorators, DOCTEST_ANONYMOUS(DOCTEST_ANON_SUITE_))
  1931. // for starting a testsuite block
  1932. #define DOCTEST_TEST_SUITE_BEGIN(decorators) \
  1933. DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(DOCTEST_ANON_VAR_), /* NOLINT(cert-err58-cpp) */ \
  1934. doctest::detail::setTestSuite(doctest::detail::TestSuite() * decorators)) \
  1935. static_assert(true, "")
  1936. // for ending a testsuite block
  1937. #define DOCTEST_TEST_SUITE_END \
  1938. DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(DOCTEST_ANON_VAR_), /* NOLINT(cert-err58-cpp) */ \
  1939. doctest::detail::setTestSuite(doctest::detail::TestSuite() * "")) \
  1940. using DOCTEST_ANONYMOUS(DOCTEST_ANON_FOR_SEMICOLON_) = int
  1941. // for registering exception translators
  1942. #define DOCTEST_REGISTER_EXCEPTION_TRANSLATOR_IMPL(translatorName, signature) \
  1943. inline doctest::String translatorName(signature); \
  1944. DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(DOCTEST_ANON_TRANSLATOR_), /* NOLINT(cert-err58-cpp) */ \
  1945. doctest::registerExceptionTranslator(translatorName)) \
  1946. doctest::String translatorName(signature)
  1947. #define DOCTEST_REGISTER_EXCEPTION_TRANSLATOR(signature) \
  1948. DOCTEST_REGISTER_EXCEPTION_TRANSLATOR_IMPL(DOCTEST_ANONYMOUS(DOCTEST_ANON_TRANSLATOR_), \
  1949. signature)
  1950. // for registering reporters
  1951. #define DOCTEST_REGISTER_REPORTER(name, priority, reporter) \
  1952. DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(DOCTEST_ANON_REPORTER_), /* NOLINT(cert-err58-cpp) */ \
  1953. doctest::registerReporter<reporter>(name, priority, true)) \
  1954. static_assert(true, "")
  1955. // for registering listeners
  1956. #define DOCTEST_REGISTER_LISTENER(name, priority, reporter) \
  1957. DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(DOCTEST_ANON_REPORTER_), /* NOLINT(cert-err58-cpp) */ \
  1958. doctest::registerReporter<reporter>(name, priority, false)) \
  1959. static_assert(true, "")
  1960. // clang-format off
  1961. // for logging - disabling formatting because it's important to have these on 2 separate lines - see PR #557
  1962. #define DOCTEST_INFO(...) \
  1963. DOCTEST_INFO_IMPL(DOCTEST_ANONYMOUS(DOCTEST_CAPTURE_), \
  1964. DOCTEST_ANONYMOUS(DOCTEST_CAPTURE_OTHER_), \
  1965. __VA_ARGS__)
  1966. // clang-format on
  1967. #define DOCTEST_INFO_IMPL(mb_name, s_name, ...) \
  1968. auto DOCTEST_ANONYMOUS(DOCTEST_CAPTURE_) = doctest::detail::MakeContextScope( \
  1969. [&](std::ostream* s_name) { \
  1970. doctest::detail::MessageBuilder mb_name(__FILE__, __LINE__, doctest::assertType::is_warn); \
  1971. mb_name.m_stream = s_name; \
  1972. mb_name * __VA_ARGS__; \
  1973. })
  1974. #define DOCTEST_CAPTURE(x) DOCTEST_INFO(#x " := ", x)
  1975. #define DOCTEST_ADD_AT_IMPL(type, file, line, mb, ...) \
  1976. DOCTEST_FUNC_SCOPE_BEGIN { \
  1977. doctest::detail::MessageBuilder mb(file, line, doctest::assertType::type); \
  1978. mb * __VA_ARGS__; \
  1979. if(mb.log()) \
  1980. DOCTEST_BREAK_INTO_DEBUGGER(); \
  1981. mb.react(); \
  1982. } DOCTEST_FUNC_SCOPE_END
  1983. // clang-format off
  1984. #define DOCTEST_ADD_MESSAGE_AT(file, line, ...) DOCTEST_ADD_AT_IMPL(is_warn, file, line, DOCTEST_ANONYMOUS(DOCTEST_MESSAGE_), __VA_ARGS__)
  1985. #define DOCTEST_ADD_FAIL_CHECK_AT(file, line, ...) DOCTEST_ADD_AT_IMPL(is_check, file, line, DOCTEST_ANONYMOUS(DOCTEST_MESSAGE_), __VA_ARGS__)
  1986. #define DOCTEST_ADD_FAIL_AT(file, line, ...) DOCTEST_ADD_AT_IMPL(is_require, file, line, DOCTEST_ANONYMOUS(DOCTEST_MESSAGE_), __VA_ARGS__)
  1987. // clang-format on
  1988. #define DOCTEST_MESSAGE(...) DOCTEST_ADD_MESSAGE_AT(__FILE__, __LINE__, __VA_ARGS__)
  1989. #define DOCTEST_FAIL_CHECK(...) DOCTEST_ADD_FAIL_CHECK_AT(__FILE__, __LINE__, __VA_ARGS__)
  1990. #define DOCTEST_FAIL(...) DOCTEST_ADD_FAIL_AT(__FILE__, __LINE__, __VA_ARGS__)
  1991. #define DOCTEST_TO_LVALUE(...) __VA_ARGS__ // Not removed to keep backwards compatibility.
  1992. #ifndef DOCTEST_CONFIG_SUPER_FAST_ASSERTS
  1993. #define DOCTEST_ASSERT_IMPLEMENT_2(assert_type, ...) \
  1994. DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Woverloaded-shift-op-parentheses") \
  1995. /* NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) */ \
  1996. doctest::detail::ResultBuilder DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \
  1997. __LINE__, #__VA_ARGS__); \
  1998. DOCTEST_WRAP_IN_TRY(DOCTEST_RB.setResult( \
  1999. doctest::detail::ExpressionDecomposer(doctest::assertType::assert_type) \
  2000. << __VA_ARGS__)) /* NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) */ \
  2001. DOCTEST_ASSERT_LOG_REACT_RETURN(DOCTEST_RB) \
  2002. DOCTEST_CLANG_SUPPRESS_WARNING_POP
  2003. #define DOCTEST_ASSERT_IMPLEMENT_1(assert_type, ...) \
  2004. DOCTEST_FUNC_SCOPE_BEGIN { \
  2005. DOCTEST_ASSERT_IMPLEMENT_2(assert_type, __VA_ARGS__); \
  2006. } DOCTEST_FUNC_SCOPE_END // NOLINT(clang-analyzer-cplusplus.NewDeleteLeaks)
  2007. #define DOCTEST_BINARY_ASSERT(assert_type, comp, ...) \
  2008. DOCTEST_FUNC_SCOPE_BEGIN { \
  2009. doctest::detail::ResultBuilder DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \
  2010. __LINE__, #__VA_ARGS__); \
  2011. DOCTEST_WRAP_IN_TRY( \
  2012. DOCTEST_RB.binary_assert<doctest::detail::binaryAssertComparison::comp>( \
  2013. __VA_ARGS__)) \
  2014. DOCTEST_ASSERT_LOG_REACT_RETURN(DOCTEST_RB); \
  2015. } DOCTEST_FUNC_SCOPE_END
  2016. #define DOCTEST_UNARY_ASSERT(assert_type, ...) \
  2017. DOCTEST_FUNC_SCOPE_BEGIN { \
  2018. doctest::detail::ResultBuilder DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \
  2019. __LINE__, #__VA_ARGS__); \
  2020. DOCTEST_WRAP_IN_TRY(DOCTEST_RB.unary_assert(__VA_ARGS__)) \
  2021. DOCTEST_ASSERT_LOG_REACT_RETURN(DOCTEST_RB); \
  2022. } DOCTEST_FUNC_SCOPE_END
  2023. #else // DOCTEST_CONFIG_SUPER_FAST_ASSERTS
  2024. // necessary for <ASSERT>_MESSAGE
  2025. #define DOCTEST_ASSERT_IMPLEMENT_2 DOCTEST_ASSERT_IMPLEMENT_1
  2026. #define DOCTEST_ASSERT_IMPLEMENT_1(assert_type, ...) \
  2027. DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Woverloaded-shift-op-parentheses") \
  2028. doctest::detail::decomp_assert( \
  2029. doctest::assertType::assert_type, __FILE__, __LINE__, #__VA_ARGS__, \
  2030. doctest::detail::ExpressionDecomposer(doctest::assertType::assert_type) \
  2031. << __VA_ARGS__) DOCTEST_CLANG_SUPPRESS_WARNING_POP
  2032. #define DOCTEST_BINARY_ASSERT(assert_type, comparison, ...) \
  2033. doctest::detail::binary_assert<doctest::detail::binaryAssertComparison::comparison>( \
  2034. doctest::assertType::assert_type, __FILE__, __LINE__, #__VA_ARGS__, __VA_ARGS__)
  2035. #define DOCTEST_UNARY_ASSERT(assert_type, ...) \
  2036. doctest::detail::unary_assert(doctest::assertType::assert_type, __FILE__, __LINE__, \
  2037. #__VA_ARGS__, __VA_ARGS__)
  2038. #endif // DOCTEST_CONFIG_SUPER_FAST_ASSERTS
  2039. #define DOCTEST_WARN(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_WARN, __VA_ARGS__)
  2040. #define DOCTEST_CHECK(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_CHECK, __VA_ARGS__)
  2041. #define DOCTEST_REQUIRE(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_REQUIRE, __VA_ARGS__)
  2042. #define DOCTEST_WARN_FALSE(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_WARN_FALSE, __VA_ARGS__)
  2043. #define DOCTEST_CHECK_FALSE(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_CHECK_FALSE, __VA_ARGS__)
  2044. #define DOCTEST_REQUIRE_FALSE(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_REQUIRE_FALSE, __VA_ARGS__)
  2045. // clang-format off
  2046. #define DOCTEST_WARN_MESSAGE(cond, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_WARN, cond); } DOCTEST_FUNC_SCOPE_END
  2047. #define DOCTEST_CHECK_MESSAGE(cond, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_CHECK, cond); } DOCTEST_FUNC_SCOPE_END
  2048. #define DOCTEST_REQUIRE_MESSAGE(cond, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_REQUIRE, cond); } DOCTEST_FUNC_SCOPE_END
  2049. #define DOCTEST_WARN_FALSE_MESSAGE(cond, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_WARN_FALSE, cond); } DOCTEST_FUNC_SCOPE_END
  2050. #define DOCTEST_CHECK_FALSE_MESSAGE(cond, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_CHECK_FALSE, cond); } DOCTEST_FUNC_SCOPE_END
  2051. #define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_REQUIRE_FALSE, cond); } DOCTEST_FUNC_SCOPE_END
  2052. // clang-format on
  2053. #define DOCTEST_WARN_EQ(...) DOCTEST_BINARY_ASSERT(DT_WARN_EQ, eq, __VA_ARGS__)
  2054. #define DOCTEST_CHECK_EQ(...) DOCTEST_BINARY_ASSERT(DT_CHECK_EQ, eq, __VA_ARGS__)
  2055. #define DOCTEST_REQUIRE_EQ(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_EQ, eq, __VA_ARGS__)
  2056. #define DOCTEST_WARN_NE(...) DOCTEST_BINARY_ASSERT(DT_WARN_NE, ne, __VA_ARGS__)
  2057. #define DOCTEST_CHECK_NE(...) DOCTEST_BINARY_ASSERT(DT_CHECK_NE, ne, __VA_ARGS__)
  2058. #define DOCTEST_REQUIRE_NE(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_NE, ne, __VA_ARGS__)
  2059. #define DOCTEST_WARN_GT(...) DOCTEST_BINARY_ASSERT(DT_WARN_GT, gt, __VA_ARGS__)
  2060. #define DOCTEST_CHECK_GT(...) DOCTEST_BINARY_ASSERT(DT_CHECK_GT, gt, __VA_ARGS__)
  2061. #define DOCTEST_REQUIRE_GT(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_GT, gt, __VA_ARGS__)
  2062. #define DOCTEST_WARN_LT(...) DOCTEST_BINARY_ASSERT(DT_WARN_LT, lt, __VA_ARGS__)
  2063. #define DOCTEST_CHECK_LT(...) DOCTEST_BINARY_ASSERT(DT_CHECK_LT, lt, __VA_ARGS__)
  2064. #define DOCTEST_REQUIRE_LT(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_LT, lt, __VA_ARGS__)
  2065. #define DOCTEST_WARN_GE(...) DOCTEST_BINARY_ASSERT(DT_WARN_GE, ge, __VA_ARGS__)
  2066. #define DOCTEST_CHECK_GE(...) DOCTEST_BINARY_ASSERT(DT_CHECK_GE, ge, __VA_ARGS__)
  2067. #define DOCTEST_REQUIRE_GE(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_GE, ge, __VA_ARGS__)
  2068. #define DOCTEST_WARN_LE(...) DOCTEST_BINARY_ASSERT(DT_WARN_LE, le, __VA_ARGS__)
  2069. #define DOCTEST_CHECK_LE(...) DOCTEST_BINARY_ASSERT(DT_CHECK_LE, le, __VA_ARGS__)
  2070. #define DOCTEST_REQUIRE_LE(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_LE, le, __VA_ARGS__)
  2071. #define DOCTEST_WARN_UNARY(...) DOCTEST_UNARY_ASSERT(DT_WARN_UNARY, __VA_ARGS__)
  2072. #define DOCTEST_CHECK_UNARY(...) DOCTEST_UNARY_ASSERT(DT_CHECK_UNARY, __VA_ARGS__)
  2073. #define DOCTEST_REQUIRE_UNARY(...) DOCTEST_UNARY_ASSERT(DT_REQUIRE_UNARY, __VA_ARGS__)
  2074. #define DOCTEST_WARN_UNARY_FALSE(...) DOCTEST_UNARY_ASSERT(DT_WARN_UNARY_FALSE, __VA_ARGS__)
  2075. #define DOCTEST_CHECK_UNARY_FALSE(...) DOCTEST_UNARY_ASSERT(DT_CHECK_UNARY_FALSE, __VA_ARGS__)
  2076. #define DOCTEST_REQUIRE_UNARY_FALSE(...) DOCTEST_UNARY_ASSERT(DT_REQUIRE_UNARY_FALSE, __VA_ARGS__)
  2077. #ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
  2078. #define DOCTEST_ASSERT_THROWS_AS(expr, assert_type, message, ...) \
  2079. DOCTEST_FUNC_SCOPE_BEGIN { \
  2080. if(!doctest::getContextOptions()->no_throw) { \
  2081. doctest::detail::ResultBuilder DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \
  2082. __LINE__, #expr, #__VA_ARGS__, message); \
  2083. try { \
  2084. DOCTEST_CAST_TO_VOID(expr) \
  2085. } catch(const typename doctest::detail::types::remove_const< \
  2086. typename doctest::detail::types::remove_reference<__VA_ARGS__>::type>::type&) {\
  2087. DOCTEST_RB.translateException(); \
  2088. DOCTEST_RB.m_threw_as = true; \
  2089. } catch(...) { DOCTEST_RB.translateException(); } \
  2090. DOCTEST_ASSERT_LOG_REACT_RETURN(DOCTEST_RB); \
  2091. } else { /* NOLINT(*-else-after-return) */ \
  2092. DOCTEST_FUNC_SCOPE_RET(false); \
  2093. } \
  2094. } DOCTEST_FUNC_SCOPE_END
  2095. #define DOCTEST_ASSERT_THROWS_WITH(expr, expr_str, assert_type, ...) \
  2096. DOCTEST_FUNC_SCOPE_BEGIN { \
  2097. if(!doctest::getContextOptions()->no_throw) { \
  2098. doctest::detail::ResultBuilder DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \
  2099. __LINE__, expr_str, "", __VA_ARGS__); \
  2100. try { \
  2101. DOCTEST_CAST_TO_VOID(expr) \
  2102. } catch(...) { DOCTEST_RB.translateException(); } \
  2103. DOCTEST_ASSERT_LOG_REACT_RETURN(DOCTEST_RB); \
  2104. } else { /* NOLINT(*-else-after-return) */ \
  2105. DOCTEST_FUNC_SCOPE_RET(false); \
  2106. } \
  2107. } DOCTEST_FUNC_SCOPE_END
  2108. #define DOCTEST_ASSERT_NOTHROW(assert_type, ...) \
  2109. DOCTEST_FUNC_SCOPE_BEGIN { \
  2110. doctest::detail::ResultBuilder DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \
  2111. __LINE__, #__VA_ARGS__); \
  2112. try { \
  2113. DOCTEST_CAST_TO_VOID(__VA_ARGS__) \
  2114. } catch(...) { DOCTEST_RB.translateException(); } \
  2115. DOCTEST_ASSERT_LOG_REACT_RETURN(DOCTEST_RB); \
  2116. } DOCTEST_FUNC_SCOPE_END
  2117. // clang-format off
  2118. #define DOCTEST_WARN_THROWS(...) DOCTEST_ASSERT_THROWS_WITH((__VA_ARGS__), #__VA_ARGS__, DT_WARN_THROWS, "")
  2119. #define DOCTEST_CHECK_THROWS(...) DOCTEST_ASSERT_THROWS_WITH((__VA_ARGS__), #__VA_ARGS__, DT_CHECK_THROWS, "")
  2120. #define DOCTEST_REQUIRE_THROWS(...) DOCTEST_ASSERT_THROWS_WITH((__VA_ARGS__), #__VA_ARGS__, DT_REQUIRE_THROWS, "")
  2121. #define DOCTEST_WARN_THROWS_AS(expr, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_WARN_THROWS_AS, "", __VA_ARGS__)
  2122. #define DOCTEST_CHECK_THROWS_AS(expr, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_CHECK_THROWS_AS, "", __VA_ARGS__)
  2123. #define DOCTEST_REQUIRE_THROWS_AS(expr, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_REQUIRE_THROWS_AS, "", __VA_ARGS__)
  2124. #define DOCTEST_WARN_THROWS_WITH(expr, ...) DOCTEST_ASSERT_THROWS_WITH(expr, #expr, DT_WARN_THROWS_WITH, __VA_ARGS__)
  2125. #define DOCTEST_CHECK_THROWS_WITH(expr, ...) DOCTEST_ASSERT_THROWS_WITH(expr, #expr, DT_CHECK_THROWS_WITH, __VA_ARGS__)
  2126. #define DOCTEST_REQUIRE_THROWS_WITH(expr, ...) DOCTEST_ASSERT_THROWS_WITH(expr, #expr, DT_REQUIRE_THROWS_WITH, __VA_ARGS__)
  2127. #define DOCTEST_WARN_THROWS_WITH_AS(expr, message, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_WARN_THROWS_WITH_AS, message, __VA_ARGS__)
  2128. #define DOCTEST_CHECK_THROWS_WITH_AS(expr, message, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_CHECK_THROWS_WITH_AS, message, __VA_ARGS__)
  2129. #define DOCTEST_REQUIRE_THROWS_WITH_AS(expr, message, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_REQUIRE_THROWS_WITH_AS, message, __VA_ARGS__)
  2130. #define DOCTEST_WARN_NOTHROW(...) DOCTEST_ASSERT_NOTHROW(DT_WARN_NOTHROW, __VA_ARGS__)
  2131. #define DOCTEST_CHECK_NOTHROW(...) DOCTEST_ASSERT_NOTHROW(DT_CHECK_NOTHROW, __VA_ARGS__)
  2132. #define DOCTEST_REQUIRE_NOTHROW(...) DOCTEST_ASSERT_NOTHROW(DT_REQUIRE_NOTHROW, __VA_ARGS__)
  2133. #define DOCTEST_WARN_THROWS_MESSAGE(expr, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS(expr); } DOCTEST_FUNC_SCOPE_END
  2134. #define DOCTEST_CHECK_THROWS_MESSAGE(expr, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS(expr); } DOCTEST_FUNC_SCOPE_END
  2135. #define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS(expr); } DOCTEST_FUNC_SCOPE_END
  2136. #define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS_AS(expr, ex); } DOCTEST_FUNC_SCOPE_END
  2137. #define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS_AS(expr, ex); } DOCTEST_FUNC_SCOPE_END
  2138. #define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS_AS(expr, ex); } DOCTEST_FUNC_SCOPE_END
  2139. #define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS_WITH(expr, with); } DOCTEST_FUNC_SCOPE_END
  2140. #define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS_WITH(expr, with); } DOCTEST_FUNC_SCOPE_END
  2141. #define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS_WITH(expr, with); } DOCTEST_FUNC_SCOPE_END
  2142. #define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS_WITH_AS(expr, with, ex); } DOCTEST_FUNC_SCOPE_END
  2143. #define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ex); } DOCTEST_FUNC_SCOPE_END
  2144. #define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ex); } DOCTEST_FUNC_SCOPE_END
  2145. #define DOCTEST_WARN_NOTHROW_MESSAGE(expr, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_NOTHROW(expr); } DOCTEST_FUNC_SCOPE_END
  2146. #define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_NOTHROW(expr); } DOCTEST_FUNC_SCOPE_END
  2147. #define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_NOTHROW(expr); } DOCTEST_FUNC_SCOPE_END
  2148. // clang-format on
  2149. #endif // DOCTEST_CONFIG_NO_EXCEPTIONS
  2150. // =================================================================================================
  2151. // == WHAT FOLLOWS IS VERSIONS OF THE MACROS THAT DO NOT DO ANY REGISTERING! ==
  2152. // == THIS CAN BE ENABLED BY DEFINING DOCTEST_CONFIG_DISABLE GLOBALLY! ==
  2153. // =================================================================================================
  2154. #else // DOCTEST_CONFIG_DISABLE
  2155. #define DOCTEST_IMPLEMENT_FIXTURE(der, base, func, name) \
  2156. namespace /* NOLINT */ { \
  2157. template <typename DOCTEST_UNUSED_TEMPLATE_TYPE> \
  2158. struct der : public base \
  2159. { void f(); }; \
  2160. } \
  2161. template <typename DOCTEST_UNUSED_TEMPLATE_TYPE> \
  2162. inline void der<DOCTEST_UNUSED_TEMPLATE_TYPE>::f()
  2163. #define DOCTEST_CREATE_AND_REGISTER_FUNCTION(f, name) \
  2164. template <typename DOCTEST_UNUSED_TEMPLATE_TYPE> \
  2165. static inline void f()
  2166. // for registering tests
  2167. #define DOCTEST_TEST_CASE(name) \
  2168. DOCTEST_CREATE_AND_REGISTER_FUNCTION(DOCTEST_ANONYMOUS(DOCTEST_ANON_FUNC_), name)
  2169. // for registering tests in classes
  2170. #define DOCTEST_TEST_CASE_CLASS(name) \
  2171. DOCTEST_CREATE_AND_REGISTER_FUNCTION(DOCTEST_ANONYMOUS(DOCTEST_ANON_FUNC_), name)
  2172. // for registering tests with a fixture
  2173. #define DOCTEST_TEST_CASE_FIXTURE(x, name) \
  2174. DOCTEST_IMPLEMENT_FIXTURE(DOCTEST_ANONYMOUS(DOCTEST_ANON_CLASS_), x, \
  2175. DOCTEST_ANONYMOUS(DOCTEST_ANON_FUNC_), name)
  2176. // for converting types to strings without the <typeinfo> header and demangling
  2177. #define DOCTEST_TYPE_TO_STRING_AS(str, ...) static_assert(true, "")
  2178. #define DOCTEST_TYPE_TO_STRING(...) static_assert(true, "")
  2179. // for typed tests
  2180. #define DOCTEST_TEST_CASE_TEMPLATE(name, type, ...) \
  2181. template <typename type> \
  2182. inline void DOCTEST_ANONYMOUS(DOCTEST_ANON_TMP_)()
  2183. #define DOCTEST_TEST_CASE_TEMPLATE_DEFINE(name, type, id) \
  2184. template <typename type> \
  2185. inline void DOCTEST_ANONYMOUS(DOCTEST_ANON_TMP_)()
  2186. #define DOCTEST_TEST_CASE_TEMPLATE_INVOKE(id, ...) static_assert(true, "")
  2187. #define DOCTEST_TEST_CASE_TEMPLATE_APPLY(id, ...) static_assert(true, "")
  2188. // for subcases
  2189. #define DOCTEST_SUBCASE(name)
  2190. // for a testsuite block
  2191. #define DOCTEST_TEST_SUITE(name) namespace // NOLINT
  2192. // for starting a testsuite block
  2193. #define DOCTEST_TEST_SUITE_BEGIN(name) static_assert(true, "")
  2194. // for ending a testsuite block
  2195. #define DOCTEST_TEST_SUITE_END using DOCTEST_ANONYMOUS(DOCTEST_ANON_FOR_SEMICOLON_) = int
  2196. #define DOCTEST_REGISTER_EXCEPTION_TRANSLATOR(signature) \
  2197. template <typename DOCTEST_UNUSED_TEMPLATE_TYPE> \
  2198. static inline doctest::String DOCTEST_ANONYMOUS(DOCTEST_ANON_TRANSLATOR_)(signature)
  2199. #define DOCTEST_REGISTER_REPORTER(name, priority, reporter)
  2200. #define DOCTEST_REGISTER_LISTENER(name, priority, reporter)
  2201. #define DOCTEST_INFO(...) (static_cast<void>(0))
  2202. #define DOCTEST_CAPTURE(x) (static_cast<void>(0))
  2203. #define DOCTEST_ADD_MESSAGE_AT(file, line, ...) (static_cast<void>(0))
  2204. #define DOCTEST_ADD_FAIL_CHECK_AT(file, line, ...) (static_cast<void>(0))
  2205. #define DOCTEST_ADD_FAIL_AT(file, line, ...) (static_cast<void>(0))
  2206. #define DOCTEST_MESSAGE(...) (static_cast<void>(0))
  2207. #define DOCTEST_FAIL_CHECK(...) (static_cast<void>(0))
  2208. #define DOCTEST_FAIL(...) (static_cast<void>(0))
  2209. #if defined(DOCTEST_CONFIG_EVALUATE_ASSERTS_EVEN_WHEN_DISABLED) \
  2210. && defined(DOCTEST_CONFIG_ASSERTS_RETURN_VALUES)
  2211. #define DOCTEST_WARN(...) [&] { return __VA_ARGS__; }()
  2212. #define DOCTEST_CHECK(...) [&] { return __VA_ARGS__; }()
  2213. #define DOCTEST_REQUIRE(...) [&] { return __VA_ARGS__; }()
  2214. #define DOCTEST_WARN_FALSE(...) [&] { return !(__VA_ARGS__); }()
  2215. #define DOCTEST_CHECK_FALSE(...) [&] { return !(__VA_ARGS__); }()
  2216. #define DOCTEST_REQUIRE_FALSE(...) [&] { return !(__VA_ARGS__); }()
  2217. #define DOCTEST_WARN_MESSAGE(cond, ...) [&] { return cond; }()
  2218. #define DOCTEST_CHECK_MESSAGE(cond, ...) [&] { return cond; }()
  2219. #define DOCTEST_REQUIRE_MESSAGE(cond, ...) [&] { return cond; }()
  2220. #define DOCTEST_WARN_FALSE_MESSAGE(cond, ...) [&] { return !(cond); }()
  2221. #define DOCTEST_CHECK_FALSE_MESSAGE(cond, ...) [&] { return !(cond); }()
  2222. #define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, ...) [&] { return !(cond); }()
  2223. namespace doctest {
  2224. namespace detail {
  2225. #define DOCTEST_RELATIONAL_OP(name, op) \
  2226. template <typename L, typename R> \
  2227. bool name(const DOCTEST_REF_WRAP(L) lhs, const DOCTEST_REF_WRAP(R) rhs) { return lhs op rhs; }
  2228. DOCTEST_RELATIONAL_OP(eq, ==)
  2229. DOCTEST_RELATIONAL_OP(ne, !=)
  2230. DOCTEST_RELATIONAL_OP(lt, <)
  2231. DOCTEST_RELATIONAL_OP(gt, >)
  2232. DOCTEST_RELATIONAL_OP(le, <=)
  2233. DOCTEST_RELATIONAL_OP(ge, >=)
  2234. } // namespace detail
  2235. } // namespace doctest
  2236. #define DOCTEST_WARN_EQ(...) [&] { return doctest::detail::eq(__VA_ARGS__); }()
  2237. #define DOCTEST_CHECK_EQ(...) [&] { return doctest::detail::eq(__VA_ARGS__); }()
  2238. #define DOCTEST_REQUIRE_EQ(...) [&] { return doctest::detail::eq(__VA_ARGS__); }()
  2239. #define DOCTEST_WARN_NE(...) [&] { return doctest::detail::ne(__VA_ARGS__); }()
  2240. #define DOCTEST_CHECK_NE(...) [&] { return doctest::detail::ne(__VA_ARGS__); }()
  2241. #define DOCTEST_REQUIRE_NE(...) [&] { return doctest::detail::ne(__VA_ARGS__); }()
  2242. #define DOCTEST_WARN_LT(...) [&] { return doctest::detail::lt(__VA_ARGS__); }()
  2243. #define DOCTEST_CHECK_LT(...) [&] { return doctest::detail::lt(__VA_ARGS__); }()
  2244. #define DOCTEST_REQUIRE_LT(...) [&] { return doctest::detail::lt(__VA_ARGS__); }()
  2245. #define DOCTEST_WARN_GT(...) [&] { return doctest::detail::gt(__VA_ARGS__); }()
  2246. #define DOCTEST_CHECK_GT(...) [&] { return doctest::detail::gt(__VA_ARGS__); }()
  2247. #define DOCTEST_REQUIRE_GT(...) [&] { return doctest::detail::gt(__VA_ARGS__); }()
  2248. #define DOCTEST_WARN_LE(...) [&] { return doctest::detail::le(__VA_ARGS__); }()
  2249. #define DOCTEST_CHECK_LE(...) [&] { return doctest::detail::le(__VA_ARGS__); }()
  2250. #define DOCTEST_REQUIRE_LE(...) [&] { return doctest::detail::le(__VA_ARGS__); }()
  2251. #define DOCTEST_WARN_GE(...) [&] { return doctest::detail::ge(__VA_ARGS__); }()
  2252. #define DOCTEST_CHECK_GE(...) [&] { return doctest::detail::ge(__VA_ARGS__); }()
  2253. #define DOCTEST_REQUIRE_GE(...) [&] { return doctest::detail::ge(__VA_ARGS__); }()
  2254. #define DOCTEST_WARN_UNARY(...) [&] { return __VA_ARGS__; }()
  2255. #define DOCTEST_CHECK_UNARY(...) [&] { return __VA_ARGS__; }()
  2256. #define DOCTEST_REQUIRE_UNARY(...) [&] { return __VA_ARGS__; }()
  2257. #define DOCTEST_WARN_UNARY_FALSE(...) [&] { return !(__VA_ARGS__); }()
  2258. #define DOCTEST_CHECK_UNARY_FALSE(...) [&] { return !(__VA_ARGS__); }()
  2259. #define DOCTEST_REQUIRE_UNARY_FALSE(...) [&] { return !(__VA_ARGS__); }()
  2260. #ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
  2261. #define DOCTEST_WARN_THROWS_WITH(expr, with, ...) [] { static_assert(false, "Exception translation is not available when doctest is disabled."); return false; }()
  2262. #define DOCTEST_CHECK_THROWS_WITH(expr, with, ...) DOCTEST_WARN_THROWS_WITH(,,)
  2263. #define DOCTEST_REQUIRE_THROWS_WITH(expr, with, ...) DOCTEST_WARN_THROWS_WITH(,,)
  2264. #define DOCTEST_WARN_THROWS_WITH_AS(expr, with, ex, ...) DOCTEST_WARN_THROWS_WITH(,,)
  2265. #define DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ex, ...) DOCTEST_WARN_THROWS_WITH(,,)
  2266. #define DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ex, ...) DOCTEST_WARN_THROWS_WITH(,,)
  2267. #define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_WARN_THROWS_WITH(,,)
  2268. #define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_WARN_THROWS_WITH(,,)
  2269. #define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_WARN_THROWS_WITH(,,)
  2270. #define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_WARN_THROWS_WITH(,,)
  2271. #define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_WARN_THROWS_WITH(,,)
  2272. #define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_WARN_THROWS_WITH(,,)
  2273. #define DOCTEST_WARN_THROWS(...) [&] { try { __VA_ARGS__; return false; } catch (...) { return true; } }()
  2274. #define DOCTEST_CHECK_THROWS(...) [&] { try { __VA_ARGS__; return false; } catch (...) { return true; } }()
  2275. #define DOCTEST_REQUIRE_THROWS(...) [&] { try { __VA_ARGS__; return false; } catch (...) { return true; } }()
  2276. #define DOCTEST_WARN_THROWS_AS(expr, ...) [&] { try { expr; } catch (__VA_ARGS__) { return true; } catch (...) { } return false; }()
  2277. #define DOCTEST_CHECK_THROWS_AS(expr, ...) [&] { try { expr; } catch (__VA_ARGS__) { return true; } catch (...) { } return false; }()
  2278. #define DOCTEST_REQUIRE_THROWS_AS(expr, ...) [&] { try { expr; } catch (__VA_ARGS__) { return true; } catch (...) { } return false; }()
  2279. #define DOCTEST_WARN_NOTHROW(...) [&] { try { __VA_ARGS__; return true; } catch (...) { return false; } }()
  2280. #define DOCTEST_CHECK_NOTHROW(...) [&] { try { __VA_ARGS__; return true; } catch (...) { return false; } }()
  2281. #define DOCTEST_REQUIRE_NOTHROW(...) [&] { try { __VA_ARGS__; return true; } catch (...) { return false; } }()
  2282. #define DOCTEST_WARN_THROWS_MESSAGE(expr, ...) [&] { try { __VA_ARGS__; return false; } catch (...) { return true; } }()
  2283. #define DOCTEST_CHECK_THROWS_MESSAGE(expr, ...) [&] { try { __VA_ARGS__; return false; } catch (...) { return true; } }()
  2284. #define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, ...) [&] { try { __VA_ARGS__; return false; } catch (...) { return true; } }()
  2285. #define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, ...) [&] { try { expr; } catch (__VA_ARGS__) { return true; } catch (...) { } return false; }()
  2286. #define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, ...) [&] { try { expr; } catch (__VA_ARGS__) { return true; } catch (...) { } return false; }()
  2287. #define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) [&] { try { expr; } catch (__VA_ARGS__) { return true; } catch (...) { } return false; }()
  2288. #define DOCTEST_WARN_NOTHROW_MESSAGE(expr, ...) [&] { try { __VA_ARGS__; return true; } catch (...) { return false; } }()
  2289. #define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, ...) [&] { try { __VA_ARGS__; return true; } catch (...) { return false; } }()
  2290. #define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, ...) [&] { try { __VA_ARGS__; return true; } catch (...) { return false; } }()
  2291. #endif // DOCTEST_CONFIG_NO_EXCEPTIONS
  2292. #else // DOCTEST_CONFIG_EVALUATE_ASSERTS_EVEN_WHEN_DISABLED
  2293. #define DOCTEST_WARN(...) DOCTEST_FUNC_EMPTY
  2294. #define DOCTEST_CHECK(...) DOCTEST_FUNC_EMPTY
  2295. #define DOCTEST_REQUIRE(...) DOCTEST_FUNC_EMPTY
  2296. #define DOCTEST_WARN_FALSE(...) DOCTEST_FUNC_EMPTY
  2297. #define DOCTEST_CHECK_FALSE(...) DOCTEST_FUNC_EMPTY
  2298. #define DOCTEST_REQUIRE_FALSE(...) DOCTEST_FUNC_EMPTY
  2299. #define DOCTEST_WARN_MESSAGE(cond, ...) DOCTEST_FUNC_EMPTY
  2300. #define DOCTEST_CHECK_MESSAGE(cond, ...) DOCTEST_FUNC_EMPTY
  2301. #define DOCTEST_REQUIRE_MESSAGE(cond, ...) DOCTEST_FUNC_EMPTY
  2302. #define DOCTEST_WARN_FALSE_MESSAGE(cond, ...) DOCTEST_FUNC_EMPTY
  2303. #define DOCTEST_CHECK_FALSE_MESSAGE(cond, ...) DOCTEST_FUNC_EMPTY
  2304. #define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, ...) DOCTEST_FUNC_EMPTY
  2305. #define DOCTEST_WARN_EQ(...) DOCTEST_FUNC_EMPTY
  2306. #define DOCTEST_CHECK_EQ(...) DOCTEST_FUNC_EMPTY
  2307. #define DOCTEST_REQUIRE_EQ(...) DOCTEST_FUNC_EMPTY
  2308. #define DOCTEST_WARN_NE(...) DOCTEST_FUNC_EMPTY
  2309. #define DOCTEST_CHECK_NE(...) DOCTEST_FUNC_EMPTY
  2310. #define DOCTEST_REQUIRE_NE(...) DOCTEST_FUNC_EMPTY
  2311. #define DOCTEST_WARN_GT(...) DOCTEST_FUNC_EMPTY
  2312. #define DOCTEST_CHECK_GT(...) DOCTEST_FUNC_EMPTY
  2313. #define DOCTEST_REQUIRE_GT(...) DOCTEST_FUNC_EMPTY
  2314. #define DOCTEST_WARN_LT(...) DOCTEST_FUNC_EMPTY
  2315. #define DOCTEST_CHECK_LT(...) DOCTEST_FUNC_EMPTY
  2316. #define DOCTEST_REQUIRE_LT(...) DOCTEST_FUNC_EMPTY
  2317. #define DOCTEST_WARN_GE(...) DOCTEST_FUNC_EMPTY
  2318. #define DOCTEST_CHECK_GE(...) DOCTEST_FUNC_EMPTY
  2319. #define DOCTEST_REQUIRE_GE(...) DOCTEST_FUNC_EMPTY
  2320. #define DOCTEST_WARN_LE(...) DOCTEST_FUNC_EMPTY
  2321. #define DOCTEST_CHECK_LE(...) DOCTEST_FUNC_EMPTY
  2322. #define DOCTEST_REQUIRE_LE(...) DOCTEST_FUNC_EMPTY
  2323. #define DOCTEST_WARN_UNARY(...) DOCTEST_FUNC_EMPTY
  2324. #define DOCTEST_CHECK_UNARY(...) DOCTEST_FUNC_EMPTY
  2325. #define DOCTEST_REQUIRE_UNARY(...) DOCTEST_FUNC_EMPTY
  2326. #define DOCTEST_WARN_UNARY_FALSE(...) DOCTEST_FUNC_EMPTY
  2327. #define DOCTEST_CHECK_UNARY_FALSE(...) DOCTEST_FUNC_EMPTY
  2328. #define DOCTEST_REQUIRE_UNARY_FALSE(...) DOCTEST_FUNC_EMPTY
  2329. #ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
  2330. #define DOCTEST_WARN_THROWS(...) DOCTEST_FUNC_EMPTY
  2331. #define DOCTEST_CHECK_THROWS(...) DOCTEST_FUNC_EMPTY
  2332. #define DOCTEST_REQUIRE_THROWS(...) DOCTEST_FUNC_EMPTY
  2333. #define DOCTEST_WARN_THROWS_AS(expr, ...) DOCTEST_FUNC_EMPTY
  2334. #define DOCTEST_CHECK_THROWS_AS(expr, ...) DOCTEST_FUNC_EMPTY
  2335. #define DOCTEST_REQUIRE_THROWS_AS(expr, ...) DOCTEST_FUNC_EMPTY
  2336. #define DOCTEST_WARN_THROWS_WITH(expr, ...) DOCTEST_FUNC_EMPTY
  2337. #define DOCTEST_CHECK_THROWS_WITH(expr, ...) DOCTEST_FUNC_EMPTY
  2338. #define DOCTEST_REQUIRE_THROWS_WITH(expr, ...) DOCTEST_FUNC_EMPTY
  2339. #define DOCTEST_WARN_THROWS_WITH_AS(expr, with, ...) DOCTEST_FUNC_EMPTY
  2340. #define DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ...) DOCTEST_FUNC_EMPTY
  2341. #define DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ...) DOCTEST_FUNC_EMPTY
  2342. #define DOCTEST_WARN_NOTHROW(...) DOCTEST_FUNC_EMPTY
  2343. #define DOCTEST_CHECK_NOTHROW(...) DOCTEST_FUNC_EMPTY
  2344. #define DOCTEST_REQUIRE_NOTHROW(...) DOCTEST_FUNC_EMPTY
  2345. #define DOCTEST_WARN_THROWS_MESSAGE(expr, ...) DOCTEST_FUNC_EMPTY
  2346. #define DOCTEST_CHECK_THROWS_MESSAGE(expr, ...) DOCTEST_FUNC_EMPTY
  2347. #define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, ...) DOCTEST_FUNC_EMPTY
  2348. #define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_FUNC_EMPTY
  2349. #define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_FUNC_EMPTY
  2350. #define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_FUNC_EMPTY
  2351. #define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_FUNC_EMPTY
  2352. #define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_FUNC_EMPTY
  2353. #define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_FUNC_EMPTY
  2354. #define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_FUNC_EMPTY
  2355. #define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_FUNC_EMPTY
  2356. #define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_FUNC_EMPTY
  2357. #define DOCTEST_WARN_NOTHROW_MESSAGE(expr, ...) DOCTEST_FUNC_EMPTY
  2358. #define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, ...) DOCTEST_FUNC_EMPTY
  2359. #define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, ...) DOCTEST_FUNC_EMPTY
  2360. #endif // DOCTEST_CONFIG_NO_EXCEPTIONS
  2361. #endif // DOCTEST_CONFIG_EVALUATE_ASSERTS_EVEN_WHEN_DISABLED
  2362. #endif // DOCTEST_CONFIG_DISABLE
  2363. #ifdef DOCTEST_CONFIG_NO_EXCEPTIONS
  2364. #ifdef DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS
  2365. #define DOCTEST_EXCEPTION_EMPTY_FUNC DOCTEST_FUNC_EMPTY
  2366. #else // DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS
  2367. #define DOCTEST_EXCEPTION_EMPTY_FUNC [] { static_assert(false, "Exceptions are disabled! " \
  2368. "Use DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS if you want to compile with exceptions disabled."); return false; }()
  2369. #undef DOCTEST_REQUIRE
  2370. #undef DOCTEST_REQUIRE_FALSE
  2371. #undef DOCTEST_REQUIRE_MESSAGE
  2372. #undef DOCTEST_REQUIRE_FALSE_MESSAGE
  2373. #undef DOCTEST_REQUIRE_EQ
  2374. #undef DOCTEST_REQUIRE_NE
  2375. #undef DOCTEST_REQUIRE_GT
  2376. #undef DOCTEST_REQUIRE_LT
  2377. #undef DOCTEST_REQUIRE_GE
  2378. #undef DOCTEST_REQUIRE_LE
  2379. #undef DOCTEST_REQUIRE_UNARY
  2380. #undef DOCTEST_REQUIRE_UNARY_FALSE
  2381. #define DOCTEST_REQUIRE DOCTEST_EXCEPTION_EMPTY_FUNC
  2382. #define DOCTEST_REQUIRE_FALSE DOCTEST_EXCEPTION_EMPTY_FUNC
  2383. #define DOCTEST_REQUIRE_MESSAGE DOCTEST_EXCEPTION_EMPTY_FUNC
  2384. #define DOCTEST_REQUIRE_FALSE_MESSAGE DOCTEST_EXCEPTION_EMPTY_FUNC
  2385. #define DOCTEST_REQUIRE_EQ DOCTEST_EXCEPTION_EMPTY_FUNC
  2386. #define DOCTEST_REQUIRE_NE DOCTEST_EXCEPTION_EMPTY_FUNC
  2387. #define DOCTEST_REQUIRE_GT DOCTEST_EXCEPTION_EMPTY_FUNC
  2388. #define DOCTEST_REQUIRE_LT DOCTEST_EXCEPTION_EMPTY_FUNC
  2389. #define DOCTEST_REQUIRE_GE DOCTEST_EXCEPTION_EMPTY_FUNC
  2390. #define DOCTEST_REQUIRE_LE DOCTEST_EXCEPTION_EMPTY_FUNC
  2391. #define DOCTEST_REQUIRE_UNARY DOCTEST_EXCEPTION_EMPTY_FUNC
  2392. #define DOCTEST_REQUIRE_UNARY_FALSE DOCTEST_EXCEPTION_EMPTY_FUNC
  2393. #endif // DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS
  2394. #define DOCTEST_WARN_THROWS(...) DOCTEST_EXCEPTION_EMPTY_FUNC
  2395. #define DOCTEST_CHECK_THROWS(...) DOCTEST_EXCEPTION_EMPTY_FUNC
  2396. #define DOCTEST_REQUIRE_THROWS(...) DOCTEST_EXCEPTION_EMPTY_FUNC
  2397. #define DOCTEST_WARN_THROWS_AS(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
  2398. #define DOCTEST_CHECK_THROWS_AS(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
  2399. #define DOCTEST_REQUIRE_THROWS_AS(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
  2400. #define DOCTEST_WARN_THROWS_WITH(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
  2401. #define DOCTEST_CHECK_THROWS_WITH(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
  2402. #define DOCTEST_REQUIRE_THROWS_WITH(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
  2403. #define DOCTEST_WARN_THROWS_WITH_AS(expr, with, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
  2404. #define DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
  2405. #define DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
  2406. #define DOCTEST_WARN_NOTHROW(...) DOCTEST_EXCEPTION_EMPTY_FUNC
  2407. #define DOCTEST_CHECK_NOTHROW(...) DOCTEST_EXCEPTION_EMPTY_FUNC
  2408. #define DOCTEST_REQUIRE_NOTHROW(...) DOCTEST_EXCEPTION_EMPTY_FUNC
  2409. #define DOCTEST_WARN_THROWS_MESSAGE(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
  2410. #define DOCTEST_CHECK_THROWS_MESSAGE(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
  2411. #define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
  2412. #define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
  2413. #define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
  2414. #define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
  2415. #define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
  2416. #define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
  2417. #define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
  2418. #define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
  2419. #define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
  2420. #define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
  2421. #define DOCTEST_WARN_NOTHROW_MESSAGE(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
  2422. #define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
  2423. #define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
  2424. #endif // DOCTEST_CONFIG_NO_EXCEPTIONS
  2425. // clang-format off
  2426. // KEPT FOR BACKWARDS COMPATIBILITY - FORWARDING TO THE RIGHT MACROS
  2427. #define DOCTEST_FAST_WARN_EQ DOCTEST_WARN_EQ
  2428. #define DOCTEST_FAST_CHECK_EQ DOCTEST_CHECK_EQ
  2429. #define DOCTEST_FAST_REQUIRE_EQ DOCTEST_REQUIRE_EQ
  2430. #define DOCTEST_FAST_WARN_NE DOCTEST_WARN_NE
  2431. #define DOCTEST_FAST_CHECK_NE DOCTEST_CHECK_NE
  2432. #define DOCTEST_FAST_REQUIRE_NE DOCTEST_REQUIRE_NE
  2433. #define DOCTEST_FAST_WARN_GT DOCTEST_WARN_GT
  2434. #define DOCTEST_FAST_CHECK_GT DOCTEST_CHECK_GT
  2435. #define DOCTEST_FAST_REQUIRE_GT DOCTEST_REQUIRE_GT
  2436. #define DOCTEST_FAST_WARN_LT DOCTEST_WARN_LT
  2437. #define DOCTEST_FAST_CHECK_LT DOCTEST_CHECK_LT
  2438. #define DOCTEST_FAST_REQUIRE_LT DOCTEST_REQUIRE_LT
  2439. #define DOCTEST_FAST_WARN_GE DOCTEST_WARN_GE
  2440. #define DOCTEST_FAST_CHECK_GE DOCTEST_CHECK_GE
  2441. #define DOCTEST_FAST_REQUIRE_GE DOCTEST_REQUIRE_GE
  2442. #define DOCTEST_FAST_WARN_LE DOCTEST_WARN_LE
  2443. #define DOCTEST_FAST_CHECK_LE DOCTEST_CHECK_LE
  2444. #define DOCTEST_FAST_REQUIRE_LE DOCTEST_REQUIRE_LE
  2445. #define DOCTEST_FAST_WARN_UNARY DOCTEST_WARN_UNARY
  2446. #define DOCTEST_FAST_CHECK_UNARY DOCTEST_CHECK_UNARY
  2447. #define DOCTEST_FAST_REQUIRE_UNARY DOCTEST_REQUIRE_UNARY
  2448. #define DOCTEST_FAST_WARN_UNARY_FALSE DOCTEST_WARN_UNARY_FALSE
  2449. #define DOCTEST_FAST_CHECK_UNARY_FALSE DOCTEST_CHECK_UNARY_FALSE
  2450. #define DOCTEST_FAST_REQUIRE_UNARY_FALSE DOCTEST_REQUIRE_UNARY_FALSE
  2451. #define DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE(id, ...) DOCTEST_TEST_CASE_TEMPLATE_INVOKE(id,__VA_ARGS__)
  2452. // clang-format on
  2453. // BDD style macros
  2454. // clang-format off
  2455. #define DOCTEST_SCENARIO(name) DOCTEST_TEST_CASE(" Scenario: " name)
  2456. #define DOCTEST_SCENARIO_CLASS(name) DOCTEST_TEST_CASE_CLASS(" Scenario: " name)
  2457. #define DOCTEST_SCENARIO_TEMPLATE(name, T, ...) DOCTEST_TEST_CASE_TEMPLATE(" Scenario: " name, T, __VA_ARGS__)
  2458. #define DOCTEST_SCENARIO_TEMPLATE_DEFINE(name, T, id) DOCTEST_TEST_CASE_TEMPLATE_DEFINE(" Scenario: " name, T, id)
  2459. #define DOCTEST_GIVEN(name) DOCTEST_SUBCASE(" Given: " name)
  2460. #define DOCTEST_WHEN(name) DOCTEST_SUBCASE(" When: " name)
  2461. #define DOCTEST_AND_WHEN(name) DOCTEST_SUBCASE("And when: " name)
  2462. #define DOCTEST_THEN(name) DOCTEST_SUBCASE(" Then: " name)
  2463. #define DOCTEST_AND_THEN(name) DOCTEST_SUBCASE(" And: " name)
  2464. // clang-format on
  2465. // == SHORT VERSIONS OF THE MACROS
  2466. #ifndef DOCTEST_CONFIG_NO_SHORT_MACRO_NAMES
  2467. #define TEST_CASE(name) DOCTEST_TEST_CASE(name)
  2468. #define TEST_CASE_CLASS(name) DOCTEST_TEST_CASE_CLASS(name)
  2469. #define TEST_CASE_FIXTURE(x, name) DOCTEST_TEST_CASE_FIXTURE(x, name)
  2470. #define TYPE_TO_STRING_AS(str, ...) DOCTEST_TYPE_TO_STRING_AS(str, __VA_ARGS__)
  2471. #define TYPE_TO_STRING(...) DOCTEST_TYPE_TO_STRING(__VA_ARGS__)
  2472. #define TEST_CASE_TEMPLATE(name, T, ...) DOCTEST_TEST_CASE_TEMPLATE(name, T, __VA_ARGS__)
  2473. #define TEST_CASE_TEMPLATE_DEFINE(name, T, id) DOCTEST_TEST_CASE_TEMPLATE_DEFINE(name, T, id)
  2474. #define TEST_CASE_TEMPLATE_INVOKE(id, ...) DOCTEST_TEST_CASE_TEMPLATE_INVOKE(id, __VA_ARGS__)
  2475. #define TEST_CASE_TEMPLATE_APPLY(id, ...) DOCTEST_TEST_CASE_TEMPLATE_APPLY(id, __VA_ARGS__)
  2476. #define SUBCASE(name) DOCTEST_SUBCASE(name)
  2477. #define TEST_SUITE(decorators) DOCTEST_TEST_SUITE(decorators)
  2478. #define TEST_SUITE_BEGIN(name) DOCTEST_TEST_SUITE_BEGIN(name)
  2479. #define TEST_SUITE_END DOCTEST_TEST_SUITE_END
  2480. #define REGISTER_EXCEPTION_TRANSLATOR(signature) DOCTEST_REGISTER_EXCEPTION_TRANSLATOR(signature)
  2481. #define REGISTER_REPORTER(name, priority, reporter) DOCTEST_REGISTER_REPORTER(name, priority, reporter)
  2482. #define REGISTER_LISTENER(name, priority, reporter) DOCTEST_REGISTER_LISTENER(name, priority, reporter)
  2483. #define INFO(...) DOCTEST_INFO(__VA_ARGS__)
  2484. #define CAPTURE(x) DOCTEST_CAPTURE(x)
  2485. #define ADD_MESSAGE_AT(file, line, ...) DOCTEST_ADD_MESSAGE_AT(file, line, __VA_ARGS__)
  2486. #define ADD_FAIL_CHECK_AT(file, line, ...) DOCTEST_ADD_FAIL_CHECK_AT(file, line, __VA_ARGS__)
  2487. #define ADD_FAIL_AT(file, line, ...) DOCTEST_ADD_FAIL_AT(file, line, __VA_ARGS__)
  2488. #define MESSAGE(...) DOCTEST_MESSAGE(__VA_ARGS__)
  2489. #define FAIL_CHECK(...) DOCTEST_FAIL_CHECK(__VA_ARGS__)
  2490. #define FAIL(...) DOCTEST_FAIL(__VA_ARGS__)
  2491. #define TO_LVALUE(...) DOCTEST_TO_LVALUE(__VA_ARGS__)
  2492. #define WARN(...) DOCTEST_WARN(__VA_ARGS__)
  2493. #define WARN_FALSE(...) DOCTEST_WARN_FALSE(__VA_ARGS__)
  2494. #define WARN_THROWS(...) DOCTEST_WARN_THROWS(__VA_ARGS__)
  2495. #define WARN_THROWS_AS(expr, ...) DOCTEST_WARN_THROWS_AS(expr, __VA_ARGS__)
  2496. #define WARN_THROWS_WITH(expr, ...) DOCTEST_WARN_THROWS_WITH(expr, __VA_ARGS__)
  2497. #define WARN_THROWS_WITH_AS(expr, with, ...) DOCTEST_WARN_THROWS_WITH_AS(expr, with, __VA_ARGS__)
  2498. #define WARN_NOTHROW(...) DOCTEST_WARN_NOTHROW(__VA_ARGS__)
  2499. #define CHECK(...) DOCTEST_CHECK(__VA_ARGS__)
  2500. #define CHECK_FALSE(...) DOCTEST_CHECK_FALSE(__VA_ARGS__)
  2501. #define CHECK_THROWS(...) DOCTEST_CHECK_THROWS(__VA_ARGS__)
  2502. #define CHECK_THROWS_AS(expr, ...) DOCTEST_CHECK_THROWS_AS(expr, __VA_ARGS__)
  2503. #define CHECK_THROWS_WITH(expr, ...) DOCTEST_CHECK_THROWS_WITH(expr, __VA_ARGS__)
  2504. #define CHECK_THROWS_WITH_AS(expr, with, ...) DOCTEST_CHECK_THROWS_WITH_AS(expr, with, __VA_ARGS__)
  2505. #define CHECK_NOTHROW(...) DOCTEST_CHECK_NOTHROW(__VA_ARGS__)
  2506. #define REQUIRE(...) DOCTEST_REQUIRE(__VA_ARGS__)
  2507. #define REQUIRE_FALSE(...) DOCTEST_REQUIRE_FALSE(__VA_ARGS__)
  2508. #define REQUIRE_THROWS(...) DOCTEST_REQUIRE_THROWS(__VA_ARGS__)
  2509. #define REQUIRE_THROWS_AS(expr, ...) DOCTEST_REQUIRE_THROWS_AS(expr, __VA_ARGS__)
  2510. #define REQUIRE_THROWS_WITH(expr, ...) DOCTEST_REQUIRE_THROWS_WITH(expr, __VA_ARGS__)
  2511. #define REQUIRE_THROWS_WITH_AS(expr, with, ...) DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, __VA_ARGS__)
  2512. #define REQUIRE_NOTHROW(...) DOCTEST_REQUIRE_NOTHROW(__VA_ARGS__)
  2513. #define WARN_MESSAGE(cond, ...) DOCTEST_WARN_MESSAGE(cond, __VA_ARGS__)
  2514. #define WARN_FALSE_MESSAGE(cond, ...) DOCTEST_WARN_FALSE_MESSAGE(cond, __VA_ARGS__)
  2515. #define WARN_THROWS_MESSAGE(expr, ...) DOCTEST_WARN_THROWS_MESSAGE(expr, __VA_ARGS__)
  2516. #define WARN_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, __VA_ARGS__)
  2517. #define WARN_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, __VA_ARGS__)
  2518. #define WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, __VA_ARGS__)
  2519. #define WARN_NOTHROW_MESSAGE(expr, ...) DOCTEST_WARN_NOTHROW_MESSAGE(expr, __VA_ARGS__)
  2520. #define CHECK_MESSAGE(cond, ...) DOCTEST_CHECK_MESSAGE(cond, __VA_ARGS__)
  2521. #define CHECK_FALSE_MESSAGE(cond, ...) DOCTEST_CHECK_FALSE_MESSAGE(cond, __VA_ARGS__)
  2522. #define CHECK_THROWS_MESSAGE(expr, ...) DOCTEST_CHECK_THROWS_MESSAGE(expr, __VA_ARGS__)
  2523. #define CHECK_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, __VA_ARGS__)
  2524. #define CHECK_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, __VA_ARGS__)
  2525. #define CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, __VA_ARGS__)
  2526. #define CHECK_NOTHROW_MESSAGE(expr, ...) DOCTEST_CHECK_NOTHROW_MESSAGE(expr, __VA_ARGS__)
  2527. #define REQUIRE_MESSAGE(cond, ...) DOCTEST_REQUIRE_MESSAGE(cond, __VA_ARGS__)
  2528. #define REQUIRE_FALSE_MESSAGE(cond, ...) DOCTEST_REQUIRE_FALSE_MESSAGE(cond, __VA_ARGS__)
  2529. #define REQUIRE_THROWS_MESSAGE(expr, ...) DOCTEST_REQUIRE_THROWS_MESSAGE(expr, __VA_ARGS__)
  2530. #define REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, __VA_ARGS__)
  2531. #define REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, __VA_ARGS__)
  2532. #define REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, __VA_ARGS__)
  2533. #define REQUIRE_NOTHROW_MESSAGE(expr, ...) DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, __VA_ARGS__)
  2534. #define SCENARIO(name) DOCTEST_SCENARIO(name)
  2535. #define SCENARIO_CLASS(name) DOCTEST_SCENARIO_CLASS(name)
  2536. #define SCENARIO_TEMPLATE(name, T, ...) DOCTEST_SCENARIO_TEMPLATE(name, T, __VA_ARGS__)
  2537. #define SCENARIO_TEMPLATE_DEFINE(name, T, id) DOCTEST_SCENARIO_TEMPLATE_DEFINE(name, T, id)
  2538. #define GIVEN(name) DOCTEST_GIVEN(name)
  2539. #define WHEN(name) DOCTEST_WHEN(name)
  2540. #define AND_WHEN(name) DOCTEST_AND_WHEN(name)
  2541. #define THEN(name) DOCTEST_THEN(name)
  2542. #define AND_THEN(name) DOCTEST_AND_THEN(name)
  2543. #define WARN_EQ(...) DOCTEST_WARN_EQ(__VA_ARGS__)
  2544. #define CHECK_EQ(...) DOCTEST_CHECK_EQ(__VA_ARGS__)
  2545. #define REQUIRE_EQ(...) DOCTEST_REQUIRE_EQ(__VA_ARGS__)
  2546. #define WARN_NE(...) DOCTEST_WARN_NE(__VA_ARGS__)
  2547. #define CHECK_NE(...) DOCTEST_CHECK_NE(__VA_ARGS__)
  2548. #define REQUIRE_NE(...) DOCTEST_REQUIRE_NE(__VA_ARGS__)
  2549. #define WARN_GT(...) DOCTEST_WARN_GT(__VA_ARGS__)
  2550. #define CHECK_GT(...) DOCTEST_CHECK_GT(__VA_ARGS__)
  2551. #define REQUIRE_GT(...) DOCTEST_REQUIRE_GT(__VA_ARGS__)
  2552. #define WARN_LT(...) DOCTEST_WARN_LT(__VA_ARGS__)
  2553. #define CHECK_LT(...) DOCTEST_CHECK_LT(__VA_ARGS__)
  2554. #define REQUIRE_LT(...) DOCTEST_REQUIRE_LT(__VA_ARGS__)
  2555. #define WARN_GE(...) DOCTEST_WARN_GE(__VA_ARGS__)
  2556. #define CHECK_GE(...) DOCTEST_CHECK_GE(__VA_ARGS__)
  2557. #define REQUIRE_GE(...) DOCTEST_REQUIRE_GE(__VA_ARGS__)
  2558. #define WARN_LE(...) DOCTEST_WARN_LE(__VA_ARGS__)
  2559. #define CHECK_LE(...) DOCTEST_CHECK_LE(__VA_ARGS__)
  2560. #define REQUIRE_LE(...) DOCTEST_REQUIRE_LE(__VA_ARGS__)
  2561. #define WARN_UNARY(...) DOCTEST_WARN_UNARY(__VA_ARGS__)
  2562. #define CHECK_UNARY(...) DOCTEST_CHECK_UNARY(__VA_ARGS__)
  2563. #define REQUIRE_UNARY(...) DOCTEST_REQUIRE_UNARY(__VA_ARGS__)
  2564. #define WARN_UNARY_FALSE(...) DOCTEST_WARN_UNARY_FALSE(__VA_ARGS__)
  2565. #define CHECK_UNARY_FALSE(...) DOCTEST_CHECK_UNARY_FALSE(__VA_ARGS__)
  2566. #define REQUIRE_UNARY_FALSE(...) DOCTEST_REQUIRE_UNARY_FALSE(__VA_ARGS__)
  2567. // KEPT FOR BACKWARDS COMPATIBILITY
  2568. #define FAST_WARN_EQ(...) DOCTEST_FAST_WARN_EQ(__VA_ARGS__)
  2569. #define FAST_CHECK_EQ(...) DOCTEST_FAST_CHECK_EQ(__VA_ARGS__)
  2570. #define FAST_REQUIRE_EQ(...) DOCTEST_FAST_REQUIRE_EQ(__VA_ARGS__)
  2571. #define FAST_WARN_NE(...) DOCTEST_FAST_WARN_NE(__VA_ARGS__)
  2572. #define FAST_CHECK_NE(...) DOCTEST_FAST_CHECK_NE(__VA_ARGS__)
  2573. #define FAST_REQUIRE_NE(...) DOCTEST_FAST_REQUIRE_NE(__VA_ARGS__)
  2574. #define FAST_WARN_GT(...) DOCTEST_FAST_WARN_GT(__VA_ARGS__)
  2575. #define FAST_CHECK_GT(...) DOCTEST_FAST_CHECK_GT(__VA_ARGS__)
  2576. #define FAST_REQUIRE_GT(...) DOCTEST_FAST_REQUIRE_GT(__VA_ARGS__)
  2577. #define FAST_WARN_LT(...) DOCTEST_FAST_WARN_LT(__VA_ARGS__)
  2578. #define FAST_CHECK_LT(...) DOCTEST_FAST_CHECK_LT(__VA_ARGS__)
  2579. #define FAST_REQUIRE_LT(...) DOCTEST_FAST_REQUIRE_LT(__VA_ARGS__)
  2580. #define FAST_WARN_GE(...) DOCTEST_FAST_WARN_GE(__VA_ARGS__)
  2581. #define FAST_CHECK_GE(...) DOCTEST_FAST_CHECK_GE(__VA_ARGS__)
  2582. #define FAST_REQUIRE_GE(...) DOCTEST_FAST_REQUIRE_GE(__VA_ARGS__)
  2583. #define FAST_WARN_LE(...) DOCTEST_FAST_WARN_LE(__VA_ARGS__)
  2584. #define FAST_CHECK_LE(...) DOCTEST_FAST_CHECK_LE(__VA_ARGS__)
  2585. #define FAST_REQUIRE_LE(...) DOCTEST_FAST_REQUIRE_LE(__VA_ARGS__)
  2586. #define FAST_WARN_UNARY(...) DOCTEST_FAST_WARN_UNARY(__VA_ARGS__)
  2587. #define FAST_CHECK_UNARY(...) DOCTEST_FAST_CHECK_UNARY(__VA_ARGS__)
  2588. #define FAST_REQUIRE_UNARY(...) DOCTEST_FAST_REQUIRE_UNARY(__VA_ARGS__)
  2589. #define FAST_WARN_UNARY_FALSE(...) DOCTEST_FAST_WARN_UNARY_FALSE(__VA_ARGS__)
  2590. #define FAST_CHECK_UNARY_FALSE(...) DOCTEST_FAST_CHECK_UNARY_FALSE(__VA_ARGS__)
  2591. #define FAST_REQUIRE_UNARY_FALSE(...) DOCTEST_FAST_REQUIRE_UNARY_FALSE(__VA_ARGS__)
  2592. #define TEST_CASE_TEMPLATE_INSTANTIATE(id, ...) DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE(id, __VA_ARGS__)
  2593. #endif // DOCTEST_CONFIG_NO_SHORT_MACRO_NAMES
  2594. #ifndef DOCTEST_CONFIG_DISABLE
  2595. // this is here to clear the 'current test suite' for the current translation unit - at the top
  2596. DOCTEST_TEST_SUITE_END();
  2597. #endif // DOCTEST_CONFIG_DISABLE
  2598. DOCTEST_CLANG_SUPPRESS_WARNING_POP
  2599. DOCTEST_MSVC_SUPPRESS_WARNING_POP
  2600. DOCTEST_GCC_SUPPRESS_WARNING_POP
  2601. DOCTEST_SUPPRESS_COMMON_WARNINGS_POP
  2602. #endif // DOCTEST_LIBRARY_INCLUDED
  2603. #ifndef DOCTEST_SINGLE_HEADER
  2604. #define DOCTEST_SINGLE_HEADER
  2605. #endif // DOCTEST_SINGLE_HEADER
  2606. #if defined(DOCTEST_CONFIG_IMPLEMENT) || !defined(DOCTEST_SINGLE_HEADER)
  2607. #ifndef DOCTEST_SINGLE_HEADER
  2608. #include "doctest_fwd.h"
  2609. #endif // DOCTEST_SINGLE_HEADER
  2610. DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wunused-macros")
  2611. #ifndef DOCTEST_LIBRARY_IMPLEMENTATION
  2612. #define DOCTEST_LIBRARY_IMPLEMENTATION
  2613. DOCTEST_CLANG_SUPPRESS_WARNING_POP
  2614. DOCTEST_SUPPRESS_COMMON_WARNINGS_PUSH
  2615. DOCTEST_CLANG_SUPPRESS_WARNING_PUSH
  2616. DOCTEST_CLANG_SUPPRESS_WARNING("-Wglobal-constructors")
  2617. DOCTEST_CLANG_SUPPRESS_WARNING("-Wexit-time-destructors")
  2618. DOCTEST_CLANG_SUPPRESS_WARNING("-Wsign-conversion")
  2619. DOCTEST_CLANG_SUPPRESS_WARNING("-Wshorten-64-to-32")
  2620. DOCTEST_CLANG_SUPPRESS_WARNING("-Wmissing-variable-declarations")
  2621. DOCTEST_CLANG_SUPPRESS_WARNING("-Wswitch")
  2622. DOCTEST_CLANG_SUPPRESS_WARNING("-Wswitch-enum")
  2623. DOCTEST_CLANG_SUPPRESS_WARNING("-Wcovered-switch-default")
  2624. DOCTEST_CLANG_SUPPRESS_WARNING("-Wmissing-noreturn")
  2625. DOCTEST_CLANG_SUPPRESS_WARNING("-Wdisabled-macro-expansion")
  2626. DOCTEST_CLANG_SUPPRESS_WARNING("-Wmissing-braces")
  2627. DOCTEST_CLANG_SUPPRESS_WARNING("-Wmissing-field-initializers")
  2628. DOCTEST_CLANG_SUPPRESS_WARNING("-Wunused-member-function")
  2629. DOCTEST_CLANG_SUPPRESS_WARNING("-Wnonportable-system-include-path")
  2630. DOCTEST_GCC_SUPPRESS_WARNING_PUSH
  2631. DOCTEST_GCC_SUPPRESS_WARNING("-Wconversion")
  2632. DOCTEST_GCC_SUPPRESS_WARNING("-Wsign-conversion")
  2633. DOCTEST_GCC_SUPPRESS_WARNING("-Wmissing-field-initializers")
  2634. DOCTEST_GCC_SUPPRESS_WARNING("-Wmissing-braces")
  2635. DOCTEST_GCC_SUPPRESS_WARNING("-Wswitch")
  2636. DOCTEST_GCC_SUPPRESS_WARNING("-Wswitch-enum")
  2637. DOCTEST_GCC_SUPPRESS_WARNING("-Wswitch-default")
  2638. DOCTEST_GCC_SUPPRESS_WARNING("-Wunsafe-loop-optimizations")
  2639. DOCTEST_GCC_SUPPRESS_WARNING("-Wold-style-cast")
  2640. DOCTEST_GCC_SUPPRESS_WARNING("-Wunused-function")
  2641. DOCTEST_GCC_SUPPRESS_WARNING("-Wmultiple-inheritance")
  2642. DOCTEST_GCC_SUPPRESS_WARNING("-Wsuggest-attribute")
  2643. DOCTEST_MSVC_SUPPRESS_WARNING_PUSH
  2644. DOCTEST_MSVC_SUPPRESS_WARNING(4267) // 'var' : conversion from 'x' to 'y', possible loss of data
  2645. DOCTEST_MSVC_SUPPRESS_WARNING(4530) // C++ exception handler used, but unwind semantics not enabled
  2646. DOCTEST_MSVC_SUPPRESS_WARNING(4577) // 'noexcept' used with no exception handling mode specified
  2647. DOCTEST_MSVC_SUPPRESS_WARNING(4774) // format string expected in argument is not a string literal
  2648. DOCTEST_MSVC_SUPPRESS_WARNING(4365) // conversion from 'int' to 'unsigned', signed/unsigned mismatch
  2649. DOCTEST_MSVC_SUPPRESS_WARNING(5039) // pointer to potentially throwing function passed to extern C
  2650. DOCTEST_MSVC_SUPPRESS_WARNING(4800) // forcing value to bool 'true' or 'false' (performance warning)
  2651. DOCTEST_MSVC_SUPPRESS_WARNING(5245) // unreferenced function with internal linkage has been removed
  2652. DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_BEGIN
  2653. // required includes - will go only in one translation unit!
  2654. #include <ctime>
  2655. #include <cmath>
  2656. #include <climits>
  2657. // borland (Embarcadero) compiler requires math.h and not cmath - https://github.com/doctest/doctest/pull/37
  2658. #ifdef __BORLANDC__
  2659. #include <math.h>
  2660. #endif // __BORLANDC__
  2661. #include <new>
  2662. #include <cstdio>
  2663. #include <cstdlib>
  2664. #include <cstring>
  2665. #include <limits>
  2666. #include <utility>
  2667. #include <fstream>
  2668. #include <sstream>
  2669. #ifndef DOCTEST_CONFIG_NO_INCLUDE_IOSTREAM
  2670. #include <iostream>
  2671. #endif // DOCTEST_CONFIG_NO_INCLUDE_IOSTREAM
  2672. #include <algorithm>
  2673. #include <iomanip>
  2674. #include <vector>
  2675. #ifndef DOCTEST_CONFIG_NO_MULTITHREADING
  2676. #include <atomic>
  2677. #include <mutex>
  2678. #define DOCTEST_DECLARE_MUTEX(name) std::mutex name;
  2679. #define DOCTEST_DECLARE_STATIC_MUTEX(name) static DOCTEST_DECLARE_MUTEX(name)
  2680. #define DOCTEST_LOCK_MUTEX(name) std::lock_guard<std::mutex> DOCTEST_ANONYMOUS(DOCTEST_ANON_LOCK_)(name);
  2681. #else // DOCTEST_CONFIG_NO_MULTITHREADING
  2682. #define DOCTEST_DECLARE_MUTEX(name)
  2683. #define DOCTEST_DECLARE_STATIC_MUTEX(name)
  2684. #define DOCTEST_LOCK_MUTEX(name)
  2685. #endif // DOCTEST_CONFIG_NO_MULTITHREADING
  2686. #include <set>
  2687. #include <map>
  2688. #include <unordered_set>
  2689. #include <exception>
  2690. #include <stdexcept>
  2691. #include <csignal>
  2692. #include <cfloat>
  2693. #include <cctype>
  2694. #include <cstdint>
  2695. #include <string>
  2696. #ifdef DOCTEST_PLATFORM_MAC
  2697. #include <sys/types.h>
  2698. #include <unistd.h>
  2699. #include <sys/sysctl.h>
  2700. #endif // DOCTEST_PLATFORM_MAC
  2701. #ifdef DOCTEST_PLATFORM_WINDOWS
  2702. // defines for a leaner windows.h
  2703. #ifndef WIN32_LEAN_AND_MEAN
  2704. #define WIN32_LEAN_AND_MEAN
  2705. #define DOCTEST_UNDEF_WIN32_LEAN_AND_MEAN
  2706. #endif // WIN32_LEAN_AND_MEAN
  2707. #ifndef NOMINMAX
  2708. #define NOMINMAX
  2709. #define DOCTEST_UNDEF_NOMINMAX
  2710. #endif // NOMINMAX
  2711. // not sure what AfxWin.h is for - here I do what Catch does
  2712. #ifdef __AFXDLL
  2713. #include <AfxWin.h>
  2714. #else
  2715. #include <windows.h>
  2716. #endif
  2717. #include <io.h>
  2718. #else // DOCTEST_PLATFORM_WINDOWS
  2719. #include <sys/time.h>
  2720. #include <unistd.h>
  2721. #endif // DOCTEST_PLATFORM_WINDOWS
  2722. // this is a fix for https://github.com/doctest/doctest/issues/348
  2723. // https://mail.gnome.org/archives/xml/2012-January/msg00000.html
  2724. #if !defined(HAVE_UNISTD_H) && !defined(STDOUT_FILENO)
  2725. #define STDOUT_FILENO fileno(stdout)
  2726. #endif // HAVE_UNISTD_H
  2727. DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_END
  2728. // counts the number of elements in a C array
  2729. #define DOCTEST_COUNTOF(x) (sizeof(x) / sizeof(x[0]))
  2730. #ifdef DOCTEST_CONFIG_DISABLE
  2731. #define DOCTEST_BRANCH_ON_DISABLED(if_disabled, if_not_disabled) if_disabled
  2732. #else // DOCTEST_CONFIG_DISABLE
  2733. #define DOCTEST_BRANCH_ON_DISABLED(if_disabled, if_not_disabled) if_not_disabled
  2734. #endif // DOCTEST_CONFIG_DISABLE
  2735. #ifndef DOCTEST_CONFIG_OPTIONS_PREFIX
  2736. #define DOCTEST_CONFIG_OPTIONS_PREFIX "dt-"
  2737. #endif
  2738. #ifndef DOCTEST_CONFIG_OPTIONS_FILE_PREFIX_SEPARATOR
  2739. #define DOCTEST_CONFIG_OPTIONS_FILE_PREFIX_SEPARATOR ':'
  2740. #endif
  2741. #ifndef DOCTEST_THREAD_LOCAL
  2742. #if defined(DOCTEST_CONFIG_NO_MULTITHREADING) || DOCTEST_MSVC && (DOCTEST_MSVC < DOCTEST_COMPILER(19, 0, 0))
  2743. #define DOCTEST_THREAD_LOCAL
  2744. #else // DOCTEST_MSVC
  2745. #define DOCTEST_THREAD_LOCAL thread_local
  2746. #endif // DOCTEST_MSVC
  2747. #endif // DOCTEST_THREAD_LOCAL
  2748. #ifndef DOCTEST_MULTI_LANE_ATOMICS_THREAD_LANES
  2749. #define DOCTEST_MULTI_LANE_ATOMICS_THREAD_LANES 32
  2750. #endif
  2751. #ifndef DOCTEST_MULTI_LANE_ATOMICS_CACHE_LINE_SIZE
  2752. #define DOCTEST_MULTI_LANE_ATOMICS_CACHE_LINE_SIZE 64
  2753. #endif
  2754. #ifdef DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS
  2755. #define DOCTEST_OPTIONS_PREFIX_DISPLAY DOCTEST_CONFIG_OPTIONS_PREFIX
  2756. #else
  2757. #define DOCTEST_OPTIONS_PREFIX_DISPLAY ""
  2758. #endif
  2759. #if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
  2760. #define DOCTEST_CONFIG_NO_MULTI_LANE_ATOMICS
  2761. #endif
  2762. #ifndef DOCTEST_CDECL
  2763. #define DOCTEST_CDECL __cdecl
  2764. #endif
  2765. namespace doctest {
  2766. bool is_running_in_test = false;
  2767. namespace {
  2768. using namespace detail;
  2769. template <typename Ex>
  2770. DOCTEST_NORETURN void throw_exception(Ex const& e) {
  2771. #ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
  2772. throw e;
  2773. #else // DOCTEST_CONFIG_NO_EXCEPTIONS
  2774. #ifdef DOCTEST_CONFIG_HANDLE_EXCEPTION
  2775. DOCTEST_CONFIG_HANDLE_EXCEPTION(e);
  2776. #else // DOCTEST_CONFIG_HANDLE_EXCEPTION
  2777. #ifndef DOCTEST_CONFIG_NO_INCLUDE_IOSTREAM
  2778. std::cerr << "doctest will terminate because it needed to throw an exception.\n"
  2779. << "The message was: " << e.what() << '\n';
  2780. #endif // DOCTEST_CONFIG_NO_INCLUDE_IOSTREAM
  2781. #endif // DOCTEST_CONFIG_HANDLE_EXCEPTION
  2782. std::terminate();
  2783. #endif // DOCTEST_CONFIG_NO_EXCEPTIONS
  2784. }
  2785. #ifndef DOCTEST_INTERNAL_ERROR
  2786. #define DOCTEST_INTERNAL_ERROR(msg) \
  2787. throw_exception(std::logic_error( \
  2788. __FILE__ ":" DOCTEST_TOSTR(__LINE__) ": Internal doctest error: " msg))
  2789. #endif // DOCTEST_INTERNAL_ERROR
  2790. // case insensitive strcmp
  2791. int stricmp(const char* a, const char* b) {
  2792. for(;; a++, b++) {
  2793. const int d = tolower(*a) - tolower(*b);
  2794. if(d != 0 || !*a)
  2795. return d;
  2796. }
  2797. }
  2798. struct Endianness
  2799. {
  2800. enum Arch
  2801. {
  2802. Big,
  2803. Little
  2804. };
  2805. static Arch which() {
  2806. int x = 1;
  2807. // casting any data pointer to char* is allowed
  2808. auto ptr = reinterpret_cast<char*>(&x);
  2809. if(*ptr)
  2810. return Little;
  2811. return Big;
  2812. }
  2813. };
  2814. } // namespace
  2815. namespace detail {
  2816. DOCTEST_THREAD_LOCAL class
  2817. {
  2818. std::vector<std::streampos> stack;
  2819. std::stringstream ss;
  2820. public:
  2821. std::ostream* push() {
  2822. stack.push_back(ss.tellp());
  2823. return &ss;
  2824. }
  2825. String pop() {
  2826. if (stack.empty())
  2827. DOCTEST_INTERNAL_ERROR("TLSS was empty when trying to pop!");
  2828. std::streampos pos = stack.back();
  2829. stack.pop_back();
  2830. unsigned sz = static_cast<unsigned>(ss.tellp() - pos);
  2831. ss.rdbuf()->pubseekpos(pos, std::ios::in | std::ios::out);
  2832. return String(ss, sz);
  2833. }
  2834. } g_oss;
  2835. std::ostream* tlssPush() {
  2836. return g_oss.push();
  2837. }
  2838. String tlssPop() {
  2839. return g_oss.pop();
  2840. }
  2841. #ifndef DOCTEST_CONFIG_DISABLE
  2842. namespace timer_large_integer
  2843. {
  2844. #if defined(DOCTEST_PLATFORM_WINDOWS)
  2845. using type = ULONGLONG;
  2846. #else // DOCTEST_PLATFORM_WINDOWS
  2847. using type = std::uint64_t;
  2848. #endif // DOCTEST_PLATFORM_WINDOWS
  2849. }
  2850. using ticks_t = timer_large_integer::type;
  2851. #ifdef DOCTEST_CONFIG_GETCURRENTTICKS
  2852. ticks_t getCurrentTicks() { return DOCTEST_CONFIG_GETCURRENTTICKS(); }
  2853. #elif defined(DOCTEST_PLATFORM_WINDOWS)
  2854. ticks_t getCurrentTicks() {
  2855. static LARGE_INTEGER hz = { {0} }, hzo = { {0} };
  2856. if(!hz.QuadPart) {
  2857. QueryPerformanceFrequency(&hz);
  2858. QueryPerformanceCounter(&hzo);
  2859. }
  2860. LARGE_INTEGER t;
  2861. QueryPerformanceCounter(&t);
  2862. return ((t.QuadPart - hzo.QuadPart) * LONGLONG(1000000)) / hz.QuadPart;
  2863. }
  2864. #else // DOCTEST_PLATFORM_WINDOWS
  2865. ticks_t getCurrentTicks() {
  2866. timeval t;
  2867. gettimeofday(&t, nullptr);
  2868. return static_cast<ticks_t>(t.tv_sec) * 1000000 + static_cast<ticks_t>(t.tv_usec);
  2869. }
  2870. #endif // DOCTEST_PLATFORM_WINDOWS
  2871. struct Timer
  2872. {
  2873. void start() { m_ticks = getCurrentTicks(); }
  2874. unsigned int getElapsedMicroseconds() const {
  2875. return static_cast<unsigned int>(getCurrentTicks() - m_ticks);
  2876. }
  2877. //unsigned int getElapsedMilliseconds() const {
  2878. // return static_cast<unsigned int>(getElapsedMicroseconds() / 1000);
  2879. //}
  2880. double getElapsedSeconds() const { return static_cast<double>(getCurrentTicks() - m_ticks) / 1000000.0; }
  2881. private:
  2882. ticks_t m_ticks = 0;
  2883. };
  2884. #ifdef DOCTEST_CONFIG_NO_MULTITHREADING
  2885. template <typename T>
  2886. using Atomic = T;
  2887. #else // DOCTEST_CONFIG_NO_MULTITHREADING
  2888. template <typename T>
  2889. using Atomic = std::atomic<T>;
  2890. #endif // DOCTEST_CONFIG_NO_MULTITHREADING
  2891. #if defined(DOCTEST_CONFIG_NO_MULTI_LANE_ATOMICS) || defined(DOCTEST_CONFIG_NO_MULTITHREADING)
  2892. template <typename T>
  2893. using MultiLaneAtomic = Atomic<T>;
  2894. #else // DOCTEST_CONFIG_NO_MULTI_LANE_ATOMICS
  2895. // Provides a multilane implementation of an atomic variable that supports add, sub, load,
  2896. // store. Instead of using a single atomic variable, this splits up into multiple ones,
  2897. // each sitting on a separate cache line. The goal is to provide a speedup when most
  2898. // operations are modifying. It achieves this with two properties:
  2899. //
  2900. // * Multiple atomics are used, so chance of congestion from the same atomic is reduced.
  2901. // * Each atomic sits on a separate cache line, so false sharing is reduced.
  2902. //
  2903. // The disadvantage is that there is a small overhead due to the use of TLS, and load/store
  2904. // is slower because all atomics have to be accessed.
  2905. template <typename T>
  2906. class MultiLaneAtomic
  2907. {
  2908. struct CacheLineAlignedAtomic
  2909. {
  2910. Atomic<T> atomic{};
  2911. char padding[DOCTEST_MULTI_LANE_ATOMICS_CACHE_LINE_SIZE - sizeof(Atomic<T>)];
  2912. };
  2913. CacheLineAlignedAtomic m_atomics[DOCTEST_MULTI_LANE_ATOMICS_THREAD_LANES];
  2914. static_assert(sizeof(CacheLineAlignedAtomic) == DOCTEST_MULTI_LANE_ATOMICS_CACHE_LINE_SIZE,
  2915. "guarantee one atomic takes exactly one cache line");
  2916. public:
  2917. T operator++() DOCTEST_NOEXCEPT { return fetch_add(1) + 1; }
  2918. T operator++(int) DOCTEST_NOEXCEPT { return fetch_add(1); }
  2919. T fetch_add(T arg, std::memory_order order = std::memory_order_seq_cst) DOCTEST_NOEXCEPT {
  2920. return myAtomic().fetch_add(arg, order);
  2921. }
  2922. T fetch_sub(T arg, std::memory_order order = std::memory_order_seq_cst) DOCTEST_NOEXCEPT {
  2923. return myAtomic().fetch_sub(arg, order);
  2924. }
  2925. operator T() const DOCTEST_NOEXCEPT { return load(); }
  2926. T load(std::memory_order order = std::memory_order_seq_cst) const DOCTEST_NOEXCEPT {
  2927. auto result = T();
  2928. for(auto const& c : m_atomics) {
  2929. result += c.atomic.load(order);
  2930. }
  2931. return result;
  2932. }
  2933. T operator=(T desired) DOCTEST_NOEXCEPT { // lgtm [cpp/assignment-does-not-return-this]
  2934. store(desired);
  2935. return desired;
  2936. }
  2937. void store(T desired, std::memory_order order = std::memory_order_seq_cst) DOCTEST_NOEXCEPT {
  2938. // first value becomes desired", all others become 0.
  2939. for(auto& c : m_atomics) {
  2940. c.atomic.store(desired, order);
  2941. desired = {};
  2942. }
  2943. }
  2944. private:
  2945. // Each thread has a different atomic that it operates on. If more than NumLanes threads
  2946. // use this, some will use the same atomic. So performance will degrade a bit, but still
  2947. // everything will work.
  2948. //
  2949. // The logic here is a bit tricky. The call should be as fast as possible, so that there
  2950. // is minimal to no overhead in determining the correct atomic for the current thread.
  2951. //
  2952. // 1. A global static counter laneCounter counts continuously up.
  2953. // 2. Each successive thread will use modulo operation of that counter so it gets an atomic
  2954. // assigned in a round-robin fashion.
  2955. // 3. This tlsLaneIdx is stored in the thread local data, so it is directly available with
  2956. // little overhead.
  2957. Atomic<T>& myAtomic() DOCTEST_NOEXCEPT {
  2958. static Atomic<size_t> laneCounter;
  2959. DOCTEST_THREAD_LOCAL size_t tlsLaneIdx =
  2960. laneCounter++ % DOCTEST_MULTI_LANE_ATOMICS_THREAD_LANES;
  2961. return m_atomics[tlsLaneIdx].atomic;
  2962. }
  2963. };
  2964. #endif // DOCTEST_CONFIG_NO_MULTI_LANE_ATOMICS
  2965. // this holds both parameters from the command line and runtime data for tests
  2966. struct ContextState : ContextOptions, TestRunStats, CurrentTestCaseStats
  2967. {
  2968. MultiLaneAtomic<int> numAssertsCurrentTest_atomic;
  2969. MultiLaneAtomic<int> numAssertsFailedCurrentTest_atomic;
  2970. std::vector<std::vector<String>> filters = decltype(filters)(9); // 9 different filters
  2971. std::vector<IReporter*> reporters_currently_used;
  2972. assert_handler ah = nullptr;
  2973. Timer timer;
  2974. std::vector<String> stringifiedContexts; // logging from INFO() due to an exception
  2975. // stuff for subcases
  2976. bool reachedLeaf;
  2977. std::vector<SubcaseSignature> subcaseStack;
  2978. std::vector<SubcaseSignature> nextSubcaseStack;
  2979. std::unordered_set<unsigned long long> fullyTraversedSubcases;
  2980. size_t currentSubcaseDepth;
  2981. Atomic<bool> shouldLogCurrentException;
  2982. void resetRunData() {
  2983. numTestCases = 0;
  2984. numTestCasesPassingFilters = 0;
  2985. numTestSuitesPassingFilters = 0;
  2986. numTestCasesFailed = 0;
  2987. numAsserts = 0;
  2988. numAssertsFailed = 0;
  2989. numAssertsCurrentTest = 0;
  2990. numAssertsFailedCurrentTest = 0;
  2991. }
  2992. void finalizeTestCaseData() {
  2993. seconds = timer.getElapsedSeconds();
  2994. // update the non-atomic counters
  2995. numAsserts += numAssertsCurrentTest_atomic;
  2996. numAssertsFailed += numAssertsFailedCurrentTest_atomic;
  2997. numAssertsCurrentTest = numAssertsCurrentTest_atomic;
  2998. numAssertsFailedCurrentTest = numAssertsFailedCurrentTest_atomic;
  2999. if(numAssertsFailedCurrentTest)
  3000. failure_flags |= TestCaseFailureReason::AssertFailure;
  3001. if(Approx(currentTest->m_timeout).epsilon(DBL_EPSILON) != 0 &&
  3002. Approx(seconds).epsilon(DBL_EPSILON) > currentTest->m_timeout)
  3003. failure_flags |= TestCaseFailureReason::Timeout;
  3004. if(currentTest->m_should_fail) {
  3005. if(failure_flags) {
  3006. failure_flags |= TestCaseFailureReason::ShouldHaveFailedAndDid;
  3007. } else {
  3008. failure_flags |= TestCaseFailureReason::ShouldHaveFailedButDidnt;
  3009. }
  3010. } else if(failure_flags && currentTest->m_may_fail) {
  3011. failure_flags |= TestCaseFailureReason::CouldHaveFailedAndDid;
  3012. } else if(currentTest->m_expected_failures > 0) {
  3013. if(numAssertsFailedCurrentTest == currentTest->m_expected_failures) {
  3014. failure_flags |= TestCaseFailureReason::FailedExactlyNumTimes;
  3015. } else {
  3016. failure_flags |= TestCaseFailureReason::DidntFailExactlyNumTimes;
  3017. }
  3018. }
  3019. bool ok_to_fail = (TestCaseFailureReason::ShouldHaveFailedAndDid & failure_flags) ||
  3020. (TestCaseFailureReason::CouldHaveFailedAndDid & failure_flags) ||
  3021. (TestCaseFailureReason::FailedExactlyNumTimes & failure_flags);
  3022. // if any subcase has failed - the whole test case has failed
  3023. testCaseSuccess = !(failure_flags && !ok_to_fail);
  3024. if(!testCaseSuccess)
  3025. numTestCasesFailed++;
  3026. }
  3027. };
  3028. ContextState* g_cs = nullptr;
  3029. // used to avoid locks for the debug output
  3030. // TODO: figure out if this is indeed necessary/correct - seems like either there still
  3031. // could be a race or that there wouldn't be a race even if using the context directly
  3032. DOCTEST_THREAD_LOCAL bool g_no_colors;
  3033. #endif // DOCTEST_CONFIG_DISABLE
  3034. } // namespace detail
  3035. char* String::allocate(size_type sz) {
  3036. if (sz <= last) {
  3037. buf[sz] = '\0';
  3038. setLast(last - sz);
  3039. return buf;
  3040. } else {
  3041. setOnHeap();
  3042. data.size = sz;
  3043. data.capacity = data.size + 1;
  3044. data.ptr = new char[data.capacity];
  3045. data.ptr[sz] = '\0';
  3046. return data.ptr;
  3047. }
  3048. }
  3049. void String::setOnHeap() noexcept { *reinterpret_cast<unsigned char*>(&buf[last]) = 128; }
  3050. void String::setLast(size_type in) noexcept { buf[last] = char(in); }
  3051. void String::setSize(size_type sz) noexcept {
  3052. if (isOnStack()) { buf[sz] = '\0'; setLast(last - sz); }
  3053. else { data.ptr[sz] = '\0'; data.size = sz; }
  3054. }
  3055. void String::copy(const String& other) {
  3056. if(other.isOnStack()) {
  3057. memcpy(buf, other.buf, len);
  3058. } else {
  3059. memcpy(allocate(other.data.size), other.data.ptr, other.data.size);
  3060. }
  3061. }
  3062. String::String() noexcept {
  3063. buf[0] = '\0';
  3064. setLast();
  3065. }
  3066. String::~String() {
  3067. if(!isOnStack())
  3068. delete[] data.ptr;
  3069. } // NOLINT(clang-analyzer-cplusplus.NewDeleteLeaks)
  3070. String::String(const char* in)
  3071. : String(in, strlen(in)) {}
  3072. String::String(const char* in, size_type in_size) {
  3073. memcpy(allocate(in_size), in, in_size);
  3074. }
  3075. String::String(std::istream& in, size_type in_size) {
  3076. in.read(allocate(in_size), in_size);
  3077. }
  3078. String::String(const String& other) { copy(other); }
  3079. String& String::operator=(const String& other) {
  3080. if(this != &other) {
  3081. if(!isOnStack())
  3082. delete[] data.ptr;
  3083. copy(other);
  3084. }
  3085. return *this;
  3086. }
  3087. String& String::operator+=(const String& other) {
  3088. const size_type my_old_size = size();
  3089. const size_type other_size = other.size();
  3090. const size_type total_size = my_old_size + other_size;
  3091. if(isOnStack()) {
  3092. if(total_size < len) {
  3093. // append to the current stack space
  3094. memcpy(buf + my_old_size, other.c_str(), other_size + 1);
  3095. // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
  3096. setLast(last - total_size);
  3097. } else {
  3098. // alloc new chunk
  3099. char* temp = new char[total_size + 1];
  3100. // copy current data to new location before writing in the union
  3101. memcpy(temp, buf, my_old_size); // skip the +1 ('\0') for speed
  3102. // update data in union
  3103. setOnHeap();
  3104. data.size = total_size;
  3105. data.capacity = data.size + 1;
  3106. data.ptr = temp;
  3107. // transfer the rest of the data
  3108. memcpy(data.ptr + my_old_size, other.c_str(), other_size + 1);
  3109. }
  3110. } else {
  3111. if(data.capacity > total_size) {
  3112. // append to the current heap block
  3113. data.size = total_size;
  3114. memcpy(data.ptr + my_old_size, other.c_str(), other_size + 1);
  3115. } else {
  3116. // resize
  3117. data.capacity *= 2;
  3118. if(data.capacity <= total_size)
  3119. data.capacity = total_size + 1;
  3120. // alloc new chunk
  3121. char* temp = new char[data.capacity];
  3122. // copy current data to new location before releasing it
  3123. memcpy(temp, data.ptr, my_old_size); // skip the +1 ('\0') for speed
  3124. // release old chunk
  3125. delete[] data.ptr;
  3126. // update the rest of the union members
  3127. data.size = total_size;
  3128. data.ptr = temp;
  3129. // transfer the rest of the data
  3130. memcpy(data.ptr + my_old_size, other.c_str(), other_size + 1);
  3131. }
  3132. }
  3133. return *this;
  3134. }
  3135. String::String(String&& other) noexcept {
  3136. memcpy(buf, other.buf, len);
  3137. other.buf[0] = '\0';
  3138. other.setLast();
  3139. }
  3140. String& String::operator=(String&& other) noexcept {
  3141. if(this != &other) {
  3142. if(!isOnStack())
  3143. delete[] data.ptr;
  3144. memcpy(buf, other.buf, len);
  3145. other.buf[0] = '\0';
  3146. other.setLast();
  3147. }
  3148. return *this;
  3149. }
  3150. char String::operator[](size_type i) const {
  3151. return const_cast<String*>(this)->operator[](i);
  3152. }
  3153. char& String::operator[](size_type i) {
  3154. if(isOnStack())
  3155. return reinterpret_cast<char*>(buf)[i];
  3156. return data.ptr[i];
  3157. }
  3158. DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wmaybe-uninitialized")
  3159. String::size_type String::size() const {
  3160. if(isOnStack())
  3161. return last - (size_type(buf[last]) & 31); // using "last" would work only if "len" is 32
  3162. return data.size;
  3163. }
  3164. DOCTEST_GCC_SUPPRESS_WARNING_POP
  3165. String::size_type String::capacity() const {
  3166. if(isOnStack())
  3167. return len;
  3168. return data.capacity;
  3169. }
  3170. String String::substr(size_type pos, size_type cnt) && {
  3171. cnt = std::min(cnt, size() - pos);
  3172. char* cptr = c_str();
  3173. memmove(cptr, cptr + pos, cnt);
  3174. setSize(cnt);
  3175. return std::move(*this);
  3176. }
  3177. String String::substr(size_type pos, size_type cnt) const & {
  3178. cnt = std::min(cnt, size() - pos);
  3179. return String{ c_str() + pos, cnt };
  3180. }
  3181. String::size_type String::find(char ch, size_type pos) const {
  3182. const char* begin = c_str();
  3183. const char* end = begin + size();
  3184. const char* it = begin + pos;
  3185. for (; it < end && *it != ch; it++);
  3186. if (it < end) { return static_cast<size_type>(it - begin); }
  3187. else { return npos; }
  3188. }
  3189. String::size_type String::rfind(char ch, size_type pos) const {
  3190. const char* begin = c_str();
  3191. const char* it = begin + std::min(pos, size() - 1);
  3192. for (; it >= begin && *it != ch; it--);
  3193. if (it >= begin) { return static_cast<size_type>(it - begin); }
  3194. else { return npos; }
  3195. }
  3196. int String::compare(const char* other, bool no_case) const {
  3197. if(no_case)
  3198. return doctest::stricmp(c_str(), other);
  3199. return std::strcmp(c_str(), other);
  3200. }
  3201. int String::compare(const String& other, bool no_case) const {
  3202. return compare(other.c_str(), no_case);
  3203. }
  3204. String operator+(const String& lhs, const String& rhs) { return String(lhs) += rhs; }
  3205. bool operator==(const String& lhs, const String& rhs) { return lhs.compare(rhs) == 0; }
  3206. bool operator!=(const String& lhs, const String& rhs) { return lhs.compare(rhs) != 0; }
  3207. bool operator< (const String& lhs, const String& rhs) { return lhs.compare(rhs) < 0; }
  3208. bool operator> (const String& lhs, const String& rhs) { return lhs.compare(rhs) > 0; }
  3209. bool operator<=(const String& lhs, const String& rhs) { return (lhs != rhs) ? lhs.compare(rhs) < 0 : true; }
  3210. bool operator>=(const String& lhs, const String& rhs) { return (lhs != rhs) ? lhs.compare(rhs) > 0 : true; }
  3211. std::ostream& operator<<(std::ostream& s, const String& in) { return s << in.c_str(); }
  3212. Contains::Contains(const String& str) : string(str) { }
  3213. bool Contains::checkWith(const String& other) const {
  3214. return strstr(other.c_str(), string.c_str()) != nullptr;
  3215. }
  3216. String toString(const Contains& in) {
  3217. return "Contains( " + in.string + " )";
  3218. }
  3219. bool operator==(const String& lhs, const Contains& rhs) { return rhs.checkWith(lhs); }
  3220. bool operator==(const Contains& lhs, const String& rhs) { return lhs.checkWith(rhs); }
  3221. bool operator!=(const String& lhs, const Contains& rhs) { return !rhs.checkWith(lhs); }
  3222. bool operator!=(const Contains& lhs, const String& rhs) { return !lhs.checkWith(rhs); }
  3223. namespace {
  3224. void color_to_stream(std::ostream&, Color::Enum) DOCTEST_BRANCH_ON_DISABLED({}, ;)
  3225. } // namespace
  3226. namespace Color {
  3227. std::ostream& operator<<(std::ostream& s, Color::Enum code) {
  3228. color_to_stream(s, code);
  3229. return s;
  3230. }
  3231. } // namespace Color
  3232. // clang-format off
  3233. const char* assertString(assertType::Enum at) {
  3234. DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4061) // enum 'x' in switch of enum 'y' is not explicitly handled
  3235. #define DOCTEST_GENERATE_ASSERT_TYPE_CASE(assert_type) case assertType::DT_ ## assert_type: return #assert_type
  3236. #define DOCTEST_GENERATE_ASSERT_TYPE_CASES(assert_type) \
  3237. DOCTEST_GENERATE_ASSERT_TYPE_CASE(WARN_ ## assert_type); \
  3238. DOCTEST_GENERATE_ASSERT_TYPE_CASE(CHECK_ ## assert_type); \
  3239. DOCTEST_GENERATE_ASSERT_TYPE_CASE(REQUIRE_ ## assert_type)
  3240. switch(at) {
  3241. DOCTEST_GENERATE_ASSERT_TYPE_CASE(WARN);
  3242. DOCTEST_GENERATE_ASSERT_TYPE_CASE(CHECK);
  3243. DOCTEST_GENERATE_ASSERT_TYPE_CASE(REQUIRE);
  3244. DOCTEST_GENERATE_ASSERT_TYPE_CASES(FALSE);
  3245. DOCTEST_GENERATE_ASSERT_TYPE_CASES(THROWS);
  3246. DOCTEST_GENERATE_ASSERT_TYPE_CASES(THROWS_AS);
  3247. DOCTEST_GENERATE_ASSERT_TYPE_CASES(THROWS_WITH);
  3248. DOCTEST_GENERATE_ASSERT_TYPE_CASES(THROWS_WITH_AS);
  3249. DOCTEST_GENERATE_ASSERT_TYPE_CASES(NOTHROW);
  3250. DOCTEST_GENERATE_ASSERT_TYPE_CASES(EQ);
  3251. DOCTEST_GENERATE_ASSERT_TYPE_CASES(NE);
  3252. DOCTEST_GENERATE_ASSERT_TYPE_CASES(GT);
  3253. DOCTEST_GENERATE_ASSERT_TYPE_CASES(LT);
  3254. DOCTEST_GENERATE_ASSERT_TYPE_CASES(GE);
  3255. DOCTEST_GENERATE_ASSERT_TYPE_CASES(LE);
  3256. DOCTEST_GENERATE_ASSERT_TYPE_CASES(UNARY);
  3257. DOCTEST_GENERATE_ASSERT_TYPE_CASES(UNARY_FALSE);
  3258. default: DOCTEST_INTERNAL_ERROR("Tried stringifying invalid assert type!");
  3259. }
  3260. DOCTEST_MSVC_SUPPRESS_WARNING_POP
  3261. }
  3262. // clang-format on
  3263. const char* failureString(assertType::Enum at) {
  3264. if(at & assertType::is_warn) //!OCLINT bitwise operator in conditional
  3265. return "WARNING";
  3266. if(at & assertType::is_check) //!OCLINT bitwise operator in conditional
  3267. return "ERROR";
  3268. if(at & assertType::is_require) //!OCLINT bitwise operator in conditional
  3269. return "FATAL ERROR";
  3270. return "";
  3271. }
  3272. DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wnull-dereference")
  3273. DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wnull-dereference")
  3274. // depending on the current options this will remove the path of filenames
  3275. const char* skipPathFromFilename(const char* file) {
  3276. #ifndef DOCTEST_CONFIG_DISABLE
  3277. if(getContextOptions()->no_path_in_filenames) {
  3278. auto back = std::strrchr(file, '\\');
  3279. auto forward = std::strrchr(file, '/');
  3280. if(back || forward) {
  3281. if(back > forward)
  3282. forward = back;
  3283. return forward + 1;
  3284. }
  3285. } else {
  3286. const auto prefixes = getContextOptions()->strip_file_prefixes;
  3287. const char separator = DOCTEST_CONFIG_OPTIONS_FILE_PREFIX_SEPARATOR;
  3288. String::size_type longest_match = 0U;
  3289. for(String::size_type pos = 0U; pos < prefixes.size(); ++pos)
  3290. {
  3291. const auto prefix_start = pos;
  3292. pos = std::min(prefixes.find(separator, prefix_start), prefixes.size());
  3293. const auto prefix_size = pos - prefix_start;
  3294. if(prefix_size > longest_match)
  3295. {
  3296. // TODO under DOCTEST_MSVC: does the comparison need strnicmp() to work with drive letter capitalization?
  3297. if(0 == std::strncmp(prefixes.c_str() + prefix_start, file, prefix_size))
  3298. {
  3299. longest_match = prefix_size;
  3300. }
  3301. }
  3302. }
  3303. return &file[longest_match];
  3304. }
  3305. #endif // DOCTEST_CONFIG_DISABLE
  3306. return file;
  3307. }
  3308. DOCTEST_CLANG_SUPPRESS_WARNING_POP
  3309. DOCTEST_GCC_SUPPRESS_WARNING_POP
  3310. bool SubcaseSignature::operator==(const SubcaseSignature& other) const {
  3311. return m_line == other.m_line
  3312. && std::strcmp(m_file, other.m_file) == 0
  3313. && m_name == other.m_name;
  3314. }
  3315. bool SubcaseSignature::operator<(const SubcaseSignature& other) const {
  3316. if(m_line != other.m_line)
  3317. return m_line < other.m_line;
  3318. if(std::strcmp(m_file, other.m_file) != 0)
  3319. return std::strcmp(m_file, other.m_file) < 0;
  3320. return m_name.compare(other.m_name) < 0;
  3321. }
  3322. DOCTEST_DEFINE_INTERFACE(IContextScope)
  3323. namespace detail {
  3324. void filldata<const void*>::fill(std::ostream* stream, const void* in) {
  3325. if (in) { *stream << in; }
  3326. else { *stream << "nullptr"; }
  3327. }
  3328. template <typename T>
  3329. String toStreamLit(T t) {
  3330. std::ostream* os = tlssPush();
  3331. os->operator<<(t);
  3332. return tlssPop();
  3333. }
  3334. }
  3335. #ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
  3336. String toString(const char* in) { return String("\"") + (in ? in : "{null string}") + "\""; }
  3337. #endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
  3338. #if DOCTEST_MSVC >= DOCTEST_COMPILER(19, 20, 0)
  3339. // see this issue on why this is needed: https://github.com/doctest/doctest/issues/183
  3340. String toString(const std::string& in) { return in.c_str(); }
  3341. #endif // VS 2019
  3342. String toString(String in) { return in; }
  3343. String toString(std::nullptr_t) { return "nullptr"; }
  3344. String toString(bool in) { return in ? "true" : "false"; }
  3345. String toString(float in) { return toStreamLit(in); }
  3346. String toString(double in) { return toStreamLit(in); }
  3347. String toString(double long in) { return toStreamLit(in); }
  3348. String toString(char in) { return toStreamLit(static_cast<signed>(in)); }
  3349. String toString(char signed in) { return toStreamLit(static_cast<signed>(in)); }
  3350. String toString(char unsigned in) { return toStreamLit(static_cast<unsigned>(in)); }
  3351. String toString(short in) { return toStreamLit(in); }
  3352. String toString(short unsigned in) { return toStreamLit(in); }
  3353. String toString(signed in) { return toStreamLit(in); }
  3354. String toString(unsigned in) { return toStreamLit(in); }
  3355. String toString(long in) { return toStreamLit(in); }
  3356. String toString(long unsigned in) { return toStreamLit(in); }
  3357. String toString(long long in) { return toStreamLit(in); }
  3358. String toString(long long unsigned in) { return toStreamLit(in); }
  3359. Approx::Approx(double value)
  3360. : m_epsilon(static_cast<double>(std::numeric_limits<float>::epsilon()) * 100)
  3361. , m_scale(1.0)
  3362. , m_value(value) {}
  3363. Approx Approx::operator()(double value) const {
  3364. Approx approx(value);
  3365. approx.epsilon(m_epsilon);
  3366. approx.scale(m_scale);
  3367. return approx;
  3368. }
  3369. Approx& Approx::epsilon(double newEpsilon) {
  3370. m_epsilon = newEpsilon;
  3371. return *this;
  3372. }
  3373. Approx& Approx::scale(double newScale) {
  3374. m_scale = newScale;
  3375. return *this;
  3376. }
  3377. bool operator==(double lhs, const Approx& rhs) {
  3378. // Thanks to Richard Harris for his help refining this formula
  3379. return std::fabs(lhs - rhs.m_value) <
  3380. rhs.m_epsilon * (rhs.m_scale + std::max<double>(std::fabs(lhs), std::fabs(rhs.m_value)));
  3381. }
  3382. bool operator==(const Approx& lhs, double rhs) { return operator==(rhs, lhs); }
  3383. bool operator!=(double lhs, const Approx& rhs) { return !operator==(lhs, rhs); }
  3384. bool operator!=(const Approx& lhs, double rhs) { return !operator==(rhs, lhs); }
  3385. bool operator<=(double lhs, const Approx& rhs) { return lhs < rhs.m_value || lhs == rhs; }
  3386. bool operator<=(const Approx& lhs, double rhs) { return lhs.m_value < rhs || lhs == rhs; }
  3387. bool operator>=(double lhs, const Approx& rhs) { return lhs > rhs.m_value || lhs == rhs; }
  3388. bool operator>=(const Approx& lhs, double rhs) { return lhs.m_value > rhs || lhs == rhs; }
  3389. bool operator<(double lhs, const Approx& rhs) { return lhs < rhs.m_value && lhs != rhs; }
  3390. bool operator<(const Approx& lhs, double rhs) { return lhs.m_value < rhs && lhs != rhs; }
  3391. bool operator>(double lhs, const Approx& rhs) { return lhs > rhs.m_value && lhs != rhs; }
  3392. bool operator>(const Approx& lhs, double rhs) { return lhs.m_value > rhs && lhs != rhs; }
  3393. String toString(const Approx& in) {
  3394. return "Approx( " + doctest::toString(in.m_value) + " )";
  3395. }
  3396. const ContextOptions* getContextOptions() { return DOCTEST_BRANCH_ON_DISABLED(nullptr, g_cs); }
  3397. DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4738)
  3398. template <typename F>
  3399. IsNaN<F>::operator bool() const {
  3400. return std::isnan(value) ^ flipped;
  3401. }
  3402. DOCTEST_MSVC_SUPPRESS_WARNING_POP
  3403. template struct DOCTEST_INTERFACE_DEF IsNaN<float>;
  3404. template struct DOCTEST_INTERFACE_DEF IsNaN<double>;
  3405. template struct DOCTEST_INTERFACE_DEF IsNaN<long double>;
  3406. template <typename F>
  3407. String toString(IsNaN<F> in) { return String(in.flipped ? "! " : "") + "IsNaN( " + doctest::toString(in.value) + " )"; }
  3408. String toString(IsNaN<float> in) { return toString<float>(in); }
  3409. String toString(IsNaN<double> in) { return toString<double>(in); }
  3410. String toString(IsNaN<double long> in) { return toString<double long>(in); }
  3411. } // namespace doctest
  3412. #ifdef DOCTEST_CONFIG_DISABLE
  3413. namespace doctest {
  3414. Context::Context(int, const char* const*) {}
  3415. Context::~Context() = default;
  3416. void Context::applyCommandLine(int, const char* const*) {}
  3417. void Context::addFilter(const char*, const char*) {}
  3418. void Context::clearFilters() {}
  3419. void Context::setOption(const char*, bool) {}
  3420. void Context::setOption(const char*, int) {}
  3421. void Context::setOption(const char*, const char*) {}
  3422. bool Context::shouldExit() { return false; }
  3423. void Context::setAsDefaultForAssertsOutOfTestCases() {}
  3424. void Context::setAssertHandler(detail::assert_handler) {}
  3425. void Context::setCout(std::ostream*) {}
  3426. int Context::run() { return 0; }
  3427. int IReporter::get_num_active_contexts() { return 0; }
  3428. const IContextScope* const* IReporter::get_active_contexts() { return nullptr; }
  3429. int IReporter::get_num_stringified_contexts() { return 0; }
  3430. const String* IReporter::get_stringified_contexts() { return nullptr; }
  3431. int registerReporter(const char*, int, IReporter*) { return 0; }
  3432. } // namespace doctest
  3433. #else // DOCTEST_CONFIG_DISABLE
  3434. #if !defined(DOCTEST_CONFIG_COLORS_NONE)
  3435. #if !defined(DOCTEST_CONFIG_COLORS_WINDOWS) && !defined(DOCTEST_CONFIG_COLORS_ANSI)
  3436. #ifdef DOCTEST_PLATFORM_WINDOWS
  3437. #define DOCTEST_CONFIG_COLORS_WINDOWS
  3438. #else // linux
  3439. #define DOCTEST_CONFIG_COLORS_ANSI
  3440. #endif // platform
  3441. #endif // DOCTEST_CONFIG_COLORS_WINDOWS && DOCTEST_CONFIG_COLORS_ANSI
  3442. #endif // DOCTEST_CONFIG_COLORS_NONE
  3443. namespace doctest_detail_test_suite_ns {
  3444. // holds the current test suite
  3445. doctest::detail::TestSuite& getCurrentTestSuite() {
  3446. static doctest::detail::TestSuite data{};
  3447. return data;
  3448. }
  3449. } // namespace doctest_detail_test_suite_ns
  3450. namespace doctest {
  3451. namespace {
  3452. // the int (priority) is part of the key for automatic sorting - sadly one can register a
  3453. // reporter with a duplicate name and a different priority but hopefully that won't happen often :|
  3454. using reporterMap = std::map<std::pair<int, String>, reporterCreatorFunc>;
  3455. reporterMap& getReporters() {
  3456. static reporterMap data;
  3457. return data;
  3458. }
  3459. reporterMap& getListeners() {
  3460. static reporterMap data;
  3461. return data;
  3462. }
  3463. } // namespace
  3464. namespace detail {
  3465. #define DOCTEST_ITERATE_THROUGH_REPORTERS(function, ...) \
  3466. for(auto& curr_rep : g_cs->reporters_currently_used) \
  3467. curr_rep->function(__VA_ARGS__)
  3468. bool checkIfShouldThrow(assertType::Enum at) {
  3469. if(at & assertType::is_require) //!OCLINT bitwise operator in conditional
  3470. return true;
  3471. if((at & assertType::is_check) //!OCLINT bitwise operator in conditional
  3472. && getContextOptions()->abort_after > 0 &&
  3473. (g_cs->numAssertsFailed + g_cs->numAssertsFailedCurrentTest_atomic) >=
  3474. getContextOptions()->abort_after)
  3475. return true;
  3476. return false;
  3477. }
  3478. #ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
  3479. DOCTEST_NORETURN void throwException() {
  3480. g_cs->shouldLogCurrentException = false;
  3481. throw TestFailureException(); // NOLINT(hicpp-exception-baseclass)
  3482. }
  3483. #else // DOCTEST_CONFIG_NO_EXCEPTIONS
  3484. void throwException() {}
  3485. #endif // DOCTEST_CONFIG_NO_EXCEPTIONS
  3486. } // namespace detail
  3487. namespace {
  3488. using namespace detail;
  3489. // matching of a string against a wildcard mask (case sensitivity configurable) taken from
  3490. // https://www.codeproject.com/Articles/1088/Wildcard-string-compare-globbing
  3491. int wildcmp(const char* str, const char* wild, bool caseSensitive) {
  3492. const char* cp = str;
  3493. const char* mp = wild;
  3494. while((*str) && (*wild != '*')) {
  3495. if((caseSensitive ? (*wild != *str) : (tolower(*wild) != tolower(*str))) &&
  3496. (*wild != '?')) {
  3497. return 0;
  3498. }
  3499. wild++;
  3500. str++;
  3501. }
  3502. while(*str) {
  3503. if(*wild == '*') {
  3504. if(!*++wild) {
  3505. return 1;
  3506. }
  3507. mp = wild;
  3508. cp = str + 1;
  3509. } else if((caseSensitive ? (*wild == *str) : (tolower(*wild) == tolower(*str))) ||
  3510. (*wild == '?')) {
  3511. wild++;
  3512. str++;
  3513. } else {
  3514. wild = mp; //!OCLINT parameter reassignment
  3515. str = cp++; //!OCLINT parameter reassignment
  3516. }
  3517. }
  3518. while(*wild == '*') {
  3519. wild++;
  3520. }
  3521. return !*wild;
  3522. }
  3523. // checks if the name matches any of the filters (and can be configured what to do when empty)
  3524. bool matchesAny(const char* name, const std::vector<String>& filters, bool matchEmpty,
  3525. bool caseSensitive) {
  3526. if (filters.empty() && matchEmpty)
  3527. return true;
  3528. for (auto& curr : filters)
  3529. if (wildcmp(name, curr.c_str(), caseSensitive))
  3530. return true;
  3531. return false;
  3532. }
  3533. DOCTEST_NO_SANITIZE_INTEGER
  3534. unsigned long long hash(unsigned long long a, unsigned long long b) {
  3535. return (a << 5) + b;
  3536. }
  3537. // C string hash function (djb2) - taken from http://www.cse.yorku.ca/~oz/hash.html
  3538. DOCTEST_NO_SANITIZE_INTEGER
  3539. unsigned long long hash(const char* str) {
  3540. unsigned long long hash = 5381;
  3541. char c;
  3542. while ((c = *str++))
  3543. hash = ((hash << 5) + hash) + c; // hash * 33 + c
  3544. return hash;
  3545. }
  3546. unsigned long long hash(const SubcaseSignature& sig) {
  3547. return hash(hash(hash(sig.m_file), hash(sig.m_name.c_str())), sig.m_line);
  3548. }
  3549. unsigned long long hash(const std::vector<SubcaseSignature>& sigs, size_t count) {
  3550. unsigned long long running = 0;
  3551. auto end = sigs.begin() + count;
  3552. for (auto it = sigs.begin(); it != end; it++) {
  3553. running = hash(running, hash(*it));
  3554. }
  3555. return running;
  3556. }
  3557. unsigned long long hash(const std::vector<SubcaseSignature>& sigs) {
  3558. unsigned long long running = 0;
  3559. for (const SubcaseSignature& sig : sigs) {
  3560. running = hash(running, hash(sig));
  3561. }
  3562. return running;
  3563. }
  3564. } // namespace
  3565. namespace detail {
  3566. bool Subcase::checkFilters() {
  3567. if (g_cs->subcaseStack.size() < size_t(g_cs->subcase_filter_levels)) {
  3568. if (!matchesAny(m_signature.m_name.c_str(), g_cs->filters[6], true, g_cs->case_sensitive))
  3569. return true;
  3570. if (matchesAny(m_signature.m_name.c_str(), g_cs->filters[7], false, g_cs->case_sensitive))
  3571. return true;
  3572. }
  3573. return false;
  3574. }
  3575. Subcase::Subcase(const String& name, const char* file, int line)
  3576. : m_signature({name, file, line}) {
  3577. if (!g_cs->reachedLeaf) {
  3578. if (g_cs->nextSubcaseStack.size() <= g_cs->subcaseStack.size()
  3579. || g_cs->nextSubcaseStack[g_cs->subcaseStack.size()] == m_signature) {
  3580. // Going down.
  3581. if (checkFilters()) { return; }
  3582. g_cs->subcaseStack.push_back(m_signature);
  3583. g_cs->currentSubcaseDepth++;
  3584. m_entered = true;
  3585. DOCTEST_ITERATE_THROUGH_REPORTERS(subcase_start, m_signature);
  3586. }
  3587. } else {
  3588. if (g_cs->subcaseStack[g_cs->currentSubcaseDepth] == m_signature) {
  3589. // This subcase is reentered via control flow.
  3590. g_cs->currentSubcaseDepth++;
  3591. m_entered = true;
  3592. DOCTEST_ITERATE_THROUGH_REPORTERS(subcase_start, m_signature);
  3593. } else if (g_cs->nextSubcaseStack.size() <= g_cs->currentSubcaseDepth
  3594. && g_cs->fullyTraversedSubcases.find(hash(hash(g_cs->subcaseStack, g_cs->currentSubcaseDepth), hash(m_signature)))
  3595. == g_cs->fullyTraversedSubcases.end()) {
  3596. if (checkFilters()) { return; }
  3597. // This subcase is part of the one to be executed next.
  3598. g_cs->nextSubcaseStack.clear();
  3599. g_cs->nextSubcaseStack.insert(g_cs->nextSubcaseStack.end(),
  3600. g_cs->subcaseStack.begin(), g_cs->subcaseStack.begin() + g_cs->currentSubcaseDepth);
  3601. g_cs->nextSubcaseStack.push_back(m_signature);
  3602. }
  3603. }
  3604. }
  3605. DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4996) // std::uncaught_exception is deprecated in C++17
  3606. DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations")
  3607. DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations")
  3608. Subcase::~Subcase() {
  3609. if (m_entered) {
  3610. g_cs->currentSubcaseDepth--;
  3611. if (!g_cs->reachedLeaf) {
  3612. // Leaf.
  3613. g_cs->fullyTraversedSubcases.insert(hash(g_cs->subcaseStack));
  3614. g_cs->nextSubcaseStack.clear();
  3615. g_cs->reachedLeaf = true;
  3616. } else if (g_cs->nextSubcaseStack.empty()) {
  3617. // All children are finished.
  3618. g_cs->fullyTraversedSubcases.insert(hash(g_cs->subcaseStack));
  3619. }
  3620. #if defined(__cpp_lib_uncaught_exceptions) && __cpp_lib_uncaught_exceptions >= 201411L && (!defined(__MAC_OS_X_VERSION_MIN_REQUIRED) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200)
  3621. if(std::uncaught_exceptions() > 0
  3622. #else
  3623. if(std::uncaught_exception()
  3624. #endif
  3625. && g_cs->shouldLogCurrentException) {
  3626. DOCTEST_ITERATE_THROUGH_REPORTERS(
  3627. test_case_exception, {"exception thrown in subcase - will translate later "
  3628. "when the whole test case has been exited (cannot "
  3629. "translate while there is an active exception)",
  3630. false});
  3631. g_cs->shouldLogCurrentException = false;
  3632. }
  3633. DOCTEST_ITERATE_THROUGH_REPORTERS(subcase_end, DOCTEST_EMPTY);
  3634. }
  3635. }
  3636. DOCTEST_CLANG_SUPPRESS_WARNING_POP
  3637. DOCTEST_GCC_SUPPRESS_WARNING_POP
  3638. DOCTEST_MSVC_SUPPRESS_WARNING_POP
  3639. Subcase::operator bool() const { return m_entered; }
  3640. Result::Result(bool passed, const String& decomposition)
  3641. : m_passed(passed)
  3642. , m_decomp(decomposition) {}
  3643. ExpressionDecomposer::ExpressionDecomposer(assertType::Enum at)
  3644. : m_at(at) {}
  3645. TestSuite& TestSuite::operator*(const char* in) {
  3646. m_test_suite = in;
  3647. return *this;
  3648. }
  3649. TestCase::TestCase(funcType test, const char* file, unsigned line, const TestSuite& test_suite,
  3650. const String& type, int template_id) {
  3651. m_file = file;
  3652. m_line = line;
  3653. m_name = nullptr; // will be later overridden in operator*
  3654. m_test_suite = test_suite.m_test_suite;
  3655. m_description = test_suite.m_description;
  3656. m_skip = test_suite.m_skip;
  3657. m_no_breaks = test_suite.m_no_breaks;
  3658. m_no_output = test_suite.m_no_output;
  3659. m_may_fail = test_suite.m_may_fail;
  3660. m_should_fail = test_suite.m_should_fail;
  3661. m_expected_failures = test_suite.m_expected_failures;
  3662. m_timeout = test_suite.m_timeout;
  3663. m_test = test;
  3664. m_type = type;
  3665. m_template_id = template_id;
  3666. }
  3667. TestCase::TestCase(const TestCase& other)
  3668. : TestCaseData() {
  3669. *this = other;
  3670. }
  3671. DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(26434) // hides a non-virtual function
  3672. TestCase& TestCase::operator=(const TestCase& other) {
  3673. TestCaseData::operator=(other);
  3674. m_test = other.m_test;
  3675. m_type = other.m_type;
  3676. m_template_id = other.m_template_id;
  3677. m_full_name = other.m_full_name;
  3678. if(m_template_id != -1)
  3679. m_name = m_full_name.c_str();
  3680. return *this;
  3681. }
  3682. DOCTEST_MSVC_SUPPRESS_WARNING_POP
  3683. TestCase& TestCase::operator*(const char* in) {
  3684. m_name = in;
  3685. // make a new name with an appended type for templated test case
  3686. if(m_template_id != -1) {
  3687. m_full_name = String(m_name) + "<" + m_type + ">";
  3688. // redirect the name to point to the newly constructed full name
  3689. m_name = m_full_name.c_str();
  3690. }
  3691. return *this;
  3692. }
  3693. bool TestCase::operator<(const TestCase& other) const {
  3694. // this will be used only to differentiate between test cases - not relevant for sorting
  3695. if(m_line != other.m_line)
  3696. return m_line < other.m_line;
  3697. const int name_cmp = strcmp(m_name, other.m_name);
  3698. if(name_cmp != 0)
  3699. return name_cmp < 0;
  3700. const int file_cmp = m_file.compare(other.m_file);
  3701. if(file_cmp != 0)
  3702. return file_cmp < 0;
  3703. return m_template_id < other.m_template_id;
  3704. }
  3705. // all the registered tests
  3706. std::set<TestCase>& getRegisteredTests() {
  3707. static std::set<TestCase> data;
  3708. return data;
  3709. }
  3710. } // namespace detail
  3711. namespace {
  3712. using namespace detail;
  3713. // for sorting tests by file/line
  3714. bool fileOrderComparator(const TestCase* lhs, const TestCase* rhs) {
  3715. // this is needed because MSVC gives different case for drive letters
  3716. // for __FILE__ when evaluated in a header and a source file
  3717. const int res = lhs->m_file.compare(rhs->m_file, bool(DOCTEST_MSVC));
  3718. if(res != 0)
  3719. return res < 0;
  3720. if(lhs->m_line != rhs->m_line)
  3721. return lhs->m_line < rhs->m_line;
  3722. return lhs->m_template_id < rhs->m_template_id;
  3723. }
  3724. // for sorting tests by suite/file/line
  3725. bool suiteOrderComparator(const TestCase* lhs, const TestCase* rhs) {
  3726. const int res = std::strcmp(lhs->m_test_suite, rhs->m_test_suite);
  3727. if(res != 0)
  3728. return res < 0;
  3729. return fileOrderComparator(lhs, rhs);
  3730. }
  3731. // for sorting tests by name/suite/file/line
  3732. bool nameOrderComparator(const TestCase* lhs, const TestCase* rhs) {
  3733. const int res = std::strcmp(lhs->m_name, rhs->m_name);
  3734. if(res != 0)
  3735. return res < 0;
  3736. return suiteOrderComparator(lhs, rhs);
  3737. }
  3738. DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations")
  3739. void color_to_stream(std::ostream& s, Color::Enum code) {
  3740. static_cast<void>(s); // for DOCTEST_CONFIG_COLORS_NONE or DOCTEST_CONFIG_COLORS_WINDOWS
  3741. static_cast<void>(code); // for DOCTEST_CONFIG_COLORS_NONE
  3742. #ifdef DOCTEST_CONFIG_COLORS_ANSI
  3743. if(g_no_colors ||
  3744. (isatty(STDOUT_FILENO) == false && getContextOptions()->force_colors == false))
  3745. return;
  3746. auto col = "";
  3747. // clang-format off
  3748. switch(code) { //!OCLINT missing break in switch statement / unnecessary default statement in covered switch statement
  3749. case Color::Red: col = "[0;31m"; break;
  3750. case Color::Green: col = "[0;32m"; break;
  3751. case Color::Blue: col = "[0;34m"; break;
  3752. case Color::Cyan: col = "[0;36m"; break;
  3753. case Color::Yellow: col = "[0;33m"; break;
  3754. case Color::Grey: col = "[1;30m"; break;
  3755. case Color::LightGrey: col = "[0;37m"; break;
  3756. case Color::BrightRed: col = "[1;31m"; break;
  3757. case Color::BrightGreen: col = "[1;32m"; break;
  3758. case Color::BrightWhite: col = "[1;37m"; break;
  3759. case Color::Bright: // invalid
  3760. case Color::None:
  3761. case Color::White:
  3762. default: col = "[0m";
  3763. }
  3764. // clang-format on
  3765. s << "\033" << col;
  3766. #endif // DOCTEST_CONFIG_COLORS_ANSI
  3767. #ifdef DOCTEST_CONFIG_COLORS_WINDOWS
  3768. if(g_no_colors ||
  3769. (_isatty(_fileno(stdout)) == false && getContextOptions()->force_colors == false))
  3770. return;
  3771. static struct ConsoleHelper {
  3772. HANDLE stdoutHandle;
  3773. WORD origFgAttrs;
  3774. WORD origBgAttrs;
  3775. ConsoleHelper() {
  3776. stdoutHandle = GetStdHandle(STD_OUTPUT_HANDLE);
  3777. CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
  3778. GetConsoleScreenBufferInfo(stdoutHandle, &csbiInfo);
  3779. origFgAttrs = csbiInfo.wAttributes & ~(BACKGROUND_GREEN | BACKGROUND_RED |
  3780. BACKGROUND_BLUE | BACKGROUND_INTENSITY);
  3781. origBgAttrs = csbiInfo.wAttributes & ~(FOREGROUND_GREEN | FOREGROUND_RED |
  3782. FOREGROUND_BLUE | FOREGROUND_INTENSITY);
  3783. }
  3784. } ch;
  3785. #define DOCTEST_SET_ATTR(x) SetConsoleTextAttribute(ch.stdoutHandle, x | ch.origBgAttrs)
  3786. // clang-format off
  3787. switch (code) {
  3788. case Color::White: DOCTEST_SET_ATTR(FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE); break;
  3789. case Color::Red: DOCTEST_SET_ATTR(FOREGROUND_RED); break;
  3790. case Color::Green: DOCTEST_SET_ATTR(FOREGROUND_GREEN); break;
  3791. case Color::Blue: DOCTEST_SET_ATTR(FOREGROUND_BLUE); break;
  3792. case Color::Cyan: DOCTEST_SET_ATTR(FOREGROUND_BLUE | FOREGROUND_GREEN); break;
  3793. case Color::Yellow: DOCTEST_SET_ATTR(FOREGROUND_RED | FOREGROUND_GREEN); break;
  3794. case Color::Grey: DOCTEST_SET_ATTR(0); break;
  3795. case Color::LightGrey: DOCTEST_SET_ATTR(FOREGROUND_INTENSITY); break;
  3796. case Color::BrightRed: DOCTEST_SET_ATTR(FOREGROUND_INTENSITY | FOREGROUND_RED); break;
  3797. case Color::BrightGreen: DOCTEST_SET_ATTR(FOREGROUND_INTENSITY | FOREGROUND_GREEN); break;
  3798. case Color::BrightWhite: DOCTEST_SET_ATTR(FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE); break;
  3799. case Color::None:
  3800. case Color::Bright: // invalid
  3801. default: DOCTEST_SET_ATTR(ch.origFgAttrs);
  3802. }
  3803. // clang-format on
  3804. #endif // DOCTEST_CONFIG_COLORS_WINDOWS
  3805. }
  3806. DOCTEST_CLANG_SUPPRESS_WARNING_POP
  3807. std::vector<const IExceptionTranslator*>& getExceptionTranslators() {
  3808. static std::vector<const IExceptionTranslator*> data;
  3809. return data;
  3810. }
  3811. String translateActiveException() {
  3812. #ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
  3813. String res;
  3814. auto& translators = getExceptionTranslators();
  3815. for(auto& curr : translators)
  3816. if(curr->translate(res))
  3817. return res;
  3818. // clang-format off
  3819. DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wcatch-value")
  3820. try {
  3821. throw;
  3822. } catch(std::exception& ex) {
  3823. return ex.what();
  3824. } catch(std::string& msg) {
  3825. return msg.c_str();
  3826. } catch(const char* msg) {
  3827. return msg;
  3828. } catch(...) {
  3829. return "unknown exception";
  3830. }
  3831. DOCTEST_GCC_SUPPRESS_WARNING_POP
  3832. // clang-format on
  3833. #else // DOCTEST_CONFIG_NO_EXCEPTIONS
  3834. return "";
  3835. #endif // DOCTEST_CONFIG_NO_EXCEPTIONS
  3836. }
  3837. } // namespace
  3838. namespace detail {
  3839. // used by the macros for registering tests
  3840. int regTest(const TestCase& tc) {
  3841. getRegisteredTests().insert(tc);
  3842. return 0;
  3843. }
  3844. // sets the current test suite
  3845. int setTestSuite(const TestSuite& ts) {
  3846. doctest_detail_test_suite_ns::getCurrentTestSuite() = ts;
  3847. return 0;
  3848. }
  3849. #ifdef DOCTEST_IS_DEBUGGER_ACTIVE
  3850. bool isDebuggerActive() { return DOCTEST_IS_DEBUGGER_ACTIVE(); }
  3851. #else // DOCTEST_IS_DEBUGGER_ACTIVE
  3852. #ifdef DOCTEST_PLATFORM_LINUX
  3853. class ErrnoGuard {
  3854. public:
  3855. ErrnoGuard() : m_oldErrno(errno) {}
  3856. ~ErrnoGuard() { errno = m_oldErrno; }
  3857. private:
  3858. int m_oldErrno;
  3859. };
  3860. // See the comments in Catch2 for the reasoning behind this implementation:
  3861. // https://github.com/catchorg/Catch2/blob/v2.13.1/include/internal/catch_debugger.cpp#L79-L102
  3862. bool isDebuggerActive() {
  3863. ErrnoGuard guard;
  3864. std::ifstream in("/proc/self/status");
  3865. for(std::string line; std::getline(in, line);) {
  3866. static const int PREFIX_LEN = 11;
  3867. if(line.compare(0, PREFIX_LEN, "TracerPid:\t") == 0) {
  3868. return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0';
  3869. }
  3870. }
  3871. return false;
  3872. }
  3873. #elif defined(DOCTEST_PLATFORM_MAC)
  3874. // The following function is taken directly from the following technical note:
  3875. // https://developer.apple.com/library/archive/qa/qa1361/_index.html
  3876. // Returns true if the current process is being debugged (either
  3877. // running under the debugger or has a debugger attached post facto).
  3878. bool isDebuggerActive() {
  3879. int mib[4];
  3880. kinfo_proc info;
  3881. size_t size;
  3882. // Initialize the flags so that, if sysctl fails for some bizarre
  3883. // reason, we get a predictable result.
  3884. info.kp_proc.p_flag = 0;
  3885. // Initialize mib, which tells sysctl the info we want, in this case
  3886. // we're looking for information about a specific process ID.
  3887. mib[0] = CTL_KERN;
  3888. mib[1] = KERN_PROC;
  3889. mib[2] = KERN_PROC_PID;
  3890. mib[3] = getpid();
  3891. // Call sysctl.
  3892. size = sizeof(info);
  3893. if(sysctl(mib, DOCTEST_COUNTOF(mib), &info, &size, 0, 0) != 0) {
  3894. std::cerr << "\nCall to sysctl failed - unable to determine if debugger is active **\n";
  3895. return false;
  3896. }
  3897. // We're being debugged if the P_TRACED flag is set.
  3898. return ((info.kp_proc.p_flag & P_TRACED) != 0);
  3899. }
  3900. #elif DOCTEST_MSVC || defined(__MINGW32__) || defined(__MINGW64__)
  3901. bool isDebuggerActive() { return ::IsDebuggerPresent() != 0; }
  3902. #else
  3903. bool isDebuggerActive() { return false; }
  3904. #endif // Platform
  3905. #endif // DOCTEST_IS_DEBUGGER_ACTIVE
  3906. void registerExceptionTranslatorImpl(const IExceptionTranslator* et) {
  3907. if(std::find(getExceptionTranslators().begin(), getExceptionTranslators().end(), et) ==
  3908. getExceptionTranslators().end())
  3909. getExceptionTranslators().push_back(et);
  3910. }
  3911. DOCTEST_THREAD_LOCAL std::vector<IContextScope*> g_infoContexts; // for logging with INFO()
  3912. ContextScopeBase::ContextScopeBase() {
  3913. g_infoContexts.push_back(this);
  3914. }
  3915. ContextScopeBase::ContextScopeBase(ContextScopeBase&& other) noexcept {
  3916. if (other.need_to_destroy) {
  3917. other.destroy();
  3918. }
  3919. other.need_to_destroy = false;
  3920. g_infoContexts.push_back(this);
  3921. }
  3922. DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4996) // std::uncaught_exception is deprecated in C++17
  3923. DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations")
  3924. DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations")
  3925. // destroy cannot be inlined into the destructor because that would mean calling stringify after
  3926. // ContextScope has been destroyed (base class destructors run after derived class destructors).
  3927. // Instead, ContextScope calls this method directly from its destructor.
  3928. void ContextScopeBase::destroy() {
  3929. #if defined(__cpp_lib_uncaught_exceptions) && __cpp_lib_uncaught_exceptions >= 201411L && (!defined(__MAC_OS_X_VERSION_MIN_REQUIRED) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200)
  3930. if(std::uncaught_exceptions() > 0) {
  3931. #else
  3932. if(std::uncaught_exception()) {
  3933. #endif
  3934. std::ostringstream s;
  3935. this->stringify(&s);
  3936. g_cs->stringifiedContexts.push_back(s.str().c_str());
  3937. }
  3938. g_infoContexts.pop_back();
  3939. }
  3940. DOCTEST_CLANG_SUPPRESS_WARNING_POP
  3941. DOCTEST_GCC_SUPPRESS_WARNING_POP
  3942. DOCTEST_MSVC_SUPPRESS_WARNING_POP
  3943. } // namespace detail
  3944. namespace {
  3945. using namespace detail;
  3946. #if !defined(DOCTEST_CONFIG_POSIX_SIGNALS) && !defined(DOCTEST_CONFIG_WINDOWS_SEH)
  3947. struct FatalConditionHandler
  3948. {
  3949. static void reset() {}
  3950. static void allocateAltStackMem() {}
  3951. static void freeAltStackMem() {}
  3952. };
  3953. #else // DOCTEST_CONFIG_POSIX_SIGNALS || DOCTEST_CONFIG_WINDOWS_SEH
  3954. void reportFatal(const std::string&);
  3955. #ifdef DOCTEST_PLATFORM_WINDOWS
  3956. struct SignalDefs
  3957. {
  3958. DWORD id;
  3959. const char* name;
  3960. };
  3961. // There is no 1-1 mapping between signals and windows exceptions.
  3962. // Windows can easily distinguish between SO and SigSegV,
  3963. // but SigInt, SigTerm, etc are handled differently.
  3964. SignalDefs signalDefs[] = {
  3965. {static_cast<DWORD>(EXCEPTION_ILLEGAL_INSTRUCTION),
  3966. "SIGILL - Illegal instruction signal"},
  3967. {static_cast<DWORD>(EXCEPTION_STACK_OVERFLOW), "SIGSEGV - Stack overflow"},
  3968. {static_cast<DWORD>(EXCEPTION_ACCESS_VIOLATION),
  3969. "SIGSEGV - Segmentation violation signal"},
  3970. {static_cast<DWORD>(EXCEPTION_INT_DIVIDE_BY_ZERO), "Divide by zero error"},
  3971. };
  3972. struct FatalConditionHandler
  3973. {
  3974. static LONG CALLBACK handleException(PEXCEPTION_POINTERS ExceptionInfo) {
  3975. // Multiple threads may enter this filter/handler at once. We want the error message to be printed on the
  3976. // console just once no matter how many threads have crashed.
  3977. DOCTEST_DECLARE_STATIC_MUTEX(mutex)
  3978. static bool execute = true;
  3979. {
  3980. DOCTEST_LOCK_MUTEX(mutex)
  3981. if(execute) {
  3982. bool reported = false;
  3983. for(size_t i = 0; i < DOCTEST_COUNTOF(signalDefs); ++i) {
  3984. if(ExceptionInfo->ExceptionRecord->ExceptionCode == signalDefs[i].id) {
  3985. reportFatal(signalDefs[i].name);
  3986. reported = true;
  3987. break;
  3988. }
  3989. }
  3990. if(reported == false)
  3991. reportFatal("Unhandled SEH exception caught");
  3992. if(isDebuggerActive() && !g_cs->no_breaks)
  3993. DOCTEST_BREAK_INTO_DEBUGGER();
  3994. }
  3995. execute = false;
  3996. }
  3997. std::exit(EXIT_FAILURE);
  3998. }
  3999. static void allocateAltStackMem() {}
  4000. static void freeAltStackMem() {}
  4001. FatalConditionHandler() {
  4002. isSet = true;
  4003. // 32k seems enough for doctest to handle stack overflow,
  4004. // but the value was found experimentally, so there is no strong guarantee
  4005. guaranteeSize = 32 * 1024;
  4006. // Register an unhandled exception filter
  4007. previousTop = SetUnhandledExceptionFilter(handleException);
  4008. // Pass in guarantee size to be filled
  4009. SetThreadStackGuarantee(&guaranteeSize);
  4010. // On Windows uncaught exceptions from another thread, exceptions from
  4011. // destructors, or calls to std::terminate are not a SEH exception
  4012. // The terminal handler gets called when:
  4013. // - std::terminate is called FROM THE TEST RUNNER THREAD
  4014. // - an exception is thrown from a destructor FROM THE TEST RUNNER THREAD
  4015. original_terminate_handler = std::get_terminate();
  4016. std::set_terminate([]() DOCTEST_NOEXCEPT {
  4017. reportFatal("Terminate handler called");
  4018. if(isDebuggerActive() && !g_cs->no_breaks)
  4019. DOCTEST_BREAK_INTO_DEBUGGER();
  4020. std::exit(EXIT_FAILURE); // explicitly exit - otherwise the SIGABRT handler may be called as well
  4021. });
  4022. // SIGABRT is raised when:
  4023. // - std::terminate is called FROM A DIFFERENT THREAD
  4024. // - an exception is thrown from a destructor FROM A DIFFERENT THREAD
  4025. // - an uncaught exception is thrown FROM A DIFFERENT THREAD
  4026. prev_sigabrt_handler = std::signal(SIGABRT, [](int signal) DOCTEST_NOEXCEPT {
  4027. if(signal == SIGABRT) {
  4028. reportFatal("SIGABRT - Abort (abnormal termination) signal");
  4029. if(isDebuggerActive() && !g_cs->no_breaks)
  4030. DOCTEST_BREAK_INTO_DEBUGGER();
  4031. std::exit(EXIT_FAILURE);
  4032. }
  4033. });
  4034. // The following settings are taken from google test, and more
  4035. // specifically from UnitTest::Run() inside of gtest.cc
  4036. // the user does not want to see pop-up dialogs about crashes
  4037. prev_error_mode_1 = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT |
  4038. SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);
  4039. // This forces the abort message to go to stderr in all circumstances.
  4040. prev_error_mode_2 = _set_error_mode(_OUT_TO_STDERR);
  4041. // In the debug version, Visual Studio pops up a separate dialog
  4042. // offering a choice to debug the aborted program - we want to disable that.
  4043. prev_abort_behavior = _set_abort_behavior(0x0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
  4044. // In debug mode, the Windows CRT can crash with an assertion over invalid
  4045. // input (e.g. passing an invalid file descriptor). The default handling
  4046. // for these assertions is to pop up a dialog and wait for user input.
  4047. // Instead ask the CRT to dump such assertions to stderr non-interactively.
  4048. prev_report_mode = _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
  4049. prev_report_file = _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
  4050. }
  4051. static void reset() {
  4052. if(isSet) {
  4053. // Unregister handler and restore the old guarantee
  4054. SetUnhandledExceptionFilter(previousTop);
  4055. SetThreadStackGuarantee(&guaranteeSize);
  4056. std::set_terminate(original_terminate_handler);
  4057. std::signal(SIGABRT, prev_sigabrt_handler);
  4058. SetErrorMode(prev_error_mode_1);
  4059. _set_error_mode(prev_error_mode_2);
  4060. _set_abort_behavior(prev_abort_behavior, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
  4061. static_cast<void>(_CrtSetReportMode(_CRT_ASSERT, prev_report_mode));
  4062. static_cast<void>(_CrtSetReportFile(_CRT_ASSERT, prev_report_file));
  4063. isSet = false;
  4064. }
  4065. }
  4066. ~FatalConditionHandler() { reset(); }
  4067. private:
  4068. static UINT prev_error_mode_1;
  4069. static int prev_error_mode_2;
  4070. static unsigned int prev_abort_behavior;
  4071. static int prev_report_mode;
  4072. static _HFILE prev_report_file;
  4073. static void (DOCTEST_CDECL *prev_sigabrt_handler)(int);
  4074. static std::terminate_handler original_terminate_handler;
  4075. static bool isSet;
  4076. static ULONG guaranteeSize;
  4077. static LPTOP_LEVEL_EXCEPTION_FILTER previousTop;
  4078. };
  4079. UINT FatalConditionHandler::prev_error_mode_1;
  4080. int FatalConditionHandler::prev_error_mode_2;
  4081. unsigned int FatalConditionHandler::prev_abort_behavior;
  4082. int FatalConditionHandler::prev_report_mode;
  4083. _HFILE FatalConditionHandler::prev_report_file;
  4084. void (DOCTEST_CDECL *FatalConditionHandler::prev_sigabrt_handler)(int);
  4085. std::terminate_handler FatalConditionHandler::original_terminate_handler;
  4086. bool FatalConditionHandler::isSet = false;
  4087. ULONG FatalConditionHandler::guaranteeSize = 0;
  4088. LPTOP_LEVEL_EXCEPTION_FILTER FatalConditionHandler::previousTop = nullptr;
  4089. #else // DOCTEST_PLATFORM_WINDOWS
  4090. struct SignalDefs
  4091. {
  4092. int id;
  4093. const char* name;
  4094. };
  4095. SignalDefs signalDefs[] = {{SIGINT, "SIGINT - Terminal interrupt signal"},
  4096. {SIGILL, "SIGILL - Illegal instruction signal"},
  4097. {SIGFPE, "SIGFPE - Floating point error signal"},
  4098. {SIGSEGV, "SIGSEGV - Segmentation violation signal"},
  4099. {SIGTERM, "SIGTERM - Termination request signal"},
  4100. {SIGABRT, "SIGABRT - Abort (abnormal termination) signal"}};
  4101. struct FatalConditionHandler
  4102. {
  4103. static bool isSet;
  4104. static struct sigaction oldSigActions[DOCTEST_COUNTOF(signalDefs)];
  4105. static stack_t oldSigStack;
  4106. static size_t altStackSize;
  4107. static char* altStackMem;
  4108. static void handleSignal(int sig) {
  4109. const char* name = "<unknown signal>";
  4110. for(std::size_t i = 0; i < DOCTEST_COUNTOF(signalDefs); ++i) {
  4111. SignalDefs& def = signalDefs[i];
  4112. if(sig == def.id) {
  4113. name = def.name;
  4114. break;
  4115. }
  4116. }
  4117. reset();
  4118. reportFatal(name);
  4119. raise(sig);
  4120. }
  4121. static void allocateAltStackMem() {
  4122. altStackMem = new char[altStackSize];
  4123. }
  4124. static void freeAltStackMem() {
  4125. delete[] altStackMem;
  4126. }
  4127. FatalConditionHandler() {
  4128. isSet = true;
  4129. stack_t sigStack;
  4130. sigStack.ss_sp = altStackMem;
  4131. sigStack.ss_size = altStackSize;
  4132. sigStack.ss_flags = 0;
  4133. sigaltstack(&sigStack, &oldSigStack);
  4134. struct sigaction sa = {};
  4135. sa.sa_handler = handleSignal;
  4136. sa.sa_flags = SA_ONSTACK;
  4137. for(std::size_t i = 0; i < DOCTEST_COUNTOF(signalDefs); ++i) {
  4138. sigaction(signalDefs[i].id, &sa, &oldSigActions[i]);
  4139. }
  4140. }
  4141. ~FatalConditionHandler() { reset(); }
  4142. static void reset() {
  4143. if(isSet) {
  4144. // Set signals back to previous values -- hopefully nobody overwrote them in the meantime
  4145. for(std::size_t i = 0; i < DOCTEST_COUNTOF(signalDefs); ++i) {
  4146. sigaction(signalDefs[i].id, &oldSigActions[i], nullptr);
  4147. }
  4148. // Return the old stack
  4149. sigaltstack(&oldSigStack, nullptr);
  4150. isSet = false;
  4151. }
  4152. }
  4153. };
  4154. bool FatalConditionHandler::isSet = false;
  4155. struct sigaction FatalConditionHandler::oldSigActions[DOCTEST_COUNTOF(signalDefs)] = {};
  4156. stack_t FatalConditionHandler::oldSigStack = {};
  4157. size_t FatalConditionHandler::altStackSize = 4 * SIGSTKSZ;
  4158. char* FatalConditionHandler::altStackMem = nullptr;
  4159. #endif // DOCTEST_PLATFORM_WINDOWS
  4160. #endif // DOCTEST_CONFIG_POSIX_SIGNALS || DOCTEST_CONFIG_WINDOWS_SEH
  4161. } // namespace
  4162. namespace {
  4163. using namespace detail;
  4164. #ifdef DOCTEST_PLATFORM_WINDOWS
  4165. #define DOCTEST_OUTPUT_DEBUG_STRING(text) ::OutputDebugStringA(text)
  4166. #else
  4167. // TODO: integration with XCode and other IDEs
  4168. #define DOCTEST_OUTPUT_DEBUG_STRING(text)
  4169. #endif // Platform
  4170. void addAssert(assertType::Enum at) {
  4171. if((at & assertType::is_warn) == 0) //!OCLINT bitwise operator in conditional
  4172. g_cs->numAssertsCurrentTest_atomic++;
  4173. }
  4174. void addFailedAssert(assertType::Enum at) {
  4175. if((at & assertType::is_warn) == 0) //!OCLINT bitwise operator in conditional
  4176. g_cs->numAssertsFailedCurrentTest_atomic++;
  4177. }
  4178. #if defined(DOCTEST_CONFIG_POSIX_SIGNALS) || defined(DOCTEST_CONFIG_WINDOWS_SEH)
  4179. void reportFatal(const std::string& message) {
  4180. g_cs->failure_flags |= TestCaseFailureReason::Crash;
  4181. DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_exception, {message.c_str(), true});
  4182. while (g_cs->subcaseStack.size()) {
  4183. g_cs->subcaseStack.pop_back();
  4184. DOCTEST_ITERATE_THROUGH_REPORTERS(subcase_end, DOCTEST_EMPTY);
  4185. }
  4186. g_cs->finalizeTestCaseData();
  4187. DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_end, *g_cs);
  4188. DOCTEST_ITERATE_THROUGH_REPORTERS(test_run_end, *g_cs);
  4189. }
  4190. #endif // DOCTEST_CONFIG_POSIX_SIGNALS || DOCTEST_CONFIG_WINDOWS_SEH
  4191. } // namespace
  4192. AssertData::AssertData(assertType::Enum at, const char* file, int line, const char* expr,
  4193. const char* exception_type, const StringContains& exception_string)
  4194. : m_test_case(g_cs->currentTest), m_at(at), m_file(file), m_line(line), m_expr(expr),
  4195. m_failed(true), m_threw(false), m_threw_as(false), m_exception_type(exception_type),
  4196. m_exception_string(exception_string) {
  4197. #if DOCTEST_MSVC
  4198. if (m_expr[0] == ' ') // this happens when variadic macros are disabled under MSVC
  4199. ++m_expr;
  4200. #endif // MSVC
  4201. }
  4202. namespace detail {
  4203. ResultBuilder::ResultBuilder(assertType::Enum at, const char* file, int line, const char* expr,
  4204. const char* exception_type, const String& exception_string)
  4205. : AssertData(at, file, line, expr, exception_type, exception_string) { }
  4206. ResultBuilder::ResultBuilder(assertType::Enum at, const char* file, int line, const char* expr,
  4207. const char* exception_type, const Contains& exception_string)
  4208. : AssertData(at, file, line, expr, exception_type, exception_string) { }
  4209. void ResultBuilder::setResult(const Result& res) {
  4210. m_decomp = res.m_decomp;
  4211. m_failed = !res.m_passed;
  4212. }
  4213. void ResultBuilder::translateException() {
  4214. m_threw = true;
  4215. m_exception = translateActiveException();
  4216. }
  4217. bool ResultBuilder::log() {
  4218. if(m_at & assertType::is_throws) { //!OCLINT bitwise operator in conditional
  4219. m_failed = !m_threw;
  4220. } else if((m_at & assertType::is_throws_as) && (m_at & assertType::is_throws_with)) { //!OCLINT
  4221. m_failed = !m_threw_as || !m_exception_string.check(m_exception);
  4222. } else if(m_at & assertType::is_throws_as) { //!OCLINT bitwise operator in conditional
  4223. m_failed = !m_threw_as;
  4224. } else if(m_at & assertType::is_throws_with) { //!OCLINT bitwise operator in conditional
  4225. m_failed = !m_exception_string.check(m_exception);
  4226. } else if(m_at & assertType::is_nothrow) { //!OCLINT bitwise operator in conditional
  4227. m_failed = m_threw;
  4228. }
  4229. if(m_exception.size())
  4230. m_exception = "\"" + m_exception + "\"";
  4231. if(is_running_in_test) {
  4232. addAssert(m_at);
  4233. DOCTEST_ITERATE_THROUGH_REPORTERS(log_assert, *this);
  4234. if(m_failed)
  4235. addFailedAssert(m_at);
  4236. } else if(m_failed) {
  4237. failed_out_of_a_testing_context(*this);
  4238. }
  4239. return m_failed && isDebuggerActive() && !getContextOptions()->no_breaks &&
  4240. (g_cs->currentTest == nullptr || !g_cs->currentTest->m_no_breaks); // break into debugger
  4241. }
  4242. void ResultBuilder::react() const {
  4243. if(m_failed && checkIfShouldThrow(m_at))
  4244. throwException();
  4245. }
  4246. void failed_out_of_a_testing_context(const AssertData& ad) {
  4247. if(g_cs->ah)
  4248. g_cs->ah(ad);
  4249. else
  4250. std::abort();
  4251. }
  4252. bool decomp_assert(assertType::Enum at, const char* file, int line, const char* expr,
  4253. const Result& result) {
  4254. bool failed = !result.m_passed;
  4255. // ###################################################################################
  4256. // IF THE DEBUGGER BREAKS HERE - GO 1 LEVEL UP IN THE CALLSTACK FOR THE FAILING ASSERT
  4257. // THIS IS THE EFFECT OF HAVING 'DOCTEST_CONFIG_SUPER_FAST_ASSERTS' DEFINED
  4258. // ###################################################################################
  4259. DOCTEST_ASSERT_OUT_OF_TESTS(result.m_decomp);
  4260. DOCTEST_ASSERT_IN_TESTS(result.m_decomp);
  4261. return !failed;
  4262. }
  4263. MessageBuilder::MessageBuilder(const char* file, int line, assertType::Enum severity) {
  4264. m_stream = tlssPush();
  4265. m_file = file;
  4266. m_line = line;
  4267. m_severity = severity;
  4268. }
  4269. MessageBuilder::~MessageBuilder() {
  4270. if (!logged)
  4271. tlssPop();
  4272. }
  4273. DOCTEST_DEFINE_INTERFACE(IExceptionTranslator)
  4274. bool MessageBuilder::log() {
  4275. if (!logged) {
  4276. m_string = tlssPop();
  4277. logged = true;
  4278. }
  4279. DOCTEST_ITERATE_THROUGH_REPORTERS(log_message, *this);
  4280. const bool isWarn = m_severity & assertType::is_warn;
  4281. // warn is just a message in this context so we don't treat it as an assert
  4282. if(!isWarn) {
  4283. addAssert(m_severity);
  4284. addFailedAssert(m_severity);
  4285. }
  4286. return isDebuggerActive() && !getContextOptions()->no_breaks && !isWarn &&
  4287. (g_cs->currentTest == nullptr || !g_cs->currentTest->m_no_breaks); // break into debugger
  4288. }
  4289. void MessageBuilder::react() {
  4290. if(m_severity & assertType::is_require) //!OCLINT bitwise operator in conditional
  4291. throwException();
  4292. }
  4293. } // namespace detail
  4294. namespace {
  4295. using namespace detail;
  4296. // clang-format off
  4297. // =================================================================================================
  4298. // The following code has been taken verbatim from Catch2/include/internal/catch_xmlwriter.h/cpp
  4299. // This is done so cherry-picking bug fixes is trivial - even the style/formatting is untouched.
  4300. // =================================================================================================
  4301. class XmlEncode {
  4302. public:
  4303. enum ForWhat { ForTextNodes, ForAttributes };
  4304. XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes );
  4305. void encodeTo( std::ostream& os ) const;
  4306. friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode );
  4307. private:
  4308. std::string m_str;
  4309. ForWhat m_forWhat;
  4310. };
  4311. class XmlWriter {
  4312. public:
  4313. class ScopedElement {
  4314. public:
  4315. ScopedElement( XmlWriter* writer );
  4316. ScopedElement( ScopedElement&& other ) DOCTEST_NOEXCEPT;
  4317. ScopedElement& operator=( ScopedElement&& other ) DOCTEST_NOEXCEPT;
  4318. ~ScopedElement();
  4319. ScopedElement& writeText( std::string const& text, bool indent = true );
  4320. template<typename T>
  4321. ScopedElement& writeAttribute( std::string const& name, T const& attribute ) {
  4322. m_writer->writeAttribute( name, attribute );
  4323. return *this;
  4324. }
  4325. private:
  4326. mutable XmlWriter* m_writer = nullptr;
  4327. };
  4328. #ifndef DOCTEST_CONFIG_NO_INCLUDE_IOSTREAM
  4329. XmlWriter( std::ostream& os = std::cout );
  4330. #else // DOCTEST_CONFIG_NO_INCLUDE_IOSTREAM
  4331. XmlWriter( std::ostream& os );
  4332. #endif // DOCTEST_CONFIG_NO_INCLUDE_IOSTREAM
  4333. ~XmlWriter();
  4334. XmlWriter( XmlWriter const& ) = delete;
  4335. XmlWriter& operator=( XmlWriter const& ) = delete;
  4336. XmlWriter& startElement( std::string const& name );
  4337. ScopedElement scopedElement( std::string const& name );
  4338. XmlWriter& endElement();
  4339. XmlWriter& writeAttribute( std::string const& name, std::string const& attribute );
  4340. XmlWriter& writeAttribute( std::string const& name, const char* attribute );
  4341. XmlWriter& writeAttribute( std::string const& name, bool attribute );
  4342. template<typename T>
  4343. XmlWriter& writeAttribute( std::string const& name, T const& attribute ) {
  4344. std::stringstream rss;
  4345. rss << attribute;
  4346. return writeAttribute( name, rss.str() );
  4347. }
  4348. XmlWriter& writeText( std::string const& text, bool indent = true );
  4349. //XmlWriter& writeComment( std::string const& text );
  4350. //void writeStylesheetRef( std::string const& url );
  4351. //XmlWriter& writeBlankLine();
  4352. void ensureTagClosed();
  4353. void writeDeclaration();
  4354. private:
  4355. void newlineIfNecessary();
  4356. bool m_tagIsOpen = false;
  4357. bool m_needsNewline = false;
  4358. std::vector<std::string> m_tags;
  4359. std::string m_indent;
  4360. std::ostream& m_os;
  4361. };
  4362. // =================================================================================================
  4363. // The following code has been taken verbatim from Catch2/include/internal/catch_xmlwriter.h/cpp
  4364. // This is done so cherry-picking bug fixes is trivial - even the style/formatting is untouched.
  4365. // =================================================================================================
  4366. using uchar = unsigned char;
  4367. namespace {
  4368. size_t trailingBytes(unsigned char c) {
  4369. if ((c & 0xE0) == 0xC0) {
  4370. return 2;
  4371. }
  4372. if ((c & 0xF0) == 0xE0) {
  4373. return 3;
  4374. }
  4375. if ((c & 0xF8) == 0xF0) {
  4376. return 4;
  4377. }
  4378. DOCTEST_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered");
  4379. }
  4380. uint32_t headerValue(unsigned char c) {
  4381. if ((c & 0xE0) == 0xC0) {
  4382. return c & 0x1F;
  4383. }
  4384. if ((c & 0xF0) == 0xE0) {
  4385. return c & 0x0F;
  4386. }
  4387. if ((c & 0xF8) == 0xF0) {
  4388. return c & 0x07;
  4389. }
  4390. DOCTEST_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered");
  4391. }
  4392. void hexEscapeChar(std::ostream& os, unsigned char c) {
  4393. std::ios_base::fmtflags f(os.flags());
  4394. os << "\\x"
  4395. << std::uppercase << std::hex << std::setfill('0') << std::setw(2)
  4396. << static_cast<int>(c);
  4397. os.flags(f);
  4398. }
  4399. } // anonymous namespace
  4400. XmlEncode::XmlEncode( std::string const& str, ForWhat forWhat )
  4401. : m_str( str ),
  4402. m_forWhat( forWhat )
  4403. {}
  4404. void XmlEncode::encodeTo( std::ostream& os ) const {
  4405. // Apostrophe escaping not necessary if we always use " to write attributes
  4406. // (see: https://www.w3.org/TR/xml/#syntax)
  4407. for( std::size_t idx = 0; idx < m_str.size(); ++ idx ) {
  4408. uchar c = m_str[idx];
  4409. switch (c) {
  4410. case '<': os << "&lt;"; break;
  4411. case '&': os << "&amp;"; break;
  4412. case '>':
  4413. // See: https://www.w3.org/TR/xml/#syntax
  4414. if (idx > 2 && m_str[idx - 1] == ']' && m_str[idx - 2] == ']')
  4415. os << "&gt;";
  4416. else
  4417. os << c;
  4418. break;
  4419. case '\"':
  4420. if (m_forWhat == ForAttributes)
  4421. os << "&quot;";
  4422. else
  4423. os << c;
  4424. break;
  4425. default:
  4426. // Check for control characters and invalid utf-8
  4427. // Escape control characters in standard ascii
  4428. // see https://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0
  4429. if (c < 0x09 || (c > 0x0D && c < 0x20) || c == 0x7F) {
  4430. hexEscapeChar(os, c);
  4431. break;
  4432. }
  4433. // Plain ASCII: Write it to stream
  4434. if (c < 0x7F) {
  4435. os << c;
  4436. break;
  4437. }
  4438. // UTF-8 territory
  4439. // Check if the encoding is valid and if it is not, hex escape bytes.
  4440. // Important: We do not check the exact decoded values for validity, only the encoding format
  4441. // First check that this bytes is a valid lead byte:
  4442. // This means that it is not encoded as 1111 1XXX
  4443. // Or as 10XX XXXX
  4444. if (c < 0xC0 ||
  4445. c >= 0xF8) {
  4446. hexEscapeChar(os, c);
  4447. break;
  4448. }
  4449. auto encBytes = trailingBytes(c);
  4450. // Are there enough bytes left to avoid accessing out-of-bounds memory?
  4451. if (idx + encBytes - 1 >= m_str.size()) {
  4452. hexEscapeChar(os, c);
  4453. break;
  4454. }
  4455. // The header is valid, check data
  4456. // The next encBytes bytes must together be a valid utf-8
  4457. // This means: bitpattern 10XX XXXX and the extracted value is sane (ish)
  4458. bool valid = true;
  4459. uint32_t value = headerValue(c);
  4460. for (std::size_t n = 1; n < encBytes; ++n) {
  4461. uchar nc = m_str[idx + n];
  4462. valid &= ((nc & 0xC0) == 0x80);
  4463. value = (value << 6) | (nc & 0x3F);
  4464. }
  4465. if (
  4466. // Wrong bit pattern of following bytes
  4467. (!valid) ||
  4468. // Overlong encodings
  4469. (value < 0x80) ||
  4470. ( value < 0x800 && encBytes > 2) || // removed "0x80 <= value &&" because redundant
  4471. (0x800 < value && value < 0x10000 && encBytes > 3) ||
  4472. // Encoded value out of range
  4473. (value >= 0x110000)
  4474. ) {
  4475. hexEscapeChar(os, c);
  4476. break;
  4477. }
  4478. // If we got here, this is in fact a valid(ish) utf-8 sequence
  4479. for (std::size_t n = 0; n < encBytes; ++n) {
  4480. os << m_str[idx + n];
  4481. }
  4482. idx += encBytes - 1;
  4483. break;
  4484. }
  4485. }
  4486. }
  4487. std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) {
  4488. xmlEncode.encodeTo( os );
  4489. return os;
  4490. }
  4491. XmlWriter::ScopedElement::ScopedElement( XmlWriter* writer )
  4492. : m_writer( writer )
  4493. {}
  4494. XmlWriter::ScopedElement::ScopedElement( ScopedElement&& other ) DOCTEST_NOEXCEPT
  4495. : m_writer( other.m_writer ){
  4496. other.m_writer = nullptr;
  4497. }
  4498. XmlWriter::ScopedElement& XmlWriter::ScopedElement::operator=( ScopedElement&& other ) DOCTEST_NOEXCEPT {
  4499. if ( m_writer ) {
  4500. m_writer->endElement();
  4501. }
  4502. m_writer = other.m_writer;
  4503. other.m_writer = nullptr;
  4504. return *this;
  4505. }
  4506. XmlWriter::ScopedElement::~ScopedElement() {
  4507. if( m_writer )
  4508. m_writer->endElement();
  4509. }
  4510. XmlWriter::ScopedElement& XmlWriter::ScopedElement::writeText( std::string const& text, bool indent ) {
  4511. m_writer->writeText( text, indent );
  4512. return *this;
  4513. }
  4514. XmlWriter::XmlWriter( std::ostream& os ) : m_os( os )
  4515. {
  4516. // writeDeclaration(); // called explicitly by the reporters that use the writer class - see issue #627
  4517. }
  4518. XmlWriter::~XmlWriter() {
  4519. while( !m_tags.empty() )
  4520. endElement();
  4521. }
  4522. XmlWriter& XmlWriter::startElement( std::string const& name ) {
  4523. ensureTagClosed();
  4524. newlineIfNecessary();
  4525. m_os << m_indent << '<' << name;
  4526. m_tags.push_back( name );
  4527. m_indent += " ";
  4528. m_tagIsOpen = true;
  4529. return *this;
  4530. }
  4531. XmlWriter::ScopedElement XmlWriter::scopedElement( std::string const& name ) {
  4532. ScopedElement scoped( this );
  4533. startElement( name );
  4534. return scoped;
  4535. }
  4536. XmlWriter& XmlWriter::endElement() {
  4537. newlineIfNecessary();
  4538. m_indent = m_indent.substr( 0, m_indent.size()-2 );
  4539. if( m_tagIsOpen ) {
  4540. m_os << "/>";
  4541. m_tagIsOpen = false;
  4542. }
  4543. else {
  4544. m_os << m_indent << "</" << m_tags.back() << ">";
  4545. }
  4546. m_os << std::endl;
  4547. m_tags.pop_back();
  4548. return *this;
  4549. }
  4550. XmlWriter& XmlWriter::writeAttribute( std::string const& name, std::string const& attribute ) {
  4551. if( !name.empty() && !attribute.empty() )
  4552. m_os << ' ' << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '"';
  4553. return *this;
  4554. }
  4555. XmlWriter& XmlWriter::writeAttribute( std::string const& name, const char* attribute ) {
  4556. if( !name.empty() && attribute && attribute[0] != '\0' )
  4557. m_os << ' ' << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '"';
  4558. return *this;
  4559. }
  4560. XmlWriter& XmlWriter::writeAttribute( std::string const& name, bool attribute ) {
  4561. m_os << ' ' << name << "=\"" << ( attribute ? "true" : "false" ) << '"';
  4562. return *this;
  4563. }
  4564. XmlWriter& XmlWriter::writeText( std::string const& text, bool indent ) {
  4565. if( !text.empty() ){
  4566. bool tagWasOpen = m_tagIsOpen;
  4567. ensureTagClosed();
  4568. if( tagWasOpen && indent )
  4569. m_os << m_indent;
  4570. m_os << XmlEncode( text );
  4571. m_needsNewline = true;
  4572. }
  4573. return *this;
  4574. }
  4575. //XmlWriter& XmlWriter::writeComment( std::string const& text ) {
  4576. // ensureTagClosed();
  4577. // m_os << m_indent << "<!--" << text << "-->";
  4578. // m_needsNewline = true;
  4579. // return *this;
  4580. //}
  4581. //void XmlWriter::writeStylesheetRef( std::string const& url ) {
  4582. // m_os << "<?xml-stylesheet type=\"text/xsl\" href=\"" << url << "\"?>\n";
  4583. //}
  4584. //XmlWriter& XmlWriter::writeBlankLine() {
  4585. // ensureTagClosed();
  4586. // m_os << '\n';
  4587. // return *this;
  4588. //}
  4589. void XmlWriter::ensureTagClosed() {
  4590. if( m_tagIsOpen ) {
  4591. m_os << ">" << std::endl;
  4592. m_tagIsOpen = false;
  4593. }
  4594. }
  4595. void XmlWriter::writeDeclaration() {
  4596. m_os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
  4597. }
  4598. void XmlWriter::newlineIfNecessary() {
  4599. if( m_needsNewline ) {
  4600. m_os << std::endl;
  4601. m_needsNewline = false;
  4602. }
  4603. }
  4604. // =================================================================================================
  4605. // End of copy-pasted code from Catch
  4606. // =================================================================================================
  4607. // clang-format on
  4608. struct XmlReporter : public IReporter
  4609. {
  4610. XmlWriter xml;
  4611. DOCTEST_DECLARE_MUTEX(mutex)
  4612. // caching pointers/references to objects of these types - safe to do
  4613. const ContextOptions& opt;
  4614. const TestCaseData* tc = nullptr;
  4615. XmlReporter(const ContextOptions& co)
  4616. : xml(*co.cout)
  4617. , opt(co) {}
  4618. void log_contexts() {
  4619. int num_contexts = get_num_active_contexts();
  4620. if(num_contexts) {
  4621. auto contexts = get_active_contexts();
  4622. std::stringstream ss;
  4623. for(int i = 0; i < num_contexts; ++i) {
  4624. contexts[i]->stringify(&ss);
  4625. xml.scopedElement("Info").writeText(ss.str());
  4626. ss.str("");
  4627. }
  4628. }
  4629. }
  4630. unsigned line(unsigned l) const { return opt.no_line_numbers ? 0 : l; }
  4631. void test_case_start_impl(const TestCaseData& in) {
  4632. bool open_ts_tag = false;
  4633. if(tc != nullptr) { // we have already opened a test suite
  4634. if(std::strcmp(tc->m_test_suite, in.m_test_suite) != 0) {
  4635. xml.endElement();
  4636. open_ts_tag = true;
  4637. }
  4638. }
  4639. else {
  4640. open_ts_tag = true; // first test case ==> first test suite
  4641. }
  4642. if(open_ts_tag) {
  4643. xml.startElement("TestSuite");
  4644. xml.writeAttribute("name", in.m_test_suite);
  4645. }
  4646. tc = &in;
  4647. xml.startElement("TestCase")
  4648. .writeAttribute("name", in.m_name)
  4649. .writeAttribute("filename", skipPathFromFilename(in.m_file.c_str()))
  4650. .writeAttribute("line", line(in.m_line))
  4651. .writeAttribute("description", in.m_description);
  4652. if(Approx(in.m_timeout) != 0)
  4653. xml.writeAttribute("timeout", in.m_timeout);
  4654. if(in.m_may_fail)
  4655. xml.writeAttribute("may_fail", true);
  4656. if(in.m_should_fail)
  4657. xml.writeAttribute("should_fail", true);
  4658. }
  4659. // =========================================================================================
  4660. // WHAT FOLLOWS ARE OVERRIDES OF THE VIRTUAL METHODS OF THE REPORTER INTERFACE
  4661. // =========================================================================================
  4662. void report_query(const QueryData& in) override {
  4663. test_run_start();
  4664. if(opt.list_reporters) {
  4665. for(auto& curr : getListeners())
  4666. xml.scopedElement("Listener")
  4667. .writeAttribute("priority", curr.first.first)
  4668. .writeAttribute("name", curr.first.second);
  4669. for(auto& curr : getReporters())
  4670. xml.scopedElement("Reporter")
  4671. .writeAttribute("priority", curr.first.first)
  4672. .writeAttribute("name", curr.first.second);
  4673. } else if(opt.count || opt.list_test_cases) {
  4674. for(unsigned i = 0; i < in.num_data; ++i) {
  4675. xml.scopedElement("TestCase").writeAttribute("name", in.data[i]->m_name)
  4676. .writeAttribute("testsuite", in.data[i]->m_test_suite)
  4677. .writeAttribute("filename", skipPathFromFilename(in.data[i]->m_file.c_str()))
  4678. .writeAttribute("line", line(in.data[i]->m_line))
  4679. .writeAttribute("skipped", in.data[i]->m_skip);
  4680. }
  4681. xml.scopedElement("OverallResultsTestCases")
  4682. .writeAttribute("unskipped", in.run_stats->numTestCasesPassingFilters);
  4683. } else if(opt.list_test_suites) {
  4684. for(unsigned i = 0; i < in.num_data; ++i)
  4685. xml.scopedElement("TestSuite").writeAttribute("name", in.data[i]->m_test_suite);
  4686. xml.scopedElement("OverallResultsTestCases")
  4687. .writeAttribute("unskipped", in.run_stats->numTestCasesPassingFilters);
  4688. xml.scopedElement("OverallResultsTestSuites")
  4689. .writeAttribute("unskipped", in.run_stats->numTestSuitesPassingFilters);
  4690. }
  4691. xml.endElement();
  4692. }
  4693. void test_run_start() override {
  4694. xml.writeDeclaration();
  4695. // remove .exe extension - mainly to have the same output on UNIX and Windows
  4696. std::string binary_name = skipPathFromFilename(opt.binary_name.c_str());
  4697. #ifdef DOCTEST_PLATFORM_WINDOWS
  4698. if(binary_name.rfind(".exe") != std::string::npos)
  4699. binary_name = binary_name.substr(0, binary_name.length() - 4);
  4700. #endif // DOCTEST_PLATFORM_WINDOWS
  4701. xml.startElement("doctest").writeAttribute("binary", binary_name);
  4702. if(opt.no_version == false)
  4703. xml.writeAttribute("version", DOCTEST_VERSION_STR);
  4704. // only the consequential ones (TODO: filters)
  4705. xml.scopedElement("Options")
  4706. .writeAttribute("order_by", opt.order_by.c_str())
  4707. .writeAttribute("rand_seed", opt.rand_seed)
  4708. .writeAttribute("first", opt.first)
  4709. .writeAttribute("last", opt.last)
  4710. .writeAttribute("abort_after", opt.abort_after)
  4711. .writeAttribute("subcase_filter_levels", opt.subcase_filter_levels)
  4712. .writeAttribute("case_sensitive", opt.case_sensitive)
  4713. .writeAttribute("no_throw", opt.no_throw)
  4714. .writeAttribute("no_skip", opt.no_skip);
  4715. }
  4716. void test_run_end(const TestRunStats& p) override {
  4717. if(tc) // the TestSuite tag - only if there has been at least 1 test case
  4718. xml.endElement();
  4719. xml.scopedElement("OverallResultsAsserts")
  4720. .writeAttribute("successes", p.numAsserts - p.numAssertsFailed)
  4721. .writeAttribute("failures", p.numAssertsFailed);
  4722. xml.startElement("OverallResultsTestCases")
  4723. .writeAttribute("successes",
  4724. p.numTestCasesPassingFilters - p.numTestCasesFailed)
  4725. .writeAttribute("failures", p.numTestCasesFailed);
  4726. if(opt.no_skipped_summary == false)
  4727. xml.writeAttribute("skipped", p.numTestCases - p.numTestCasesPassingFilters);
  4728. xml.endElement();
  4729. xml.endElement();
  4730. }
  4731. void test_case_start(const TestCaseData& in) override {
  4732. test_case_start_impl(in);
  4733. xml.ensureTagClosed();
  4734. }
  4735. void test_case_reenter(const TestCaseData&) override {}
  4736. void test_case_end(const CurrentTestCaseStats& st) override {
  4737. xml.startElement("OverallResultsAsserts")
  4738. .writeAttribute("successes",
  4739. st.numAssertsCurrentTest - st.numAssertsFailedCurrentTest)
  4740. .writeAttribute("failures", st.numAssertsFailedCurrentTest)
  4741. .writeAttribute("test_case_success", st.testCaseSuccess);
  4742. if(opt.duration)
  4743. xml.writeAttribute("duration", st.seconds);
  4744. if(tc->m_expected_failures)
  4745. xml.writeAttribute("expected_failures", tc->m_expected_failures);
  4746. xml.endElement();
  4747. xml.endElement();
  4748. }
  4749. void test_case_exception(const TestCaseException& e) override {
  4750. DOCTEST_LOCK_MUTEX(mutex)
  4751. xml.scopedElement("Exception")
  4752. .writeAttribute("crash", e.is_crash)
  4753. .writeText(e.error_string.c_str());
  4754. }
  4755. void subcase_start(const SubcaseSignature& in) override {
  4756. xml.startElement("SubCase")
  4757. .writeAttribute("name", in.m_name)
  4758. .writeAttribute("filename", skipPathFromFilename(in.m_file))
  4759. .writeAttribute("line", line(in.m_line));
  4760. xml.ensureTagClosed();
  4761. }
  4762. void subcase_end() override { xml.endElement(); }
  4763. void log_assert(const AssertData& rb) override {
  4764. if(!rb.m_failed && !opt.success)
  4765. return;
  4766. DOCTEST_LOCK_MUTEX(mutex)
  4767. xml.startElement("Expression")
  4768. .writeAttribute("success", !rb.m_failed)
  4769. .writeAttribute("type", assertString(rb.m_at))
  4770. .writeAttribute("filename", skipPathFromFilename(rb.m_file))
  4771. .writeAttribute("line", line(rb.m_line));
  4772. xml.scopedElement("Original").writeText(rb.m_expr);
  4773. if(rb.m_threw)
  4774. xml.scopedElement("Exception").writeText(rb.m_exception.c_str());
  4775. if(rb.m_at & assertType::is_throws_as)
  4776. xml.scopedElement("ExpectedException").writeText(rb.m_exception_type);
  4777. if(rb.m_at & assertType::is_throws_with)
  4778. xml.scopedElement("ExpectedExceptionString").writeText(rb.m_exception_string.c_str());
  4779. if((rb.m_at & assertType::is_normal) && !rb.m_threw)
  4780. xml.scopedElement("Expanded").writeText(rb.m_decomp.c_str());
  4781. log_contexts();
  4782. xml.endElement();
  4783. }
  4784. void log_message(const MessageData& mb) override {
  4785. DOCTEST_LOCK_MUTEX(mutex)
  4786. xml.startElement("Message")
  4787. .writeAttribute("type", failureString(mb.m_severity))
  4788. .writeAttribute("filename", skipPathFromFilename(mb.m_file))
  4789. .writeAttribute("line", line(mb.m_line));
  4790. xml.scopedElement("Text").writeText(mb.m_string.c_str());
  4791. log_contexts();
  4792. xml.endElement();
  4793. }
  4794. void test_case_skipped(const TestCaseData& in) override {
  4795. if(opt.no_skipped_summary == false) {
  4796. test_case_start_impl(in);
  4797. xml.writeAttribute("skipped", "true");
  4798. xml.endElement();
  4799. }
  4800. }
  4801. };
  4802. DOCTEST_REGISTER_REPORTER("xml", 0, XmlReporter);
  4803. void fulltext_log_assert_to_stream(std::ostream& s, const AssertData& rb) {
  4804. if((rb.m_at & (assertType::is_throws_as | assertType::is_throws_with)) ==
  4805. 0) //!OCLINT bitwise operator in conditional
  4806. s << Color::Cyan << assertString(rb.m_at) << "( " << rb.m_expr << " ) "
  4807. << Color::None;
  4808. if(rb.m_at & assertType::is_throws) { //!OCLINT bitwise operator in conditional
  4809. s << (rb.m_threw ? "threw as expected!" : "did NOT throw at all!") << "\n";
  4810. } else if((rb.m_at & assertType::is_throws_as) &&
  4811. (rb.m_at & assertType::is_throws_with)) { //!OCLINT
  4812. s << Color::Cyan << assertString(rb.m_at) << "( " << rb.m_expr << ", \""
  4813. << rb.m_exception_string.c_str()
  4814. << "\", " << rb.m_exception_type << " ) " << Color::None;
  4815. if(rb.m_threw) {
  4816. if(!rb.m_failed) {
  4817. s << "threw as expected!\n";
  4818. } else {
  4819. s << "threw a DIFFERENT exception! (contents: " << rb.m_exception << ")\n";
  4820. }
  4821. } else {
  4822. s << "did NOT throw at all!\n";
  4823. }
  4824. } else if(rb.m_at &
  4825. assertType::is_throws_as) { //!OCLINT bitwise operator in conditional
  4826. s << Color::Cyan << assertString(rb.m_at) << "( " << rb.m_expr << ", "
  4827. << rb.m_exception_type << " ) " << Color::None
  4828. << (rb.m_threw ? (rb.m_threw_as ? "threw as expected!" :
  4829. "threw a DIFFERENT exception: ") :
  4830. "did NOT throw at all!")
  4831. << Color::Cyan << rb.m_exception << "\n";
  4832. } else if(rb.m_at &
  4833. assertType::is_throws_with) { //!OCLINT bitwise operator in conditional
  4834. s << Color::Cyan << assertString(rb.m_at) << "( " << rb.m_expr << ", \""
  4835. << rb.m_exception_string.c_str()
  4836. << "\" ) " << Color::None
  4837. << (rb.m_threw ? (!rb.m_failed ? "threw as expected!" :
  4838. "threw a DIFFERENT exception: ") :
  4839. "did NOT throw at all!")
  4840. << Color::Cyan << rb.m_exception << "\n";
  4841. } else if(rb.m_at & assertType::is_nothrow) { //!OCLINT bitwise operator in conditional
  4842. s << (rb.m_threw ? "THREW exception: " : "didn't throw!") << Color::Cyan
  4843. << rb.m_exception << "\n";
  4844. } else {
  4845. s << (rb.m_threw ? "THREW exception: " :
  4846. (!rb.m_failed ? "is correct!\n" : "is NOT correct!\n"));
  4847. if(rb.m_threw)
  4848. s << rb.m_exception << "\n";
  4849. else
  4850. s << " values: " << assertString(rb.m_at) << "( " << rb.m_decomp << " )\n";
  4851. }
  4852. }
  4853. // TODO:
  4854. // - log_message()
  4855. // - respond to queries
  4856. // - honor remaining options
  4857. // - more attributes in tags
  4858. struct JUnitReporter : public IReporter
  4859. {
  4860. XmlWriter xml;
  4861. DOCTEST_DECLARE_MUTEX(mutex)
  4862. Timer timer;
  4863. std::vector<String> deepestSubcaseStackNames;
  4864. struct JUnitTestCaseData
  4865. {
  4866. static std::string getCurrentTimestamp() {
  4867. // Beware, this is not reentrant because of backward compatibility issues
  4868. // Also, UTC only, again because of backward compatibility (%z is C++11)
  4869. time_t rawtime;
  4870. std::time(&rawtime);
  4871. auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
  4872. std::tm timeInfo;
  4873. #ifdef DOCTEST_PLATFORM_WINDOWS
  4874. gmtime_s(&timeInfo, &rawtime);
  4875. #else // DOCTEST_PLATFORM_WINDOWS
  4876. gmtime_r(&rawtime, &timeInfo);
  4877. #endif // DOCTEST_PLATFORM_WINDOWS
  4878. char timeStamp[timeStampSize];
  4879. const char* const fmt = "%Y-%m-%dT%H:%M:%SZ";
  4880. std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
  4881. return std::string(timeStamp);
  4882. }
  4883. struct JUnitTestMessage
  4884. {
  4885. JUnitTestMessage(const std::string& _message, const std::string& _type, const std::string& _details)
  4886. : message(_message), type(_type), details(_details) {}
  4887. JUnitTestMessage(const std::string& _message, const std::string& _details)
  4888. : message(_message), type(), details(_details) {}
  4889. std::string message, type, details;
  4890. };
  4891. struct JUnitTestCase
  4892. {
  4893. JUnitTestCase(const std::string& _classname, const std::string& _name)
  4894. : classname(_classname), name(_name), time(0), failures() {}
  4895. std::string classname, name;
  4896. double time;
  4897. std::vector<JUnitTestMessage> failures, errors;
  4898. };
  4899. void add(const std::string& classname, const std::string& name) {
  4900. testcases.emplace_back(classname, name);
  4901. }
  4902. void appendSubcaseNamesToLastTestcase(std::vector<String> nameStack) {
  4903. for(auto& curr: nameStack)
  4904. if(curr.size())
  4905. testcases.back().name += std::string("/") + curr.c_str();
  4906. }
  4907. void addTime(double time) {
  4908. if(time < 1e-4)
  4909. time = 0;
  4910. testcases.back().time = time;
  4911. totalSeconds += time;
  4912. }
  4913. void addFailure(const std::string& message, const std::string& type, const std::string& details) {
  4914. testcases.back().failures.emplace_back(message, type, details);
  4915. ++totalFailures;
  4916. }
  4917. void addError(const std::string& message, const std::string& details) {
  4918. testcases.back().errors.emplace_back(message, details);
  4919. ++totalErrors;
  4920. }
  4921. std::vector<JUnitTestCase> testcases;
  4922. double totalSeconds = 0;
  4923. int totalErrors = 0, totalFailures = 0;
  4924. };
  4925. JUnitTestCaseData testCaseData;
  4926. // caching pointers/references to objects of these types - safe to do
  4927. const ContextOptions& opt;
  4928. const TestCaseData* tc = nullptr;
  4929. JUnitReporter(const ContextOptions& co)
  4930. : xml(*co.cout)
  4931. , opt(co) {}
  4932. unsigned line(unsigned l) const { return opt.no_line_numbers ? 0 : l; }
  4933. // =========================================================================================
  4934. // WHAT FOLLOWS ARE OVERRIDES OF THE VIRTUAL METHODS OF THE REPORTER INTERFACE
  4935. // =========================================================================================
  4936. void report_query(const QueryData&) override {
  4937. xml.writeDeclaration();
  4938. }
  4939. void test_run_start() override {
  4940. xml.writeDeclaration();
  4941. }
  4942. void test_run_end(const TestRunStats& p) override {
  4943. // remove .exe extension - mainly to have the same output on UNIX and Windows
  4944. std::string binary_name = skipPathFromFilename(opt.binary_name.c_str());
  4945. #ifdef DOCTEST_PLATFORM_WINDOWS
  4946. if(binary_name.rfind(".exe") != std::string::npos)
  4947. binary_name = binary_name.substr(0, binary_name.length() - 4);
  4948. #endif // DOCTEST_PLATFORM_WINDOWS
  4949. xml.startElement("testsuites");
  4950. xml.startElement("testsuite").writeAttribute("name", binary_name)
  4951. .writeAttribute("errors", testCaseData.totalErrors)
  4952. .writeAttribute("failures", testCaseData.totalFailures)
  4953. .writeAttribute("tests", p.numAsserts);
  4954. if(opt.no_time_in_output == false) {
  4955. xml.writeAttribute("time", testCaseData.totalSeconds);
  4956. xml.writeAttribute("timestamp", JUnitTestCaseData::getCurrentTimestamp());
  4957. }
  4958. if(opt.no_version == false)
  4959. xml.writeAttribute("doctest_version", DOCTEST_VERSION_STR);
  4960. for(const auto& testCase : testCaseData.testcases) {
  4961. xml.startElement("testcase")
  4962. .writeAttribute("classname", testCase.classname)
  4963. .writeAttribute("name", testCase.name);
  4964. if(opt.no_time_in_output == false)
  4965. xml.writeAttribute("time", testCase.time);
  4966. // This is not ideal, but it should be enough to mimic gtest's junit output.
  4967. xml.writeAttribute("status", "run");
  4968. for(const auto& failure : testCase.failures) {
  4969. xml.scopedElement("failure")
  4970. .writeAttribute("message", failure.message)
  4971. .writeAttribute("type", failure.type)
  4972. .writeText(failure.details, false);
  4973. }
  4974. for(const auto& error : testCase.errors) {
  4975. xml.scopedElement("error")
  4976. .writeAttribute("message", error.message)
  4977. .writeText(error.details);
  4978. }
  4979. xml.endElement();
  4980. }
  4981. xml.endElement();
  4982. xml.endElement();
  4983. }
  4984. void test_case_start(const TestCaseData& in) override {
  4985. testCaseData.add(skipPathFromFilename(in.m_file.c_str()), in.m_name);
  4986. timer.start();
  4987. }
  4988. void test_case_reenter(const TestCaseData& in) override {
  4989. testCaseData.addTime(timer.getElapsedSeconds());
  4990. testCaseData.appendSubcaseNamesToLastTestcase(deepestSubcaseStackNames);
  4991. deepestSubcaseStackNames.clear();
  4992. timer.start();
  4993. testCaseData.add(skipPathFromFilename(in.m_file.c_str()), in.m_name);
  4994. }
  4995. void test_case_end(const CurrentTestCaseStats&) override {
  4996. testCaseData.addTime(timer.getElapsedSeconds());
  4997. testCaseData.appendSubcaseNamesToLastTestcase(deepestSubcaseStackNames);
  4998. deepestSubcaseStackNames.clear();
  4999. }
  5000. void test_case_exception(const TestCaseException& e) override {
  5001. DOCTEST_LOCK_MUTEX(mutex)
  5002. testCaseData.addError("exception", e.error_string.c_str());
  5003. }
  5004. void subcase_start(const SubcaseSignature& in) override {
  5005. deepestSubcaseStackNames.push_back(in.m_name);
  5006. }
  5007. void subcase_end() override {}
  5008. void log_assert(const AssertData& rb) override {
  5009. if(!rb.m_failed) // report only failures & ignore the `success` option
  5010. return;
  5011. DOCTEST_LOCK_MUTEX(mutex)
  5012. std::ostringstream os;
  5013. os << skipPathFromFilename(rb.m_file) << (opt.gnu_file_line ? ":" : "(")
  5014. << line(rb.m_line) << (opt.gnu_file_line ? ":" : "):") << std::endl;
  5015. fulltext_log_assert_to_stream(os, rb);
  5016. log_contexts(os);
  5017. testCaseData.addFailure(rb.m_decomp.c_str(), assertString(rb.m_at), os.str());
  5018. }
  5019. void log_message(const MessageData& mb) override {
  5020. if(mb.m_severity & assertType::is_warn) // report only failures
  5021. return;
  5022. DOCTEST_LOCK_MUTEX(mutex)
  5023. std::ostringstream os;
  5024. os << skipPathFromFilename(mb.m_file) << (opt.gnu_file_line ? ":" : "(")
  5025. << line(mb.m_line) << (opt.gnu_file_line ? ":" : "):") << std::endl;
  5026. os << mb.m_string.c_str() << "\n";
  5027. log_contexts(os);
  5028. testCaseData.addFailure(mb.m_string.c_str(),
  5029. mb.m_severity & assertType::is_check ? "FAIL_CHECK" : "FAIL", os.str());
  5030. }
  5031. void test_case_skipped(const TestCaseData&) override {}
  5032. void log_contexts(std::ostringstream& s) {
  5033. int num_contexts = get_num_active_contexts();
  5034. if(num_contexts) {
  5035. auto contexts = get_active_contexts();
  5036. s << " logged: ";
  5037. for(int i = 0; i < num_contexts; ++i) {
  5038. s << (i == 0 ? "" : " ");
  5039. contexts[i]->stringify(&s);
  5040. s << std::endl;
  5041. }
  5042. }
  5043. }
  5044. };
  5045. DOCTEST_REGISTER_REPORTER("junit", 0, JUnitReporter);
  5046. struct Whitespace
  5047. {
  5048. int nrSpaces;
  5049. explicit Whitespace(int nr)
  5050. : nrSpaces(nr) {}
  5051. };
  5052. std::ostream& operator<<(std::ostream& out, const Whitespace& ws) {
  5053. if(ws.nrSpaces != 0)
  5054. out << std::setw(ws.nrSpaces) << ' ';
  5055. return out;
  5056. }
  5057. struct ConsoleReporter : public IReporter
  5058. {
  5059. std::ostream& s;
  5060. bool hasLoggedCurrentTestStart;
  5061. std::vector<SubcaseSignature> subcasesStack;
  5062. size_t currentSubcaseLevel;
  5063. DOCTEST_DECLARE_MUTEX(mutex)
  5064. // caching pointers/references to objects of these types - safe to do
  5065. const ContextOptions& opt;
  5066. const TestCaseData* tc;
  5067. ConsoleReporter(const ContextOptions& co)
  5068. : s(*co.cout)
  5069. , opt(co) {}
  5070. ConsoleReporter(const ContextOptions& co, std::ostream& ostr)
  5071. : s(ostr)
  5072. , opt(co) {}
  5073. // =========================================================================================
  5074. // WHAT FOLLOWS ARE HELPERS USED BY THE OVERRIDES OF THE VIRTUAL METHODS OF THE INTERFACE
  5075. // =========================================================================================
  5076. void separator_to_stream() {
  5077. s << Color::Yellow
  5078. << "==============================================================================="
  5079. "\n";
  5080. }
  5081. const char* getSuccessOrFailString(bool success, assertType::Enum at,
  5082. const char* success_str) {
  5083. if(success)
  5084. return success_str;
  5085. return failureString(at);
  5086. }
  5087. Color::Enum getSuccessOrFailColor(bool success, assertType::Enum at) {
  5088. return success ? Color::BrightGreen :
  5089. (at & assertType::is_warn) ? Color::Yellow : Color::Red;
  5090. }
  5091. void successOrFailColoredStringToStream(bool success, assertType::Enum at,
  5092. const char* success_str = "SUCCESS") {
  5093. s << getSuccessOrFailColor(success, at)
  5094. << getSuccessOrFailString(success, at, success_str) << ": ";
  5095. }
  5096. void log_contexts() {
  5097. int num_contexts = get_num_active_contexts();
  5098. if(num_contexts) {
  5099. auto contexts = get_active_contexts();
  5100. s << Color::None << " logged: ";
  5101. for(int i = 0; i < num_contexts; ++i) {
  5102. s << (i == 0 ? "" : " ");
  5103. contexts[i]->stringify(&s);
  5104. s << "\n";
  5105. }
  5106. }
  5107. s << "\n";
  5108. }
  5109. // this was requested to be made virtual so users could override it
  5110. virtual void file_line_to_stream(const char* file, int line,
  5111. const char* tail = "") {
  5112. s << Color::LightGrey << skipPathFromFilename(file) << (opt.gnu_file_line ? ":" : "(")
  5113. << (opt.no_line_numbers ? 0 : line) // 0 or the real num depending on the option
  5114. << (opt.gnu_file_line ? ":" : "):") << tail;
  5115. }
  5116. void logTestStart() {
  5117. if(hasLoggedCurrentTestStart)
  5118. return;
  5119. separator_to_stream();
  5120. file_line_to_stream(tc->m_file.c_str(), tc->m_line, "\n");
  5121. if(tc->m_description)
  5122. s << Color::Yellow << "DESCRIPTION: " << Color::None << tc->m_description << "\n";
  5123. if(tc->m_test_suite && tc->m_test_suite[0] != '\0')
  5124. s << Color::Yellow << "TEST SUITE: " << Color::None << tc->m_test_suite << "\n";
  5125. if(strncmp(tc->m_name, " Scenario:", 11) != 0)
  5126. s << Color::Yellow << "TEST CASE: ";
  5127. s << Color::None << tc->m_name << "\n";
  5128. for(size_t i = 0; i < currentSubcaseLevel; ++i) {
  5129. if(subcasesStack[i].m_name[0] != '\0')
  5130. s << " " << subcasesStack[i].m_name << "\n";
  5131. }
  5132. if(currentSubcaseLevel != subcasesStack.size()) {
  5133. s << Color::Yellow << "\nDEEPEST SUBCASE STACK REACHED (DIFFERENT FROM THE CURRENT ONE):\n" << Color::None;
  5134. for(size_t i = 0; i < subcasesStack.size(); ++i) {
  5135. if(subcasesStack[i].m_name[0] != '\0')
  5136. s << " " << subcasesStack[i].m_name << "\n";
  5137. }
  5138. }
  5139. s << "\n";
  5140. hasLoggedCurrentTestStart = true;
  5141. }
  5142. void printVersion() {
  5143. if(opt.no_version == false)
  5144. s << Color::Cyan << "[doctest] " << Color::None << "doctest version is \""
  5145. << DOCTEST_VERSION_STR << "\"\n";
  5146. }
  5147. void printIntro() {
  5148. if(opt.no_intro == false) {
  5149. printVersion();
  5150. s << Color::Cyan << "[doctest] " << Color::None
  5151. << "run with \"--" DOCTEST_OPTIONS_PREFIX_DISPLAY "help\" for options\n";
  5152. }
  5153. }
  5154. void printHelp() {
  5155. int sizePrefixDisplay = static_cast<int>(strlen(DOCTEST_OPTIONS_PREFIX_DISPLAY));
  5156. printVersion();
  5157. // clang-format off
  5158. s << Color::Cyan << "[doctest]\n" << Color::None;
  5159. s << Color::Cyan << "[doctest] " << Color::None;
  5160. s << "boolean values: \"1/on/yes/true\" or \"0/off/no/false\"\n";
  5161. s << Color::Cyan << "[doctest] " << Color::None;
  5162. s << "filter values: \"str1,str2,str3\" (comma separated strings)\n";
  5163. s << Color::Cyan << "[doctest]\n" << Color::None;
  5164. s << Color::Cyan << "[doctest] " << Color::None;
  5165. s << "filters use wildcards for matching strings\n";
  5166. s << Color::Cyan << "[doctest] " << Color::None;
  5167. s << "something passes a filter if any of the strings in a filter matches\n";
  5168. #ifndef DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS
  5169. s << Color::Cyan << "[doctest]\n" << Color::None;
  5170. s << Color::Cyan << "[doctest] " << Color::None;
  5171. s << "ALL FLAGS, OPTIONS AND FILTERS ALSO AVAILABLE WITH A \"" DOCTEST_CONFIG_OPTIONS_PREFIX "\" PREFIX!!!\n";
  5172. #endif
  5173. s << Color::Cyan << "[doctest]\n" << Color::None;
  5174. s << Color::Cyan << "[doctest] " << Color::None;
  5175. s << "Query flags - the program quits after them. Available:\n\n";
  5176. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "?, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "help, -" DOCTEST_OPTIONS_PREFIX_DISPLAY "h "
  5177. << Whitespace(sizePrefixDisplay*0) << "prints this message\n";
  5178. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "v, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "version "
  5179. << Whitespace(sizePrefixDisplay*1) << "prints the version\n";
  5180. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "c, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "count "
  5181. << Whitespace(sizePrefixDisplay*1) << "prints the number of matching tests\n";
  5182. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "ltc, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "list-test-cases "
  5183. << Whitespace(sizePrefixDisplay*1) << "lists all matching tests by name\n";
  5184. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "lts, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "list-test-suites "
  5185. << Whitespace(sizePrefixDisplay*1) << "lists all matching test suites\n";
  5186. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "lr, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "list-reporters "
  5187. << Whitespace(sizePrefixDisplay*1) << "lists all registered reporters\n\n";
  5188. // ================================================================================== << 79
  5189. s << Color::Cyan << "[doctest] " << Color::None;
  5190. s << "The available <int>/<string> options/filters are:\n\n";
  5191. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "tc, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "test-case=<filters> "
  5192. << Whitespace(sizePrefixDisplay*1) << "filters tests by their name\n";
  5193. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "tce, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "test-case-exclude=<filters> "
  5194. << Whitespace(sizePrefixDisplay*1) << "filters OUT tests by their name\n";
  5195. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "sf, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "source-file=<filters> "
  5196. << Whitespace(sizePrefixDisplay*1) << "filters tests by their file\n";
  5197. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "sfe, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "source-file-exclude=<filters> "
  5198. << Whitespace(sizePrefixDisplay*1) << "filters OUT tests by their file\n";
  5199. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "ts, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "test-suite=<filters> "
  5200. << Whitespace(sizePrefixDisplay*1) << "filters tests by their test suite\n";
  5201. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "tse, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "test-suite-exclude=<filters> "
  5202. << Whitespace(sizePrefixDisplay*1) << "filters OUT tests by their test suite\n";
  5203. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "sc, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "subcase=<filters> "
  5204. << Whitespace(sizePrefixDisplay*1) << "filters subcases by their name\n";
  5205. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "sce, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "subcase-exclude=<filters> "
  5206. << Whitespace(sizePrefixDisplay*1) << "filters OUT subcases by their name\n";
  5207. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "r, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "reporters=<filters> "
  5208. << Whitespace(sizePrefixDisplay*1) << "reporters to use (console is default)\n";
  5209. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "o, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "out=<string> "
  5210. << Whitespace(sizePrefixDisplay*1) << "output filename\n";
  5211. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "ob, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "order-by=<string> "
  5212. << Whitespace(sizePrefixDisplay*1) << "how the tests should be ordered\n";
  5213. s << Whitespace(sizePrefixDisplay*3) << " <string> - [file/suite/name/rand/none]\n";
  5214. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "rs, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "rand-seed=<int> "
  5215. << Whitespace(sizePrefixDisplay*1) << "seed for random ordering\n";
  5216. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "f, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "first=<int> "
  5217. << Whitespace(sizePrefixDisplay*1) << "the first test passing the filters to\n";
  5218. s << Whitespace(sizePrefixDisplay*3) << " execute - for range-based execution\n";
  5219. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "l, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "last=<int> "
  5220. << Whitespace(sizePrefixDisplay*1) << "the last test passing the filters to\n";
  5221. s << Whitespace(sizePrefixDisplay*3) << " execute - for range-based execution\n";
  5222. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "aa, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "abort-after=<int> "
  5223. << Whitespace(sizePrefixDisplay*1) << "stop after <int> failed assertions\n";
  5224. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "scfl,--" DOCTEST_OPTIONS_PREFIX_DISPLAY "subcase-filter-levels=<int> "
  5225. << Whitespace(sizePrefixDisplay*1) << "apply filters for the first <int> levels\n";
  5226. s << Color::Cyan << "\n[doctest] " << Color::None;
  5227. s << "Bool options - can be used like flags and true is assumed. Available:\n\n";
  5228. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "s, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "success=<bool> "
  5229. << Whitespace(sizePrefixDisplay*1) << "include successful assertions in output\n";
  5230. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "cs, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "case-sensitive=<bool> "
  5231. << Whitespace(sizePrefixDisplay*1) << "filters being treated as case sensitive\n";
  5232. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "e, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "exit=<bool> "
  5233. << Whitespace(sizePrefixDisplay*1) << "exits after the tests finish\n";
  5234. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "d, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "duration=<bool> "
  5235. << Whitespace(sizePrefixDisplay*1) << "prints the time duration of each test\n";
  5236. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "m, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "minimal=<bool> "
  5237. << Whitespace(sizePrefixDisplay*1) << "minimal console output (only failures)\n";
  5238. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "q, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "quiet=<bool> "
  5239. << Whitespace(sizePrefixDisplay*1) << "no console output\n";
  5240. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "nt, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-throw=<bool> "
  5241. << Whitespace(sizePrefixDisplay*1) << "skips exceptions-related assert checks\n";
  5242. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "ne, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-exitcode=<bool> "
  5243. << Whitespace(sizePrefixDisplay*1) << "returns (or exits) always with success\n";
  5244. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "nr, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-run=<bool> "
  5245. << Whitespace(sizePrefixDisplay*1) << "skips all runtime doctest operations\n";
  5246. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "ni, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-intro=<bool> "
  5247. << Whitespace(sizePrefixDisplay*1) << "omit the framework intro in the output\n";
  5248. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "nv, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-version=<bool> "
  5249. << Whitespace(sizePrefixDisplay*1) << "omit the framework version in the output\n";
  5250. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "nc, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-colors=<bool> "
  5251. << Whitespace(sizePrefixDisplay*1) << "disables colors in output\n";
  5252. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "fc, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "force-colors=<bool> "
  5253. << Whitespace(sizePrefixDisplay*1) << "use colors even when not in a tty\n";
  5254. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "nb, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-breaks=<bool> "
  5255. << Whitespace(sizePrefixDisplay*1) << "disables breakpoints in debuggers\n";
  5256. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "ns, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-skip=<bool> "
  5257. << Whitespace(sizePrefixDisplay*1) << "don't skip test cases marked as skip\n";
  5258. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "gfl, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "gnu-file-line=<bool> "
  5259. << Whitespace(sizePrefixDisplay*1) << ":n: vs (n): for line numbers in output\n";
  5260. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "npf, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-path-filenames=<bool> "
  5261. << Whitespace(sizePrefixDisplay*1) << "only filenames and no paths in output\n";
  5262. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "spp, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "skip-path-prefixes=<p1:p2> "
  5263. << Whitespace(sizePrefixDisplay*1) << "whenever file paths start with this prefix, remove it from the output\n";
  5264. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "nln, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-line-numbers=<bool> "
  5265. << Whitespace(sizePrefixDisplay*1) << "0 instead of real line numbers in output\n";
  5266. // ================================================================================== << 79
  5267. // clang-format on
  5268. s << Color::Cyan << "\n[doctest] " << Color::None;
  5269. s << "for more information visit the project documentation\n\n";
  5270. }
  5271. void printRegisteredReporters() {
  5272. printVersion();
  5273. auto printReporters = [this] (const reporterMap& reporters, const char* type) {
  5274. if(reporters.size()) {
  5275. s << Color::Cyan << "[doctest] " << Color::None << "listing all registered " << type << "\n";
  5276. for(auto& curr : reporters)
  5277. s << "priority: " << std::setw(5) << curr.first.first
  5278. << " name: " << curr.first.second << "\n";
  5279. }
  5280. };
  5281. printReporters(getListeners(), "listeners");
  5282. printReporters(getReporters(), "reporters");
  5283. }
  5284. // =========================================================================================
  5285. // WHAT FOLLOWS ARE OVERRIDES OF THE VIRTUAL METHODS OF THE REPORTER INTERFACE
  5286. // =========================================================================================
  5287. void report_query(const QueryData& in) override {
  5288. if(opt.version) {
  5289. printVersion();
  5290. } else if(opt.help) {
  5291. printHelp();
  5292. } else if(opt.list_reporters) {
  5293. printRegisteredReporters();
  5294. } else if(opt.count || opt.list_test_cases) {
  5295. if(opt.list_test_cases) {
  5296. s << Color::Cyan << "[doctest] " << Color::None
  5297. << "listing all test case names\n";
  5298. separator_to_stream();
  5299. }
  5300. for(unsigned i = 0; i < in.num_data; ++i)
  5301. s << Color::None << in.data[i]->m_name << "\n";
  5302. separator_to_stream();
  5303. s << Color::Cyan << "[doctest] " << Color::None
  5304. << "unskipped test cases passing the current filters: "
  5305. << g_cs->numTestCasesPassingFilters << "\n";
  5306. } else if(opt.list_test_suites) {
  5307. s << Color::Cyan << "[doctest] " << Color::None << "listing all test suites\n";
  5308. separator_to_stream();
  5309. for(unsigned i = 0; i < in.num_data; ++i)
  5310. s << Color::None << in.data[i]->m_test_suite << "\n";
  5311. separator_to_stream();
  5312. s << Color::Cyan << "[doctest] " << Color::None
  5313. << "unskipped test cases passing the current filters: "
  5314. << g_cs->numTestCasesPassingFilters << "\n";
  5315. s << Color::Cyan << "[doctest] " << Color::None
  5316. << "test suites with unskipped test cases passing the current filters: "
  5317. << g_cs->numTestSuitesPassingFilters << "\n";
  5318. }
  5319. }
  5320. void test_run_start() override {
  5321. if(!opt.minimal)
  5322. printIntro();
  5323. }
  5324. void test_run_end(const TestRunStats& p) override {
  5325. if(opt.minimal && p.numTestCasesFailed == 0)
  5326. return;
  5327. separator_to_stream();
  5328. s << std::dec;
  5329. auto totwidth = int(std::ceil(log10(static_cast<double>(std::max(p.numTestCasesPassingFilters, static_cast<unsigned>(p.numAsserts))) + 1)));
  5330. auto passwidth = int(std::ceil(log10(static_cast<double>(std::max(p.numTestCasesPassingFilters - p.numTestCasesFailed, static_cast<unsigned>(p.numAsserts - p.numAssertsFailed))) + 1)));
  5331. auto failwidth = int(std::ceil(log10(static_cast<double>(std::max(p.numTestCasesFailed, static_cast<unsigned>(p.numAssertsFailed))) + 1)));
  5332. const bool anythingFailed = p.numTestCasesFailed > 0 || p.numAssertsFailed > 0;
  5333. s << Color::Cyan << "[doctest] " << Color::None << "test cases: " << std::setw(totwidth)
  5334. << p.numTestCasesPassingFilters << " | "
  5335. << ((p.numTestCasesPassingFilters == 0 || anythingFailed) ? Color::None :
  5336. Color::Green)
  5337. << std::setw(passwidth) << p.numTestCasesPassingFilters - p.numTestCasesFailed << " passed"
  5338. << Color::None << " | " << (p.numTestCasesFailed > 0 ? Color::Red : Color::None)
  5339. << std::setw(failwidth) << p.numTestCasesFailed << " failed" << Color::None << " |";
  5340. if(opt.no_skipped_summary == false) {
  5341. const int numSkipped = p.numTestCases - p.numTestCasesPassingFilters;
  5342. s << " " << (numSkipped == 0 ? Color::None : Color::Yellow) << numSkipped
  5343. << " skipped" << Color::None;
  5344. }
  5345. s << "\n";
  5346. s << Color::Cyan << "[doctest] " << Color::None << "assertions: " << std::setw(totwidth)
  5347. << p.numAsserts << " | "
  5348. << ((p.numAsserts == 0 || anythingFailed) ? Color::None : Color::Green)
  5349. << std::setw(passwidth) << (p.numAsserts - p.numAssertsFailed) << " passed" << Color::None
  5350. << " | " << (p.numAssertsFailed > 0 ? Color::Red : Color::None) << std::setw(failwidth)
  5351. << p.numAssertsFailed << " failed" << Color::None << " |\n";
  5352. s << Color::Cyan << "[doctest] " << Color::None
  5353. << "Status: " << (p.numTestCasesFailed > 0 ? Color::Red : Color::Green)
  5354. << ((p.numTestCasesFailed > 0) ? "FAILURE!" : "SUCCESS!") << Color::None << std::endl;
  5355. }
  5356. void test_case_start(const TestCaseData& in) override {
  5357. hasLoggedCurrentTestStart = false;
  5358. tc = &in;
  5359. subcasesStack.clear();
  5360. currentSubcaseLevel = 0;
  5361. }
  5362. void test_case_reenter(const TestCaseData&) override {
  5363. subcasesStack.clear();
  5364. }
  5365. void test_case_end(const CurrentTestCaseStats& st) override {
  5366. if(tc->m_no_output)
  5367. return;
  5368. // log the preamble of the test case only if there is something
  5369. // else to print - something other than that an assert has failed
  5370. if(opt.duration ||
  5371. (st.failure_flags && st.failure_flags != static_cast<int>(TestCaseFailureReason::AssertFailure)))
  5372. logTestStart();
  5373. if(opt.duration)
  5374. s << Color::None << std::setprecision(6) << std::fixed << st.seconds
  5375. << " s: " << tc->m_name << "\n";
  5376. if(st.failure_flags & TestCaseFailureReason::Timeout)
  5377. s << Color::Red << "Test case exceeded time limit of " << std::setprecision(6)
  5378. << std::fixed << tc->m_timeout << "!\n";
  5379. if(st.failure_flags & TestCaseFailureReason::ShouldHaveFailedButDidnt) {
  5380. s << Color::Red << "Should have failed but didn't! Marking it as failed!\n";
  5381. } else if(st.failure_flags & TestCaseFailureReason::ShouldHaveFailedAndDid) {
  5382. s << Color::Yellow << "Failed as expected so marking it as not failed\n";
  5383. } else if(st.failure_flags & TestCaseFailureReason::CouldHaveFailedAndDid) {
  5384. s << Color::Yellow << "Allowed to fail so marking it as not failed\n";
  5385. } else if(st.failure_flags & TestCaseFailureReason::DidntFailExactlyNumTimes) {
  5386. s << Color::Red << "Didn't fail exactly " << tc->m_expected_failures
  5387. << " times so marking it as failed!\n";
  5388. } else if(st.failure_flags & TestCaseFailureReason::FailedExactlyNumTimes) {
  5389. s << Color::Yellow << "Failed exactly " << tc->m_expected_failures
  5390. << " times as expected so marking it as not failed!\n";
  5391. }
  5392. if(st.failure_flags & TestCaseFailureReason::TooManyFailedAsserts) {
  5393. s << Color::Red << "Aborting - too many failed asserts!\n";
  5394. }
  5395. s << Color::None; // lgtm [cpp/useless-expression]
  5396. }
  5397. void test_case_exception(const TestCaseException& e) override {
  5398. DOCTEST_LOCK_MUTEX(mutex)
  5399. if(tc->m_no_output)
  5400. return;
  5401. logTestStart();
  5402. file_line_to_stream(tc->m_file.c_str(), tc->m_line, " ");
  5403. successOrFailColoredStringToStream(false, e.is_crash ? assertType::is_require :
  5404. assertType::is_check);
  5405. s << Color::Red << (e.is_crash ? "test case CRASHED: " : "test case THREW exception: ")
  5406. << Color::Cyan << e.error_string << "\n";
  5407. int num_stringified_contexts = get_num_stringified_contexts();
  5408. if(num_stringified_contexts) {
  5409. auto stringified_contexts = get_stringified_contexts();
  5410. s << Color::None << " logged: ";
  5411. for(int i = num_stringified_contexts; i > 0; --i) {
  5412. s << (i == num_stringified_contexts ? "" : " ")
  5413. << stringified_contexts[i - 1] << "\n";
  5414. }
  5415. }
  5416. s << "\n" << Color::None;
  5417. }
  5418. void subcase_start(const SubcaseSignature& subc) override {
  5419. subcasesStack.push_back(subc);
  5420. ++currentSubcaseLevel;
  5421. hasLoggedCurrentTestStart = false;
  5422. }
  5423. void subcase_end() override {
  5424. --currentSubcaseLevel;
  5425. hasLoggedCurrentTestStart = false;
  5426. }
  5427. void log_assert(const AssertData& rb) override {
  5428. if((!rb.m_failed && !opt.success) || tc->m_no_output)
  5429. return;
  5430. DOCTEST_LOCK_MUTEX(mutex)
  5431. logTestStart();
  5432. file_line_to_stream(rb.m_file, rb.m_line, " ");
  5433. successOrFailColoredStringToStream(!rb.m_failed, rb.m_at);
  5434. fulltext_log_assert_to_stream(s, rb);
  5435. log_contexts();
  5436. }
  5437. void log_message(const MessageData& mb) override {
  5438. if(tc->m_no_output)
  5439. return;
  5440. DOCTEST_LOCK_MUTEX(mutex)
  5441. logTestStart();
  5442. file_line_to_stream(mb.m_file, mb.m_line, " ");
  5443. s << getSuccessOrFailColor(false, mb.m_severity)
  5444. << getSuccessOrFailString(mb.m_severity & assertType::is_warn, mb.m_severity,
  5445. "MESSAGE") << ": ";
  5446. s << Color::None << mb.m_string << "\n";
  5447. log_contexts();
  5448. }
  5449. void test_case_skipped(const TestCaseData&) override {}
  5450. };
  5451. DOCTEST_REGISTER_REPORTER("console", 0, ConsoleReporter);
  5452. #ifdef DOCTEST_PLATFORM_WINDOWS
  5453. struct DebugOutputWindowReporter : public ConsoleReporter
  5454. {
  5455. DOCTEST_THREAD_LOCAL static std::ostringstream oss;
  5456. DebugOutputWindowReporter(const ContextOptions& co)
  5457. : ConsoleReporter(co, oss) {}
  5458. #define DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(func, type, arg) \
  5459. void func(type arg) override { \
  5460. bool with_col = g_no_colors; \
  5461. g_no_colors = false; \
  5462. ConsoleReporter::func(arg); \
  5463. if(oss.tellp() != std::streampos{}) { \
  5464. DOCTEST_OUTPUT_DEBUG_STRING(oss.str().c_str()); \
  5465. oss.str(""); \
  5466. } \
  5467. g_no_colors = with_col; \
  5468. }
  5469. DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_run_start, DOCTEST_EMPTY, DOCTEST_EMPTY)
  5470. DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_run_end, const TestRunStats&, in)
  5471. DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_case_start, const TestCaseData&, in)
  5472. DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_case_reenter, const TestCaseData&, in)
  5473. DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_case_end, const CurrentTestCaseStats&, in)
  5474. DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_case_exception, const TestCaseException&, in)
  5475. DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(subcase_start, const SubcaseSignature&, in)
  5476. DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(subcase_end, DOCTEST_EMPTY, DOCTEST_EMPTY)
  5477. DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(log_assert, const AssertData&, in)
  5478. DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(log_message, const MessageData&, in)
  5479. DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_case_skipped, const TestCaseData&, in)
  5480. };
  5481. DOCTEST_THREAD_LOCAL std::ostringstream DebugOutputWindowReporter::oss;
  5482. #endif // DOCTEST_PLATFORM_WINDOWS
  5483. // the implementation of parseOption()
  5484. bool parseOptionImpl(int argc, const char* const* argv, const char* pattern, String* value) {
  5485. // going from the end to the beginning and stopping on the first occurrence from the end
  5486. for(int i = argc; i > 0; --i) {
  5487. auto index = i - 1;
  5488. auto temp = std::strstr(argv[index], pattern);
  5489. if(temp && (value || strlen(temp) == strlen(pattern))) { //!OCLINT prefer early exits and continue
  5490. // eliminate matches in which the chars before the option are not '-'
  5491. bool noBadCharsFound = true;
  5492. auto curr = argv[index];
  5493. while(curr != temp) {
  5494. if(*curr++ != '-') {
  5495. noBadCharsFound = false;
  5496. break;
  5497. }
  5498. }
  5499. if(noBadCharsFound && argv[index][0] == '-') {
  5500. if(value) {
  5501. // parsing the value of an option
  5502. temp += strlen(pattern);
  5503. const unsigned len = strlen(temp);
  5504. if(len) {
  5505. *value = temp;
  5506. return true;
  5507. }
  5508. } else {
  5509. // just a flag - no value
  5510. return true;
  5511. }
  5512. }
  5513. }
  5514. }
  5515. return false;
  5516. }
  5517. // parses an option and returns the string after the '=' character
  5518. bool parseOption(int argc, const char* const* argv, const char* pattern, String* value = nullptr,
  5519. const String& defaultVal = String()) {
  5520. if(value)
  5521. *value = defaultVal;
  5522. #ifndef DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS
  5523. // offset (normally 3 for "dt-") to skip prefix
  5524. if(parseOptionImpl(argc, argv, pattern + strlen(DOCTEST_CONFIG_OPTIONS_PREFIX), value))
  5525. return true;
  5526. #endif // DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS
  5527. return parseOptionImpl(argc, argv, pattern, value);
  5528. }
  5529. // locates a flag on the command line
  5530. bool parseFlag(int argc, const char* const* argv, const char* pattern) {
  5531. return parseOption(argc, argv, pattern);
  5532. }
  5533. // parses a comma separated list of words after a pattern in one of the arguments in argv
  5534. bool parseCommaSepArgs(int argc, const char* const* argv, const char* pattern,
  5535. std::vector<String>& res) {
  5536. String filtersString;
  5537. if(parseOption(argc, argv, pattern, &filtersString)) {
  5538. // tokenize with "," as a separator, unless escaped with backslash
  5539. std::ostringstream s;
  5540. auto flush = [&s, &res]() {
  5541. auto string = s.str();
  5542. if(string.size() > 0) {
  5543. res.push_back(string.c_str());
  5544. }
  5545. s.str("");
  5546. };
  5547. bool seenBackslash = false;
  5548. const char* current = filtersString.c_str();
  5549. const char* end = current + strlen(current);
  5550. while(current != end) {
  5551. char character = *current++;
  5552. if(seenBackslash) {
  5553. seenBackslash = false;
  5554. if(character == ',' || character == '\\') {
  5555. s.put(character);
  5556. continue;
  5557. }
  5558. s.put('\\');
  5559. }
  5560. if(character == '\\') {
  5561. seenBackslash = true;
  5562. } else if(character == ',') {
  5563. flush();
  5564. } else {
  5565. s.put(character);
  5566. }
  5567. }
  5568. if(seenBackslash) {
  5569. s.put('\\');
  5570. }
  5571. flush();
  5572. return true;
  5573. }
  5574. return false;
  5575. }
  5576. enum optionType
  5577. {
  5578. option_bool,
  5579. option_int
  5580. };
  5581. // parses an int/bool option from the command line
  5582. bool parseIntOption(int argc, const char* const* argv, const char* pattern, optionType type,
  5583. int& res) {
  5584. String parsedValue;
  5585. if(!parseOption(argc, argv, pattern, &parsedValue))
  5586. return false;
  5587. if(type) {
  5588. // integer
  5589. // TODO: change this to use std::stoi or something else! currently it uses undefined behavior - assumes '0' on failed parse...
  5590. int theInt = std::atoi(parsedValue.c_str());
  5591. if (theInt != 0) {
  5592. res = theInt; //!OCLINT parameter reassignment
  5593. return true;
  5594. }
  5595. } else {
  5596. // boolean
  5597. const char positive[][5] = { "1", "true", "on", "yes" }; // 5 - strlen("true") + 1
  5598. const char negative[][6] = { "0", "false", "off", "no" }; // 6 - strlen("false") + 1
  5599. // if the value matches any of the positive/negative possibilities
  5600. for (unsigned i = 0; i < 4; i++) {
  5601. if (parsedValue.compare(positive[i], true) == 0) {
  5602. res = 1; //!OCLINT parameter reassignment
  5603. return true;
  5604. }
  5605. if (parsedValue.compare(negative[i], true) == 0) {
  5606. res = 0; //!OCLINT parameter reassignment
  5607. return true;
  5608. }
  5609. }
  5610. }
  5611. return false;
  5612. }
  5613. } // namespace
  5614. Context::Context(int argc, const char* const* argv)
  5615. : p(new detail::ContextState) {
  5616. parseArgs(argc, argv, true);
  5617. if(argc)
  5618. p->binary_name = argv[0];
  5619. }
  5620. Context::~Context() {
  5621. if(g_cs == p)
  5622. g_cs = nullptr;
  5623. delete p;
  5624. }
  5625. void Context::applyCommandLine(int argc, const char* const* argv) {
  5626. parseArgs(argc, argv);
  5627. if(argc)
  5628. p->binary_name = argv[0];
  5629. }
  5630. // parses args
  5631. void Context::parseArgs(int argc, const char* const* argv, bool withDefaults) {
  5632. using namespace detail;
  5633. // clang-format off
  5634. parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "source-file=", p->filters[0]);
  5635. parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "sf=", p->filters[0]);
  5636. parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "source-file-exclude=",p->filters[1]);
  5637. parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "sfe=", p->filters[1]);
  5638. parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "test-suite=", p->filters[2]);
  5639. parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "ts=", p->filters[2]);
  5640. parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "test-suite-exclude=", p->filters[3]);
  5641. parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "tse=", p->filters[3]);
  5642. parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "test-case=", p->filters[4]);
  5643. parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "tc=", p->filters[4]);
  5644. parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "test-case-exclude=", p->filters[5]);
  5645. parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "tce=", p->filters[5]);
  5646. parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "subcase=", p->filters[6]);
  5647. parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "sc=", p->filters[6]);
  5648. parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "subcase-exclude=", p->filters[7]);
  5649. parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "sce=", p->filters[7]);
  5650. parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "reporters=", p->filters[8]);
  5651. parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "r=", p->filters[8]);
  5652. // clang-format on
  5653. int intRes = 0;
  5654. String strRes;
  5655. #define DOCTEST_PARSE_AS_BOOL_OR_FLAG(name, sname, var, default) \
  5656. if(parseIntOption(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX name "=", option_bool, intRes) || \
  5657. parseIntOption(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX sname "=", option_bool, intRes)) \
  5658. p->var = static_cast<bool>(intRes); \
  5659. else if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX name) || \
  5660. parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX sname)) \
  5661. p->var = true; \
  5662. else if(withDefaults) \
  5663. p->var = default
  5664. #define DOCTEST_PARSE_INT_OPTION(name, sname, var, default) \
  5665. if(parseIntOption(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX name "=", option_int, intRes) || \
  5666. parseIntOption(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX sname "=", option_int, intRes)) \
  5667. p->var = intRes; \
  5668. else if(withDefaults) \
  5669. p->var = default
  5670. #define DOCTEST_PARSE_STR_OPTION(name, sname, var, default) \
  5671. if(parseOption(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX name "=", &strRes, default) || \
  5672. parseOption(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX sname "=", &strRes, default) || \
  5673. withDefaults) \
  5674. p->var = strRes
  5675. // clang-format off
  5676. DOCTEST_PARSE_STR_OPTION("out", "o", out, "");
  5677. DOCTEST_PARSE_STR_OPTION("order-by", "ob", order_by, "file");
  5678. DOCTEST_PARSE_INT_OPTION("rand-seed", "rs", rand_seed, 0);
  5679. DOCTEST_PARSE_INT_OPTION("first", "f", first, 0);
  5680. DOCTEST_PARSE_INT_OPTION("last", "l", last, UINT_MAX);
  5681. DOCTEST_PARSE_INT_OPTION("abort-after", "aa", abort_after, 0);
  5682. DOCTEST_PARSE_INT_OPTION("subcase-filter-levels", "scfl", subcase_filter_levels, INT_MAX);
  5683. DOCTEST_PARSE_AS_BOOL_OR_FLAG("success", "s", success, false);
  5684. DOCTEST_PARSE_AS_BOOL_OR_FLAG("case-sensitive", "cs", case_sensitive, false);
  5685. DOCTEST_PARSE_AS_BOOL_OR_FLAG("exit", "e", exit, false);
  5686. DOCTEST_PARSE_AS_BOOL_OR_FLAG("duration", "d", duration, false);
  5687. DOCTEST_PARSE_AS_BOOL_OR_FLAG("minimal", "m", minimal, false);
  5688. DOCTEST_PARSE_AS_BOOL_OR_FLAG("quiet", "q", quiet, false);
  5689. DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-throw", "nt", no_throw, false);
  5690. DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-exitcode", "ne", no_exitcode, false);
  5691. DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-run", "nr", no_run, false);
  5692. DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-intro", "ni", no_intro, false);
  5693. DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-version", "nv", no_version, false);
  5694. DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-colors", "nc", no_colors, false);
  5695. DOCTEST_PARSE_AS_BOOL_OR_FLAG("force-colors", "fc", force_colors, false);
  5696. DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-breaks", "nb", no_breaks, false);
  5697. DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-skip", "ns", no_skip, false);
  5698. DOCTEST_PARSE_AS_BOOL_OR_FLAG("gnu-file-line", "gfl", gnu_file_line, !bool(DOCTEST_MSVC));
  5699. DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-path-filenames", "npf", no_path_in_filenames, false);
  5700. DOCTEST_PARSE_STR_OPTION("strip-file-prefixes", "sfp", strip_file_prefixes, "");
  5701. DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-line-numbers", "nln", no_line_numbers, false);
  5702. DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-debug-output", "ndo", no_debug_output, false);
  5703. DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-skipped-summary", "nss", no_skipped_summary, false);
  5704. DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-time-in-output", "ntio", no_time_in_output, false);
  5705. // clang-format on
  5706. if(withDefaults) {
  5707. p->help = false;
  5708. p->version = false;
  5709. p->count = false;
  5710. p->list_test_cases = false;
  5711. p->list_test_suites = false;
  5712. p->list_reporters = false;
  5713. }
  5714. if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "help") ||
  5715. parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "h") ||
  5716. parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "?")) {
  5717. p->help = true;
  5718. p->exit = true;
  5719. }
  5720. if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "version") ||
  5721. parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "v")) {
  5722. p->version = true;
  5723. p->exit = true;
  5724. }
  5725. if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "count") ||
  5726. parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "c")) {
  5727. p->count = true;
  5728. p->exit = true;
  5729. }
  5730. if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "list-test-cases") ||
  5731. parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "ltc")) {
  5732. p->list_test_cases = true;
  5733. p->exit = true;
  5734. }
  5735. if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "list-test-suites") ||
  5736. parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "lts")) {
  5737. p->list_test_suites = true;
  5738. p->exit = true;
  5739. }
  5740. if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "list-reporters") ||
  5741. parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "lr")) {
  5742. p->list_reporters = true;
  5743. p->exit = true;
  5744. }
  5745. }
  5746. // allows the user to add procedurally to the filters from the command line
  5747. void Context::addFilter(const char* filter, const char* value) { setOption(filter, value); }
  5748. // allows the user to clear all filters from the command line
  5749. void Context::clearFilters() {
  5750. for(auto& curr : p->filters)
  5751. curr.clear();
  5752. }
  5753. // allows the user to override procedurally the bool options from the command line
  5754. void Context::setOption(const char* option, bool value) {
  5755. setOption(option, value ? "true" : "false");
  5756. }
  5757. // allows the user to override procedurally the int options from the command line
  5758. void Context::setOption(const char* option, int value) {
  5759. setOption(option, toString(value).c_str());
  5760. }
  5761. // allows the user to override procedurally the string options from the command line
  5762. void Context::setOption(const char* option, const char* value) {
  5763. auto argv = String("-") + option + "=" + value;
  5764. auto lvalue = argv.c_str();
  5765. parseArgs(1, &lvalue);
  5766. }
  5767. // users should query this in their main() and exit the program if true
  5768. bool Context::shouldExit() { return p->exit; }
  5769. void Context::setAsDefaultForAssertsOutOfTestCases() { g_cs = p; }
  5770. void Context::setAssertHandler(detail::assert_handler ah) { p->ah = ah; }
  5771. void Context::setCout(std::ostream* out) { p->cout = out; }
  5772. static class DiscardOStream : public std::ostream
  5773. {
  5774. private:
  5775. class : public std::streambuf
  5776. {
  5777. private:
  5778. // allowing some buffering decreases the amount of calls to overflow
  5779. char buf[1024];
  5780. protected:
  5781. std::streamsize xsputn(const char_type*, std::streamsize count) override { return count; }
  5782. int_type overflow(int_type ch) override {
  5783. setp(std::begin(buf), std::end(buf));
  5784. return traits_type::not_eof(ch);
  5785. }
  5786. } discardBuf;
  5787. public:
  5788. DiscardOStream()
  5789. : std::ostream(&discardBuf) {}
  5790. } discardOut;
  5791. // the main function that does all the filtering and test running
  5792. int Context::run() {
  5793. using namespace detail;
  5794. // save the old context state in case such was setup - for using asserts out of a testing context
  5795. auto old_cs = g_cs;
  5796. // this is the current contest
  5797. g_cs = p;
  5798. is_running_in_test = true;
  5799. g_no_colors = p->no_colors;
  5800. p->resetRunData();
  5801. std::fstream fstr;
  5802. if(p->cout == nullptr) {
  5803. if(p->quiet) {
  5804. p->cout = &discardOut;
  5805. } else if(p->out.size()) {
  5806. // to a file if specified
  5807. fstr.open(p->out.c_str(), std::fstream::out);
  5808. p->cout = &fstr;
  5809. } else {
  5810. #ifndef DOCTEST_CONFIG_NO_INCLUDE_IOSTREAM
  5811. // stdout by default
  5812. p->cout = &std::cout;
  5813. #else // DOCTEST_CONFIG_NO_INCLUDE_IOSTREAM
  5814. return EXIT_FAILURE;
  5815. #endif // DOCTEST_CONFIG_NO_INCLUDE_IOSTREAM
  5816. }
  5817. }
  5818. FatalConditionHandler::allocateAltStackMem();
  5819. auto cleanup_and_return = [&]() {
  5820. FatalConditionHandler::freeAltStackMem();
  5821. if(fstr.is_open())
  5822. fstr.close();
  5823. // restore context
  5824. g_cs = old_cs;
  5825. is_running_in_test = false;
  5826. // we have to free the reporters which were allocated when the run started
  5827. for(auto& curr : p->reporters_currently_used)
  5828. delete curr;
  5829. p->reporters_currently_used.clear();
  5830. if(p->numTestCasesFailed && !p->no_exitcode)
  5831. return EXIT_FAILURE;
  5832. return EXIT_SUCCESS;
  5833. };
  5834. // setup default reporter if none is given through the command line
  5835. if(p->filters[8].empty())
  5836. p->filters[8].push_back("console");
  5837. // check to see if any of the registered reporters has been selected
  5838. for(auto& curr : getReporters()) {
  5839. if(matchesAny(curr.first.second.c_str(), p->filters[8], false, p->case_sensitive))
  5840. p->reporters_currently_used.push_back(curr.second(*g_cs));
  5841. }
  5842. // TODO: check if there is nothing in reporters_currently_used
  5843. // prepend all listeners
  5844. for(auto& curr : getListeners())
  5845. p->reporters_currently_used.insert(p->reporters_currently_used.begin(), curr.second(*g_cs));
  5846. #ifdef DOCTEST_PLATFORM_WINDOWS
  5847. if(isDebuggerActive() && p->no_debug_output == false)
  5848. p->reporters_currently_used.push_back(new DebugOutputWindowReporter(*g_cs));
  5849. #endif // DOCTEST_PLATFORM_WINDOWS
  5850. // handle version, help and no_run
  5851. if(p->no_run || p->version || p->help || p->list_reporters) {
  5852. DOCTEST_ITERATE_THROUGH_REPORTERS(report_query, QueryData());
  5853. return cleanup_and_return();
  5854. }
  5855. std::vector<const TestCase*> testArray;
  5856. for(auto& curr : getRegisteredTests())
  5857. testArray.push_back(&curr);
  5858. p->numTestCases = testArray.size();
  5859. // sort the collected records
  5860. if(!testArray.empty()) {
  5861. if(p->order_by.compare("file", true) == 0) {
  5862. std::sort(testArray.begin(), testArray.end(), fileOrderComparator);
  5863. } else if(p->order_by.compare("suite", true) == 0) {
  5864. std::sort(testArray.begin(), testArray.end(), suiteOrderComparator);
  5865. } else if(p->order_by.compare("name", true) == 0) {
  5866. std::sort(testArray.begin(), testArray.end(), nameOrderComparator);
  5867. } else if(p->order_by.compare("rand", true) == 0) {
  5868. std::srand(p->rand_seed);
  5869. // random_shuffle implementation
  5870. const auto first = &testArray[0];
  5871. for(size_t i = testArray.size() - 1; i > 0; --i) {
  5872. int idxToSwap = std::rand() % (i + 1);
  5873. const auto temp = first[i];
  5874. first[i] = first[idxToSwap];
  5875. first[idxToSwap] = temp;
  5876. }
  5877. } else if(p->order_by.compare("none", true) == 0) {
  5878. // means no sorting - beneficial for death tests which call into the executable
  5879. // with a specific test case in mind - we don't want to slow down the startup times
  5880. }
  5881. }
  5882. std::set<String> testSuitesPassingFilt;
  5883. bool query_mode = p->count || p->list_test_cases || p->list_test_suites;
  5884. std::vector<const TestCaseData*> queryResults;
  5885. if(!query_mode)
  5886. DOCTEST_ITERATE_THROUGH_REPORTERS(test_run_start, DOCTEST_EMPTY);
  5887. // invoke the registered functions if they match the filter criteria (or just count them)
  5888. for(auto& curr : testArray) {
  5889. const auto& tc = *curr;
  5890. bool skip_me = false;
  5891. if(tc.m_skip && !p->no_skip)
  5892. skip_me = true;
  5893. if(!matchesAny(tc.m_file.c_str(), p->filters[0], true, p->case_sensitive))
  5894. skip_me = true;
  5895. if(matchesAny(tc.m_file.c_str(), p->filters[1], false, p->case_sensitive))
  5896. skip_me = true;
  5897. if(!matchesAny(tc.m_test_suite, p->filters[2], true, p->case_sensitive))
  5898. skip_me = true;
  5899. if(matchesAny(tc.m_test_suite, p->filters[3], false, p->case_sensitive))
  5900. skip_me = true;
  5901. if(!matchesAny(tc.m_name, p->filters[4], true, p->case_sensitive))
  5902. skip_me = true;
  5903. if(matchesAny(tc.m_name, p->filters[5], false, p->case_sensitive))
  5904. skip_me = true;
  5905. if(!skip_me)
  5906. p->numTestCasesPassingFilters++;
  5907. // skip the test if it is not in the execution range
  5908. if((p->last < p->numTestCasesPassingFilters && p->first <= p->last) ||
  5909. (p->first > p->numTestCasesPassingFilters))
  5910. skip_me = true;
  5911. if(skip_me) {
  5912. if(!query_mode)
  5913. DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_skipped, tc);
  5914. continue;
  5915. }
  5916. // do not execute the test if we are to only count the number of filter passing tests
  5917. if(p->count)
  5918. continue;
  5919. // print the name of the test and don't execute it
  5920. if(p->list_test_cases) {
  5921. queryResults.push_back(&tc);
  5922. continue;
  5923. }
  5924. // print the name of the test suite if not done already and don't execute it
  5925. if(p->list_test_suites) {
  5926. if((testSuitesPassingFilt.count(tc.m_test_suite) == 0) && tc.m_test_suite[0] != '\0') {
  5927. queryResults.push_back(&tc);
  5928. testSuitesPassingFilt.insert(tc.m_test_suite);
  5929. p->numTestSuitesPassingFilters++;
  5930. }
  5931. continue;
  5932. }
  5933. // execute the test if it passes all the filtering
  5934. {
  5935. p->currentTest = &tc;
  5936. p->failure_flags = TestCaseFailureReason::None;
  5937. p->seconds = 0;
  5938. // reset atomic counters
  5939. p->numAssertsFailedCurrentTest_atomic = 0;
  5940. p->numAssertsCurrentTest_atomic = 0;
  5941. p->fullyTraversedSubcases.clear();
  5942. DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_start, tc);
  5943. p->timer.start();
  5944. bool run_test = true;
  5945. do {
  5946. // reset some of the fields for subcases (except for the set of fully passed ones)
  5947. p->reachedLeaf = false;
  5948. // May not be empty if previous subcase exited via exception.
  5949. p->subcaseStack.clear();
  5950. p->currentSubcaseDepth = 0;
  5951. p->shouldLogCurrentException = true;
  5952. // reset stuff for logging with INFO()
  5953. p->stringifiedContexts.clear();
  5954. #ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
  5955. try {
  5956. #endif // DOCTEST_CONFIG_NO_EXCEPTIONS
  5957. // MSVC 2015 diagnoses fatalConditionHandler as unused (because reset() is a static method)
  5958. DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4101) // unreferenced local variable
  5959. FatalConditionHandler fatalConditionHandler; // Handle signals
  5960. // execute the test
  5961. tc.m_test();
  5962. fatalConditionHandler.reset();
  5963. DOCTEST_MSVC_SUPPRESS_WARNING_POP
  5964. #ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
  5965. } catch(const TestFailureException&) {
  5966. p->failure_flags |= TestCaseFailureReason::AssertFailure;
  5967. } catch(...) {
  5968. DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_exception,
  5969. {translateActiveException(), false});
  5970. p->failure_flags |= TestCaseFailureReason::Exception;
  5971. }
  5972. #endif // DOCTEST_CONFIG_NO_EXCEPTIONS
  5973. // exit this loop if enough assertions have failed - even if there are more subcases
  5974. if(p->abort_after > 0 &&
  5975. p->numAssertsFailed + p->numAssertsFailedCurrentTest_atomic >= p->abort_after) {
  5976. run_test = false;
  5977. p->failure_flags |= TestCaseFailureReason::TooManyFailedAsserts;
  5978. }
  5979. if(!p->nextSubcaseStack.empty() && run_test)
  5980. DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_reenter, tc);
  5981. if(p->nextSubcaseStack.empty())
  5982. run_test = false;
  5983. } while(run_test);
  5984. p->finalizeTestCaseData();
  5985. DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_end, *g_cs);
  5986. p->currentTest = nullptr;
  5987. // stop executing tests if enough assertions have failed
  5988. if(p->abort_after > 0 && p->numAssertsFailed >= p->abort_after)
  5989. break;
  5990. }
  5991. }
  5992. if(!query_mode) {
  5993. DOCTEST_ITERATE_THROUGH_REPORTERS(test_run_end, *g_cs);
  5994. } else {
  5995. QueryData qdata;
  5996. qdata.run_stats = g_cs;
  5997. qdata.data = queryResults.data();
  5998. qdata.num_data = unsigned(queryResults.size());
  5999. DOCTEST_ITERATE_THROUGH_REPORTERS(report_query, qdata);
  6000. }
  6001. return cleanup_and_return();
  6002. }
  6003. DOCTEST_DEFINE_INTERFACE(IReporter)
  6004. int IReporter::get_num_active_contexts() { return detail::g_infoContexts.size(); }
  6005. const IContextScope* const* IReporter::get_active_contexts() {
  6006. return get_num_active_contexts() ? &detail::g_infoContexts[0] : nullptr;
  6007. }
  6008. int IReporter::get_num_stringified_contexts() { return detail::g_cs->stringifiedContexts.size(); }
  6009. const String* IReporter::get_stringified_contexts() {
  6010. return get_num_stringified_contexts() ? &detail::g_cs->stringifiedContexts[0] : nullptr;
  6011. }
  6012. namespace detail {
  6013. void registerReporterImpl(const char* name, int priority, reporterCreatorFunc c, bool isReporter) {
  6014. if(isReporter)
  6015. getReporters().insert(reporterMap::value_type(reporterMap::key_type(priority, name), c));
  6016. else
  6017. getListeners().insert(reporterMap::value_type(reporterMap::key_type(priority, name), c));
  6018. }
  6019. } // namespace detail
  6020. } // namespace doctest
  6021. #endif // DOCTEST_CONFIG_DISABLE
  6022. #ifdef DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
  6023. DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4007) // 'function' : must be 'attribute' - see issue #182
  6024. int main(int argc, char** argv) { return doctest::Context(argc, argv).run(); }
  6025. DOCTEST_MSVC_SUPPRESS_WARNING_POP
  6026. #endif // DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
  6027. DOCTEST_CLANG_SUPPRESS_WARNING_POP
  6028. DOCTEST_MSVC_SUPPRESS_WARNING_POP
  6029. DOCTEST_GCC_SUPPRESS_WARNING_POP
  6030. DOCTEST_SUPPRESS_COMMON_WARNINGS_POP
  6031. #endif // DOCTEST_LIBRARY_IMPLEMENTATION
  6032. #endif // DOCTEST_CONFIG_IMPLEMENT
  6033. #ifdef DOCTEST_UNDEF_WIN32_LEAN_AND_MEAN
  6034. #undef WIN32_LEAN_AND_MEAN
  6035. #undef DOCTEST_UNDEF_WIN32_LEAN_AND_MEAN
  6036. #endif // DOCTEST_UNDEF_WIN32_LEAN_AND_MEAN
  6037. #ifdef DOCTEST_UNDEF_NOMINMAX
  6038. #undef NOMINMAX
  6039. #undef DOCTEST_UNDEF_NOMINMAX
  6040. #endif // DOCTEST_UNDEF_NOMINMAX