json.hpp 197 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306
  1. // __ _____ _____ _____
  2. // __| | __| | | | JSON for Modern C++
  3. // | | |__ | | | | | | version 3.12.0
  4. // |_____|_____|_____|_|___| https://github.com/nlohmann/json
  5. //
  6. // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
  7. // SPDX-License-Identifier: MIT
  8. /****************************************************************************\
  9. * Note on documentation: The source files contain links to the online *
  10. * documentation of the public API at https://json.nlohmann.me. This URL *
  11. * contains the most recent documentation and should also be applicable to *
  12. * previous versions; documentation for deprecated functions is not *
  13. * removed, but marked deprecated. See "Generate documentation" section in *
  14. * file docs/README.md. *
  15. \****************************************************************************/
  16. #ifndef INCLUDE_NLOHMANN_JSON_HPP_
  17. #define INCLUDE_NLOHMANN_JSON_HPP_
  18. #include <algorithm> // all_of, find, for_each
  19. #include <cstddef> // nullptr_t, ptrdiff_t, size_t
  20. #include <functional> // hash, less
  21. #include <initializer_list> // initializer_list
  22. #ifndef JSON_NO_IO
  23. #include <iosfwd> // istream, ostream
  24. #endif // JSON_NO_IO
  25. #include <iterator> // random_access_iterator_tag
  26. #include <memory> // unique_ptr
  27. #include <string> // string, stoi, to_string
  28. #include <utility> // declval, forward, move, pair, swap
  29. #include <vector> // vector
  30. #include <nlohmann/adl_serializer.hpp>
  31. #include <nlohmann/byte_container_with_subtype.hpp>
  32. #include <nlohmann/detail/conversions/from_json.hpp>
  33. #include <nlohmann/detail/conversions/to_json.hpp>
  34. #include <nlohmann/detail/exceptions.hpp>
  35. #include <nlohmann/detail/hash.hpp>
  36. #include <nlohmann/detail/input/binary_reader.hpp>
  37. #include <nlohmann/detail/input/input_adapters.hpp>
  38. #include <nlohmann/detail/input/lexer.hpp>
  39. #include <nlohmann/detail/input/parser.hpp>
  40. #include <nlohmann/detail/iterators/internal_iterator.hpp>
  41. #include <nlohmann/detail/iterators/iter_impl.hpp>
  42. #include <nlohmann/detail/iterators/iteration_proxy.hpp>
  43. #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
  44. #include <nlohmann/detail/iterators/primitive_iterator.hpp>
  45. #include <nlohmann/detail/json_custom_base_class.hpp>
  46. #include <nlohmann/detail/json_pointer.hpp>
  47. #include <nlohmann/detail/json_ref.hpp>
  48. #include <nlohmann/detail/macro_scope.hpp>
  49. #include <nlohmann/detail/string_concat.hpp>
  50. #include <nlohmann/detail/string_escape.hpp>
  51. #include <nlohmann/detail/string_utils.hpp>
  52. #include <nlohmann/detail/meta/cpp_future.hpp>
  53. #include <nlohmann/detail/meta/type_traits.hpp>
  54. #include <nlohmann/detail/output/binary_writer.hpp>
  55. #include <nlohmann/detail/output/output_adapters.hpp>
  56. #include <nlohmann/detail/output/serializer.hpp>
  57. #include <nlohmann/detail/value_t.hpp>
  58. #include <nlohmann/json_fwd.hpp>
  59. #include <nlohmann/ordered_map.hpp>
  60. #if defined(JSON_HAS_CPP_17)
  61. #if JSON_HAS_STATIC_RTTI
  62. #include <any>
  63. #endif
  64. #include <string_view>
  65. #endif
  66. /*!
  67. @brief namespace for Niels Lohmann
  68. @see https://github.com/nlohmann
  69. @since version 1.0.0
  70. */
  71. NLOHMANN_JSON_NAMESPACE_BEGIN
  72. /*!
  73. @brief a class to store JSON values
  74. @internal
  75. @invariant The member variables @a m_value and @a m_type have the following
  76. relationship:
  77. - If `m_type == value_t::object`, then `m_value.object != nullptr`.
  78. - If `m_type == value_t::array`, then `m_value.array != nullptr`.
  79. - If `m_type == value_t::string`, then `m_value.string != nullptr`.
  80. The invariants are checked by member function assert_invariant().
  81. @note ObjectType trick from https://stackoverflow.com/a/9860911
  82. @endinternal
  83. @since version 1.0.0
  84. @nosubgrouping
  85. */
  86. NLOHMANN_BASIC_JSON_TPL_DECLARATION
  87. class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
  88. : public ::nlohmann::detail::json_base_class<CustomBaseClass>
  89. {
  90. private:
  91. template<detail::value_t> friend struct detail::external_constructor;
  92. template<typename>
  93. friend class ::nlohmann::json_pointer;
  94. // can be restored when json_pointer backwards compatibility is removed
  95. // friend ::nlohmann::json_pointer<StringType>;
  96. template<typename BasicJsonType, typename InputType>
  97. friend class ::nlohmann::detail::parser;
  98. friend ::nlohmann::detail::serializer<basic_json>;
  99. template<typename BasicJsonType>
  100. friend class ::nlohmann::detail::iter_impl;
  101. template<typename BasicJsonType, typename CharType>
  102. friend class ::nlohmann::detail::binary_writer;
  103. template<typename BasicJsonType, typename InputType, typename SAX>
  104. friend class ::nlohmann::detail::binary_reader;
  105. template<typename BasicJsonType, typename InputAdapterType>
  106. friend class ::nlohmann::detail::json_sax_dom_parser;
  107. template<typename BasicJsonType, typename InputAdapterType>
  108. friend class ::nlohmann::detail::json_sax_dom_callback_parser;
  109. friend class ::nlohmann::detail::exception;
  110. /// workaround type for MSVC
  111. using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
  112. using json_base_class_t = ::nlohmann::detail::json_base_class<CustomBaseClass>;
  113. JSON_PRIVATE_UNLESS_TESTED:
  114. // convenience aliases for types residing in namespace detail;
  115. using lexer = ::nlohmann::detail::lexer_base<basic_json>;
  116. template<typename InputAdapterType>
  117. static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(
  118. InputAdapterType adapter,
  119. detail::parser_callback_t<basic_json>cb = nullptr,
  120. const bool allow_exceptions = true,
  121. const bool ignore_comments = false
  122. )
  123. {
  124. return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter),
  125. std::move(cb), allow_exceptions, ignore_comments);
  126. }
  127. private:
  128. using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
  129. template<typename BasicJsonType>
  130. using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
  131. template<typename BasicJsonType>
  132. using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
  133. template<typename Iterator>
  134. using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
  135. template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
  136. template<typename CharType>
  137. using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
  138. template<typename InputType>
  139. using binary_reader = ::nlohmann::detail::binary_reader<basic_json, InputType>;
  140. template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
  141. JSON_PRIVATE_UNLESS_TESTED:
  142. using serializer = ::nlohmann::detail::serializer<basic_json>;
  143. public:
  144. using value_t = detail::value_t;
  145. /// JSON Pointer, see @ref nlohmann::json_pointer
  146. using json_pointer = ::nlohmann::json_pointer<StringType>;
  147. template<typename T, typename SFINAE>
  148. using json_serializer = JSONSerializer<T, SFINAE>;
  149. /// how to treat decoding errors
  150. using error_handler_t = detail::error_handler_t;
  151. /// how to treat CBOR tags
  152. using cbor_tag_handler_t = detail::cbor_tag_handler_t;
  153. /// how to encode BJData
  154. using bjdata_version_t = detail::bjdata_version_t;
  155. /// helper type for initializer lists of basic_json values
  156. using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
  157. using input_format_t = detail::input_format_t;
  158. /// SAX interface type, see @ref nlohmann::json_sax
  159. using json_sax_t = json_sax<basic_json>;
  160. ////////////////
  161. // exceptions //
  162. ////////////////
  163. /// @name exceptions
  164. /// Classes to implement user-defined exceptions.
  165. /// @{
  166. using exception = detail::exception;
  167. using parse_error = detail::parse_error;
  168. using invalid_iterator = detail::invalid_iterator;
  169. using type_error = detail::type_error;
  170. using out_of_range = detail::out_of_range;
  171. using other_error = detail::other_error;
  172. /// @}
  173. /////////////////////
  174. // container types //
  175. /////////////////////
  176. /// @name container types
  177. /// The canonic container types to use @ref basic_json like any other STL
  178. /// container.
  179. /// @{
  180. /// the type of elements in a basic_json container
  181. using value_type = basic_json;
  182. /// the type of an element reference
  183. using reference = value_type&;
  184. /// the type of an element const reference
  185. using const_reference = const value_type&;
  186. /// a type to represent differences between iterators
  187. using difference_type = std::ptrdiff_t;
  188. /// a type to represent container sizes
  189. using size_type = std::size_t;
  190. /// the allocator type
  191. using allocator_type = AllocatorType<basic_json>;
  192. /// the type of an element pointer
  193. using pointer = typename std::allocator_traits<allocator_type>::pointer;
  194. /// the type of an element const pointer
  195. using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
  196. /// an iterator for a basic_json container
  197. using iterator = iter_impl<basic_json>;
  198. /// a const iterator for a basic_json container
  199. using const_iterator = iter_impl<const basic_json>;
  200. /// a reverse iterator for a basic_json container
  201. using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
  202. /// a const reverse iterator for a basic_json container
  203. using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
  204. /// @}
  205. /// @brief returns the allocator associated with the container
  206. /// @sa https://json.nlohmann.me/api/basic_json/get_allocator/
  207. static allocator_type get_allocator()
  208. {
  209. return allocator_type();
  210. }
  211. /// @brief returns version information on the library
  212. /// @sa https://json.nlohmann.me/api/basic_json/meta/
  213. JSON_HEDLEY_WARN_UNUSED_RESULT
  214. static basic_json meta()
  215. {
  216. basic_json result;
  217. result["copyright"] = "(C) 2013-2025 Niels Lohmann";
  218. result["name"] = "JSON for Modern C++";
  219. result["url"] = "https://github.com/nlohmann/json";
  220. result["version"]["string"] =
  221. detail::concat(std::to_string(NLOHMANN_JSON_VERSION_MAJOR), '.',
  222. std::to_string(NLOHMANN_JSON_VERSION_MINOR), '.',
  223. std::to_string(NLOHMANN_JSON_VERSION_PATCH));
  224. result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
  225. result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
  226. result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
  227. #ifdef _WIN32
  228. result["platform"] = "win32";
  229. #elif defined __linux__
  230. result["platform"] = "linux";
  231. #elif defined __APPLE__
  232. result["platform"] = "apple";
  233. #elif defined __unix__
  234. result["platform"] = "unix";
  235. #else
  236. result["platform"] = "unknown";
  237. #endif
  238. #if defined(__ICC) || defined(__INTEL_COMPILER)
  239. result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
  240. #elif defined(__clang__)
  241. result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
  242. #elif defined(__GNUC__) || defined(__GNUG__)
  243. result["compiler"] = {{"family", "gcc"}, {"version", detail::concat(
  244. std::to_string(__GNUC__), '.',
  245. std::to_string(__GNUC_MINOR__), '.',
  246. std::to_string(__GNUC_PATCHLEVEL__))
  247. }
  248. };
  249. #elif defined(__HP_cc) || defined(__HP_aCC)
  250. result["compiler"] = "hp"
  251. #elif defined(__IBMCPP__)
  252. result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
  253. #elif defined(_MSC_VER)
  254. result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
  255. #elif defined(__PGI)
  256. result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
  257. #elif defined(__SUNPRO_CC)
  258. result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
  259. #else
  260. result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
  261. #endif
  262. #if defined(_MSVC_LANG)
  263. result["compiler"]["c++"] = std::to_string(_MSVC_LANG);
  264. #elif defined(__cplusplus)
  265. result["compiler"]["c++"] = std::to_string(__cplusplus);
  266. #else
  267. result["compiler"]["c++"] = "unknown";
  268. #endif
  269. return result;
  270. }
  271. ///////////////////////////
  272. // JSON value data types //
  273. ///////////////////////////
  274. /// @name JSON value data types
  275. /// The data types to store a JSON value. These types are derived from
  276. /// the template arguments passed to class @ref basic_json.
  277. /// @{
  278. /// @brief default object key comparator type
  279. /// The actual object key comparator type (@ref object_comparator_t) may be
  280. /// different.
  281. /// @sa https://json.nlohmann.me/api/basic_json/default_object_comparator_t/
  282. #if defined(JSON_HAS_CPP_14)
  283. // use of transparent comparator avoids unnecessary repeated construction of temporaries
  284. // in functions involving lookup by key with types other than object_t::key_type (aka. StringType)
  285. using default_object_comparator_t = std::less<>;
  286. #else
  287. using default_object_comparator_t = std::less<StringType>;
  288. #endif
  289. /// @brief a type for an object
  290. /// @sa https://json.nlohmann.me/api/basic_json/object_t/
  291. using object_t = ObjectType<StringType,
  292. basic_json,
  293. default_object_comparator_t,
  294. AllocatorType<std::pair<const StringType,
  295. basic_json>>>;
  296. /// @brief a type for an array
  297. /// @sa https://json.nlohmann.me/api/basic_json/array_t/
  298. using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
  299. /// @brief a type for a string
  300. /// @sa https://json.nlohmann.me/api/basic_json/string_t/
  301. using string_t = StringType;
  302. /// @brief a type for a boolean
  303. /// @sa https://json.nlohmann.me/api/basic_json/boolean_t/
  304. using boolean_t = BooleanType;
  305. /// @brief a type for a number (integer)
  306. /// @sa https://json.nlohmann.me/api/basic_json/number_integer_t/
  307. using number_integer_t = NumberIntegerType;
  308. /// @brief a type for a number (unsigned)
  309. /// @sa https://json.nlohmann.me/api/basic_json/number_unsigned_t/
  310. using number_unsigned_t = NumberUnsignedType;
  311. /// @brief a type for a number (floating-point)
  312. /// @sa https://json.nlohmann.me/api/basic_json/number_float_t/
  313. using number_float_t = NumberFloatType;
  314. /// @brief a type for a packed binary type
  315. /// @sa https://json.nlohmann.me/api/basic_json/binary_t/
  316. using binary_t = nlohmann::byte_container_with_subtype<BinaryType>;
  317. /// @brief object key comparator type
  318. /// @sa https://json.nlohmann.me/api/basic_json/object_comparator_t/
  319. using object_comparator_t = detail::actual_object_comparator_t<basic_json>;
  320. /// @}
  321. private:
  322. /// helper for exception-safe object creation
  323. template<typename T, typename... Args>
  324. JSON_HEDLEY_RETURNS_NON_NULL
  325. static T* create(Args&& ... args)
  326. {
  327. AllocatorType<T> alloc;
  328. using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
  329. auto deleter = [&](T * obj)
  330. {
  331. AllocatorTraits::deallocate(alloc, obj, 1);
  332. };
  333. std::unique_ptr<T, decltype(deleter)> obj(AllocatorTraits::allocate(alloc, 1), deleter);
  334. AllocatorTraits::construct(alloc, obj.get(), std::forward<Args>(args)...);
  335. JSON_ASSERT(obj != nullptr);
  336. return obj.release();
  337. }
  338. ////////////////////////
  339. // JSON value storage //
  340. ////////////////////////
  341. JSON_PRIVATE_UNLESS_TESTED:
  342. /*!
  343. @brief a JSON value
  344. The actual storage for a JSON value of the @ref basic_json class. This
  345. union combines the different storage types for the JSON value types
  346. defined in @ref value_t.
  347. JSON type | value_t type | used type
  348. --------- | --------------- | ------------------------
  349. object | object | pointer to @ref object_t
  350. array | array | pointer to @ref array_t
  351. string | string | pointer to @ref string_t
  352. boolean | boolean | @ref boolean_t
  353. number | number_integer | @ref number_integer_t
  354. number | number_unsigned | @ref number_unsigned_t
  355. number | number_float | @ref number_float_t
  356. binary | binary | pointer to @ref binary_t
  357. null | null | *no value is stored*
  358. @note Variable-length types (objects, arrays, and strings) are stored as
  359. pointers. The size of the union should not exceed 64 bits if the default
  360. value types are used.
  361. @since version 1.0.0
  362. */
  363. union json_value
  364. {
  365. /// object (stored with pointer to save storage)
  366. object_t* object;
  367. /// array (stored with pointer to save storage)
  368. array_t* array;
  369. /// string (stored with pointer to save storage)
  370. string_t* string;
  371. /// binary (stored with pointer to save storage)
  372. binary_t* binary;
  373. /// boolean
  374. boolean_t boolean;
  375. /// number (integer)
  376. number_integer_t number_integer;
  377. /// number (unsigned integer)
  378. number_unsigned_t number_unsigned;
  379. /// number (floating-point)
  380. number_float_t number_float;
  381. /// default constructor (for null values)
  382. json_value() = default;
  383. /// constructor for booleans
  384. json_value(boolean_t v) noexcept : boolean(v) {}
  385. /// constructor for numbers (integer)
  386. json_value(number_integer_t v) noexcept : number_integer(v) {}
  387. /// constructor for numbers (unsigned)
  388. json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
  389. /// constructor for numbers (floating-point)
  390. json_value(number_float_t v) noexcept : number_float(v) {}
  391. /// constructor for empty values of a given type
  392. json_value(value_t t)
  393. {
  394. switch (t)
  395. {
  396. case value_t::object:
  397. {
  398. object = create<object_t>();
  399. break;
  400. }
  401. case value_t::array:
  402. {
  403. array = create<array_t>();
  404. break;
  405. }
  406. case value_t::string:
  407. {
  408. string = create<string_t>("");
  409. break;
  410. }
  411. case value_t::binary:
  412. {
  413. binary = create<binary_t>();
  414. break;
  415. }
  416. case value_t::boolean:
  417. {
  418. boolean = static_cast<boolean_t>(false);
  419. break;
  420. }
  421. case value_t::number_integer:
  422. {
  423. number_integer = static_cast<number_integer_t>(0);
  424. break;
  425. }
  426. case value_t::number_unsigned:
  427. {
  428. number_unsigned = static_cast<number_unsigned_t>(0);
  429. break;
  430. }
  431. case value_t::number_float:
  432. {
  433. number_float = static_cast<number_float_t>(0.0);
  434. break;
  435. }
  436. case value_t::null:
  437. {
  438. object = nullptr; // silence warning, see #821
  439. break;
  440. }
  441. case value_t::discarded:
  442. default:
  443. {
  444. object = nullptr; // silence warning, see #821
  445. if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
  446. {
  447. JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.12.0", nullptr)); // LCOV_EXCL_LINE
  448. }
  449. break;
  450. }
  451. }
  452. }
  453. /// constructor for strings
  454. json_value(const string_t& value) : string(create<string_t>(value)) {}
  455. /// constructor for rvalue strings
  456. json_value(string_t&& value) : string(create<string_t>(std::move(value))) {}
  457. /// constructor for objects
  458. json_value(const object_t& value) : object(create<object_t>(value)) {}
  459. /// constructor for rvalue objects
  460. json_value(object_t&& value) : object(create<object_t>(std::move(value))) {}
  461. /// constructor for arrays
  462. json_value(const array_t& value) : array(create<array_t>(value)) {}
  463. /// constructor for rvalue arrays
  464. json_value(array_t&& value) : array(create<array_t>(std::move(value))) {}
  465. /// constructor for binary arrays
  466. json_value(const typename binary_t::container_type& value) : binary(create<binary_t>(value)) {}
  467. /// constructor for rvalue binary arrays
  468. json_value(typename binary_t::container_type&& value) : binary(create<binary_t>(std::move(value))) {}
  469. /// constructor for binary arrays (internal type)
  470. json_value(const binary_t& value) : binary(create<binary_t>(value)) {}
  471. /// constructor for rvalue binary arrays (internal type)
  472. json_value(binary_t&& value) : binary(create<binary_t>(std::move(value))) {}
  473. void destroy(value_t t)
  474. {
  475. if (
  476. (t == value_t::object && object == nullptr) ||
  477. (t == value_t::array && array == nullptr) ||
  478. (t == value_t::string && string == nullptr) ||
  479. (t == value_t::binary && binary == nullptr)
  480. )
  481. {
  482. //not initialized (e.g. due to exception in the ctor)
  483. return;
  484. }
  485. if (t == value_t::array || t == value_t::object)
  486. {
  487. // flatten the current json_value to a heap-allocated stack
  488. std::vector<basic_json> stack;
  489. // move the top-level items to stack
  490. if (t == value_t::array)
  491. {
  492. stack.reserve(array->size());
  493. std::move(array->begin(), array->end(), std::back_inserter(stack));
  494. }
  495. else
  496. {
  497. stack.reserve(object->size());
  498. for (auto&& it : *object)
  499. {
  500. stack.push_back(std::move(it.second));
  501. }
  502. }
  503. while (!stack.empty())
  504. {
  505. // move the last item to local variable to be processed
  506. basic_json current_item(std::move(stack.back()));
  507. stack.pop_back();
  508. // if current_item is array/object, move
  509. // its children to the stack to be processed later
  510. if (current_item.is_array())
  511. {
  512. std::move(current_item.m_data.m_value.array->begin(), current_item.m_data.m_value.array->end(), std::back_inserter(stack));
  513. current_item.m_data.m_value.array->clear();
  514. }
  515. else if (current_item.is_object())
  516. {
  517. for (auto&& it : *current_item.m_data.m_value.object)
  518. {
  519. stack.push_back(std::move(it.second));
  520. }
  521. current_item.m_data.m_value.object->clear();
  522. }
  523. // it's now safe that current_item get destructed
  524. // since it doesn't have any children
  525. }
  526. }
  527. switch (t)
  528. {
  529. case value_t::object:
  530. {
  531. AllocatorType<object_t> alloc;
  532. std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
  533. std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
  534. break;
  535. }
  536. case value_t::array:
  537. {
  538. AllocatorType<array_t> alloc;
  539. std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
  540. std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
  541. break;
  542. }
  543. case value_t::string:
  544. {
  545. AllocatorType<string_t> alloc;
  546. std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
  547. std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
  548. break;
  549. }
  550. case value_t::binary:
  551. {
  552. AllocatorType<binary_t> alloc;
  553. std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);
  554. std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);
  555. break;
  556. }
  557. case value_t::null:
  558. case value_t::boolean:
  559. case value_t::number_integer:
  560. case value_t::number_unsigned:
  561. case value_t::number_float:
  562. case value_t::discarded:
  563. default:
  564. {
  565. break;
  566. }
  567. }
  568. }
  569. };
  570. private:
  571. /*!
  572. @brief checks the class invariants
  573. This function asserts the class invariants. It needs to be called at the
  574. end of every constructor to make sure that created objects respect the
  575. invariant. Furthermore, it has to be called each time the type of a JSON
  576. value is changed, because the invariant expresses a relationship between
  577. @a m_type and @a m_value.
  578. Furthermore, the parent relation is checked for arrays and objects: If
  579. @a check_parents true and the value is an array or object, then the
  580. container's elements must have the current value as parent.
  581. @param[in] check_parents whether the parent relation should be checked.
  582. The value is true by default and should only be set to false
  583. during destruction of objects when the invariant does not
  584. need to hold.
  585. */
  586. void assert_invariant(bool check_parents = true) const noexcept
  587. {
  588. JSON_ASSERT(m_data.m_type != value_t::object || m_data.m_value.object != nullptr);
  589. JSON_ASSERT(m_data.m_type != value_t::array || m_data.m_value.array != nullptr);
  590. JSON_ASSERT(m_data.m_type != value_t::string || m_data.m_value.string != nullptr);
  591. JSON_ASSERT(m_data.m_type != value_t::binary || m_data.m_value.binary != nullptr);
  592. #if JSON_DIAGNOSTICS
  593. JSON_TRY
  594. {
  595. // cppcheck-suppress assertWithSideEffect
  596. JSON_ASSERT(!check_parents || !is_structured() || std::all_of(begin(), end(), [this](const basic_json & j)
  597. {
  598. return j.m_parent == this;
  599. }));
  600. }
  601. JSON_CATCH(...) {} // LCOV_EXCL_LINE
  602. #endif
  603. static_cast<void>(check_parents);
  604. }
  605. void set_parents()
  606. {
  607. #if JSON_DIAGNOSTICS
  608. switch (m_data.m_type)
  609. {
  610. case value_t::array:
  611. {
  612. for (auto& element : *m_data.m_value.array)
  613. {
  614. element.m_parent = this;
  615. }
  616. break;
  617. }
  618. case value_t::object:
  619. {
  620. for (auto& element : *m_data.m_value.object)
  621. {
  622. element.second.m_parent = this;
  623. }
  624. break;
  625. }
  626. case value_t::null:
  627. case value_t::string:
  628. case value_t::boolean:
  629. case value_t::number_integer:
  630. case value_t::number_unsigned:
  631. case value_t::number_float:
  632. case value_t::binary:
  633. case value_t::discarded:
  634. default:
  635. break;
  636. }
  637. #endif
  638. }
  639. iterator set_parents(iterator it, typename iterator::difference_type count_set_parents)
  640. {
  641. #if JSON_DIAGNOSTICS
  642. for (typename iterator::difference_type i = 0; i < count_set_parents; ++i)
  643. {
  644. (it + i)->m_parent = this;
  645. }
  646. #else
  647. static_cast<void>(count_set_parents);
  648. #endif
  649. return it;
  650. }
  651. reference set_parent(reference j, std::size_t old_capacity = detail::unknown_size())
  652. {
  653. #if JSON_DIAGNOSTICS
  654. if (old_capacity != detail::unknown_size())
  655. {
  656. // see https://github.com/nlohmann/json/issues/2838
  657. JSON_ASSERT(type() == value_t::array);
  658. if (JSON_HEDLEY_UNLIKELY(m_data.m_value.array->capacity() != old_capacity))
  659. {
  660. // capacity has changed: update all parents
  661. set_parents();
  662. return j;
  663. }
  664. }
  665. // ordered_json uses a vector internally, so pointers could have
  666. // been invalidated; see https://github.com/nlohmann/json/issues/2962
  667. #ifdef JSON_HEDLEY_MSVC_VERSION
  668. #pragma warning(push )
  669. #pragma warning(disable : 4127) // ignore warning to replace if with if constexpr
  670. #endif
  671. if (detail::is_ordered_map<object_t>::value)
  672. {
  673. set_parents();
  674. return j;
  675. }
  676. #ifdef JSON_HEDLEY_MSVC_VERSION
  677. #pragma warning( pop )
  678. #endif
  679. j.m_parent = this;
  680. #else
  681. static_cast<void>(j);
  682. static_cast<void>(old_capacity);
  683. #endif
  684. return j;
  685. }
  686. public:
  687. //////////////////////////
  688. // JSON parser callback //
  689. //////////////////////////
  690. /// @brief parser event types
  691. /// @sa https://json.nlohmann.me/api/basic_json/parse_event_t/
  692. using parse_event_t = detail::parse_event_t;
  693. /// @brief per-element parser callback type
  694. /// @sa https://json.nlohmann.me/api/basic_json/parser_callback_t/
  695. using parser_callback_t = detail::parser_callback_t<basic_json>;
  696. //////////////////
  697. // constructors //
  698. //////////////////
  699. /// @name constructors and destructors
  700. /// Constructors of class @ref basic_json, copy/move constructor, copy
  701. /// assignment, static functions creating objects, and the destructor.
  702. /// @{
  703. /// @brief create an empty value with a given type
  704. /// @sa https://json.nlohmann.me/api/basic_json/basic_json/
  705. basic_json(const value_t v)
  706. : m_data(v)
  707. {
  708. assert_invariant();
  709. }
  710. /// @brief create a null object
  711. /// @sa https://json.nlohmann.me/api/basic_json/basic_json/
  712. basic_json(std::nullptr_t = nullptr) noexcept // NOLINT(bugprone-exception-escape)
  713. : basic_json(value_t::null)
  714. {
  715. assert_invariant();
  716. }
  717. /// @brief create a JSON value from compatible types
  718. /// @sa https://json.nlohmann.me/api/basic_json/basic_json/
  719. template < typename CompatibleType,
  720. typename U = detail::uncvref_t<CompatibleType>,
  721. detail::enable_if_t <
  722. !detail::is_basic_json<U>::value && detail::is_compatible_type<basic_json_t, U>::value, int > = 0 >
  723. basic_json(CompatibleType && val) noexcept(noexcept( // NOLINT(bugprone-forwarding-reference-overload,bugprone-exception-escape)
  724. JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
  725. std::forward<CompatibleType>(val))))
  726. {
  727. JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
  728. set_parents();
  729. assert_invariant();
  730. }
  731. /// @brief create a JSON value from an existing one
  732. /// @sa https://json.nlohmann.me/api/basic_json/basic_json/
  733. template < typename BasicJsonType,
  734. detail::enable_if_t <
  735. detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value, int > = 0 >
  736. basic_json(const BasicJsonType& val)
  737. #if JSON_DIAGNOSTIC_POSITIONS
  738. : start_position(val.start_pos()),
  739. end_position(val.end_pos())
  740. #endif
  741. {
  742. using other_boolean_t = typename BasicJsonType::boolean_t;
  743. using other_number_float_t = typename BasicJsonType::number_float_t;
  744. using other_number_integer_t = typename BasicJsonType::number_integer_t;
  745. using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
  746. using other_string_t = typename BasicJsonType::string_t;
  747. using other_object_t = typename BasicJsonType::object_t;
  748. using other_array_t = typename BasicJsonType::array_t;
  749. using other_binary_t = typename BasicJsonType::binary_t;
  750. switch (val.type())
  751. {
  752. case value_t::boolean:
  753. JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
  754. break;
  755. case value_t::number_float:
  756. JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
  757. break;
  758. case value_t::number_integer:
  759. JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
  760. break;
  761. case value_t::number_unsigned:
  762. JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
  763. break;
  764. case value_t::string:
  765. JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
  766. break;
  767. case value_t::object:
  768. JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
  769. break;
  770. case value_t::array:
  771. JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
  772. break;
  773. case value_t::binary:
  774. JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>());
  775. break;
  776. case value_t::null:
  777. *this = nullptr;
  778. break;
  779. case value_t::discarded:
  780. m_data.m_type = value_t::discarded;
  781. break;
  782. default: // LCOV_EXCL_LINE
  783. JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
  784. }
  785. JSON_ASSERT(m_data.m_type == val.type());
  786. set_parents();
  787. assert_invariant();
  788. }
  789. /// @brief create a container (array or object) from an initializer list
  790. /// @sa https://json.nlohmann.me/api/basic_json/basic_json/
  791. basic_json(initializer_list_t init,
  792. bool type_deduction = true,
  793. value_t manual_type = value_t::array)
  794. {
  795. // check if each element is an array with two elements whose first
  796. // element is a string
  797. bool is_an_object = std::all_of(init.begin(), init.end(),
  798. [](const detail::json_ref<basic_json>& element_ref)
  799. {
  800. // The cast is to ensure op[size_type] is called, bearing in mind size_type may not be int;
  801. // (many string types can be constructed from 0 via its null-pointer guise, so we get a
  802. // broken call to op[key_type], the wrong semantics and a 4804 warning on Windows)
  803. return element_ref->is_array() && element_ref->size() == 2 && (*element_ref)[static_cast<size_type>(0)].is_string();
  804. });
  805. // adjust type if type deduction is not wanted
  806. if (!type_deduction)
  807. {
  808. // if array is wanted, do not create an object though possible
  809. if (manual_type == value_t::array)
  810. {
  811. is_an_object = false;
  812. }
  813. // if object is wanted but impossible, throw an exception
  814. if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object && !is_an_object))
  815. {
  816. JSON_THROW(type_error::create(301, "cannot create object from initializer list", nullptr));
  817. }
  818. }
  819. if (is_an_object)
  820. {
  821. // the initializer list is a list of pairs -> create object
  822. m_data.m_type = value_t::object;
  823. m_data.m_value = value_t::object;
  824. for (auto& element_ref : init)
  825. {
  826. auto element = element_ref.moved_or_copied();
  827. m_data.m_value.object->emplace(
  828. std::move(*((*element.m_data.m_value.array)[0].m_data.m_value.string)),
  829. std::move((*element.m_data.m_value.array)[1]));
  830. }
  831. }
  832. else
  833. {
  834. // the initializer list describes an array -> create array
  835. m_data.m_type = value_t::array;
  836. m_data.m_value.array = create<array_t>(init.begin(), init.end());
  837. }
  838. set_parents();
  839. assert_invariant();
  840. }
  841. /// @brief explicitly create a binary array (without subtype)
  842. /// @sa https://json.nlohmann.me/api/basic_json/binary/
  843. JSON_HEDLEY_WARN_UNUSED_RESULT
  844. static basic_json binary(const typename binary_t::container_type& init)
  845. {
  846. auto res = basic_json();
  847. res.m_data.m_type = value_t::binary;
  848. res.m_data.m_value = init;
  849. return res;
  850. }
  851. /// @brief explicitly create a binary array (with subtype)
  852. /// @sa https://json.nlohmann.me/api/basic_json/binary/
  853. JSON_HEDLEY_WARN_UNUSED_RESULT
  854. static basic_json binary(const typename binary_t::container_type& init, typename binary_t::subtype_type subtype)
  855. {
  856. auto res = basic_json();
  857. res.m_data.m_type = value_t::binary;
  858. res.m_data.m_value = binary_t(init, subtype);
  859. return res;
  860. }
  861. /// @brief explicitly create a binary array
  862. /// @sa https://json.nlohmann.me/api/basic_json/binary/
  863. JSON_HEDLEY_WARN_UNUSED_RESULT
  864. static basic_json binary(typename binary_t::container_type&& init)
  865. {
  866. auto res = basic_json();
  867. res.m_data.m_type = value_t::binary;
  868. res.m_data.m_value = std::move(init);
  869. return res;
  870. }
  871. /// @brief explicitly create a binary array (with subtype)
  872. /// @sa https://json.nlohmann.me/api/basic_json/binary/
  873. JSON_HEDLEY_WARN_UNUSED_RESULT
  874. static basic_json binary(typename binary_t::container_type&& init, typename binary_t::subtype_type subtype)
  875. {
  876. auto res = basic_json();
  877. res.m_data.m_type = value_t::binary;
  878. res.m_data.m_value = binary_t(std::move(init), subtype);
  879. return res;
  880. }
  881. /// @brief explicitly create an array from an initializer list
  882. /// @sa https://json.nlohmann.me/api/basic_json/array/
  883. JSON_HEDLEY_WARN_UNUSED_RESULT
  884. static basic_json array(initializer_list_t init = {})
  885. {
  886. return basic_json(init, false, value_t::array);
  887. }
  888. /// @brief explicitly create an object from an initializer list
  889. /// @sa https://json.nlohmann.me/api/basic_json/object/
  890. JSON_HEDLEY_WARN_UNUSED_RESULT
  891. static basic_json object(initializer_list_t init = {})
  892. {
  893. return basic_json(init, false, value_t::object);
  894. }
  895. /// @brief construct an array with count copies of given value
  896. /// @sa https://json.nlohmann.me/api/basic_json/basic_json/
  897. basic_json(size_type cnt, const basic_json& val):
  898. m_data{cnt, val}
  899. {
  900. set_parents();
  901. assert_invariant();
  902. }
  903. /// @brief construct a JSON container given an iterator range
  904. /// @sa https://json.nlohmann.me/api/basic_json/basic_json/
  905. template < class InputIT, typename std::enable_if <
  906. std::is_same<InputIT, typename basic_json_t::iterator>::value ||
  907. std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int >::type = 0 >
  908. basic_json(InputIT first, InputIT last) // NOLINT(performance-unnecessary-value-param)
  909. {
  910. JSON_ASSERT(first.m_object != nullptr);
  911. JSON_ASSERT(last.m_object != nullptr);
  912. // make sure iterator fits the current value
  913. if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
  914. {
  915. JSON_THROW(invalid_iterator::create(201, "iterators are not compatible", nullptr));
  916. }
  917. // copy type from first iterator
  918. m_data.m_type = first.m_object->m_data.m_type;
  919. // check if iterator range is complete for primitive values
  920. switch (m_data.m_type)
  921. {
  922. case value_t::boolean:
  923. case value_t::number_float:
  924. case value_t::number_integer:
  925. case value_t::number_unsigned:
  926. case value_t::string:
  927. {
  928. if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin()
  929. || !last.m_it.primitive_iterator.is_end()))
  930. {
  931. JSON_THROW(invalid_iterator::create(204, "iterators out of range", first.m_object));
  932. }
  933. break;
  934. }
  935. case value_t::null:
  936. case value_t::object:
  937. case value_t::array:
  938. case value_t::binary:
  939. case value_t::discarded:
  940. default:
  941. break;
  942. }
  943. switch (m_data.m_type)
  944. {
  945. case value_t::number_integer:
  946. {
  947. m_data.m_value.number_integer = first.m_object->m_data.m_value.number_integer;
  948. break;
  949. }
  950. case value_t::number_unsigned:
  951. {
  952. m_data.m_value.number_unsigned = first.m_object->m_data.m_value.number_unsigned;
  953. break;
  954. }
  955. case value_t::number_float:
  956. {
  957. m_data.m_value.number_float = first.m_object->m_data.m_value.number_float;
  958. break;
  959. }
  960. case value_t::boolean:
  961. {
  962. m_data.m_value.boolean = first.m_object->m_data.m_value.boolean;
  963. break;
  964. }
  965. case value_t::string:
  966. {
  967. m_data.m_value = *first.m_object->m_data.m_value.string;
  968. break;
  969. }
  970. case value_t::object:
  971. {
  972. m_data.m_value.object = create<object_t>(first.m_it.object_iterator,
  973. last.m_it.object_iterator);
  974. break;
  975. }
  976. case value_t::array:
  977. {
  978. m_data.m_value.array = create<array_t>(first.m_it.array_iterator,
  979. last.m_it.array_iterator);
  980. break;
  981. }
  982. case value_t::binary:
  983. {
  984. m_data.m_value = *first.m_object->m_data.m_value.binary;
  985. break;
  986. }
  987. case value_t::null:
  988. case value_t::discarded:
  989. default:
  990. JSON_THROW(invalid_iterator::create(206, detail::concat("cannot construct with iterators from ", first.m_object->type_name()), first.m_object));
  991. }
  992. set_parents();
  993. assert_invariant();
  994. }
  995. ///////////////////////////////////////
  996. // other constructors and destructor //
  997. ///////////////////////////////////////
  998. template<typename JsonRef,
  999. detail::enable_if_t<detail::conjunction<detail::is_json_ref<JsonRef>,
  1000. std::is_same<typename JsonRef::value_type, basic_json>>::value, int> = 0 >
  1001. basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {}
  1002. /// @brief copy constructor
  1003. /// @sa https://json.nlohmann.me/api/basic_json/basic_json/
  1004. basic_json(const basic_json& other)
  1005. : json_base_class_t(other)
  1006. #if JSON_DIAGNOSTIC_POSITIONS
  1007. , start_position(other.start_position)
  1008. , end_position(other.end_position)
  1009. #endif
  1010. {
  1011. m_data.m_type = other.m_data.m_type;
  1012. // check of passed value is valid
  1013. other.assert_invariant();
  1014. switch (m_data.m_type)
  1015. {
  1016. case value_t::object:
  1017. {
  1018. m_data.m_value = *other.m_data.m_value.object;
  1019. break;
  1020. }
  1021. case value_t::array:
  1022. {
  1023. m_data.m_value = *other.m_data.m_value.array;
  1024. break;
  1025. }
  1026. case value_t::string:
  1027. {
  1028. m_data.m_value = *other.m_data.m_value.string;
  1029. break;
  1030. }
  1031. case value_t::boolean:
  1032. {
  1033. m_data.m_value = other.m_data.m_value.boolean;
  1034. break;
  1035. }
  1036. case value_t::number_integer:
  1037. {
  1038. m_data.m_value = other.m_data.m_value.number_integer;
  1039. break;
  1040. }
  1041. case value_t::number_unsigned:
  1042. {
  1043. m_data.m_value = other.m_data.m_value.number_unsigned;
  1044. break;
  1045. }
  1046. case value_t::number_float:
  1047. {
  1048. m_data.m_value = other.m_data.m_value.number_float;
  1049. break;
  1050. }
  1051. case value_t::binary:
  1052. {
  1053. m_data.m_value = *other.m_data.m_value.binary;
  1054. break;
  1055. }
  1056. case value_t::null:
  1057. case value_t::discarded:
  1058. default:
  1059. break;
  1060. }
  1061. set_parents();
  1062. assert_invariant();
  1063. }
  1064. /// @brief move constructor
  1065. /// @sa https://json.nlohmann.me/api/basic_json/basic_json/
  1066. basic_json(basic_json&& other) noexcept
  1067. : json_base_class_t(std::forward<json_base_class_t>(other)),
  1068. m_data(std::move(other.m_data)) // cppcheck-suppress[accessForwarded] TODO check
  1069. #if JSON_DIAGNOSTIC_POSITIONS
  1070. , start_position(other.start_position) // cppcheck-suppress[accessForwarded] TODO check
  1071. , end_position(other.end_position) // cppcheck-suppress[accessForwarded] TODO check
  1072. #endif
  1073. {
  1074. // check that passed value is valid
  1075. other.assert_invariant(false); // cppcheck-suppress[accessForwarded]
  1076. // invalidate payload
  1077. other.m_data.m_type = value_t::null;
  1078. other.m_data.m_value = {};
  1079. #if JSON_DIAGNOSTIC_POSITIONS
  1080. other.start_position = std::string::npos;
  1081. other.end_position = std::string::npos;
  1082. #endif
  1083. set_parents();
  1084. assert_invariant();
  1085. }
  1086. /// @brief copy assignment
  1087. /// @sa https://json.nlohmann.me/api/basic_json/operator=/
  1088. basic_json& operator=(basic_json other) noexcept (
  1089. std::is_nothrow_move_constructible<value_t>::value&&
  1090. std::is_nothrow_move_assignable<value_t>::value&&
  1091. std::is_nothrow_move_constructible<json_value>::value&&
  1092. std::is_nothrow_move_assignable<json_value>::value&&
  1093. std::is_nothrow_move_assignable<json_base_class_t>::value
  1094. )
  1095. {
  1096. // check that passed value is valid
  1097. other.assert_invariant();
  1098. using std::swap;
  1099. swap(m_data.m_type, other.m_data.m_type);
  1100. swap(m_data.m_value, other.m_data.m_value);
  1101. #if JSON_DIAGNOSTIC_POSITIONS
  1102. swap(start_position, other.start_position);
  1103. swap(end_position, other.end_position);
  1104. #endif
  1105. json_base_class_t::operator=(std::move(other));
  1106. set_parents();
  1107. assert_invariant();
  1108. return *this;
  1109. }
  1110. /// @brief destructor
  1111. /// @sa https://json.nlohmann.me/api/basic_json/~basic_json/
  1112. ~basic_json() noexcept
  1113. {
  1114. assert_invariant(false);
  1115. }
  1116. /// @}
  1117. public:
  1118. ///////////////////////
  1119. // object inspection //
  1120. ///////////////////////
  1121. /// @name object inspection
  1122. /// Functions to inspect the type of a JSON value.
  1123. /// @{
  1124. /// @brief serialization
  1125. /// @sa https://json.nlohmann.me/api/basic_json/dump/
  1126. string_t dump(const int indent = -1,
  1127. const char indent_char = ' ',
  1128. const bool ensure_ascii = false,
  1129. const error_handler_t error_handler = error_handler_t::strict) const
  1130. {
  1131. string_t result;
  1132. serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
  1133. if (indent >= 0)
  1134. {
  1135. s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
  1136. }
  1137. else
  1138. {
  1139. s.dump(*this, false, ensure_ascii, 0);
  1140. }
  1141. return result;
  1142. }
  1143. /// @brief return the type of the JSON value (explicit)
  1144. /// @sa https://json.nlohmann.me/api/basic_json/type/
  1145. constexpr value_t type() const noexcept
  1146. {
  1147. return m_data.m_type;
  1148. }
  1149. /// @brief return whether type is primitive
  1150. /// @sa https://json.nlohmann.me/api/basic_json/is_primitive/
  1151. constexpr bool is_primitive() const noexcept
  1152. {
  1153. return is_null() || is_string() || is_boolean() || is_number() || is_binary();
  1154. }
  1155. /// @brief return whether type is structured
  1156. /// @sa https://json.nlohmann.me/api/basic_json/is_structured/
  1157. constexpr bool is_structured() const noexcept
  1158. {
  1159. return is_array() || is_object();
  1160. }
  1161. /// @brief return whether value is null
  1162. /// @sa https://json.nlohmann.me/api/basic_json/is_null/
  1163. constexpr bool is_null() const noexcept
  1164. {
  1165. return m_data.m_type == value_t::null;
  1166. }
  1167. /// @brief return whether value is a boolean
  1168. /// @sa https://json.nlohmann.me/api/basic_json/is_boolean/
  1169. constexpr bool is_boolean() const noexcept
  1170. {
  1171. return m_data.m_type == value_t::boolean;
  1172. }
  1173. /// @brief return whether value is a number
  1174. /// @sa https://json.nlohmann.me/api/basic_json/is_number/
  1175. constexpr bool is_number() const noexcept
  1176. {
  1177. return is_number_integer() || is_number_float();
  1178. }
  1179. /// @brief return whether value is an integer number
  1180. /// @sa https://json.nlohmann.me/api/basic_json/is_number_integer/
  1181. constexpr bool is_number_integer() const noexcept
  1182. {
  1183. return m_data.m_type == value_t::number_integer || m_data.m_type == value_t::number_unsigned;
  1184. }
  1185. /// @brief return whether value is an unsigned integer number
  1186. /// @sa https://json.nlohmann.me/api/basic_json/is_number_unsigned/
  1187. constexpr bool is_number_unsigned() const noexcept
  1188. {
  1189. return m_data.m_type == value_t::number_unsigned;
  1190. }
  1191. /// @brief return whether value is a floating-point number
  1192. /// @sa https://json.nlohmann.me/api/basic_json/is_number_float/
  1193. constexpr bool is_number_float() const noexcept
  1194. {
  1195. return m_data.m_type == value_t::number_float;
  1196. }
  1197. /// @brief return whether value is an object
  1198. /// @sa https://json.nlohmann.me/api/basic_json/is_object/
  1199. constexpr bool is_object() const noexcept
  1200. {
  1201. return m_data.m_type == value_t::object;
  1202. }
  1203. /// @brief return whether value is an array
  1204. /// @sa https://json.nlohmann.me/api/basic_json/is_array/
  1205. constexpr bool is_array() const noexcept
  1206. {
  1207. return m_data.m_type == value_t::array;
  1208. }
  1209. /// @brief return whether value is a string
  1210. /// @sa https://json.nlohmann.me/api/basic_json/is_string/
  1211. constexpr bool is_string() const noexcept
  1212. {
  1213. return m_data.m_type == value_t::string;
  1214. }
  1215. /// @brief return whether value is a binary array
  1216. /// @sa https://json.nlohmann.me/api/basic_json/is_binary/
  1217. constexpr bool is_binary() const noexcept
  1218. {
  1219. return m_data.m_type == value_t::binary;
  1220. }
  1221. /// @brief return whether value is discarded
  1222. /// @sa https://json.nlohmann.me/api/basic_json/is_discarded/
  1223. constexpr bool is_discarded() const noexcept
  1224. {
  1225. return m_data.m_type == value_t::discarded;
  1226. }
  1227. /// @brief return the type of the JSON value (implicit)
  1228. /// @sa https://json.nlohmann.me/api/basic_json/operator_value_t/
  1229. constexpr operator value_t() const noexcept
  1230. {
  1231. return m_data.m_type;
  1232. }
  1233. /// @}
  1234. private:
  1235. //////////////////
  1236. // value access //
  1237. //////////////////
  1238. /// get a boolean (explicit)
  1239. boolean_t get_impl(boolean_t* /*unused*/) const
  1240. {
  1241. if (JSON_HEDLEY_LIKELY(is_boolean()))
  1242. {
  1243. return m_data.m_value.boolean;
  1244. }
  1245. JSON_THROW(type_error::create(302, detail::concat("type must be boolean, but is ", type_name()), this));
  1246. }
  1247. /// get a pointer to the value (object)
  1248. object_t* get_impl_ptr(object_t* /*unused*/) noexcept
  1249. {
  1250. return is_object() ? m_data.m_value.object : nullptr;
  1251. }
  1252. /// get a pointer to the value (object)
  1253. constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
  1254. {
  1255. return is_object() ? m_data.m_value.object : nullptr;
  1256. }
  1257. /// get a pointer to the value (array)
  1258. array_t* get_impl_ptr(array_t* /*unused*/) noexcept
  1259. {
  1260. return is_array() ? m_data.m_value.array : nullptr;
  1261. }
  1262. /// get a pointer to the value (array)
  1263. constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
  1264. {
  1265. return is_array() ? m_data.m_value.array : nullptr;
  1266. }
  1267. /// get a pointer to the value (string)
  1268. string_t* get_impl_ptr(string_t* /*unused*/) noexcept
  1269. {
  1270. return is_string() ? m_data.m_value.string : nullptr;
  1271. }
  1272. /// get a pointer to the value (string)
  1273. constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
  1274. {
  1275. return is_string() ? m_data.m_value.string : nullptr;
  1276. }
  1277. /// get a pointer to the value (boolean)
  1278. boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
  1279. {
  1280. return is_boolean() ? &m_data.m_value.boolean : nullptr;
  1281. }
  1282. /// get a pointer to the value (boolean)
  1283. constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
  1284. {
  1285. return is_boolean() ? &m_data.m_value.boolean : nullptr;
  1286. }
  1287. /// get a pointer to the value (integer number)
  1288. number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
  1289. {
  1290. return m_data.m_type == value_t::number_integer ? &m_data.m_value.number_integer : nullptr;
  1291. }
  1292. /// get a pointer to the value (integer number)
  1293. constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
  1294. {
  1295. return m_data.m_type == value_t::number_integer ? &m_data.m_value.number_integer : nullptr;
  1296. }
  1297. /// get a pointer to the value (unsigned number)
  1298. number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept
  1299. {
  1300. return is_number_unsigned() ? &m_data.m_value.number_unsigned : nullptr;
  1301. }
  1302. /// get a pointer to the value (unsigned number)
  1303. constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
  1304. {
  1305. return is_number_unsigned() ? &m_data.m_value.number_unsigned : nullptr;
  1306. }
  1307. /// get a pointer to the value (floating-point number)
  1308. number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept
  1309. {
  1310. return is_number_float() ? &m_data.m_value.number_float : nullptr;
  1311. }
  1312. /// get a pointer to the value (floating-point number)
  1313. constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
  1314. {
  1315. return is_number_float() ? &m_data.m_value.number_float : nullptr;
  1316. }
  1317. /// get a pointer to the value (binary)
  1318. binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept
  1319. {
  1320. return is_binary() ? m_data.m_value.binary : nullptr;
  1321. }
  1322. /// get a pointer to the value (binary)
  1323. constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept
  1324. {
  1325. return is_binary() ? m_data.m_value.binary : nullptr;
  1326. }
  1327. /*!
  1328. @brief helper function to implement get_ref()
  1329. This function helps to implement get_ref() without code duplication for
  1330. const and non-const overloads
  1331. @tparam ThisType will be deduced as `basic_json` or `const basic_json`
  1332. @throw type_error.303 if ReferenceType does not match underlying value
  1333. type of the current JSON
  1334. */
  1335. template<typename ReferenceType, typename ThisType>
  1336. static ReferenceType get_ref_impl(ThisType& obj)
  1337. {
  1338. // delegate the call to get_ptr<>()
  1339. auto* ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
  1340. if (JSON_HEDLEY_LIKELY(ptr != nullptr))
  1341. {
  1342. return *ptr;
  1343. }
  1344. JSON_THROW(type_error::create(303, detail::concat("incompatible ReferenceType for get_ref, actual type is ", obj.type_name()), &obj));
  1345. }
  1346. public:
  1347. /// @name value access
  1348. /// Direct access to the stored value of a JSON value.
  1349. /// @{
  1350. /// @brief get a pointer value (implicit)
  1351. /// @sa https://json.nlohmann.me/api/basic_json/get_ptr/
  1352. template<typename PointerType, typename std::enable_if<
  1353. std::is_pointer<PointerType>::value, int>::type = 0>
  1354. auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
  1355. {
  1356. // delegate the call to get_impl_ptr<>()
  1357. return get_impl_ptr(static_cast<PointerType>(nullptr));
  1358. }
  1359. /// @brief get a pointer value (implicit)
  1360. /// @sa https://json.nlohmann.me/api/basic_json/get_ptr/
  1361. template < typename PointerType, typename std::enable_if <
  1362. std::is_pointer<PointerType>::value&&
  1363. std::is_const<typename std::remove_pointer<PointerType>::type>::value, int >::type = 0 >
  1364. constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
  1365. {
  1366. // delegate the call to get_impl_ptr<>() const
  1367. return get_impl_ptr(static_cast<PointerType>(nullptr));
  1368. }
  1369. private:
  1370. /*!
  1371. @brief get a value (explicit)
  1372. Explicit type conversion between the JSON value and a compatible value
  1373. which is [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)
  1374. and [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).
  1375. The value is converted by calling the @ref json_serializer<ValueType>
  1376. `from_json()` method.
  1377. The function is equivalent to executing
  1378. @code {.cpp}
  1379. ValueType ret;
  1380. JSONSerializer<ValueType>::from_json(*this, ret);
  1381. return ret;
  1382. @endcode
  1383. This overloads is chosen if:
  1384. - @a ValueType is not @ref basic_json,
  1385. - @ref json_serializer<ValueType> has a `from_json()` method of the form
  1386. `void from_json(const basic_json&, ValueType&)`, and
  1387. - @ref json_serializer<ValueType> does not have a `from_json()` method of
  1388. the form `ValueType from_json(const basic_json&)`
  1389. @tparam ValueType the returned value type
  1390. @return copy of the JSON value, converted to @a ValueType
  1391. @throw what @ref json_serializer<ValueType> `from_json()` method throws
  1392. @liveexample{The example below shows several conversions from JSON values
  1393. to other types. There a few things to note: (1) Floating-point numbers can
  1394. be converted to integers\, (2) A JSON array can be converted to a standard
  1395. `std::vector<short>`\, (3) A JSON object can be converted to C++
  1396. associative containers such as `std::unordered_map<std::string\,
  1397. json>`.,get__ValueType_const}
  1398. @since version 2.1.0
  1399. */
  1400. template < typename ValueType,
  1401. detail::enable_if_t <
  1402. detail::is_default_constructible<ValueType>::value&&
  1403. detail::has_from_json<basic_json_t, ValueType>::value,
  1404. int > = 0 >
  1405. ValueType get_impl(detail::priority_tag<0> /*unused*/) const noexcept(noexcept(
  1406. JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
  1407. {
  1408. auto ret = ValueType();
  1409. JSONSerializer<ValueType>::from_json(*this, ret);
  1410. return ret;
  1411. }
  1412. /*!
  1413. @brief get a value (explicit); special case
  1414. Explicit type conversion between the JSON value and a compatible value
  1415. which is **not** [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)
  1416. and **not** [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).
  1417. The value is converted by calling the @ref json_serializer<ValueType>
  1418. `from_json()` method.
  1419. The function is equivalent to executing
  1420. @code {.cpp}
  1421. return JSONSerializer<ValueType>::from_json(*this);
  1422. @endcode
  1423. This overloads is chosen if:
  1424. - @a ValueType is not @ref basic_json and
  1425. - @ref json_serializer<ValueType> has a `from_json()` method of the form
  1426. `ValueType from_json(const basic_json&)`
  1427. @note If @ref json_serializer<ValueType> has both overloads of
  1428. `from_json()`, this one is chosen.
  1429. @tparam ValueType the returned value type
  1430. @return copy of the JSON value, converted to @a ValueType
  1431. @throw what @ref json_serializer<ValueType> `from_json()` method throws
  1432. @since version 2.1.0
  1433. */
  1434. template < typename ValueType,
  1435. detail::enable_if_t <
  1436. detail::has_non_default_from_json<basic_json_t, ValueType>::value,
  1437. int > = 0 >
  1438. ValueType get_impl(detail::priority_tag<1> /*unused*/) const noexcept(noexcept(
  1439. JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
  1440. {
  1441. return JSONSerializer<ValueType>::from_json(*this);
  1442. }
  1443. /*!
  1444. @brief get special-case overload
  1445. This overloads converts the current @ref basic_json in a different
  1446. @ref basic_json type
  1447. @tparam BasicJsonType == @ref basic_json
  1448. @return a copy of *this, converted into @a BasicJsonType
  1449. @complexity Depending on the implementation of the called `from_json()`
  1450. method.
  1451. @since version 3.2.0
  1452. */
  1453. template < typename BasicJsonType,
  1454. detail::enable_if_t <
  1455. detail::is_basic_json<BasicJsonType>::value,
  1456. int > = 0 >
  1457. BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const
  1458. {
  1459. return *this;
  1460. }
  1461. /*!
  1462. @brief get special-case overload
  1463. This overloads avoids a lot of template boilerplate, it can be seen as the
  1464. identity method
  1465. @tparam BasicJsonType == @ref basic_json
  1466. @return a copy of *this
  1467. @complexity Constant.
  1468. @since version 2.1.0
  1469. */
  1470. template<typename BasicJsonType,
  1471. detail::enable_if_t<
  1472. std::is_same<BasicJsonType, basic_json_t>::value,
  1473. int> = 0>
  1474. basic_json get_impl(detail::priority_tag<3> /*unused*/) const
  1475. {
  1476. return *this;
  1477. }
  1478. /*!
  1479. @brief get a pointer value (explicit)
  1480. @copydoc get()
  1481. */
  1482. template<typename PointerType,
  1483. detail::enable_if_t<
  1484. std::is_pointer<PointerType>::value,
  1485. int> = 0>
  1486. constexpr auto get_impl(detail::priority_tag<4> /*unused*/) const noexcept
  1487. -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
  1488. {
  1489. // delegate the call to get_ptr
  1490. return get_ptr<PointerType>();
  1491. }
  1492. public:
  1493. /*!
  1494. @brief get a (pointer) value (explicit)
  1495. Performs explicit type conversion between the JSON value and a compatible value if required.
  1496. - If the requested type is a pointer to the internally stored JSON value that pointer is returned.
  1497. No copies are made.
  1498. - If the requested type is the current @ref basic_json, or a different @ref basic_json convertible
  1499. from the current @ref basic_json.
  1500. - Otherwise the value is converted by calling the @ref json_serializer<ValueType> `from_json()`
  1501. method.
  1502. @tparam ValueTypeCV the provided value type
  1503. @tparam ValueType the returned value type
  1504. @return copy of the JSON value, converted to @tparam ValueType if necessary
  1505. @throw what @ref json_serializer<ValueType> `from_json()` method throws if conversion is required
  1506. @since version 2.1.0
  1507. */
  1508. template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>>
  1509. #if defined(JSON_HAS_CPP_14)
  1510. constexpr
  1511. #endif
  1512. auto get() const noexcept(
  1513. noexcept(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {})))
  1514. -> decltype(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {}))
  1515. {
  1516. // we cannot static_assert on ValueTypeCV being non-const, because
  1517. // there is support for get<const basic_json_t>(), which is why we
  1518. // still need the uncvref
  1519. static_assert(!std::is_reference<ValueTypeCV>::value,
  1520. "get() cannot be used with reference types, you might want to use get_ref()");
  1521. return get_impl<ValueType>(detail::priority_tag<4> {});
  1522. }
  1523. /*!
  1524. @brief get a pointer value (explicit)
  1525. Explicit pointer access to the internally stored JSON value. No copies are
  1526. made.
  1527. @warning The pointer becomes invalid if the underlying JSON object
  1528. changes.
  1529. @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
  1530. object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
  1531. @ref number_unsigned_t, or @ref number_float_t.
  1532. @return pointer to the internally stored JSON value if the requested
  1533. pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
  1534. @complexity Constant.
  1535. @liveexample{The example below shows how pointers to internal values of a
  1536. JSON value can be requested. Note that no type conversions are made and a
  1537. `nullptr` is returned if the value and the requested pointer type does not
  1538. match.,get__PointerType}
  1539. @sa see @ref get_ptr() for explicit pointer-member access
  1540. @since version 1.0.0
  1541. */
  1542. template<typename PointerType, typename std::enable_if<
  1543. std::is_pointer<PointerType>::value, int>::type = 0>
  1544. auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
  1545. {
  1546. // delegate the call to get_ptr
  1547. return get_ptr<PointerType>();
  1548. }
  1549. /// @brief get a value (explicit)
  1550. /// @sa https://json.nlohmann.me/api/basic_json/get_to/
  1551. template < typename ValueType,
  1552. detail::enable_if_t <
  1553. !detail::is_basic_json<ValueType>::value&&
  1554. detail::has_from_json<basic_json_t, ValueType>::value,
  1555. int > = 0 >
  1556. ValueType & get_to(ValueType& v) const noexcept(noexcept(
  1557. JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
  1558. {
  1559. JSONSerializer<ValueType>::from_json(*this, v);
  1560. return v;
  1561. }
  1562. // specialization to allow calling get_to with a basic_json value
  1563. // see https://github.com/nlohmann/json/issues/2175
  1564. template<typename ValueType,
  1565. detail::enable_if_t <
  1566. detail::is_basic_json<ValueType>::value,
  1567. int> = 0>
  1568. ValueType & get_to(ValueType& v) const
  1569. {
  1570. v = *this;
  1571. return v;
  1572. }
  1573. template <
  1574. typename T, std::size_t N,
  1575. typename Array = T (&)[N], // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
  1576. detail::enable_if_t <
  1577. detail::has_from_json<basic_json_t, Array>::value, int > = 0 >
  1578. Array get_to(T (&v)[N]) const // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
  1579. noexcept(noexcept(JSONSerializer<Array>::from_json(
  1580. std::declval<const basic_json_t&>(), v)))
  1581. {
  1582. JSONSerializer<Array>::from_json(*this, v);
  1583. return v;
  1584. }
  1585. /// @brief get a reference value (implicit)
  1586. /// @sa https://json.nlohmann.me/api/basic_json/get_ref/
  1587. template<typename ReferenceType, typename std::enable_if<
  1588. std::is_reference<ReferenceType>::value, int>::type = 0>
  1589. ReferenceType get_ref()
  1590. {
  1591. // delegate call to get_ref_impl
  1592. return get_ref_impl<ReferenceType>(*this);
  1593. }
  1594. /// @brief get a reference value (implicit)
  1595. /// @sa https://json.nlohmann.me/api/basic_json/get_ref/
  1596. template < typename ReferenceType, typename std::enable_if <
  1597. std::is_reference<ReferenceType>::value&&
  1598. std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int >::type = 0 >
  1599. ReferenceType get_ref() const
  1600. {
  1601. // delegate call to get_ref_impl
  1602. return get_ref_impl<ReferenceType>(*this);
  1603. }
  1604. /*!
  1605. @brief get a value (implicit)
  1606. Implicit type conversion between the JSON value and a compatible value.
  1607. The call is realized by calling @ref get() const.
  1608. @tparam ValueType non-pointer type compatible to the JSON value, for
  1609. instance `int` for JSON integer numbers, `bool` for JSON booleans, or
  1610. `std::vector` types for JSON arrays. The character type of @ref string_t
  1611. as well as an initializer list of this type is excluded to avoid
  1612. ambiguities as these types implicitly convert to `std::string`.
  1613. @return copy of the JSON value, converted to type @a ValueType
  1614. @throw type_error.302 in case passed type @a ValueType is incompatible
  1615. to the JSON value type (e.g., the JSON value is of type boolean, but a
  1616. string is requested); see example below
  1617. @complexity Linear in the size of the JSON value.
  1618. @liveexample{The example below shows several conversions from JSON values
  1619. to other types. There a few things to note: (1) Floating-point numbers can
  1620. be converted to integers\, (2) A JSON array can be converted to a standard
  1621. `std::vector<short>`\, (3) A JSON object can be converted to C++
  1622. associative containers such as `std::unordered_map<std::string\,
  1623. json>`.,operator__ValueType}
  1624. @since version 1.0.0
  1625. */
  1626. template < typename ValueType, typename std::enable_if <
  1627. detail::conjunction <
  1628. detail::negation<std::is_pointer<ValueType>>,
  1629. detail::negation<std::is_same<ValueType, std::nullptr_t>>,
  1630. detail::negation<std::is_same<ValueType, detail::json_ref<basic_json>>>,
  1631. detail::negation<std::is_same<ValueType, typename string_t::value_type>>,
  1632. detail::negation<detail::is_basic_json<ValueType>>,
  1633. detail::negation<std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>>,
  1634. #if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914))
  1635. detail::negation<std::is_same<ValueType, std::string_view>>,
  1636. #endif
  1637. #if defined(JSON_HAS_CPP_17) && JSON_HAS_STATIC_RTTI
  1638. detail::negation<std::is_same<ValueType, std::any>>,
  1639. #endif
  1640. detail::is_detected_lazy<detail::get_template_function, const basic_json_t&, ValueType>
  1641. >::value, int >::type = 0 >
  1642. JSON_EXPLICIT operator ValueType() const
  1643. {
  1644. // delegate the call to get<>() const
  1645. return get<ValueType>();
  1646. }
  1647. /// @brief get a binary value
  1648. /// @sa https://json.nlohmann.me/api/basic_json/get_binary/
  1649. binary_t& get_binary()
  1650. {
  1651. if (!is_binary())
  1652. {
  1653. JSON_THROW(type_error::create(302, detail::concat("type must be binary, but is ", type_name()), this));
  1654. }
  1655. return *get_ptr<binary_t*>();
  1656. }
  1657. /// @brief get a binary value
  1658. /// @sa https://json.nlohmann.me/api/basic_json/get_binary/
  1659. const binary_t& get_binary() const
  1660. {
  1661. if (!is_binary())
  1662. {
  1663. JSON_THROW(type_error::create(302, detail::concat("type must be binary, but is ", type_name()), this));
  1664. }
  1665. return *get_ptr<const binary_t*>();
  1666. }
  1667. /// @}
  1668. ////////////////////
  1669. // element access //
  1670. ////////////////////
  1671. /// @name element access
  1672. /// Access to the JSON value.
  1673. /// @{
  1674. /// @brief access specified array element with bounds checking
  1675. /// @sa https://json.nlohmann.me/api/basic_json/at/
  1676. reference at(size_type idx)
  1677. {
  1678. // at only works for arrays
  1679. if (JSON_HEDLEY_LIKELY(is_array()))
  1680. {
  1681. JSON_TRY
  1682. {
  1683. return set_parent(m_data.m_value.array->at(idx));
  1684. }
  1685. JSON_CATCH (std::out_of_range&)
  1686. {
  1687. // create better exception explanation
  1688. JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
  1689. } // cppcheck-suppress[missingReturn]
  1690. }
  1691. else
  1692. {
  1693. JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
  1694. }
  1695. }
  1696. /// @brief access specified array element with bounds checking
  1697. /// @sa https://json.nlohmann.me/api/basic_json/at/
  1698. const_reference at(size_type idx) const
  1699. {
  1700. // at only works for arrays
  1701. if (JSON_HEDLEY_LIKELY(is_array()))
  1702. {
  1703. JSON_TRY
  1704. {
  1705. return m_data.m_value.array->at(idx);
  1706. }
  1707. JSON_CATCH (std::out_of_range&)
  1708. {
  1709. // create better exception explanation
  1710. JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
  1711. } // cppcheck-suppress[missingReturn]
  1712. }
  1713. else
  1714. {
  1715. JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
  1716. }
  1717. }
  1718. /// @brief access specified object element with bounds checking
  1719. /// @sa https://json.nlohmann.me/api/basic_json/at/
  1720. reference at(const typename object_t::key_type& key)
  1721. {
  1722. // at only works for objects
  1723. if (JSON_HEDLEY_UNLIKELY(!is_object()))
  1724. {
  1725. JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
  1726. }
  1727. auto it = m_data.m_value.object->find(key);
  1728. if (it == m_data.m_value.object->end())
  1729. {
  1730. JSON_THROW(out_of_range::create(403, detail::concat("key '", key, "' not found"), this));
  1731. }
  1732. return set_parent(it->second);
  1733. }
  1734. /// @brief access specified object element with bounds checking
  1735. /// @sa https://json.nlohmann.me/api/basic_json/at/
  1736. template<class KeyType, detail::enable_if_t<
  1737. detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value, int> = 0>
  1738. reference at(KeyType && key)
  1739. {
  1740. // at only works for objects
  1741. if (JSON_HEDLEY_UNLIKELY(!is_object()))
  1742. {
  1743. JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
  1744. }
  1745. auto it = m_data.m_value.object->find(std::forward<KeyType>(key));
  1746. if (it == m_data.m_value.object->end())
  1747. {
  1748. JSON_THROW(out_of_range::create(403, detail::concat("key '", string_t(std::forward<KeyType>(key)), "' not found"), this));
  1749. }
  1750. return set_parent(it->second);
  1751. }
  1752. /// @brief access specified object element with bounds checking
  1753. /// @sa https://json.nlohmann.me/api/basic_json/at/
  1754. const_reference at(const typename object_t::key_type& key) const
  1755. {
  1756. // at only works for objects
  1757. if (JSON_HEDLEY_UNLIKELY(!is_object()))
  1758. {
  1759. JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
  1760. }
  1761. auto it = m_data.m_value.object->find(key);
  1762. if (it == m_data.m_value.object->end())
  1763. {
  1764. JSON_THROW(out_of_range::create(403, detail::concat("key '", key, "' not found"), this));
  1765. }
  1766. return it->second;
  1767. }
  1768. /// @brief access specified object element with bounds checking
  1769. /// @sa https://json.nlohmann.me/api/basic_json/at/
  1770. template<class KeyType, detail::enable_if_t<
  1771. detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value, int> = 0>
  1772. const_reference at(KeyType && key) const
  1773. {
  1774. // at only works for objects
  1775. if (JSON_HEDLEY_UNLIKELY(!is_object()))
  1776. {
  1777. JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
  1778. }
  1779. auto it = m_data.m_value.object->find(std::forward<KeyType>(key));
  1780. if (it == m_data.m_value.object->end())
  1781. {
  1782. JSON_THROW(out_of_range::create(403, detail::concat("key '", string_t(std::forward<KeyType>(key)), "' not found"), this));
  1783. }
  1784. return it->second;
  1785. }
  1786. /// @brief access specified array element
  1787. /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/
  1788. reference operator[](size_type idx)
  1789. {
  1790. // implicitly convert null value to an empty array
  1791. if (is_null())
  1792. {
  1793. m_data.m_type = value_t::array;
  1794. m_data.m_value.array = create<array_t>();
  1795. assert_invariant();
  1796. }
  1797. // operator[] only works for arrays
  1798. if (JSON_HEDLEY_LIKELY(is_array()))
  1799. {
  1800. // fill up array with null values if given idx is outside range
  1801. if (idx >= m_data.m_value.array->size())
  1802. {
  1803. #if JSON_DIAGNOSTICS
  1804. // remember array size & capacity before resizing
  1805. const auto old_size = m_data.m_value.array->size();
  1806. const auto old_capacity = m_data.m_value.array->capacity();
  1807. #endif
  1808. m_data.m_value.array->resize(idx + 1);
  1809. #if JSON_DIAGNOSTICS
  1810. if (JSON_HEDLEY_UNLIKELY(m_data.m_value.array->capacity() != old_capacity))
  1811. {
  1812. // capacity has changed: update all parents
  1813. set_parents();
  1814. }
  1815. else
  1816. {
  1817. // set parent for values added above
  1818. set_parents(begin() + static_cast<typename iterator::difference_type>(old_size), static_cast<typename iterator::difference_type>(idx + 1 - old_size));
  1819. }
  1820. #endif
  1821. assert_invariant();
  1822. }
  1823. return m_data.m_value.array->operator[](idx);
  1824. }
  1825. JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a numeric argument with ", type_name()), this));
  1826. }
  1827. /// @brief access specified array element
  1828. /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/
  1829. const_reference operator[](size_type idx) const
  1830. {
  1831. // const operator[] only works for arrays
  1832. if (JSON_HEDLEY_LIKELY(is_array()))
  1833. {
  1834. return m_data.m_value.array->operator[](idx);
  1835. }
  1836. JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a numeric argument with ", type_name()), this));
  1837. }
  1838. /// @brief access specified object element
  1839. /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/
  1840. reference operator[](typename object_t::key_type key) // NOLINT(performance-unnecessary-value-param)
  1841. {
  1842. // implicitly convert null value to an empty object
  1843. if (is_null())
  1844. {
  1845. m_data.m_type = value_t::object;
  1846. m_data.m_value.object = create<object_t>();
  1847. assert_invariant();
  1848. }
  1849. // operator[] only works for objects
  1850. if (JSON_HEDLEY_LIKELY(is_object()))
  1851. {
  1852. auto result = m_data.m_value.object->emplace(std::move(key), nullptr);
  1853. return set_parent(result.first->second);
  1854. }
  1855. JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
  1856. }
  1857. /// @brief access specified object element
  1858. /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/
  1859. const_reference operator[](const typename object_t::key_type& key) const
  1860. {
  1861. // const operator[] only works for objects
  1862. if (JSON_HEDLEY_LIKELY(is_object()))
  1863. {
  1864. auto it = m_data.m_value.object->find(key);
  1865. JSON_ASSERT(it != m_data.m_value.object->end());
  1866. return it->second;
  1867. }
  1868. JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
  1869. }
  1870. // these two functions resolve a (const) char * ambiguity affecting Clang and MSVC
  1871. // (they seemingly cannot be constrained to resolve the ambiguity)
  1872. template<typename T>
  1873. reference operator[](T* key)
  1874. {
  1875. return operator[](typename object_t::key_type(key));
  1876. }
  1877. template<typename T>
  1878. const_reference operator[](T* key) const
  1879. {
  1880. return operator[](typename object_t::key_type(key));
  1881. }
  1882. /// @brief access specified object element
  1883. /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/
  1884. template<class KeyType, detail::enable_if_t<
  1885. detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value, int > = 0 >
  1886. reference operator[](KeyType && key)
  1887. {
  1888. // implicitly convert null value to an empty object
  1889. if (is_null())
  1890. {
  1891. m_data.m_type = value_t::object;
  1892. m_data.m_value.object = create<object_t>();
  1893. assert_invariant();
  1894. }
  1895. // operator[] only works for objects
  1896. if (JSON_HEDLEY_LIKELY(is_object()))
  1897. {
  1898. auto result = m_data.m_value.object->emplace(std::forward<KeyType>(key), nullptr);
  1899. return set_parent(result.first->second);
  1900. }
  1901. JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
  1902. }
  1903. /// @brief access specified object element
  1904. /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/
  1905. template<class KeyType, detail::enable_if_t<
  1906. detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value, int > = 0 >
  1907. const_reference operator[](KeyType && key) const
  1908. {
  1909. // const operator[] only works for objects
  1910. if (JSON_HEDLEY_LIKELY(is_object()))
  1911. {
  1912. auto it = m_data.m_value.object->find(std::forward<KeyType>(key));
  1913. JSON_ASSERT(it != m_data.m_value.object->end());
  1914. return it->second;
  1915. }
  1916. JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
  1917. }
  1918. private:
  1919. template<typename KeyType>
  1920. using is_comparable_with_object_key = detail::is_comparable <
  1921. object_comparator_t, const typename object_t::key_type&, KeyType >;
  1922. template<typename ValueType>
  1923. using value_return_type = std::conditional <
  1924. detail::is_c_string_uncvref<ValueType>::value,
  1925. string_t, typename std::decay<ValueType>::type >;
  1926. public:
  1927. /// @brief access specified object element with default value
  1928. /// @sa https://json.nlohmann.me/api/basic_json/value/
  1929. template < class ValueType, detail::enable_if_t <
  1930. !detail::is_transparent<object_comparator_t>::value
  1931. && detail::is_getable<basic_json_t, ValueType>::value
  1932. && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
  1933. ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
  1934. {
  1935. // value only works for objects
  1936. if (JSON_HEDLEY_LIKELY(is_object()))
  1937. {
  1938. // if key is found, return value and given default value otherwise
  1939. const auto it = find(key);
  1940. if (it != end())
  1941. {
  1942. return it->template get<ValueType>();
  1943. }
  1944. return default_value;
  1945. }
  1946. JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
  1947. }
  1948. /// @brief access specified object element with default value
  1949. /// @sa https://json.nlohmann.me/api/basic_json/value/
  1950. template < class ValueType, class ReturnType = typename value_return_type<ValueType>::type,
  1951. detail::enable_if_t <
  1952. !detail::is_transparent<object_comparator_t>::value
  1953. && detail::is_getable<basic_json_t, ReturnType>::value
  1954. && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
  1955. ReturnType value(const typename object_t::key_type& key, ValueType && default_value) const
  1956. {
  1957. // value only works for objects
  1958. if (JSON_HEDLEY_LIKELY(is_object()))
  1959. {
  1960. // if key is found, return value and given default value otherwise
  1961. const auto it = find(key);
  1962. if (it != end())
  1963. {
  1964. return it->template get<ReturnType>();
  1965. }
  1966. return std::forward<ValueType>(default_value);
  1967. }
  1968. JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
  1969. }
  1970. /// @brief access specified object element with default value
  1971. /// @sa https://json.nlohmann.me/api/basic_json/value/
  1972. template < class ValueType, class KeyType, detail::enable_if_t <
  1973. detail::is_transparent<object_comparator_t>::value
  1974. && !detail::is_json_pointer<KeyType>::value
  1975. && is_comparable_with_object_key<KeyType>::value
  1976. && detail::is_getable<basic_json_t, ValueType>::value
  1977. && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
  1978. ValueType value(KeyType && key, const ValueType& default_value) const
  1979. {
  1980. // value only works for objects
  1981. if (JSON_HEDLEY_LIKELY(is_object()))
  1982. {
  1983. // if key is found, return value and given default value otherwise
  1984. const auto it = find(std::forward<KeyType>(key));
  1985. if (it != end())
  1986. {
  1987. return it->template get<ValueType>();
  1988. }
  1989. return default_value;
  1990. }
  1991. JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
  1992. }
  1993. /// @brief access specified object element via JSON Pointer with default value
  1994. /// @sa https://json.nlohmann.me/api/basic_json/value/
  1995. template < class ValueType, class KeyType, class ReturnType = typename value_return_type<ValueType>::type,
  1996. detail::enable_if_t <
  1997. detail::is_transparent<object_comparator_t>::value
  1998. && !detail::is_json_pointer<KeyType>::value
  1999. && is_comparable_with_object_key<KeyType>::value
  2000. && detail::is_getable<basic_json_t, ReturnType>::value
  2001. && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
  2002. ReturnType value(KeyType && key, ValueType && default_value) const
  2003. {
  2004. // value only works for objects
  2005. if (JSON_HEDLEY_LIKELY(is_object()))
  2006. {
  2007. // if key is found, return value and given default value otherwise
  2008. const auto it = find(std::forward<KeyType>(key));
  2009. if (it != end())
  2010. {
  2011. return it->template get<ReturnType>();
  2012. }
  2013. return std::forward<ValueType>(default_value);
  2014. }
  2015. JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
  2016. }
  2017. /// @brief access specified object element via JSON Pointer with default value
  2018. /// @sa https://json.nlohmann.me/api/basic_json/value/
  2019. template < class ValueType, detail::enable_if_t <
  2020. detail::is_getable<basic_json_t, ValueType>::value
  2021. && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
  2022. ValueType value(const json_pointer& ptr, const ValueType& default_value) const
  2023. {
  2024. // value only works for objects
  2025. if (JSON_HEDLEY_LIKELY(is_object()))
  2026. {
  2027. // if pointer resolves a value, return it or use default value
  2028. JSON_TRY
  2029. {
  2030. return ptr.get_checked(this).template get<ValueType>();
  2031. }
  2032. JSON_INTERNAL_CATCH (out_of_range&)
  2033. {
  2034. return default_value;
  2035. }
  2036. }
  2037. JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
  2038. }
  2039. /// @brief access specified object element via JSON Pointer with default value
  2040. /// @sa https://json.nlohmann.me/api/basic_json/value/
  2041. template < class ValueType, class ReturnType = typename value_return_type<ValueType>::type,
  2042. detail::enable_if_t <
  2043. detail::is_getable<basic_json_t, ReturnType>::value
  2044. && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
  2045. ReturnType value(const json_pointer& ptr, ValueType && default_value) const
  2046. {
  2047. // value only works for objects
  2048. if (JSON_HEDLEY_LIKELY(is_object()))
  2049. {
  2050. // if pointer resolves a value, return it or use default value
  2051. JSON_TRY
  2052. {
  2053. return ptr.get_checked(this).template get<ReturnType>();
  2054. }
  2055. JSON_INTERNAL_CATCH (out_of_range&)
  2056. {
  2057. return std::forward<ValueType>(default_value);
  2058. }
  2059. }
  2060. JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
  2061. }
  2062. template < class ValueType, class BasicJsonType, detail::enable_if_t <
  2063. detail::is_basic_json<BasicJsonType>::value
  2064. && detail::is_getable<basic_json_t, ValueType>::value
  2065. && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
  2066. JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
  2067. ValueType value(const ::nlohmann::json_pointer<BasicJsonType>& ptr, const ValueType& default_value) const
  2068. {
  2069. return value(ptr.convert(), default_value);
  2070. }
  2071. template < class ValueType, class BasicJsonType, class ReturnType = typename value_return_type<ValueType>::type,
  2072. detail::enable_if_t <
  2073. detail::is_basic_json<BasicJsonType>::value
  2074. && detail::is_getable<basic_json_t, ReturnType>::value
  2075. && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
  2076. JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
  2077. ReturnType value(const ::nlohmann::json_pointer<BasicJsonType>& ptr, ValueType && default_value) const
  2078. {
  2079. return value(ptr.convert(), std::forward<ValueType>(default_value));
  2080. }
  2081. /// @brief access the first element
  2082. /// @sa https://json.nlohmann.me/api/basic_json/front/
  2083. reference front()
  2084. {
  2085. return *begin();
  2086. }
  2087. /// @brief access the first element
  2088. /// @sa https://json.nlohmann.me/api/basic_json/front/
  2089. const_reference front() const
  2090. {
  2091. return *cbegin();
  2092. }
  2093. /// @brief access the last element
  2094. /// @sa https://json.nlohmann.me/api/basic_json/back/
  2095. reference back()
  2096. {
  2097. auto tmp = end();
  2098. --tmp;
  2099. return *tmp;
  2100. }
  2101. /// @brief access the last element
  2102. /// @sa https://json.nlohmann.me/api/basic_json/back/
  2103. const_reference back() const
  2104. {
  2105. auto tmp = cend();
  2106. --tmp;
  2107. return *tmp;
  2108. }
  2109. /// @brief remove element given an iterator
  2110. /// @sa https://json.nlohmann.me/api/basic_json/erase/
  2111. template < class IteratorType, detail::enable_if_t <
  2112. std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
  2113. std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int > = 0 >
  2114. IteratorType erase(IteratorType pos) // NOLINT(performance-unnecessary-value-param)
  2115. {
  2116. // make sure iterator fits the current value
  2117. if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))
  2118. {
  2119. JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
  2120. }
  2121. IteratorType result = end();
  2122. switch (m_data.m_type)
  2123. {
  2124. case value_t::boolean:
  2125. case value_t::number_float:
  2126. case value_t::number_integer:
  2127. case value_t::number_unsigned:
  2128. case value_t::string:
  2129. case value_t::binary:
  2130. {
  2131. if (JSON_HEDLEY_UNLIKELY(!pos.m_it.primitive_iterator.is_begin()))
  2132. {
  2133. JSON_THROW(invalid_iterator::create(205, "iterator out of range", this));
  2134. }
  2135. if (is_string())
  2136. {
  2137. AllocatorType<string_t> alloc;
  2138. std::allocator_traits<decltype(alloc)>::destroy(alloc, m_data.m_value.string);
  2139. std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_data.m_value.string, 1);
  2140. m_data.m_value.string = nullptr;
  2141. }
  2142. else if (is_binary())
  2143. {
  2144. AllocatorType<binary_t> alloc;
  2145. std::allocator_traits<decltype(alloc)>::destroy(alloc, m_data.m_value.binary);
  2146. std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_data.m_value.binary, 1);
  2147. m_data.m_value.binary = nullptr;
  2148. }
  2149. m_data.m_type = value_t::null;
  2150. assert_invariant();
  2151. break;
  2152. }
  2153. case value_t::object:
  2154. {
  2155. result.m_it.object_iterator = m_data.m_value.object->erase(pos.m_it.object_iterator);
  2156. break;
  2157. }
  2158. case value_t::array:
  2159. {
  2160. result.m_it.array_iterator = m_data.m_value.array->erase(pos.m_it.array_iterator);
  2161. break;
  2162. }
  2163. case value_t::null:
  2164. case value_t::discarded:
  2165. default:
  2166. JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
  2167. }
  2168. return result;
  2169. }
  2170. /// @brief remove elements given an iterator range
  2171. /// @sa https://json.nlohmann.me/api/basic_json/erase/
  2172. template < class IteratorType, detail::enable_if_t <
  2173. std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
  2174. std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int > = 0 >
  2175. IteratorType erase(IteratorType first, IteratorType last) // NOLINT(performance-unnecessary-value-param)
  2176. {
  2177. // make sure iterator fits the current value
  2178. if (JSON_HEDLEY_UNLIKELY(this != first.m_object || this != last.m_object))
  2179. {
  2180. JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value", this));
  2181. }
  2182. IteratorType result = end();
  2183. switch (m_data.m_type)
  2184. {
  2185. case value_t::boolean:
  2186. case value_t::number_float:
  2187. case value_t::number_integer:
  2188. case value_t::number_unsigned:
  2189. case value_t::string:
  2190. case value_t::binary:
  2191. {
  2192. if (JSON_HEDLEY_LIKELY(!first.m_it.primitive_iterator.is_begin()
  2193. || !last.m_it.primitive_iterator.is_end()))
  2194. {
  2195. JSON_THROW(invalid_iterator::create(204, "iterators out of range", this));
  2196. }
  2197. if (is_string())
  2198. {
  2199. AllocatorType<string_t> alloc;
  2200. std::allocator_traits<decltype(alloc)>::destroy(alloc, m_data.m_value.string);
  2201. std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_data.m_value.string, 1);
  2202. m_data.m_value.string = nullptr;
  2203. }
  2204. else if (is_binary())
  2205. {
  2206. AllocatorType<binary_t> alloc;
  2207. std::allocator_traits<decltype(alloc)>::destroy(alloc, m_data.m_value.binary);
  2208. std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_data.m_value.binary, 1);
  2209. m_data.m_value.binary = nullptr;
  2210. }
  2211. m_data.m_type = value_t::null;
  2212. assert_invariant();
  2213. break;
  2214. }
  2215. case value_t::object:
  2216. {
  2217. result.m_it.object_iterator = m_data.m_value.object->erase(first.m_it.object_iterator,
  2218. last.m_it.object_iterator);
  2219. break;
  2220. }
  2221. case value_t::array:
  2222. {
  2223. result.m_it.array_iterator = m_data.m_value.array->erase(first.m_it.array_iterator,
  2224. last.m_it.array_iterator);
  2225. break;
  2226. }
  2227. case value_t::null:
  2228. case value_t::discarded:
  2229. default:
  2230. JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
  2231. }
  2232. return result;
  2233. }
  2234. private:
  2235. template < typename KeyType, detail::enable_if_t <
  2236. detail::has_erase_with_key_type<basic_json_t, KeyType>::value, int > = 0 >
  2237. size_type erase_internal(KeyType && key)
  2238. {
  2239. // this erase only works for objects
  2240. if (JSON_HEDLEY_UNLIKELY(!is_object()))
  2241. {
  2242. JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
  2243. }
  2244. return m_data.m_value.object->erase(std::forward<KeyType>(key));
  2245. }
  2246. template < typename KeyType, detail::enable_if_t <
  2247. !detail::has_erase_with_key_type<basic_json_t, KeyType>::value, int > = 0 >
  2248. size_type erase_internal(KeyType && key)
  2249. {
  2250. // this erase only works for objects
  2251. if (JSON_HEDLEY_UNLIKELY(!is_object()))
  2252. {
  2253. JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
  2254. }
  2255. const auto it = m_data.m_value.object->find(std::forward<KeyType>(key));
  2256. if (it != m_data.m_value.object->end())
  2257. {
  2258. m_data.m_value.object->erase(it);
  2259. return 1;
  2260. }
  2261. return 0;
  2262. }
  2263. public:
  2264. /// @brief remove element from a JSON object given a key
  2265. /// @sa https://json.nlohmann.me/api/basic_json/erase/
  2266. size_type erase(const typename object_t::key_type& key)
  2267. {
  2268. // the indirection via erase_internal() is added to avoid making this
  2269. // function a template and thus de-rank it during overload resolution
  2270. return erase_internal(key);
  2271. }
  2272. /// @brief remove element from a JSON object given a key
  2273. /// @sa https://json.nlohmann.me/api/basic_json/erase/
  2274. template<class KeyType, detail::enable_if_t<
  2275. detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value, int> = 0>
  2276. size_type erase(KeyType && key)
  2277. {
  2278. return erase_internal(std::forward<KeyType>(key));
  2279. }
  2280. /// @brief remove element from a JSON array given an index
  2281. /// @sa https://json.nlohmann.me/api/basic_json/erase/
  2282. void erase(const size_type idx)
  2283. {
  2284. // this erase only works for arrays
  2285. if (JSON_HEDLEY_LIKELY(is_array()))
  2286. {
  2287. if (JSON_HEDLEY_UNLIKELY(idx >= size()))
  2288. {
  2289. JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
  2290. }
  2291. m_data.m_value.array->erase(m_data.m_value.array->begin() + static_cast<difference_type>(idx));
  2292. }
  2293. else
  2294. {
  2295. JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
  2296. }
  2297. }
  2298. /// @}
  2299. ////////////
  2300. // lookup //
  2301. ////////////
  2302. /// @name lookup
  2303. /// @{
  2304. /// @brief find an element in a JSON object
  2305. /// @sa https://json.nlohmann.me/api/basic_json/find/
  2306. iterator find(const typename object_t::key_type& key)
  2307. {
  2308. auto result = end();
  2309. if (is_object())
  2310. {
  2311. result.m_it.object_iterator = m_data.m_value.object->find(key);
  2312. }
  2313. return result;
  2314. }
  2315. /// @brief find an element in a JSON object
  2316. /// @sa https://json.nlohmann.me/api/basic_json/find/
  2317. const_iterator find(const typename object_t::key_type& key) const
  2318. {
  2319. auto result = cend();
  2320. if (is_object())
  2321. {
  2322. result.m_it.object_iterator = m_data.m_value.object->find(key);
  2323. }
  2324. return result;
  2325. }
  2326. /// @brief find an element in a JSON object
  2327. /// @sa https://json.nlohmann.me/api/basic_json/find/
  2328. template<class KeyType, detail::enable_if_t<
  2329. detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value, int> = 0>
  2330. iterator find(KeyType && key)
  2331. {
  2332. auto result = end();
  2333. if (is_object())
  2334. {
  2335. result.m_it.object_iterator = m_data.m_value.object->find(std::forward<KeyType>(key));
  2336. }
  2337. return result;
  2338. }
  2339. /// @brief find an element in a JSON object
  2340. /// @sa https://json.nlohmann.me/api/basic_json/find/
  2341. template<class KeyType, detail::enable_if_t<
  2342. detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value, int> = 0>
  2343. const_iterator find(KeyType && key) const
  2344. {
  2345. auto result = cend();
  2346. if (is_object())
  2347. {
  2348. result.m_it.object_iterator = m_data.m_value.object->find(std::forward<KeyType>(key));
  2349. }
  2350. return result;
  2351. }
  2352. /// @brief returns the number of occurrences of a key in a JSON object
  2353. /// @sa https://json.nlohmann.me/api/basic_json/count/
  2354. size_type count(const typename object_t::key_type& key) const
  2355. {
  2356. // return 0 for all nonobject types
  2357. return is_object() ? m_data.m_value.object->count(key) : 0;
  2358. }
  2359. /// @brief returns the number of occurrences of a key in a JSON object
  2360. /// @sa https://json.nlohmann.me/api/basic_json/count/
  2361. template<class KeyType, detail::enable_if_t<
  2362. detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value, int> = 0>
  2363. size_type count(KeyType && key) const
  2364. {
  2365. // return 0 for all nonobject types
  2366. return is_object() ? m_data.m_value.object->count(std::forward<KeyType>(key)) : 0;
  2367. }
  2368. /// @brief check the existence of an element in a JSON object
  2369. /// @sa https://json.nlohmann.me/api/basic_json/contains/
  2370. bool contains(const typename object_t::key_type& key) const
  2371. {
  2372. return is_object() && m_data.m_value.object->find(key) != m_data.m_value.object->end();
  2373. }
  2374. /// @brief check the existence of an element in a JSON object
  2375. /// @sa https://json.nlohmann.me/api/basic_json/contains/
  2376. template<class KeyType, detail::enable_if_t<
  2377. detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value, int> = 0>
  2378. bool contains(KeyType && key) const
  2379. {
  2380. return is_object() && m_data.m_value.object->find(std::forward<KeyType>(key)) != m_data.m_value.object->end();
  2381. }
  2382. /// @brief check the existence of an element in a JSON object given a JSON pointer
  2383. /// @sa https://json.nlohmann.me/api/basic_json/contains/
  2384. bool contains(const json_pointer& ptr) const
  2385. {
  2386. return ptr.contains(this);
  2387. }
  2388. template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
  2389. JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
  2390. bool contains(const typename ::nlohmann::json_pointer<BasicJsonType>& ptr) const
  2391. {
  2392. return ptr.contains(this);
  2393. }
  2394. /// @}
  2395. ///////////////
  2396. // iterators //
  2397. ///////////////
  2398. /// @name iterators
  2399. /// @{
  2400. /// @brief returns an iterator to the first element
  2401. /// @sa https://json.nlohmann.me/api/basic_json/begin/
  2402. iterator begin() noexcept
  2403. {
  2404. iterator result(this);
  2405. result.set_begin();
  2406. return result;
  2407. }
  2408. /// @brief returns an iterator to the first element
  2409. /// @sa https://json.nlohmann.me/api/basic_json/begin/
  2410. const_iterator begin() const noexcept
  2411. {
  2412. return cbegin();
  2413. }
  2414. /// @brief returns a const iterator to the first element
  2415. /// @sa https://json.nlohmann.me/api/basic_json/cbegin/
  2416. const_iterator cbegin() const noexcept
  2417. {
  2418. const_iterator result(this);
  2419. result.set_begin();
  2420. return result;
  2421. }
  2422. /// @brief returns an iterator to one past the last element
  2423. /// @sa https://json.nlohmann.me/api/basic_json/end/
  2424. iterator end() noexcept
  2425. {
  2426. iterator result(this);
  2427. result.set_end();
  2428. return result;
  2429. }
  2430. /// @brief returns an iterator to one past the last element
  2431. /// @sa https://json.nlohmann.me/api/basic_json/end/
  2432. const_iterator end() const noexcept
  2433. {
  2434. return cend();
  2435. }
  2436. /// @brief returns an iterator to one past the last element
  2437. /// @sa https://json.nlohmann.me/api/basic_json/cend/
  2438. const_iterator cend() const noexcept
  2439. {
  2440. const_iterator result(this);
  2441. result.set_end();
  2442. return result;
  2443. }
  2444. /// @brief returns an iterator to the reverse-beginning
  2445. /// @sa https://json.nlohmann.me/api/basic_json/rbegin/
  2446. reverse_iterator rbegin() noexcept
  2447. {
  2448. return reverse_iterator(end());
  2449. }
  2450. /// @brief returns an iterator to the reverse-beginning
  2451. /// @sa https://json.nlohmann.me/api/basic_json/rbegin/
  2452. const_reverse_iterator rbegin() const noexcept
  2453. {
  2454. return crbegin();
  2455. }
  2456. /// @brief returns an iterator to the reverse-end
  2457. /// @sa https://json.nlohmann.me/api/basic_json/rend/
  2458. reverse_iterator rend() noexcept
  2459. {
  2460. return reverse_iterator(begin());
  2461. }
  2462. /// @brief returns an iterator to the reverse-end
  2463. /// @sa https://json.nlohmann.me/api/basic_json/rend/
  2464. const_reverse_iterator rend() const noexcept
  2465. {
  2466. return crend();
  2467. }
  2468. /// @brief returns a const reverse iterator to the last element
  2469. /// @sa https://json.nlohmann.me/api/basic_json/crbegin/
  2470. const_reverse_iterator crbegin() const noexcept
  2471. {
  2472. return const_reverse_iterator(cend());
  2473. }
  2474. /// @brief returns a const reverse iterator to one before the first
  2475. /// @sa https://json.nlohmann.me/api/basic_json/crend/
  2476. const_reverse_iterator crend() const noexcept
  2477. {
  2478. return const_reverse_iterator(cbegin());
  2479. }
  2480. public:
  2481. /// @brief wrapper to access iterator member functions in range-based for
  2482. /// @sa https://json.nlohmann.me/api/basic_json/items/
  2483. /// @deprecated This function is deprecated since 3.1.0 and will be removed in
  2484. /// version 4.0.0 of the library. Please use @ref items() instead;
  2485. /// that is, replace `json::iterator_wrapper(j)` with `j.items()`.
  2486. JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
  2487. static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
  2488. {
  2489. return ref.items();
  2490. }
  2491. /// @brief wrapper to access iterator member functions in range-based for
  2492. /// @sa https://json.nlohmann.me/api/basic_json/items/
  2493. /// @deprecated This function is deprecated since 3.1.0 and will be removed in
  2494. /// version 4.0.0 of the library. Please use @ref items() instead;
  2495. /// that is, replace `json::iterator_wrapper(j)` with `j.items()`.
  2496. JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
  2497. static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
  2498. {
  2499. return ref.items();
  2500. }
  2501. /// @brief helper to access iterator member functions in range-based for
  2502. /// @sa https://json.nlohmann.me/api/basic_json/items/
  2503. iteration_proxy<iterator> items() noexcept
  2504. {
  2505. return iteration_proxy<iterator>(*this);
  2506. }
  2507. /// @brief helper to access iterator member functions in range-based for
  2508. /// @sa https://json.nlohmann.me/api/basic_json/items/
  2509. iteration_proxy<const_iterator> items() const noexcept
  2510. {
  2511. return iteration_proxy<const_iterator>(*this);
  2512. }
  2513. /// @}
  2514. //////////////
  2515. // capacity //
  2516. //////////////
  2517. /// @name capacity
  2518. /// @{
  2519. /// @brief checks whether the container is empty.
  2520. /// @sa https://json.nlohmann.me/api/basic_json/empty/
  2521. bool empty() const noexcept
  2522. {
  2523. switch (m_data.m_type)
  2524. {
  2525. case value_t::null:
  2526. {
  2527. // null values are empty
  2528. return true;
  2529. }
  2530. case value_t::array:
  2531. {
  2532. // delegate call to array_t::empty()
  2533. return m_data.m_value.array->empty();
  2534. }
  2535. case value_t::object:
  2536. {
  2537. // delegate call to object_t::empty()
  2538. return m_data.m_value.object->empty();
  2539. }
  2540. case value_t::string:
  2541. case value_t::boolean:
  2542. case value_t::number_integer:
  2543. case value_t::number_unsigned:
  2544. case value_t::number_float:
  2545. case value_t::binary:
  2546. case value_t::discarded:
  2547. default:
  2548. {
  2549. // all other types are nonempty
  2550. return false;
  2551. }
  2552. }
  2553. }
  2554. /// @brief returns the number of elements
  2555. /// @sa https://json.nlohmann.me/api/basic_json/size/
  2556. size_type size() const noexcept
  2557. {
  2558. switch (m_data.m_type)
  2559. {
  2560. case value_t::null:
  2561. {
  2562. // null values are empty
  2563. return 0;
  2564. }
  2565. case value_t::array:
  2566. {
  2567. // delegate call to array_t::size()
  2568. return m_data.m_value.array->size();
  2569. }
  2570. case value_t::object:
  2571. {
  2572. // delegate call to object_t::size()
  2573. return m_data.m_value.object->size();
  2574. }
  2575. case value_t::string:
  2576. case value_t::boolean:
  2577. case value_t::number_integer:
  2578. case value_t::number_unsigned:
  2579. case value_t::number_float:
  2580. case value_t::binary:
  2581. case value_t::discarded:
  2582. default:
  2583. {
  2584. // all other types have size 1
  2585. return 1;
  2586. }
  2587. }
  2588. }
  2589. /// @brief returns the maximum possible number of elements
  2590. /// @sa https://json.nlohmann.me/api/basic_json/max_size/
  2591. size_type max_size() const noexcept
  2592. {
  2593. switch (m_data.m_type)
  2594. {
  2595. case value_t::array:
  2596. {
  2597. // delegate call to array_t::max_size()
  2598. return m_data.m_value.array->max_size();
  2599. }
  2600. case value_t::object:
  2601. {
  2602. // delegate call to object_t::max_size()
  2603. return m_data.m_value.object->max_size();
  2604. }
  2605. case value_t::null:
  2606. case value_t::string:
  2607. case value_t::boolean:
  2608. case value_t::number_integer:
  2609. case value_t::number_unsigned:
  2610. case value_t::number_float:
  2611. case value_t::binary:
  2612. case value_t::discarded:
  2613. default:
  2614. {
  2615. // all other types have max_size() == size()
  2616. return size();
  2617. }
  2618. }
  2619. }
  2620. /// @}
  2621. ///////////////
  2622. // modifiers //
  2623. ///////////////
  2624. /// @name modifiers
  2625. /// @{
  2626. /// @brief clears the contents
  2627. /// @sa https://json.nlohmann.me/api/basic_json/clear/
  2628. void clear() noexcept
  2629. {
  2630. switch (m_data.m_type)
  2631. {
  2632. case value_t::number_integer:
  2633. {
  2634. m_data.m_value.number_integer = 0;
  2635. break;
  2636. }
  2637. case value_t::number_unsigned:
  2638. {
  2639. m_data.m_value.number_unsigned = 0;
  2640. break;
  2641. }
  2642. case value_t::number_float:
  2643. {
  2644. m_data.m_value.number_float = 0.0;
  2645. break;
  2646. }
  2647. case value_t::boolean:
  2648. {
  2649. m_data.m_value.boolean = false;
  2650. break;
  2651. }
  2652. case value_t::string:
  2653. {
  2654. m_data.m_value.string->clear();
  2655. break;
  2656. }
  2657. case value_t::binary:
  2658. {
  2659. m_data.m_value.binary->clear();
  2660. break;
  2661. }
  2662. case value_t::array:
  2663. {
  2664. m_data.m_value.array->clear();
  2665. break;
  2666. }
  2667. case value_t::object:
  2668. {
  2669. m_data.m_value.object->clear();
  2670. break;
  2671. }
  2672. case value_t::null:
  2673. case value_t::discarded:
  2674. default:
  2675. break;
  2676. }
  2677. }
  2678. /// @brief add an object to an array
  2679. /// @sa https://json.nlohmann.me/api/basic_json/push_back/
  2680. void push_back(basic_json&& val)
  2681. {
  2682. // push_back only works for null objects or arrays
  2683. if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
  2684. {
  2685. JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));
  2686. }
  2687. // transform null object into an array
  2688. if (is_null())
  2689. {
  2690. m_data.m_type = value_t::array;
  2691. m_data.m_value = value_t::array;
  2692. assert_invariant();
  2693. }
  2694. // add element to array (move semantics)
  2695. const auto old_capacity = m_data.m_value.array->capacity();
  2696. m_data.m_value.array->push_back(std::move(val));
  2697. set_parent(m_data.m_value.array->back(), old_capacity);
  2698. // if val is moved from, basic_json move constructor marks it null, so we do not call the destructor
  2699. }
  2700. /// @brief add an object to an array
  2701. /// @sa https://json.nlohmann.me/api/basic_json/operator+=/
  2702. reference operator+=(basic_json&& val)
  2703. {
  2704. push_back(std::move(val));
  2705. return *this;
  2706. }
  2707. /// @brief add an object to an array
  2708. /// @sa https://json.nlohmann.me/api/basic_json/push_back/
  2709. void push_back(const basic_json& val)
  2710. {
  2711. // push_back only works for null objects or arrays
  2712. if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
  2713. {
  2714. JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));
  2715. }
  2716. // transform null object into an array
  2717. if (is_null())
  2718. {
  2719. m_data.m_type = value_t::array;
  2720. m_data.m_value = value_t::array;
  2721. assert_invariant();
  2722. }
  2723. // add element to array
  2724. const auto old_capacity = m_data.m_value.array->capacity();
  2725. m_data.m_value.array->push_back(val);
  2726. set_parent(m_data.m_value.array->back(), old_capacity);
  2727. }
  2728. /// @brief add an object to an array
  2729. /// @sa https://json.nlohmann.me/api/basic_json/operator+=/
  2730. reference operator+=(const basic_json& val)
  2731. {
  2732. push_back(val);
  2733. return *this;
  2734. }
  2735. /// @brief add an object to an object
  2736. /// @sa https://json.nlohmann.me/api/basic_json/push_back/
  2737. void push_back(const typename object_t::value_type& val)
  2738. {
  2739. // push_back only works for null objects or objects
  2740. if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
  2741. {
  2742. JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));
  2743. }
  2744. // transform null object into an object
  2745. if (is_null())
  2746. {
  2747. m_data.m_type = value_t::object;
  2748. m_data.m_value = value_t::object;
  2749. assert_invariant();
  2750. }
  2751. // add element to object
  2752. auto res = m_data.m_value.object->insert(val);
  2753. set_parent(res.first->second);
  2754. }
  2755. /// @brief add an object to an object
  2756. /// @sa https://json.nlohmann.me/api/basic_json/operator+=/
  2757. reference operator+=(const typename object_t::value_type& val)
  2758. {
  2759. push_back(val);
  2760. return *this;
  2761. }
  2762. /// @brief add an object to an object
  2763. /// @sa https://json.nlohmann.me/api/basic_json/push_back/
  2764. void push_back(initializer_list_t init)
  2765. {
  2766. if (is_object() && init.size() == 2 && (*init.begin())->is_string())
  2767. {
  2768. basic_json&& key = init.begin()->moved_or_copied();
  2769. push_back(typename object_t::value_type(
  2770. std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
  2771. }
  2772. else
  2773. {
  2774. push_back(basic_json(init));
  2775. }
  2776. }
  2777. /// @brief add an object to an object
  2778. /// @sa https://json.nlohmann.me/api/basic_json/operator+=/
  2779. reference operator+=(initializer_list_t init)
  2780. {
  2781. push_back(init);
  2782. return *this;
  2783. }
  2784. /// @brief add an object to an array
  2785. /// @sa https://json.nlohmann.me/api/basic_json/emplace_back/
  2786. template<class... Args>
  2787. reference emplace_back(Args&& ... args)
  2788. {
  2789. // emplace_back only works for null objects or arrays
  2790. if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
  2791. {
  2792. JSON_THROW(type_error::create(311, detail::concat("cannot use emplace_back() with ", type_name()), this));
  2793. }
  2794. // transform null object into an array
  2795. if (is_null())
  2796. {
  2797. m_data.m_type = value_t::array;
  2798. m_data.m_value = value_t::array;
  2799. assert_invariant();
  2800. }
  2801. // add element to array (perfect forwarding)
  2802. const auto old_capacity = m_data.m_value.array->capacity();
  2803. m_data.m_value.array->emplace_back(std::forward<Args>(args)...);
  2804. return set_parent(m_data.m_value.array->back(), old_capacity);
  2805. }
  2806. /// @brief add an object to an object if key does not exist
  2807. /// @sa https://json.nlohmann.me/api/basic_json/emplace/
  2808. template<class... Args>
  2809. std::pair<iterator, bool> emplace(Args&& ... args)
  2810. {
  2811. // emplace only works for null objects or arrays
  2812. if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
  2813. {
  2814. JSON_THROW(type_error::create(311, detail::concat("cannot use emplace() with ", type_name()), this));
  2815. }
  2816. // transform null object into an object
  2817. if (is_null())
  2818. {
  2819. m_data.m_type = value_t::object;
  2820. m_data.m_value = value_t::object;
  2821. assert_invariant();
  2822. }
  2823. // add element to array (perfect forwarding)
  2824. auto res = m_data.m_value.object->emplace(std::forward<Args>(args)...);
  2825. set_parent(res.first->second);
  2826. // create result iterator and set iterator to the result of emplace
  2827. auto it = begin();
  2828. it.m_it.object_iterator = res.first;
  2829. // return pair of iterator and boolean
  2830. return {it, res.second};
  2831. }
  2832. /// Helper for insertion of an iterator
  2833. /// @note: This uses std::distance to support GCC 4.8,
  2834. /// see https://github.com/nlohmann/json/pull/1257
  2835. template<typename... Args>
  2836. iterator insert_iterator(const_iterator pos, Args&& ... args) // NOLINT(performance-unnecessary-value-param)
  2837. {
  2838. iterator result(this);
  2839. JSON_ASSERT(m_data.m_value.array != nullptr);
  2840. auto insert_pos = std::distance(m_data.m_value.array->begin(), pos.m_it.array_iterator);
  2841. m_data.m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
  2842. result.m_it.array_iterator = m_data.m_value.array->begin() + insert_pos;
  2843. // This could have been written as:
  2844. // result.m_it.array_iterator = m_data.m_value.array->insert(pos.m_it.array_iterator, cnt, val);
  2845. // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
  2846. set_parents();
  2847. return result;
  2848. }
  2849. /// @brief inserts element into array
  2850. /// @sa https://json.nlohmann.me/api/basic_json/insert/
  2851. iterator insert(const_iterator pos, const basic_json& val) // NOLINT(performance-unnecessary-value-param)
  2852. {
  2853. // insert only works for arrays
  2854. if (JSON_HEDLEY_LIKELY(is_array()))
  2855. {
  2856. // check if iterator pos fits to this JSON value
  2857. if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
  2858. {
  2859. JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
  2860. }
  2861. // insert to array and return iterator
  2862. return insert_iterator(pos, val);
  2863. }
  2864. JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
  2865. }
  2866. /// @brief inserts element into array
  2867. /// @sa https://json.nlohmann.me/api/basic_json/insert/
  2868. iterator insert(const_iterator pos, basic_json&& val) // NOLINT(performance-unnecessary-value-param)
  2869. {
  2870. return insert(pos, val);
  2871. }
  2872. /// @brief inserts copies of element into array
  2873. /// @sa https://json.nlohmann.me/api/basic_json/insert/
  2874. iterator insert(const_iterator pos, size_type cnt, const basic_json& val) // NOLINT(performance-unnecessary-value-param)
  2875. {
  2876. // insert only works for arrays
  2877. if (JSON_HEDLEY_LIKELY(is_array()))
  2878. {
  2879. // check if iterator pos fits to this JSON value
  2880. if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
  2881. {
  2882. JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
  2883. }
  2884. // insert to array and return iterator
  2885. return insert_iterator(pos, cnt, val);
  2886. }
  2887. JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
  2888. }
  2889. /// @brief inserts range of elements into array
  2890. /// @sa https://json.nlohmann.me/api/basic_json/insert/
  2891. iterator insert(const_iterator pos, const_iterator first, const_iterator last) // NOLINT(performance-unnecessary-value-param)
  2892. {
  2893. // insert only works for arrays
  2894. if (JSON_HEDLEY_UNLIKELY(!is_array()))
  2895. {
  2896. JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
  2897. }
  2898. // check if iterator pos fits to this JSON value
  2899. if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
  2900. {
  2901. JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
  2902. }
  2903. // check if range iterators belong to the same JSON object
  2904. if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
  2905. {
  2906. JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));
  2907. }
  2908. if (JSON_HEDLEY_UNLIKELY(first.m_object == this))
  2909. {
  2910. JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container", this));
  2911. }
  2912. // insert to array and return iterator
  2913. return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
  2914. }
  2915. /// @brief inserts elements from initializer list into array
  2916. /// @sa https://json.nlohmann.me/api/basic_json/insert/
  2917. iterator insert(const_iterator pos, initializer_list_t ilist) // NOLINT(performance-unnecessary-value-param)
  2918. {
  2919. // insert only works for arrays
  2920. if (JSON_HEDLEY_UNLIKELY(!is_array()))
  2921. {
  2922. JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
  2923. }
  2924. // check if iterator pos fits to this JSON value
  2925. if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
  2926. {
  2927. JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
  2928. }
  2929. // insert to array and return iterator
  2930. return insert_iterator(pos, ilist.begin(), ilist.end());
  2931. }
  2932. /// @brief inserts range of elements into object
  2933. /// @sa https://json.nlohmann.me/api/basic_json/insert/
  2934. void insert(const_iterator first, const_iterator last) // NOLINT(performance-unnecessary-value-param)
  2935. {
  2936. // insert only works for objects
  2937. if (JSON_HEDLEY_UNLIKELY(!is_object()))
  2938. {
  2939. JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
  2940. }
  2941. // check if range iterators belong to the same JSON object
  2942. if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
  2943. {
  2944. JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));
  2945. }
  2946. // passed iterators must belong to objects
  2947. if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
  2948. {
  2949. JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", this));
  2950. }
  2951. m_data.m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
  2952. set_parents();
  2953. }
  2954. /// @brief updates a JSON object from another object, overwriting existing keys
  2955. /// @sa https://json.nlohmann.me/api/basic_json/update/
  2956. void update(const_reference j, bool merge_objects = false)
  2957. {
  2958. update(j.begin(), j.end(), merge_objects);
  2959. }
  2960. /// @brief updates a JSON object from another object, overwriting existing keys
  2961. /// @sa https://json.nlohmann.me/api/basic_json/update/
  2962. void update(const_iterator first, const_iterator last, bool merge_objects = false) // NOLINT(performance-unnecessary-value-param)
  2963. {
  2964. // implicitly convert null value to an empty object
  2965. if (is_null())
  2966. {
  2967. m_data.m_type = value_t::object;
  2968. m_data.m_value.object = create<object_t>();
  2969. assert_invariant();
  2970. }
  2971. if (JSON_HEDLEY_UNLIKELY(!is_object()))
  2972. {
  2973. JSON_THROW(type_error::create(312, detail::concat("cannot use update() with ", type_name()), this));
  2974. }
  2975. // check if range iterators belong to the same JSON object
  2976. if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
  2977. {
  2978. JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));
  2979. }
  2980. // passed iterators must belong to objects
  2981. if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
  2982. {
  2983. JSON_THROW(type_error::create(312, detail::concat("cannot use update() with ", first.m_object->type_name()), first.m_object));
  2984. }
  2985. for (auto it = first; it != last; ++it)
  2986. {
  2987. if (merge_objects && it.value().is_object())
  2988. {
  2989. auto it2 = m_data.m_value.object->find(it.key());
  2990. if (it2 != m_data.m_value.object->end())
  2991. {
  2992. it2->second.update(it.value(), true);
  2993. continue;
  2994. }
  2995. }
  2996. m_data.m_value.object->operator[](it.key()) = it.value();
  2997. #if JSON_DIAGNOSTICS
  2998. m_data.m_value.object->operator[](it.key()).m_parent = this;
  2999. #endif
  3000. }
  3001. }
  3002. /// @brief exchanges the values
  3003. /// @sa https://json.nlohmann.me/api/basic_json/swap/
  3004. void swap(reference other) noexcept (
  3005. std::is_nothrow_move_constructible<value_t>::value&&
  3006. std::is_nothrow_move_assignable<value_t>::value&&
  3007. std::is_nothrow_move_constructible<json_value>::value&& // NOLINT(cppcoreguidelines-noexcept-swap,performance-noexcept-swap)
  3008. std::is_nothrow_move_assignable<json_value>::value
  3009. )
  3010. {
  3011. std::swap(m_data.m_type, other.m_data.m_type);
  3012. std::swap(m_data.m_value, other.m_data.m_value);
  3013. set_parents();
  3014. other.set_parents();
  3015. assert_invariant();
  3016. }
  3017. /// @brief exchanges the values
  3018. /// @sa https://json.nlohmann.me/api/basic_json/swap/
  3019. friend void swap(reference left, reference right) noexcept (
  3020. std::is_nothrow_move_constructible<value_t>::value&&
  3021. std::is_nothrow_move_assignable<value_t>::value&&
  3022. std::is_nothrow_move_constructible<json_value>::value&& // NOLINT(cppcoreguidelines-noexcept-swap,performance-noexcept-swap)
  3023. std::is_nothrow_move_assignable<json_value>::value
  3024. )
  3025. {
  3026. left.swap(right);
  3027. }
  3028. /// @brief exchanges the values
  3029. /// @sa https://json.nlohmann.me/api/basic_json/swap/
  3030. void swap(array_t& other) // NOLINT(bugprone-exception-escape,cppcoreguidelines-noexcept-swap,performance-noexcept-swap)
  3031. {
  3032. // swap only works for arrays
  3033. if (JSON_HEDLEY_LIKELY(is_array()))
  3034. {
  3035. using std::swap;
  3036. swap(*(m_data.m_value.array), other);
  3037. }
  3038. else
  3039. {
  3040. JSON_THROW(type_error::create(310, detail::concat("cannot use swap(array_t&) with ", type_name()), this));
  3041. }
  3042. }
  3043. /// @brief exchanges the values
  3044. /// @sa https://json.nlohmann.me/api/basic_json/swap/
  3045. void swap(object_t& other) // NOLINT(bugprone-exception-escape,cppcoreguidelines-noexcept-swap,performance-noexcept-swap)
  3046. {
  3047. // swap only works for objects
  3048. if (JSON_HEDLEY_LIKELY(is_object()))
  3049. {
  3050. using std::swap;
  3051. swap(*(m_data.m_value.object), other);
  3052. }
  3053. else
  3054. {
  3055. JSON_THROW(type_error::create(310, detail::concat("cannot use swap(object_t&) with ", type_name()), this));
  3056. }
  3057. }
  3058. /// @brief exchanges the values
  3059. /// @sa https://json.nlohmann.me/api/basic_json/swap/
  3060. void swap(string_t& other) // NOLINT(bugprone-exception-escape,cppcoreguidelines-noexcept-swap,performance-noexcept-swap)
  3061. {
  3062. // swap only works for strings
  3063. if (JSON_HEDLEY_LIKELY(is_string()))
  3064. {
  3065. using std::swap;
  3066. swap(*(m_data.m_value.string), other);
  3067. }
  3068. else
  3069. {
  3070. JSON_THROW(type_error::create(310, detail::concat("cannot use swap(string_t&) with ", type_name()), this));
  3071. }
  3072. }
  3073. /// @brief exchanges the values
  3074. /// @sa https://json.nlohmann.me/api/basic_json/swap/
  3075. void swap(binary_t& other) // NOLINT(bugprone-exception-escape,cppcoreguidelines-noexcept-swap,performance-noexcept-swap)
  3076. {
  3077. // swap only works for strings
  3078. if (JSON_HEDLEY_LIKELY(is_binary()))
  3079. {
  3080. using std::swap;
  3081. swap(*(m_data.m_value.binary), other);
  3082. }
  3083. else
  3084. {
  3085. JSON_THROW(type_error::create(310, detail::concat("cannot use swap(binary_t&) with ", type_name()), this));
  3086. }
  3087. }
  3088. /// @brief exchanges the values
  3089. /// @sa https://json.nlohmann.me/api/basic_json/swap/
  3090. void swap(typename binary_t::container_type& other) // NOLINT(bugprone-exception-escape)
  3091. {
  3092. // swap only works for strings
  3093. if (JSON_HEDLEY_LIKELY(is_binary()))
  3094. {
  3095. using std::swap;
  3096. swap(*(m_data.m_value.binary), other);
  3097. }
  3098. else
  3099. {
  3100. JSON_THROW(type_error::create(310, detail::concat("cannot use swap(binary_t::container_type&) with ", type_name()), this));
  3101. }
  3102. }
  3103. /// @}
  3104. //////////////////////////////////////////
  3105. // lexicographical comparison operators //
  3106. //////////////////////////////////////////
  3107. /// @name lexicographical comparison operators
  3108. /// @{
  3109. // note parentheses around operands are necessary; see
  3110. // https://github.com/nlohmann/json/issues/1530
  3111. #define JSON_IMPLEMENT_OPERATOR(op, null_result, unordered_result, default_result) \
  3112. const auto lhs_type = lhs.type(); \
  3113. const auto rhs_type = rhs.type(); \
  3114. \
  3115. if (lhs_type == rhs_type) /* NOLINT(readability/braces) */ \
  3116. { \
  3117. switch (lhs_type) \
  3118. { \
  3119. case value_t::array: \
  3120. return (*lhs.m_data.m_value.array) op (*rhs.m_data.m_value.array); \
  3121. \
  3122. case value_t::object: \
  3123. return (*lhs.m_data.m_value.object) op (*rhs.m_data.m_value.object); \
  3124. \
  3125. case value_t::null: \
  3126. return (null_result); \
  3127. \
  3128. case value_t::string: \
  3129. return (*lhs.m_data.m_value.string) op (*rhs.m_data.m_value.string); \
  3130. \
  3131. case value_t::boolean: \
  3132. return (lhs.m_data.m_value.boolean) op (rhs.m_data.m_value.boolean); \
  3133. \
  3134. case value_t::number_integer: \
  3135. return (lhs.m_data.m_value.number_integer) op (rhs.m_data.m_value.number_integer); \
  3136. \
  3137. case value_t::number_unsigned: \
  3138. return (lhs.m_data.m_value.number_unsigned) op (rhs.m_data.m_value.number_unsigned); \
  3139. \
  3140. case value_t::number_float: \
  3141. return (lhs.m_data.m_value.number_float) op (rhs.m_data.m_value.number_float); \
  3142. \
  3143. case value_t::binary: \
  3144. return (*lhs.m_data.m_value.binary) op (*rhs.m_data.m_value.binary); \
  3145. \
  3146. case value_t::discarded: \
  3147. default: \
  3148. return (unordered_result); \
  3149. } \
  3150. } \
  3151. else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float) \
  3152. { \
  3153. return static_cast<number_float_t>(lhs.m_data.m_value.number_integer) op rhs.m_data.m_value.number_float; \
  3154. } \
  3155. else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer) \
  3156. { \
  3157. return lhs.m_data.m_value.number_float op static_cast<number_float_t>(rhs.m_data.m_value.number_integer); \
  3158. } \
  3159. else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float) \
  3160. { \
  3161. return static_cast<number_float_t>(lhs.m_data.m_value.number_unsigned) op rhs.m_data.m_value.number_float; \
  3162. } \
  3163. else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned) \
  3164. { \
  3165. return lhs.m_data.m_value.number_float op static_cast<number_float_t>(rhs.m_data.m_value.number_unsigned); \
  3166. } \
  3167. else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer) \
  3168. { \
  3169. return static_cast<number_integer_t>(lhs.m_data.m_value.number_unsigned) op rhs.m_data.m_value.number_integer; \
  3170. } \
  3171. else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned) \
  3172. { \
  3173. return lhs.m_data.m_value.number_integer op static_cast<number_integer_t>(rhs.m_data.m_value.number_unsigned); \
  3174. } \
  3175. else if(compares_unordered(lhs, rhs))\
  3176. {\
  3177. return (unordered_result);\
  3178. }\
  3179. \
  3180. return (default_result);
  3181. JSON_PRIVATE_UNLESS_TESTED:
  3182. // returns true if:
  3183. // - any operand is NaN and the other operand is of number type
  3184. // - any operand is discarded
  3185. // in legacy mode, discarded values are considered ordered if
  3186. // an operation is computed as an odd number of inverses of others
  3187. static bool compares_unordered(const_reference lhs, const_reference rhs, bool inverse = false) noexcept
  3188. {
  3189. if ((lhs.is_number_float() && std::isnan(lhs.m_data.m_value.number_float) && rhs.is_number())
  3190. || (rhs.is_number_float() && std::isnan(rhs.m_data.m_value.number_float) && lhs.is_number()))
  3191. {
  3192. return true;
  3193. }
  3194. #if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
  3195. return (lhs.is_discarded() || rhs.is_discarded()) && !inverse;
  3196. #else
  3197. static_cast<void>(inverse);
  3198. return lhs.is_discarded() || rhs.is_discarded();
  3199. #endif
  3200. }
  3201. private:
  3202. bool compares_unordered(const_reference rhs, bool inverse = false) const noexcept
  3203. {
  3204. return compares_unordered(*this, rhs, inverse);
  3205. }
  3206. public:
  3207. #if JSON_HAS_THREE_WAY_COMPARISON
  3208. /// @brief comparison: equal
  3209. /// @sa https://json.nlohmann.me/api/basic_json/operator_eq/
  3210. bool operator==(const_reference rhs) const noexcept
  3211. {
  3212. #ifdef __GNUC__
  3213. #pragma GCC diagnostic push
  3214. #pragma GCC diagnostic ignored "-Wfloat-equal"
  3215. #endif
  3216. const_reference lhs = *this;
  3217. JSON_IMPLEMENT_OPERATOR( ==, true, false, false)
  3218. #ifdef __GNUC__
  3219. #pragma GCC diagnostic pop
  3220. #endif
  3221. }
  3222. /// @brief comparison: equal
  3223. /// @sa https://json.nlohmann.me/api/basic_json/operator_eq/
  3224. template<typename ScalarType>
  3225. requires std::is_scalar_v<ScalarType>
  3226. bool operator==(ScalarType rhs) const noexcept
  3227. {
  3228. return *this == basic_json(rhs);
  3229. }
  3230. /// @brief comparison: not equal
  3231. /// @sa https://json.nlohmann.me/api/basic_json/operator_ne/
  3232. bool operator!=(const_reference rhs) const noexcept
  3233. {
  3234. if (compares_unordered(rhs, true))
  3235. {
  3236. return false;
  3237. }
  3238. return !operator==(rhs);
  3239. }
  3240. /// @brief comparison: 3-way
  3241. /// @sa https://json.nlohmann.me/api/basic_json/operator_spaceship/
  3242. std::partial_ordering operator<=>(const_reference rhs) const noexcept // *NOPAD*
  3243. {
  3244. const_reference lhs = *this;
  3245. // default_result is used if we cannot compare values. In that case,
  3246. // we compare types.
  3247. JSON_IMPLEMENT_OPERATOR(<=>, // *NOPAD*
  3248. std::partial_ordering::equivalent,
  3249. std::partial_ordering::unordered,
  3250. lhs_type <=> rhs_type) // *NOPAD*
  3251. }
  3252. /// @brief comparison: 3-way
  3253. /// @sa https://json.nlohmann.me/api/basic_json/operator_spaceship/
  3254. template<typename ScalarType>
  3255. requires std::is_scalar_v<ScalarType>
  3256. std::partial_ordering operator<=>(ScalarType rhs) const noexcept // *NOPAD*
  3257. {
  3258. return *this <=> basic_json(rhs); // *NOPAD*
  3259. }
  3260. #if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
  3261. // all operators that are computed as an odd number of inverses of others
  3262. // need to be overloaded to emulate the legacy comparison behavior
  3263. /// @brief comparison: less than or equal
  3264. /// @sa https://json.nlohmann.me/api/basic_json/operator_le/
  3265. JSON_HEDLEY_DEPRECATED_FOR(3.11.0, undef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON)
  3266. bool operator<=(const_reference rhs) const noexcept
  3267. {
  3268. if (compares_unordered(rhs, true))
  3269. {
  3270. return false;
  3271. }
  3272. return !(rhs < *this);
  3273. }
  3274. /// @brief comparison: less than or equal
  3275. /// @sa https://json.nlohmann.me/api/basic_json/operator_le/
  3276. template<typename ScalarType>
  3277. requires std::is_scalar_v<ScalarType>
  3278. bool operator<=(ScalarType rhs) const noexcept
  3279. {
  3280. return *this <= basic_json(rhs);
  3281. }
  3282. /// @brief comparison: greater than or equal
  3283. /// @sa https://json.nlohmann.me/api/basic_json/operator_ge/
  3284. JSON_HEDLEY_DEPRECATED_FOR(3.11.0, undef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON)
  3285. bool operator>=(const_reference rhs) const noexcept
  3286. {
  3287. if (compares_unordered(rhs, true))
  3288. {
  3289. return false;
  3290. }
  3291. return !(*this < rhs);
  3292. }
  3293. /// @brief comparison: greater than or equal
  3294. /// @sa https://json.nlohmann.me/api/basic_json/operator_ge/
  3295. template<typename ScalarType>
  3296. requires std::is_scalar_v<ScalarType>
  3297. bool operator>=(ScalarType rhs) const noexcept
  3298. {
  3299. return *this >= basic_json(rhs);
  3300. }
  3301. #endif
  3302. #else
  3303. /// @brief comparison: equal
  3304. /// @sa https://json.nlohmann.me/api/basic_json/operator_eq/
  3305. friend bool operator==(const_reference lhs, const_reference rhs) noexcept
  3306. {
  3307. #ifdef __GNUC__
  3308. #pragma GCC diagnostic push
  3309. #pragma GCC diagnostic ignored "-Wfloat-equal"
  3310. #endif
  3311. JSON_IMPLEMENT_OPERATOR( ==, true, false, false)
  3312. #ifdef __GNUC__
  3313. #pragma GCC diagnostic pop
  3314. #endif
  3315. }
  3316. /// @brief comparison: equal
  3317. /// @sa https://json.nlohmann.me/api/basic_json/operator_eq/
  3318. template<typename ScalarType, typename std::enable_if<
  3319. std::is_scalar<ScalarType>::value, int>::type = 0>
  3320. friend bool operator==(const_reference lhs, ScalarType rhs) noexcept
  3321. {
  3322. return lhs == basic_json(rhs);
  3323. }
  3324. /// @brief comparison: equal
  3325. /// @sa https://json.nlohmann.me/api/basic_json/operator_eq/
  3326. template<typename ScalarType, typename std::enable_if<
  3327. std::is_scalar<ScalarType>::value, int>::type = 0>
  3328. friend bool operator==(ScalarType lhs, const_reference rhs) noexcept
  3329. {
  3330. return basic_json(lhs) == rhs;
  3331. }
  3332. /// @brief comparison: not equal
  3333. /// @sa https://json.nlohmann.me/api/basic_json/operator_ne/
  3334. friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
  3335. {
  3336. if (compares_unordered(lhs, rhs, true))
  3337. {
  3338. return false;
  3339. }
  3340. return !(lhs == rhs);
  3341. }
  3342. /// @brief comparison: not equal
  3343. /// @sa https://json.nlohmann.me/api/basic_json/operator_ne/
  3344. template<typename ScalarType, typename std::enable_if<
  3345. std::is_scalar<ScalarType>::value, int>::type = 0>
  3346. friend bool operator!=(const_reference lhs, ScalarType rhs) noexcept
  3347. {
  3348. return lhs != basic_json(rhs);
  3349. }
  3350. /// @brief comparison: not equal
  3351. /// @sa https://json.nlohmann.me/api/basic_json/operator_ne/
  3352. template<typename ScalarType, typename std::enable_if<
  3353. std::is_scalar<ScalarType>::value, int>::type = 0>
  3354. friend bool operator!=(ScalarType lhs, const_reference rhs) noexcept
  3355. {
  3356. return basic_json(lhs) != rhs;
  3357. }
  3358. /// @brief comparison: less than
  3359. /// @sa https://json.nlohmann.me/api/basic_json/operator_lt/
  3360. friend bool operator<(const_reference lhs, const_reference rhs) noexcept
  3361. {
  3362. // default_result is used if we cannot compare values. In that case,
  3363. // we compare types. Note we have to call the operator explicitly,
  3364. // because MSVC has problems otherwise.
  3365. JSON_IMPLEMENT_OPERATOR( <, false, false, operator<(lhs_type, rhs_type))
  3366. }
  3367. /// @brief comparison: less than
  3368. /// @sa https://json.nlohmann.me/api/basic_json/operator_lt/
  3369. template<typename ScalarType, typename std::enable_if<
  3370. std::is_scalar<ScalarType>::value, int>::type = 0>
  3371. friend bool operator<(const_reference lhs, ScalarType rhs) noexcept
  3372. {
  3373. return lhs < basic_json(rhs);
  3374. }
  3375. /// @brief comparison: less than
  3376. /// @sa https://json.nlohmann.me/api/basic_json/operator_lt/
  3377. template<typename ScalarType, typename std::enable_if<
  3378. std::is_scalar<ScalarType>::value, int>::type = 0>
  3379. friend bool operator<(ScalarType lhs, const_reference rhs) noexcept
  3380. {
  3381. return basic_json(lhs) < rhs;
  3382. }
  3383. /// @brief comparison: less than or equal
  3384. /// @sa https://json.nlohmann.me/api/basic_json/operator_le/
  3385. friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
  3386. {
  3387. if (compares_unordered(lhs, rhs, true))
  3388. {
  3389. return false;
  3390. }
  3391. return !(rhs < lhs);
  3392. }
  3393. /// @brief comparison: less than or equal
  3394. /// @sa https://json.nlohmann.me/api/basic_json/operator_le/
  3395. template<typename ScalarType, typename std::enable_if<
  3396. std::is_scalar<ScalarType>::value, int>::type = 0>
  3397. friend bool operator<=(const_reference lhs, ScalarType rhs) noexcept
  3398. {
  3399. return lhs <= basic_json(rhs);
  3400. }
  3401. /// @brief comparison: less than or equal
  3402. /// @sa https://json.nlohmann.me/api/basic_json/operator_le/
  3403. template<typename ScalarType, typename std::enable_if<
  3404. std::is_scalar<ScalarType>::value, int>::type = 0>
  3405. friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept
  3406. {
  3407. return basic_json(lhs) <= rhs;
  3408. }
  3409. /// @brief comparison: greater than
  3410. /// @sa https://json.nlohmann.me/api/basic_json/operator_gt/
  3411. friend bool operator>(const_reference lhs, const_reference rhs) noexcept
  3412. {
  3413. // double inverse
  3414. if (compares_unordered(lhs, rhs))
  3415. {
  3416. return false;
  3417. }
  3418. return !(lhs <= rhs);
  3419. }
  3420. /// @brief comparison: greater than
  3421. /// @sa https://json.nlohmann.me/api/basic_json/operator_gt/
  3422. template<typename ScalarType, typename std::enable_if<
  3423. std::is_scalar<ScalarType>::value, int>::type = 0>
  3424. friend bool operator>(const_reference lhs, ScalarType rhs) noexcept
  3425. {
  3426. return lhs > basic_json(rhs);
  3427. }
  3428. /// @brief comparison: greater than
  3429. /// @sa https://json.nlohmann.me/api/basic_json/operator_gt/
  3430. template<typename ScalarType, typename std::enable_if<
  3431. std::is_scalar<ScalarType>::value, int>::type = 0>
  3432. friend bool operator>(ScalarType lhs, const_reference rhs) noexcept
  3433. {
  3434. return basic_json(lhs) > rhs;
  3435. }
  3436. /// @brief comparison: greater than or equal
  3437. /// @sa https://json.nlohmann.me/api/basic_json/operator_ge/
  3438. friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
  3439. {
  3440. if (compares_unordered(lhs, rhs, true))
  3441. {
  3442. return false;
  3443. }
  3444. return !(lhs < rhs);
  3445. }
  3446. /// @brief comparison: greater than or equal
  3447. /// @sa https://json.nlohmann.me/api/basic_json/operator_ge/
  3448. template<typename ScalarType, typename std::enable_if<
  3449. std::is_scalar<ScalarType>::value, int>::type = 0>
  3450. friend bool operator>=(const_reference lhs, ScalarType rhs) noexcept
  3451. {
  3452. return lhs >= basic_json(rhs);
  3453. }
  3454. /// @brief comparison: greater than or equal
  3455. /// @sa https://json.nlohmann.me/api/basic_json/operator_ge/
  3456. template<typename ScalarType, typename std::enable_if<
  3457. std::is_scalar<ScalarType>::value, int>::type = 0>
  3458. friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept
  3459. {
  3460. return basic_json(lhs) >= rhs;
  3461. }
  3462. #endif
  3463. #undef JSON_IMPLEMENT_OPERATOR
  3464. /// @}
  3465. ///////////////////
  3466. // serialization //
  3467. ///////////////////
  3468. /// @name serialization
  3469. /// @{
  3470. #ifndef JSON_NO_IO
  3471. /// @brief serialize to stream
  3472. /// @sa https://json.nlohmann.me/api/basic_json/operator_ltlt/
  3473. friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
  3474. {
  3475. // read width member and use it as indentation parameter if nonzero
  3476. const bool pretty_print = o.width() > 0;
  3477. const auto indentation = pretty_print ? o.width() : 0;
  3478. // reset width to 0 for subsequent calls to this stream
  3479. o.width(0);
  3480. // do the actual serialization
  3481. serializer s(detail::output_adapter<char>(o), o.fill());
  3482. s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
  3483. return o;
  3484. }
  3485. /// @brief serialize to stream
  3486. /// @sa https://json.nlohmann.me/api/basic_json/operator_ltlt/
  3487. /// @deprecated This function is deprecated since 3.0.0 and will be removed in
  3488. /// version 4.0.0 of the library. Please use
  3489. /// operator<<(std::ostream&, const basic_json&) instead; that is,
  3490. /// replace calls like `j >> o;` with `o << j;`.
  3491. JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream&, const basic_json&))
  3492. friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
  3493. {
  3494. return o << j;
  3495. }
  3496. #endif // JSON_NO_IO
  3497. /// @}
  3498. /////////////////////
  3499. // deserialization //
  3500. /////////////////////
  3501. /// @name deserialization
  3502. /// @{
  3503. /// @brief deserialize from a compatible input
  3504. /// @sa https://json.nlohmann.me/api/basic_json/parse/
  3505. template<typename InputType>
  3506. JSON_HEDLEY_WARN_UNUSED_RESULT
  3507. static basic_json parse(InputType&& i,
  3508. parser_callback_t cb = nullptr,
  3509. const bool allow_exceptions = true,
  3510. const bool ignore_comments = false)
  3511. {
  3512. basic_json result;
  3513. parser(detail::input_adapter(std::forward<InputType>(i)), std::move(cb), allow_exceptions, ignore_comments).parse(true, result); // cppcheck-suppress[accessMoved,accessForwarded]
  3514. return result;
  3515. }
  3516. /// @brief deserialize from a pair of character iterators
  3517. /// @sa https://json.nlohmann.me/api/basic_json/parse/
  3518. template<typename IteratorType>
  3519. JSON_HEDLEY_WARN_UNUSED_RESULT
  3520. static basic_json parse(IteratorType first,
  3521. IteratorType last,
  3522. parser_callback_t cb = nullptr,
  3523. const bool allow_exceptions = true,
  3524. const bool ignore_comments = false)
  3525. {
  3526. basic_json result;
  3527. parser(detail::input_adapter(std::move(first), std::move(last)), std::move(cb), allow_exceptions, ignore_comments).parse(true, result); // cppcheck-suppress[accessMoved]
  3528. return result;
  3529. }
  3530. JSON_HEDLEY_WARN_UNUSED_RESULT
  3531. JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len))
  3532. static basic_json parse(detail::span_input_adapter&& i,
  3533. parser_callback_t cb = nullptr,
  3534. const bool allow_exceptions = true,
  3535. const bool ignore_comments = false)
  3536. {
  3537. basic_json result;
  3538. parser(i.get(), std::move(cb), allow_exceptions, ignore_comments).parse(true, result); // cppcheck-suppress[accessMoved]
  3539. return result;
  3540. }
  3541. /// @brief check if the input is valid JSON
  3542. /// @sa https://json.nlohmann.me/api/basic_json/accept/
  3543. template<typename InputType>
  3544. static bool accept(InputType&& i,
  3545. const bool ignore_comments = false)
  3546. {
  3547. return parser(detail::input_adapter(std::forward<InputType>(i)), nullptr, false, ignore_comments).accept(true);
  3548. }
  3549. /// @brief check if the input is valid JSON
  3550. /// @sa https://json.nlohmann.me/api/basic_json/accept/
  3551. template<typename IteratorType>
  3552. static bool accept(IteratorType first, IteratorType last,
  3553. const bool ignore_comments = false)
  3554. {
  3555. return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments).accept(true);
  3556. }
  3557. JSON_HEDLEY_WARN_UNUSED_RESULT
  3558. JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len))
  3559. static bool accept(detail::span_input_adapter&& i,
  3560. const bool ignore_comments = false)
  3561. {
  3562. return parser(i.get(), nullptr, false, ignore_comments).accept(true);
  3563. }
  3564. /// @brief generate SAX events
  3565. /// @sa https://json.nlohmann.me/api/basic_json/sax_parse/
  3566. template <typename InputType, typename SAX>
  3567. JSON_HEDLEY_NON_NULL(2)
  3568. static bool sax_parse(InputType&& i, SAX* sax,
  3569. input_format_t format = input_format_t::json,
  3570. const bool strict = true,
  3571. const bool ignore_comments = false)
  3572. {
  3573. auto ia = detail::input_adapter(std::forward<InputType>(i));
  3574. return format == input_format_t::json
  3575. ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
  3576. : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict);
  3577. }
  3578. /// @brief generate SAX events
  3579. /// @sa https://json.nlohmann.me/api/basic_json/sax_parse/
  3580. template<class IteratorType, class SAX>
  3581. JSON_HEDLEY_NON_NULL(3)
  3582. static bool sax_parse(IteratorType first, IteratorType last, SAX* sax,
  3583. input_format_t format = input_format_t::json,
  3584. const bool strict = true,
  3585. const bool ignore_comments = false)
  3586. {
  3587. auto ia = detail::input_adapter(std::move(first), std::move(last));
  3588. return format == input_format_t::json
  3589. ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
  3590. : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict);
  3591. }
  3592. /// @brief generate SAX events
  3593. /// @sa https://json.nlohmann.me/api/basic_json/sax_parse/
  3594. /// @deprecated This function is deprecated since 3.8.0 and will be removed in
  3595. /// version 4.0.0 of the library. Please use
  3596. /// sax_parse(ptr, ptr + len) instead.
  3597. template <typename SAX>
  3598. JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))
  3599. JSON_HEDLEY_NON_NULL(2)
  3600. static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,
  3601. input_format_t format = input_format_t::json,
  3602. const bool strict = true,
  3603. const bool ignore_comments = false)
  3604. {
  3605. auto ia = i.get();
  3606. return format == input_format_t::json
  3607. // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
  3608. ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
  3609. // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
  3610. : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict);
  3611. }
  3612. #ifndef JSON_NO_IO
  3613. /// @brief deserialize from stream
  3614. /// @sa https://json.nlohmann.me/api/basic_json/operator_gtgt/
  3615. /// @deprecated This stream operator is deprecated since 3.0.0 and will be removed in
  3616. /// version 4.0.0 of the library. Please use
  3617. /// operator>>(std::istream&, basic_json&) instead; that is,
  3618. /// replace calls like `j << i;` with `i >> j;`.
  3619. JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&))
  3620. friend std::istream& operator<<(basic_json& j, std::istream& i)
  3621. {
  3622. return operator>>(i, j);
  3623. }
  3624. /// @brief deserialize from stream
  3625. /// @sa https://json.nlohmann.me/api/basic_json/operator_gtgt/
  3626. friend std::istream& operator>>(std::istream& i, basic_json& j)
  3627. {
  3628. parser(detail::input_adapter(i)).parse(false, j);
  3629. return i;
  3630. }
  3631. #endif // JSON_NO_IO
  3632. /// @}
  3633. ///////////////////////////
  3634. // convenience functions //
  3635. ///////////////////////////
  3636. /// @brief return the type as string
  3637. /// @sa https://json.nlohmann.me/api/basic_json/type_name/
  3638. JSON_HEDLEY_RETURNS_NON_NULL
  3639. const char* type_name() const noexcept
  3640. {
  3641. switch (m_data.m_type)
  3642. {
  3643. case value_t::null:
  3644. return "null";
  3645. case value_t::object:
  3646. return "object";
  3647. case value_t::array:
  3648. return "array";
  3649. case value_t::string:
  3650. return "string";
  3651. case value_t::boolean:
  3652. return "boolean";
  3653. case value_t::binary:
  3654. return "binary";
  3655. case value_t::discarded:
  3656. return "discarded";
  3657. case value_t::number_integer:
  3658. case value_t::number_unsigned:
  3659. case value_t::number_float:
  3660. default:
  3661. return "number";
  3662. }
  3663. }
  3664. JSON_PRIVATE_UNLESS_TESTED:
  3665. //////////////////////
  3666. // member variables //
  3667. //////////////////////
  3668. struct data
  3669. {
  3670. /// the type of the current element
  3671. value_t m_type = value_t::null;
  3672. /// the value of the current element
  3673. json_value m_value = {};
  3674. data(const value_t v)
  3675. : m_type(v), m_value(v)
  3676. {
  3677. }
  3678. data(size_type cnt, const basic_json& val)
  3679. : m_type(value_t::array)
  3680. {
  3681. m_value.array = create<array_t>(cnt, val);
  3682. }
  3683. data() noexcept = default;
  3684. data(data&&) noexcept = default;
  3685. data(const data&) noexcept = delete;
  3686. data& operator=(data&&) noexcept = delete;
  3687. data& operator=(const data&) noexcept = delete;
  3688. ~data() noexcept
  3689. {
  3690. m_value.destroy(m_type);
  3691. }
  3692. };
  3693. data m_data = {};
  3694. #if JSON_DIAGNOSTICS
  3695. /// a pointer to a parent value (for debugging purposes)
  3696. basic_json* m_parent = nullptr;
  3697. #endif
  3698. #if JSON_DIAGNOSTIC_POSITIONS
  3699. /// the start position of the value
  3700. std::size_t start_position = std::string::npos;
  3701. /// the end position of the value
  3702. std::size_t end_position = std::string::npos;
  3703. public:
  3704. constexpr std::size_t start_pos() const noexcept
  3705. {
  3706. return start_position;
  3707. }
  3708. constexpr std::size_t end_pos() const noexcept
  3709. {
  3710. return end_position;
  3711. }
  3712. #endif
  3713. //////////////////////////////////////////
  3714. // binary serialization/deserialization //
  3715. //////////////////////////////////////////
  3716. /// @name binary serialization/deserialization support
  3717. /// @{
  3718. public:
  3719. /// @brief create a CBOR serialization of a given JSON value
  3720. /// @sa https://json.nlohmann.me/api/basic_json/to_cbor/
  3721. static std::vector<std::uint8_t> to_cbor(const basic_json& j)
  3722. {
  3723. std::vector<std::uint8_t> result;
  3724. to_cbor(j, result);
  3725. return result;
  3726. }
  3727. /// @brief create a CBOR serialization of a given JSON value
  3728. /// @sa https://json.nlohmann.me/api/basic_json/to_cbor/
  3729. static void to_cbor(const basic_json& j, detail::output_adapter<std::uint8_t> o)
  3730. {
  3731. binary_writer<std::uint8_t>(o).write_cbor(j);
  3732. }
  3733. /// @brief create a CBOR serialization of a given JSON value
  3734. /// @sa https://json.nlohmann.me/api/basic_json/to_cbor/
  3735. static void to_cbor(const basic_json& j, detail::output_adapter<char> o)
  3736. {
  3737. binary_writer<char>(o).write_cbor(j);
  3738. }
  3739. /// @brief create a MessagePack serialization of a given JSON value
  3740. /// @sa https://json.nlohmann.me/api/basic_json/to_msgpack/
  3741. static std::vector<std::uint8_t> to_msgpack(const basic_json& j)
  3742. {
  3743. std::vector<std::uint8_t> result;
  3744. to_msgpack(j, result);
  3745. return result;
  3746. }
  3747. /// @brief create a MessagePack serialization of a given JSON value
  3748. /// @sa https://json.nlohmann.me/api/basic_json/to_msgpack/
  3749. static void to_msgpack(const basic_json& j, detail::output_adapter<std::uint8_t> o)
  3750. {
  3751. binary_writer<std::uint8_t>(o).write_msgpack(j);
  3752. }
  3753. /// @brief create a MessagePack serialization of a given JSON value
  3754. /// @sa https://json.nlohmann.me/api/basic_json/to_msgpack/
  3755. static void to_msgpack(const basic_json& j, detail::output_adapter<char> o)
  3756. {
  3757. binary_writer<char>(o).write_msgpack(j);
  3758. }
  3759. /// @brief create a UBJSON serialization of a given JSON value
  3760. /// @sa https://json.nlohmann.me/api/basic_json/to_ubjson/
  3761. static std::vector<std::uint8_t> to_ubjson(const basic_json& j,
  3762. const bool use_size = false,
  3763. const bool use_type = false)
  3764. {
  3765. std::vector<std::uint8_t> result;
  3766. to_ubjson(j, result, use_size, use_type);
  3767. return result;
  3768. }
  3769. /// @brief create a UBJSON serialization of a given JSON value
  3770. /// @sa https://json.nlohmann.me/api/basic_json/to_ubjson/
  3771. static void to_ubjson(const basic_json& j, detail::output_adapter<std::uint8_t> o,
  3772. const bool use_size = false, const bool use_type = false)
  3773. {
  3774. binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type);
  3775. }
  3776. /// @brief create a UBJSON serialization of a given JSON value
  3777. /// @sa https://json.nlohmann.me/api/basic_json/to_ubjson/
  3778. static void to_ubjson(const basic_json& j, detail::output_adapter<char> o,
  3779. const bool use_size = false, const bool use_type = false)
  3780. {
  3781. binary_writer<char>(o).write_ubjson(j, use_size, use_type);
  3782. }
  3783. /// @brief create a BJData serialization of a given JSON value
  3784. /// @sa https://json.nlohmann.me/api/basic_json/to_bjdata/
  3785. static std::vector<std::uint8_t> to_bjdata(const basic_json& j,
  3786. const bool use_size = false,
  3787. const bool use_type = false,
  3788. const bjdata_version_t version = bjdata_version_t::draft2)
  3789. {
  3790. std::vector<std::uint8_t> result;
  3791. to_bjdata(j, result, use_size, use_type, version);
  3792. return result;
  3793. }
  3794. /// @brief create a BJData serialization of a given JSON value
  3795. /// @sa https://json.nlohmann.me/api/basic_json/to_bjdata/
  3796. static void to_bjdata(const basic_json& j, detail::output_adapter<std::uint8_t> o,
  3797. const bool use_size = false, const bool use_type = false,
  3798. const bjdata_version_t version = bjdata_version_t::draft2)
  3799. {
  3800. binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type, true, true, version);
  3801. }
  3802. /// @brief create a BJData serialization of a given JSON value
  3803. /// @sa https://json.nlohmann.me/api/basic_json/to_bjdata/
  3804. static void to_bjdata(const basic_json& j, detail::output_adapter<char> o,
  3805. const bool use_size = false, const bool use_type = false,
  3806. const bjdata_version_t version = bjdata_version_t::draft2)
  3807. {
  3808. binary_writer<char>(o).write_ubjson(j, use_size, use_type, true, true, version);
  3809. }
  3810. /// @brief create a BSON serialization of a given JSON value
  3811. /// @sa https://json.nlohmann.me/api/basic_json/to_bson/
  3812. static std::vector<std::uint8_t> to_bson(const basic_json& j)
  3813. {
  3814. std::vector<std::uint8_t> result;
  3815. to_bson(j, result);
  3816. return result;
  3817. }
  3818. /// @brief create a BSON serialization of a given JSON value
  3819. /// @sa https://json.nlohmann.me/api/basic_json/to_bson/
  3820. static void to_bson(const basic_json& j, detail::output_adapter<std::uint8_t> o)
  3821. {
  3822. binary_writer<std::uint8_t>(o).write_bson(j);
  3823. }
  3824. /// @brief create a BSON serialization of a given JSON value
  3825. /// @sa https://json.nlohmann.me/api/basic_json/to_bson/
  3826. static void to_bson(const basic_json& j, detail::output_adapter<char> o)
  3827. {
  3828. binary_writer<char>(o).write_bson(j);
  3829. }
  3830. /// @brief create a JSON value from an input in CBOR format
  3831. /// @sa https://json.nlohmann.me/api/basic_json/from_cbor/
  3832. template<typename InputType>
  3833. JSON_HEDLEY_WARN_UNUSED_RESULT
  3834. static basic_json from_cbor(InputType&& i,
  3835. const bool strict = true,
  3836. const bool allow_exceptions = true,
  3837. const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
  3838. {
  3839. basic_json result;
  3840. auto ia = detail::input_adapter(std::forward<InputType>(i));
  3841. detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
  3842. const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler); // cppcheck-suppress[accessMoved]
  3843. return res ? result : basic_json(value_t::discarded);
  3844. }
  3845. /// @brief create a JSON value from an input in CBOR format
  3846. /// @sa https://json.nlohmann.me/api/basic_json/from_cbor/
  3847. template<typename IteratorType>
  3848. JSON_HEDLEY_WARN_UNUSED_RESULT
  3849. static basic_json from_cbor(IteratorType first, IteratorType last,
  3850. const bool strict = true,
  3851. const bool allow_exceptions = true,
  3852. const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
  3853. {
  3854. basic_json result;
  3855. auto ia = detail::input_adapter(std::move(first), std::move(last));
  3856. detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
  3857. const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler); // cppcheck-suppress[accessMoved]
  3858. return res ? result : basic_json(value_t::discarded);
  3859. }
  3860. template<typename T>
  3861. JSON_HEDLEY_WARN_UNUSED_RESULT
  3862. JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
  3863. static basic_json from_cbor(const T* ptr, std::size_t len,
  3864. const bool strict = true,
  3865. const bool allow_exceptions = true,
  3866. const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
  3867. {
  3868. return from_cbor(ptr, ptr + len, strict, allow_exceptions, tag_handler);
  3869. }
  3870. JSON_HEDLEY_WARN_UNUSED_RESULT
  3871. JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
  3872. static basic_json from_cbor(detail::span_input_adapter&& i,
  3873. const bool strict = true,
  3874. const bool allow_exceptions = true,
  3875. const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
  3876. {
  3877. basic_json result;
  3878. auto ia = i.get();
  3879. detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
  3880. // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
  3881. const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler); // cppcheck-suppress[accessMoved]
  3882. return res ? result : basic_json(value_t::discarded);
  3883. }
  3884. /// @brief create a JSON value from an input in MessagePack format
  3885. /// @sa https://json.nlohmann.me/api/basic_json/from_msgpack/
  3886. template<typename InputType>
  3887. JSON_HEDLEY_WARN_UNUSED_RESULT
  3888. static basic_json from_msgpack(InputType&& i,
  3889. const bool strict = true,
  3890. const bool allow_exceptions = true)
  3891. {
  3892. basic_json result;
  3893. auto ia = detail::input_adapter(std::forward<InputType>(i));
  3894. detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
  3895. const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict); // cppcheck-suppress[accessMoved]
  3896. return res ? result : basic_json(value_t::discarded);
  3897. }
  3898. /// @brief create a JSON value from an input in MessagePack format
  3899. /// @sa https://json.nlohmann.me/api/basic_json/from_msgpack/
  3900. template<typename IteratorType>
  3901. JSON_HEDLEY_WARN_UNUSED_RESULT
  3902. static basic_json from_msgpack(IteratorType first, IteratorType last,
  3903. const bool strict = true,
  3904. const bool allow_exceptions = true)
  3905. {
  3906. basic_json result;
  3907. auto ia = detail::input_adapter(std::move(first), std::move(last));
  3908. detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
  3909. const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict); // cppcheck-suppress[accessMoved]
  3910. return res ? result : basic_json(value_t::discarded);
  3911. }
  3912. template<typename T>
  3913. JSON_HEDLEY_WARN_UNUSED_RESULT
  3914. JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
  3915. static basic_json from_msgpack(const T* ptr, std::size_t len,
  3916. const bool strict = true,
  3917. const bool allow_exceptions = true)
  3918. {
  3919. return from_msgpack(ptr, ptr + len, strict, allow_exceptions);
  3920. }
  3921. JSON_HEDLEY_WARN_UNUSED_RESULT
  3922. JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
  3923. static basic_json from_msgpack(detail::span_input_adapter&& i,
  3924. const bool strict = true,
  3925. const bool allow_exceptions = true)
  3926. {
  3927. basic_json result;
  3928. auto ia = i.get();
  3929. detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
  3930. // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
  3931. const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict); // cppcheck-suppress[accessMoved]
  3932. return res ? result : basic_json(value_t::discarded);
  3933. }
  3934. /// @brief create a JSON value from an input in UBJSON format
  3935. /// @sa https://json.nlohmann.me/api/basic_json/from_ubjson/
  3936. template<typename InputType>
  3937. JSON_HEDLEY_WARN_UNUSED_RESULT
  3938. static basic_json from_ubjson(InputType&& i,
  3939. const bool strict = true,
  3940. const bool allow_exceptions = true)
  3941. {
  3942. basic_json result;
  3943. auto ia = detail::input_adapter(std::forward<InputType>(i));
  3944. detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
  3945. const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict); // cppcheck-suppress[accessMoved]
  3946. return res ? result : basic_json(value_t::discarded);
  3947. }
  3948. /// @brief create a JSON value from an input in UBJSON format
  3949. /// @sa https://json.nlohmann.me/api/basic_json/from_ubjson/
  3950. template<typename IteratorType>
  3951. JSON_HEDLEY_WARN_UNUSED_RESULT
  3952. static basic_json from_ubjson(IteratorType first, IteratorType last,
  3953. const bool strict = true,
  3954. const bool allow_exceptions = true)
  3955. {
  3956. basic_json result;
  3957. auto ia = detail::input_adapter(std::move(first), std::move(last));
  3958. detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
  3959. const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict); // cppcheck-suppress[accessMoved]
  3960. return res ? result : basic_json(value_t::discarded);
  3961. }
  3962. template<typename T>
  3963. JSON_HEDLEY_WARN_UNUSED_RESULT
  3964. JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
  3965. static basic_json from_ubjson(const T* ptr, std::size_t len,
  3966. const bool strict = true,
  3967. const bool allow_exceptions = true)
  3968. {
  3969. return from_ubjson(ptr, ptr + len, strict, allow_exceptions);
  3970. }
  3971. JSON_HEDLEY_WARN_UNUSED_RESULT
  3972. JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
  3973. static basic_json from_ubjson(detail::span_input_adapter&& i,
  3974. const bool strict = true,
  3975. const bool allow_exceptions = true)
  3976. {
  3977. basic_json result;
  3978. auto ia = i.get();
  3979. detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
  3980. // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
  3981. const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict); // cppcheck-suppress[accessMoved]
  3982. return res ? result : basic_json(value_t::discarded);
  3983. }
  3984. /// @brief create a JSON value from an input in BJData format
  3985. /// @sa https://json.nlohmann.me/api/basic_json/from_bjdata/
  3986. template<typename InputType>
  3987. JSON_HEDLEY_WARN_UNUSED_RESULT
  3988. static basic_json from_bjdata(InputType&& i,
  3989. const bool strict = true,
  3990. const bool allow_exceptions = true)
  3991. {
  3992. basic_json result;
  3993. auto ia = detail::input_adapter(std::forward<InputType>(i));
  3994. detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
  3995. const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bjdata).sax_parse(input_format_t::bjdata, &sdp, strict); // cppcheck-suppress[accessMoved]
  3996. return res ? result : basic_json(value_t::discarded);
  3997. }
  3998. /// @brief create a JSON value from an input in BJData format
  3999. /// @sa https://json.nlohmann.me/api/basic_json/from_bjdata/
  4000. template<typename IteratorType>
  4001. JSON_HEDLEY_WARN_UNUSED_RESULT
  4002. static basic_json from_bjdata(IteratorType first, IteratorType last,
  4003. const bool strict = true,
  4004. const bool allow_exceptions = true)
  4005. {
  4006. basic_json result;
  4007. auto ia = detail::input_adapter(std::move(first), std::move(last));
  4008. detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
  4009. const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bjdata).sax_parse(input_format_t::bjdata, &sdp, strict); // cppcheck-suppress[accessMoved]
  4010. return res ? result : basic_json(value_t::discarded);
  4011. }
  4012. /// @brief create a JSON value from an input in BSON format
  4013. /// @sa https://json.nlohmann.me/api/basic_json/from_bson/
  4014. template<typename InputType>
  4015. JSON_HEDLEY_WARN_UNUSED_RESULT
  4016. static basic_json from_bson(InputType&& i,
  4017. const bool strict = true,
  4018. const bool allow_exceptions = true)
  4019. {
  4020. basic_json result;
  4021. auto ia = detail::input_adapter(std::forward<InputType>(i));
  4022. detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
  4023. const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict); // cppcheck-suppress[accessMoved]
  4024. return res ? result : basic_json(value_t::discarded);
  4025. }
  4026. /// @brief create a JSON value from an input in BSON format
  4027. /// @sa https://json.nlohmann.me/api/basic_json/from_bson/
  4028. template<typename IteratorType>
  4029. JSON_HEDLEY_WARN_UNUSED_RESULT
  4030. static basic_json from_bson(IteratorType first, IteratorType last,
  4031. const bool strict = true,
  4032. const bool allow_exceptions = true)
  4033. {
  4034. basic_json result;
  4035. auto ia = detail::input_adapter(std::move(first), std::move(last));
  4036. detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
  4037. const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict); // cppcheck-suppress[accessMoved]
  4038. return res ? result : basic_json(value_t::discarded);
  4039. }
  4040. template<typename T>
  4041. JSON_HEDLEY_WARN_UNUSED_RESULT
  4042. JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
  4043. static basic_json from_bson(const T* ptr, std::size_t len,
  4044. const bool strict = true,
  4045. const bool allow_exceptions = true)
  4046. {
  4047. return from_bson(ptr, ptr + len, strict, allow_exceptions);
  4048. }
  4049. JSON_HEDLEY_WARN_UNUSED_RESULT
  4050. JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
  4051. static basic_json from_bson(detail::span_input_adapter&& i,
  4052. const bool strict = true,
  4053. const bool allow_exceptions = true)
  4054. {
  4055. basic_json result;
  4056. auto ia = i.get();
  4057. detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
  4058. // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
  4059. const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict); // cppcheck-suppress[accessMoved]
  4060. return res ? result : basic_json(value_t::discarded);
  4061. }
  4062. /// @}
  4063. //////////////////////////
  4064. // JSON Pointer support //
  4065. //////////////////////////
  4066. /// @name JSON Pointer functions
  4067. /// @{
  4068. /// @brief access specified element via JSON Pointer
  4069. /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/
  4070. reference operator[](const json_pointer& ptr)
  4071. {
  4072. return ptr.get_unchecked(this);
  4073. }
  4074. template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
  4075. JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
  4076. reference operator[](const ::nlohmann::json_pointer<BasicJsonType>& ptr)
  4077. {
  4078. return ptr.get_unchecked(this);
  4079. }
  4080. /// @brief access specified element via JSON Pointer
  4081. /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/
  4082. const_reference operator[](const json_pointer& ptr) const
  4083. {
  4084. return ptr.get_unchecked(this);
  4085. }
  4086. template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
  4087. JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
  4088. const_reference operator[](const ::nlohmann::json_pointer<BasicJsonType>& ptr) const
  4089. {
  4090. return ptr.get_unchecked(this);
  4091. }
  4092. /// @brief access specified element via JSON Pointer
  4093. /// @sa https://json.nlohmann.me/api/basic_json/at/
  4094. reference at(const json_pointer& ptr)
  4095. {
  4096. return ptr.get_checked(this);
  4097. }
  4098. template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
  4099. JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
  4100. reference at(const ::nlohmann::json_pointer<BasicJsonType>& ptr)
  4101. {
  4102. return ptr.get_checked(this);
  4103. }
  4104. /// @brief access specified element via JSON Pointer
  4105. /// @sa https://json.nlohmann.me/api/basic_json/at/
  4106. const_reference at(const json_pointer& ptr) const
  4107. {
  4108. return ptr.get_checked(this);
  4109. }
  4110. template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
  4111. JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
  4112. const_reference at(const ::nlohmann::json_pointer<BasicJsonType>& ptr) const
  4113. {
  4114. return ptr.get_checked(this);
  4115. }
  4116. /// @brief return flattened JSON value
  4117. /// @sa https://json.nlohmann.me/api/basic_json/flatten/
  4118. basic_json flatten() const
  4119. {
  4120. basic_json result(value_t::object);
  4121. json_pointer::flatten("", *this, result);
  4122. return result;
  4123. }
  4124. /// @brief unflatten a previously flattened JSON value
  4125. /// @sa https://json.nlohmann.me/api/basic_json/unflatten/
  4126. basic_json unflatten() const
  4127. {
  4128. return json_pointer::unflatten(*this);
  4129. }
  4130. /// @}
  4131. //////////////////////////
  4132. // JSON Patch functions //
  4133. //////////////////////////
  4134. /// @name JSON Patch functions
  4135. /// @{
  4136. /// @brief applies a JSON patch in-place without copying the object
  4137. /// @sa https://json.nlohmann.me/api/basic_json/patch/
  4138. void patch_inplace(const basic_json& json_patch)
  4139. {
  4140. basic_json& result = *this;
  4141. // the valid JSON Patch operations
  4142. enum class patch_operations {add, remove, replace, move, copy, test, invalid};
  4143. const auto get_op = [](const string_t& op)
  4144. {
  4145. if (op == "add")
  4146. {
  4147. return patch_operations::add;
  4148. }
  4149. if (op == "remove")
  4150. {
  4151. return patch_operations::remove;
  4152. }
  4153. if (op == "replace")
  4154. {
  4155. return patch_operations::replace;
  4156. }
  4157. if (op == "move")
  4158. {
  4159. return patch_operations::move;
  4160. }
  4161. if (op == "copy")
  4162. {
  4163. return patch_operations::copy;
  4164. }
  4165. if (op == "test")
  4166. {
  4167. return patch_operations::test;
  4168. }
  4169. return patch_operations::invalid;
  4170. };
  4171. // wrapper for "add" operation; add value at ptr
  4172. const auto operation_add = [&result](json_pointer & ptr, const basic_json & val)
  4173. {
  4174. // adding to the root of the target document means replacing it
  4175. if (ptr.empty())
  4176. {
  4177. result = val;
  4178. return;
  4179. }
  4180. // make sure the top element of the pointer exists
  4181. json_pointer const top_pointer = ptr.top();
  4182. if (top_pointer != ptr)
  4183. {
  4184. result.at(top_pointer);
  4185. }
  4186. // get reference to parent of JSON pointer ptr
  4187. const auto last_path = ptr.back();
  4188. ptr.pop_back();
  4189. // parent must exist when performing patch add per RFC6902 specs
  4190. basic_json& parent = result.at(ptr);
  4191. switch (parent.m_data.m_type)
  4192. {
  4193. case value_t::null:
  4194. case value_t::object:
  4195. {
  4196. // use operator[] to add value
  4197. parent[last_path] = val;
  4198. break;
  4199. }
  4200. case value_t::array:
  4201. {
  4202. if (last_path == "-")
  4203. {
  4204. // special case: append to back
  4205. parent.push_back(val);
  4206. }
  4207. else
  4208. {
  4209. const auto idx = json_pointer::template array_index<basic_json_t>(last_path);
  4210. if (JSON_HEDLEY_UNLIKELY(idx > parent.size()))
  4211. {
  4212. // avoid undefined behavior
  4213. JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), &parent));
  4214. }
  4215. // default case: insert add offset
  4216. parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
  4217. }
  4218. break;
  4219. }
  4220. // if there exists a parent it cannot be primitive
  4221. case value_t::string: // LCOV_EXCL_LINE
  4222. case value_t::boolean: // LCOV_EXCL_LINE
  4223. case value_t::number_integer: // LCOV_EXCL_LINE
  4224. case value_t::number_unsigned: // LCOV_EXCL_LINE
  4225. case value_t::number_float: // LCOV_EXCL_LINE
  4226. case value_t::binary: // LCOV_EXCL_LINE
  4227. case value_t::discarded: // LCOV_EXCL_LINE
  4228. default: // LCOV_EXCL_LINE
  4229. JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
  4230. }
  4231. };
  4232. // wrapper for "remove" operation; remove value at ptr
  4233. const auto operation_remove = [this, & result](json_pointer & ptr)
  4234. {
  4235. // get reference to parent of JSON pointer ptr
  4236. const auto last_path = ptr.back();
  4237. ptr.pop_back();
  4238. basic_json& parent = result.at(ptr);
  4239. // remove child
  4240. if (parent.is_object())
  4241. {
  4242. // perform range check
  4243. auto it = parent.find(last_path);
  4244. if (JSON_HEDLEY_LIKELY(it != parent.end()))
  4245. {
  4246. parent.erase(it);
  4247. }
  4248. else
  4249. {
  4250. JSON_THROW(out_of_range::create(403, detail::concat("key '", last_path, "' not found"), this));
  4251. }
  4252. }
  4253. else if (parent.is_array())
  4254. {
  4255. // note erase performs range check
  4256. parent.erase(json_pointer::template array_index<basic_json_t>(last_path));
  4257. }
  4258. };
  4259. // type check: top level value must be an array
  4260. if (JSON_HEDLEY_UNLIKELY(!json_patch.is_array()))
  4261. {
  4262. JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", &json_patch));
  4263. }
  4264. // iterate and apply the operations
  4265. for (const auto& val : json_patch)
  4266. {
  4267. // wrapper to get a value for an operation
  4268. const auto get_value = [&val](const string_t& op,
  4269. const string_t& member,
  4270. bool string_type) -> basic_json &
  4271. {
  4272. // find value
  4273. auto it = val.m_data.m_value.object->find(member);
  4274. // context-sensitive error message
  4275. const auto error_msg = (op == "op") ? "operation" : detail::concat("operation '", op, '\''); // NOLINT(bugprone-unused-local-non-trivial-variable)
  4276. // check if desired value is present
  4277. if (JSON_HEDLEY_UNLIKELY(it == val.m_data.m_value.object->end()))
  4278. {
  4279. // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
  4280. JSON_THROW(parse_error::create(105, 0, detail::concat(error_msg, " must have member '", member, "'"), &val));
  4281. }
  4282. // check if result is of type string
  4283. if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string()))
  4284. {
  4285. // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
  4286. JSON_THROW(parse_error::create(105, 0, detail::concat(error_msg, " must have string member '", member, "'"), &val));
  4287. }
  4288. // no error: return value
  4289. return it->second;
  4290. };
  4291. // type check: every element of the array must be an object
  4292. if (JSON_HEDLEY_UNLIKELY(!val.is_object()))
  4293. {
  4294. JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", &val));
  4295. }
  4296. // collect mandatory members
  4297. const auto op = get_value("op", "op", true).template get<string_t>();
  4298. const auto path = get_value(op, "path", true).template get<string_t>();
  4299. json_pointer ptr(path);
  4300. switch (get_op(op))
  4301. {
  4302. case patch_operations::add:
  4303. {
  4304. operation_add(ptr, get_value("add", "value", false));
  4305. break;
  4306. }
  4307. case patch_operations::remove:
  4308. {
  4309. operation_remove(ptr);
  4310. break;
  4311. }
  4312. case patch_operations::replace:
  4313. {
  4314. // the "path" location must exist - use at()
  4315. result.at(ptr) = get_value("replace", "value", false);
  4316. break;
  4317. }
  4318. case patch_operations::move:
  4319. {
  4320. const auto from_path = get_value("move", "from", true).template get<string_t>();
  4321. json_pointer from_ptr(from_path);
  4322. // the "from" location must exist - use at()
  4323. basic_json const v = result.at(from_ptr);
  4324. // The move operation is functionally identical to a
  4325. // "remove" operation on the "from" location, followed
  4326. // immediately by an "add" operation at the target
  4327. // location with the value that was just removed.
  4328. operation_remove(from_ptr);
  4329. operation_add(ptr, v);
  4330. break;
  4331. }
  4332. case patch_operations::copy:
  4333. {
  4334. const auto from_path = get_value("copy", "from", true).template get<string_t>();
  4335. const json_pointer from_ptr(from_path);
  4336. // the "from" location must exist - use at()
  4337. basic_json const v = result.at(from_ptr);
  4338. // The copy is functionally identical to an "add"
  4339. // operation at the target location using the value
  4340. // specified in the "from" member.
  4341. operation_add(ptr, v);
  4342. break;
  4343. }
  4344. case patch_operations::test:
  4345. {
  4346. bool success = false;
  4347. JSON_TRY
  4348. {
  4349. // check if "value" matches the one at "path"
  4350. // the "path" location must exist - use at()
  4351. success = (result.at(ptr) == get_value("test", "value", false));
  4352. }
  4353. JSON_INTERNAL_CATCH (out_of_range&)
  4354. {
  4355. // ignore out of range errors: success remains false
  4356. }
  4357. // throw an exception if test fails
  4358. if (JSON_HEDLEY_UNLIKELY(!success))
  4359. {
  4360. JSON_THROW(other_error::create(501, detail::concat("unsuccessful: ", val.dump()), &val));
  4361. }
  4362. break;
  4363. }
  4364. case patch_operations::invalid:
  4365. default:
  4366. {
  4367. // op must be "add", "remove", "replace", "move", "copy", or
  4368. // "test"
  4369. JSON_THROW(parse_error::create(105, 0, detail::concat("operation value '", op, "' is invalid"), &val));
  4370. }
  4371. }
  4372. }
  4373. }
  4374. /// @brief applies a JSON patch to a copy of the current object
  4375. /// @sa https://json.nlohmann.me/api/basic_json/patch/
  4376. basic_json patch(const basic_json& json_patch) const
  4377. {
  4378. basic_json result = *this;
  4379. result.patch_inplace(json_patch);
  4380. return result;
  4381. }
  4382. /// @brief creates a diff as a JSON patch
  4383. /// @sa https://json.nlohmann.me/api/basic_json/diff/
  4384. JSON_HEDLEY_WARN_UNUSED_RESULT
  4385. static basic_json diff(const basic_json& source, const basic_json& target,
  4386. const string_t& path = "")
  4387. {
  4388. // the patch
  4389. basic_json result(value_t::array);
  4390. // if the values are the same, return empty patch
  4391. if (source == target)
  4392. {
  4393. return result;
  4394. }
  4395. if (source.type() != target.type())
  4396. {
  4397. // different types: replace value
  4398. result.push_back(
  4399. {
  4400. {"op", "replace"}, {"path", path}, {"value", target}
  4401. });
  4402. return result;
  4403. }
  4404. switch (source.type())
  4405. {
  4406. case value_t::array:
  4407. {
  4408. // first pass: traverse common elements
  4409. std::size_t i = 0;
  4410. while (i < source.size() && i < target.size())
  4411. {
  4412. // recursive call to compare array values at index i
  4413. auto temp_diff = diff(source[i], target[i], detail::concat<string_t>(path, '/', detail::to_string<string_t>(i)));
  4414. result.insert(result.end(), temp_diff.begin(), temp_diff.end());
  4415. ++i;
  4416. }
  4417. // We now reached the end of at least one array
  4418. // in a second pass, traverse the remaining elements
  4419. // remove my remaining elements
  4420. const auto end_index = static_cast<difference_type>(result.size());
  4421. while (i < source.size())
  4422. {
  4423. // add operations in reverse order to avoid invalid
  4424. // indices
  4425. result.insert(result.begin() + end_index, object(
  4426. {
  4427. {"op", "remove"},
  4428. {"path", detail::concat<string_t>(path, '/', detail::to_string<string_t>(i))}
  4429. }));
  4430. ++i;
  4431. }
  4432. // add other remaining elements
  4433. while (i < target.size())
  4434. {
  4435. result.push_back(
  4436. {
  4437. {"op", "add"},
  4438. {"path", detail::concat<string_t>(path, "/-")},
  4439. {"value", target[i]}
  4440. });
  4441. ++i;
  4442. }
  4443. break;
  4444. }
  4445. case value_t::object:
  4446. {
  4447. // first pass: traverse this object's elements
  4448. for (auto it = source.cbegin(); it != source.cend(); ++it)
  4449. {
  4450. // escape the key name to be used in a JSON patch
  4451. const auto path_key = detail::concat<string_t>(path, '/', detail::escape(it.key()));
  4452. if (target.find(it.key()) != target.end())
  4453. {
  4454. // recursive call to compare object values at key it
  4455. auto temp_diff = diff(it.value(), target[it.key()], path_key);
  4456. result.insert(result.end(), temp_diff.begin(), temp_diff.end());
  4457. }
  4458. else
  4459. {
  4460. // found a key that is not in o -> remove it
  4461. result.push_back(object(
  4462. {
  4463. {"op", "remove"}, {"path", path_key}
  4464. }));
  4465. }
  4466. }
  4467. // second pass: traverse other object's elements
  4468. for (auto it = target.cbegin(); it != target.cend(); ++it)
  4469. {
  4470. if (source.find(it.key()) == source.end())
  4471. {
  4472. // found a key that is not in this -> add it
  4473. const auto path_key = detail::concat<string_t>(path, '/', detail::escape(it.key()));
  4474. result.push_back(
  4475. {
  4476. {"op", "add"}, {"path", path_key},
  4477. {"value", it.value()}
  4478. });
  4479. }
  4480. }
  4481. break;
  4482. }
  4483. case value_t::null:
  4484. case value_t::string:
  4485. case value_t::boolean:
  4486. case value_t::number_integer:
  4487. case value_t::number_unsigned:
  4488. case value_t::number_float:
  4489. case value_t::binary:
  4490. case value_t::discarded:
  4491. default:
  4492. {
  4493. // both primitive type: replace value
  4494. result.push_back(
  4495. {
  4496. {"op", "replace"}, {"path", path}, {"value", target}
  4497. });
  4498. break;
  4499. }
  4500. }
  4501. return result;
  4502. }
  4503. /// @}
  4504. ////////////////////////////////
  4505. // JSON Merge Patch functions //
  4506. ////////////////////////////////
  4507. /// @name JSON Merge Patch functions
  4508. /// @{
  4509. /// @brief applies a JSON Merge Patch
  4510. /// @sa https://json.nlohmann.me/api/basic_json/merge_patch/
  4511. void merge_patch(const basic_json& apply_patch)
  4512. {
  4513. if (apply_patch.is_object())
  4514. {
  4515. if (!is_object())
  4516. {
  4517. *this = object();
  4518. }
  4519. for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
  4520. {
  4521. if (it.value().is_null())
  4522. {
  4523. erase(it.key());
  4524. }
  4525. else
  4526. {
  4527. operator[](it.key()).merge_patch(it.value());
  4528. }
  4529. }
  4530. }
  4531. else
  4532. {
  4533. *this = apply_patch;
  4534. }
  4535. }
  4536. /// @}
  4537. };
  4538. /// @brief user-defined to_string function for JSON values
  4539. /// @sa https://json.nlohmann.me/api/basic_json/to_string/
  4540. NLOHMANN_BASIC_JSON_TPL_DECLARATION
  4541. std::string to_string(const NLOHMANN_BASIC_JSON_TPL& j)
  4542. {
  4543. return j.dump();
  4544. }
  4545. inline namespace literals
  4546. {
  4547. inline namespace json_literals
  4548. {
  4549. /// @brief user-defined string literal for JSON values
  4550. /// @sa https://json.nlohmann.me/api/basic_json/operator_literal_json/
  4551. JSON_HEDLEY_NON_NULL(1)
  4552. #if !defined(JSON_HEDLEY_GCC_VERSION) || JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0)
  4553. inline nlohmann::json operator ""_json(const char* s, std::size_t n)
  4554. #else
  4555. inline nlohmann::json operator "" _json(const char* s, std::size_t n)
  4556. #endif
  4557. {
  4558. return nlohmann::json::parse(s, s + n);
  4559. }
  4560. /// @brief user-defined string literal for JSON pointer
  4561. /// @sa https://json.nlohmann.me/api/basic_json/operator_literal_json_pointer/
  4562. JSON_HEDLEY_NON_NULL(1)
  4563. #if !defined(JSON_HEDLEY_GCC_VERSION) || JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0)
  4564. inline nlohmann::json::json_pointer operator ""_json_pointer(const char* s, std::size_t n)
  4565. #else
  4566. inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
  4567. #endif
  4568. {
  4569. return nlohmann::json::json_pointer(std::string(s, n));
  4570. }
  4571. } // namespace json_literals
  4572. } // namespace literals
  4573. NLOHMANN_JSON_NAMESPACE_END
  4574. ///////////////////////
  4575. // nonmember support //
  4576. ///////////////////////
  4577. namespace std // NOLINT(cert-dcl58-cpp)
  4578. {
  4579. /// @brief hash value for JSON objects
  4580. /// @sa https://json.nlohmann.me/api/basic_json/std_hash/
  4581. NLOHMANN_BASIC_JSON_TPL_DECLARATION
  4582. struct hash<nlohmann::NLOHMANN_BASIC_JSON_TPL> // NOLINT(cert-dcl58-cpp)
  4583. {
  4584. std::size_t operator()(const nlohmann::NLOHMANN_BASIC_JSON_TPL& j) const
  4585. {
  4586. return nlohmann::detail::hash(j);
  4587. }
  4588. };
  4589. // specialization for std::less<value_t>
  4590. template<>
  4591. struct less< ::nlohmann::detail::value_t> // do not remove the space after '<', see https://github.com/nlohmann/json/pull/679
  4592. {
  4593. /*!
  4594. @brief compare two value_t enum values
  4595. @since version 3.0.0
  4596. */
  4597. bool operator()(::nlohmann::detail::value_t lhs,
  4598. ::nlohmann::detail::value_t rhs) const noexcept
  4599. {
  4600. #if JSON_HAS_THREE_WAY_COMPARISON
  4601. return std::is_lt(lhs <=> rhs); // *NOPAD*
  4602. #else
  4603. return ::nlohmann::detail::operator<(lhs, rhs);
  4604. #endif
  4605. }
  4606. };
  4607. // C++20 prohibit function specialization in the std namespace.
  4608. #ifndef JSON_HAS_CPP_20
  4609. /// @brief exchanges the values of two JSON objects
  4610. /// @sa https://json.nlohmann.me/api/basic_json/std_swap/
  4611. NLOHMANN_BASIC_JSON_TPL_DECLARATION
  4612. inline void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL& j1, nlohmann::NLOHMANN_BASIC_JSON_TPL& j2) noexcept( // NOLINT(readability-inconsistent-declaration-parameter-name, cert-dcl58-cpp)
  4613. is_nothrow_move_constructible<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value&& // NOLINT(misc-redundant-expression,cppcoreguidelines-noexcept-swap,performance-noexcept-swap)
  4614. is_nothrow_move_assignable<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value)
  4615. {
  4616. j1.swap(j2);
  4617. }
  4618. #endif
  4619. } // namespace std
  4620. #if JSON_USE_GLOBAL_UDLS
  4621. #if !defined(JSON_HEDLEY_GCC_VERSION) || JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0)
  4622. using nlohmann::literals::json_literals::operator ""_json; // NOLINT(misc-unused-using-decls,google-global-names-in-headers)
  4623. using nlohmann::literals::json_literals::operator ""_json_pointer; //NOLINT(misc-unused-using-decls,google-global-names-in-headers)
  4624. #else
  4625. using nlohmann::literals::json_literals::operator "" _json; // NOLINT(misc-unused-using-decls,google-global-names-in-headers)
  4626. using nlohmann::literals::json_literals::operator "" _json_pointer; //NOLINT(misc-unused-using-decls,google-global-names-in-headers)
  4627. #endif
  4628. #endif
  4629. #include <nlohmann/detail/macro_unscope.hpp>
  4630. #endif // INCLUDE_NLOHMANN_JSON_HPP_