json.hpp 167 KB

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