value.hpp 122 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867
  1. //
  2. // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
  3. // Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com)
  4. //
  5. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  6. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7. //
  8. // Official repository: https://github.com/boostorg/json
  9. //
  10. #ifndef BOOST_JSON_VALUE_HPP
  11. #define BOOST_JSON_VALUE_HPP
  12. #include <boost/json/detail/config.hpp>
  13. #include <boost/json/array.hpp>
  14. #include <boost/json/kind.hpp>
  15. #include <boost/json/object.hpp>
  16. #include <boost/json/pilfer.hpp>
  17. #include <boost/json/set_pointer_options.hpp>
  18. #include <boost/json/storage_ptr.hpp>
  19. #include <boost/json/string.hpp>
  20. #include <boost/json/string_view.hpp>
  21. #include <boost/json/value_ref.hpp>
  22. #include <boost/json/detail/except.hpp>
  23. #include <boost/json/detail/value.hpp>
  24. #include <cstdlib>
  25. #include <cstring>
  26. #include <initializer_list>
  27. #include <iosfwd>
  28. #include <limits>
  29. #include <new>
  30. #include <type_traits>
  31. #include <utility>
  32. namespace boost {
  33. namespace json {
  34. //----------------------------------------------------------
  35. /** The type used to represent any JSON value
  36. This is a
  37. <a href="https://en.cppreference.com/w/cpp/concepts/regular"><em>Regular</em></a>
  38. type which works like
  39. a variant of the basic JSON data types: array,
  40. object, string, number, boolean, and null.
  41. @par Thread Safety
  42. Distinct instances may be accessed concurrently.
  43. Non-const member functions of a shared instance
  44. may not be called concurrently with any other
  45. member functions of that instance.
  46. */
  47. class value
  48. {
  49. #ifndef BOOST_JSON_DOCS
  50. using scalar = detail::scalar;
  51. union
  52. {
  53. storage_ptr sp_; // must come first
  54. array arr_;
  55. object obj_;
  56. string str_;
  57. scalar sca_;
  58. };
  59. #endif
  60. struct init_iter;
  61. #ifndef BOOST_JSON_DOCS
  62. // VFALCO doc toolchain incorrectly treats this as public
  63. friend struct detail::access;
  64. #endif
  65. explicit
  66. value(
  67. detail::unchecked_array&& ua)
  68. : arr_(std::move(ua))
  69. {
  70. }
  71. explicit
  72. value(
  73. detail::unchecked_object&& uo)
  74. : obj_(std::move(uo))
  75. {
  76. }
  77. value(
  78. detail::key_t const&,
  79. string_view s,
  80. storage_ptr sp)
  81. : str_(detail::key_t{}, s, std::move(sp))
  82. {
  83. }
  84. value(
  85. detail::key_t const&,
  86. string_view s1,
  87. string_view s2,
  88. storage_ptr sp)
  89. : str_(detail::key_t{}, s1, s2, std::move(sp))
  90. {
  91. }
  92. inline bool is_scalar() const noexcept
  93. {
  94. return sca_.k < json::kind::string;
  95. }
  96. public:
  97. /// Associated [Allocator](https://en.cppreference.com/w/cpp/named_req/Allocator)
  98. using allocator_type = container::pmr::polymorphic_allocator<value>;
  99. /** Destructor.
  100. The value and all of its contents are destroyed.
  101. Any dynamically allocated memory that was allocated
  102. internally is freed.
  103. @par Complexity
  104. Constant, or linear in size for array or object.
  105. @par Exception Safety
  106. No-throw guarantee.
  107. */
  108. BOOST_JSON_DECL
  109. ~value() noexcept;
  110. /** Default constructor.
  111. The constructed value is null,
  112. using the [default memory resource].
  113. @par Complexity
  114. Constant.
  115. @par Exception Safety
  116. No-throw guarantee.
  117. [default memory resource]: json/allocators/storage_ptr.html#json.allocators.storage_ptr.default_memory_resource
  118. */
  119. value() noexcept
  120. : sca_()
  121. {
  122. }
  123. /** Constructor.
  124. The constructed value is null, using the
  125. specified `boost::container::pmr::memory_resource`.
  126. @par Complexity
  127. Constant.
  128. @par Exception Safety
  129. No-throw guarantee.
  130. @param sp A pointer to the `boost::container::pmr::memory_resource` to
  131. use. The container will acquire shared ownership of the memory
  132. resource.
  133. */
  134. explicit
  135. value(storage_ptr sp) noexcept
  136. : sca_(std::move(sp))
  137. {
  138. }
  139. /** Pilfer constructor.
  140. The value is constructed by acquiring ownership
  141. of the contents of `other` using pilfer semantics.
  142. This is more efficient than move construction, when
  143. it is known that the moved-from object will be
  144. immediately destroyed afterwards.
  145. @par Complexity
  146. Constant.
  147. @par Exception Safety
  148. No-throw guarantee.
  149. @param other The value to pilfer. After pilfer
  150. construction, `other` is not in a usable state
  151. and may only be destroyed.
  152. @see @ref pilfer,
  153. <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html">
  154. Valueless Variants Considered Harmful</a>
  155. */
  156. value(pilfered<value> other) noexcept
  157. {
  158. relocate(this, other.get());
  159. ::new(&other.get().sca_) scalar();
  160. }
  161. /** Copy constructor.
  162. The value is constructed with a copy of the
  163. contents of `other`, using the same
  164. memory resource as `other`.
  165. @par Complexity
  166. Linear in the size of `other`.
  167. @par Exception Safety
  168. Strong guarantee.
  169. Calls to `memory_resource::allocate` may throw.
  170. @param other The value to copy.
  171. */
  172. value(value const& other)
  173. : value(other, other.storage())
  174. {
  175. }
  176. /** Copy constructor
  177. The value is constructed with a copy of the
  178. contents of `other`, using the
  179. specified memory resource.
  180. @par Complexity
  181. Linear in the size of `other`.
  182. @par Exception Safety
  183. Strong guarantee.
  184. Calls to `memory_resource::allocate` may throw.
  185. @param other The value to copy.
  186. @param sp A pointer to the `boost::container::pmr::memory_resource` to
  187. use. The container will acquire shared ownership of the memory
  188. resource.
  189. */
  190. BOOST_JSON_DECL
  191. value(
  192. value const& other,
  193. storage_ptr sp);
  194. /** Move constructor
  195. The value is constructed by acquiring ownership of
  196. the contents of `other` and shared ownership of
  197. `other`'s memory resource.
  198. @note
  199. After construction, the moved-from value becomes a
  200. null value with its current storage pointer.
  201. @par Complexity
  202. Constant.
  203. @par Exception Safety
  204. No-throw guarantee.
  205. @param other The value to move.
  206. */
  207. BOOST_JSON_DECL
  208. value(value&& other) noexcept;
  209. /** Move constructor
  210. The value is constructed with the contents of
  211. `other` by move semantics, using the specified
  212. memory resource:
  213. @li If `*other.storage() == *sp`, ownership of
  214. the underlying memory is transferred in constant
  215. time, with no possibility of exceptions.
  216. After construction, the moved-from value becomes
  217. a null value with its current storage pointer.
  218. @li If `*other.storage() != *sp`, an
  219. element-wise copy is performed if
  220. `other.is_structured() == true`, which may throw.
  221. In this case, the moved-from value is not
  222. changed.
  223. @par Complexity
  224. Constant or linear in the size of `other`.
  225. @par Exception Safety
  226. Strong guarantee.
  227. Calls to `memory_resource::allocate` may throw.
  228. @param other The value to move.
  229. @param sp A pointer to the `boost::container::pmr::memory_resource` to
  230. use. The container will acquire shared ownership of the memory
  231. resource.
  232. */
  233. BOOST_JSON_DECL
  234. value(
  235. value&& other,
  236. storage_ptr sp);
  237. //------------------------------------------------------
  238. //
  239. // Conversion
  240. //
  241. //------------------------------------------------------
  242. /** Construct a null.
  243. A null value is a monostate.
  244. @par Complexity
  245. Constant.
  246. @par Exception Safety
  247. No-throw guarantee.
  248. @param sp A pointer to the `boost::container::pmr::memory_resource` to
  249. use. The container will acquire shared ownership of the memory
  250. resource.
  251. */
  252. value(
  253. std::nullptr_t,
  254. storage_ptr sp = {}) noexcept
  255. : sca_(std::move(sp))
  256. {
  257. }
  258. /** Construct a bool.
  259. This constructs a `bool` value using
  260. the specified memory resource.
  261. @par Complexity
  262. Constant.
  263. @par Exception Safety
  264. No-throw guarantee.
  265. @param b The initial value.
  266. @param sp A pointer to the `boost::container::pmr::memory_resource` to
  267. use. The container will acquire shared ownership of the memory
  268. resource.
  269. */
  270. #ifdef BOOST_JSON_DOCS
  271. value(
  272. bool b,
  273. storage_ptr sp = {}) noexcept;
  274. #else
  275. template<class T
  276. ,class = typename std::enable_if<
  277. std::is_same<T, bool>::value>::type
  278. >
  279. value(
  280. T b,
  281. storage_ptr sp = {}) noexcept
  282. : sca_(b, std::move(sp))
  283. {
  284. }
  285. #endif
  286. /** Construct a `std::int64_t`.
  287. @par Complexity
  288. Constant.
  289. @par Exception Safety
  290. No-throw guarantee.
  291. @param i The initial value.
  292. @param sp A pointer to the `boost::container::pmr::memory_resource` to
  293. use. The container will acquire shared ownership of the memory
  294. resource.
  295. */
  296. value(
  297. signed char i,
  298. storage_ptr sp = {}) noexcept
  299. : sca_(static_cast<std::int64_t>(
  300. i), std::move(sp))
  301. {
  302. }
  303. /** Construct a `std::int64_t`.
  304. @par Complexity
  305. Constant.
  306. @par Exception Safety
  307. No-throw guarantee.
  308. @param i The initial value.
  309. @param sp A pointer to the `boost::container::pmr::memory_resource` to
  310. use. The container will acquire shared ownership of the memory
  311. resource.
  312. */
  313. value(
  314. short i,
  315. storage_ptr sp = {}) noexcept
  316. : sca_(static_cast<std::int64_t>(
  317. i), std::move(sp))
  318. {
  319. }
  320. /** Construct a `std::int64_t`.
  321. @par Complexity
  322. Constant.
  323. @par Exception Safety
  324. No-throw guarantee.
  325. @param i The initial value.
  326. @param sp A pointer to the `boost::container::pmr::memory_resource` to
  327. use. The container will acquire shared ownership of the memory
  328. resource.
  329. */
  330. value(
  331. int i,
  332. storage_ptr sp = {}) noexcept
  333. : sca_(static_cast<std::int64_t>(i),
  334. std::move(sp))
  335. {
  336. }
  337. /** Construct a `std::int64_t`.
  338. @par Complexity
  339. Constant.
  340. @par Exception Safety
  341. No-throw guarantee.
  342. @param i The initial value.
  343. @param sp A pointer to the `boost::container::pmr::memory_resource` to
  344. use. The container will acquire shared ownership of the memory
  345. resource.
  346. */
  347. value(
  348. long i,
  349. storage_ptr sp = {}) noexcept
  350. : sca_(static_cast<std::int64_t>(i),
  351. std::move(sp))
  352. {
  353. }
  354. /** Construct a `std::int64_t`.
  355. @par Complexity
  356. Constant.
  357. @par Exception Safety
  358. No-throw guarantee.
  359. @param i The initial value.
  360. @param sp A pointer to the `boost::container::pmr::memory_resource` to
  361. use. The container will acquire shared ownership of the memory
  362. resource.
  363. */
  364. value(
  365. long long i,
  366. storage_ptr sp = {}) noexcept
  367. : sca_(static_cast<std::int64_t>(i),
  368. std::move(sp))
  369. {
  370. }
  371. /** Construct a `std::uint64_t`.
  372. @par Complexity
  373. Constant.
  374. @par Exception Safety
  375. No-throw guarantee.
  376. @param u The initial value.
  377. @param sp A pointer to the `boost::container::pmr::memory_resource` to
  378. use. The container will acquire shared ownership of the memory
  379. resource.
  380. */
  381. value(
  382. unsigned char u,
  383. storage_ptr sp = {}) noexcept
  384. : sca_(static_cast<std::uint64_t>(
  385. u), std::move(sp))
  386. {
  387. }
  388. /** Construct a `std::uint64_t`.
  389. @par Complexity
  390. Constant.
  391. @par Exception Safety
  392. No-throw guarantee.
  393. @param u The initial value.
  394. @param sp A pointer to the `boost::container::pmr::memory_resource` to
  395. use. The container will acquire shared ownership of the memory
  396. resource.
  397. */
  398. value(
  399. unsigned short u,
  400. storage_ptr sp = {}) noexcept
  401. : sca_(static_cast<std::uint64_t>(u),
  402. std::move(sp))
  403. {
  404. }
  405. /** Construct a `std::uint64_t`.
  406. @par Complexity
  407. Constant.
  408. @par Exception Safety
  409. No-throw guarantee.
  410. @param u The initial value.
  411. @param sp A pointer to the `boost::container::pmr::memory_resource` to
  412. use. The container will acquire shared ownership of the memory
  413. resource.
  414. */
  415. value(
  416. unsigned int u,
  417. storage_ptr sp = {}) noexcept
  418. : sca_(static_cast<std::uint64_t>(u),
  419. std::move(sp))
  420. {
  421. }
  422. /** Construct a `std::uint64_t`.
  423. @par Complexity
  424. Constant.
  425. @par Exception Safety
  426. No-throw guarantee.
  427. @param u The initial value.
  428. @param sp A pointer to the `boost::container::pmr::memory_resource` to
  429. use. The container will acquire shared ownership of the memory
  430. resource.
  431. */
  432. value(
  433. unsigned long u,
  434. storage_ptr sp = {}) noexcept
  435. : sca_(static_cast<std::uint64_t>(u),
  436. std::move(sp))
  437. {
  438. }
  439. /** Construct a `std::uint64_t`.
  440. @par Complexity
  441. Constant.
  442. @par Exception Safety
  443. No-throw guarantee.
  444. @param u The initial value.
  445. @param sp A pointer to the `boost::container::pmr::memory_resource` to
  446. use. The container will acquire shared ownership of the memory
  447. resource.
  448. */
  449. value(
  450. unsigned long long u,
  451. storage_ptr sp = {}) noexcept
  452. : sca_(static_cast<std::uint64_t>(u),
  453. std::move(sp))
  454. {
  455. }
  456. /** Construct a `double`.
  457. @par Complexity
  458. Constant.
  459. @par Exception Safety
  460. No-throw guarantee.
  461. @param d The initial value.
  462. @param sp A pointer to the `boost::container::pmr::memory_resource` to
  463. use. The container will acquire shared ownership of the memory
  464. resource.
  465. */
  466. value(
  467. double d,
  468. storage_ptr sp = {}) noexcept
  469. : sca_(d, std::move(sp))
  470. {
  471. }
  472. /** Construct a @ref string.
  473. The string is constructed with a copy of the
  474. string view `s`, using the specified memory resource.
  475. @par Complexity
  476. Linear in `s.size()`.
  477. @par Exception Safety
  478. Strong guarantee.
  479. Calls to `memory_resource::allocate` may throw.
  480. @param s The string view to construct with.
  481. @param sp A pointer to the `boost::container::pmr::memory_resource` to
  482. use. The container will acquire shared ownership of the memory
  483. resource.
  484. */
  485. value(
  486. string_view s,
  487. storage_ptr sp = {})
  488. : str_(s, std::move(sp))
  489. {
  490. }
  491. /** Construct a @ref string.
  492. The string is constructed with a copy of the
  493. null-terminated string `s`, using the specified
  494. memory resource.
  495. @par Complexity
  496. Linear in `std::strlen(s)`.
  497. @par Exception Safety
  498. Strong guarantee.
  499. Calls to `memory_resource::allocate` may throw.
  500. @param s The null-terminated string to construct
  501. with.
  502. @param sp A pointer to the `boost::container::pmr::memory_resource` to
  503. use. The container will acquire shared ownership of the memory
  504. resource.
  505. */
  506. value(
  507. char const* s,
  508. storage_ptr sp = {})
  509. : str_(s, std::move(sp))
  510. {
  511. }
  512. /** Construct a @ref string.
  513. The value is constructed from `other`, using the
  514. same memory resource. To transfer ownership, use `std::move`:
  515. @par Example
  516. @code
  517. string str = "The Boost C++ Library Collection";
  518. // transfer ownership
  519. value jv( std::move(str) );
  520. assert( str.empty() );
  521. assert( *str.storage() == *jv.storage() );
  522. @endcode
  523. @par Complexity
  524. Constant.
  525. @par Exception Safety
  526. No-throw guarantee.
  527. @param other The string to construct with.
  528. */
  529. value(
  530. string other) noexcept
  531. : str_(std::move(other))
  532. {
  533. }
  534. /** Construct a @ref string.
  535. The value is copy constructed from `other`,
  536. using the specified memory resource.
  537. @par Complexity
  538. Linear in `other.size()`.
  539. @par Exception Safety
  540. Strong guarantee.
  541. Calls to `memory_resource::allocate` may throw.
  542. @param other The string to construct with.
  543. @param sp A pointer to the `boost::container::pmr::memory_resource` to
  544. use. The container will acquire shared ownership of the memory
  545. resource.
  546. */
  547. value(
  548. string const& other,
  549. storage_ptr sp)
  550. : str_(
  551. other,
  552. std::move(sp))
  553. {
  554. }
  555. /** Construct a @ref string.
  556. The value is move constructed from `other`,
  557. using the specified memory resource.
  558. @par Complexity
  559. Constant or linear in `other.size()`.
  560. @par Exception Safety
  561. Strong guarantee.
  562. Calls to `memory_resource::allocate` may throw.
  563. @param other The string to construct with.
  564. @param sp A pointer to the `boost::container::pmr::memory_resource` to
  565. use. The container will acquire shared ownership of the memory
  566. resource.
  567. */
  568. value(
  569. string&& other,
  570. storage_ptr sp)
  571. : str_(
  572. std::move(other),
  573. std::move(sp))
  574. {
  575. }
  576. /** Construct a @ref string.
  577. This is the fastest way to construct
  578. an empty string, using the specified
  579. memory resource. The variable @ref string_kind
  580. may be passed as the first parameter
  581. to select this overload:
  582. @par Example
  583. @code
  584. // Construct an empty string
  585. value jv( string_kind );
  586. @endcode
  587. @par Complexity
  588. Constant.
  589. @par Exception Safety
  590. No-throw guarantee.
  591. @param sp A pointer to the `boost::container::pmr::memory_resource` to
  592. use. The container will acquire shared ownership of the memory
  593. resource.
  594. @see @ref string_kind
  595. */
  596. value(
  597. string_kind_t,
  598. storage_ptr sp = {}) noexcept
  599. : str_(std::move(sp))
  600. {
  601. }
  602. /** Construct an @ref array.
  603. The value is constructed from `other`, using the
  604. same memory resource. To transfer ownership, use `std::move`:
  605. @par Example
  606. @code
  607. array arr( {1, 2, 3, 4, 5} );
  608. // transfer ownership
  609. value jv( std::move(arr) );
  610. assert( arr.empty() );
  611. assert( *arr.storage() == *jv.storage() );
  612. @endcode
  613. @par Complexity
  614. Constant.
  615. @par Exception Safety
  616. No-throw guarantee.
  617. @param other The array to construct with.
  618. */
  619. value(array other) noexcept
  620. : arr_(std::move(other))
  621. {
  622. }
  623. /** Construct an @ref array.
  624. The value is copy constructed from `other`,
  625. using the specified memory resource.
  626. @par Complexity
  627. Linear in `other.size()`.
  628. @par Exception Safety
  629. Strong guarantee.
  630. Calls to `memory_resource::allocate` may throw.
  631. @param other The array to construct with.
  632. @param sp A pointer to the `boost::container::pmr::memory_resource` to
  633. use. The container will acquire shared ownership of the memory
  634. resource.
  635. */
  636. value(
  637. array const& other,
  638. storage_ptr sp)
  639. : arr_(
  640. other,
  641. std::move(sp))
  642. {
  643. }
  644. /** Construct an @ref array.
  645. The value is move-constructed from `other`,
  646. using the specified memory resource.
  647. @par Complexity
  648. Constant or linear in `other.size()`.
  649. @par Exception Safety
  650. Strong guarantee.
  651. Calls to `memory_resource::allocate` may throw.
  652. @param other The array to construct with.
  653. @param sp A pointer to the `boost::container::pmr::memory_resource` to
  654. use. The container will acquire shared ownership of the memory
  655. resource.
  656. */
  657. value(
  658. array&& other,
  659. storage_ptr sp)
  660. : arr_(
  661. std::move(other),
  662. std::move(sp))
  663. {
  664. }
  665. /** Construct an @ref array.
  666. This is the fastest way to construct
  667. an empty array, using the specified
  668. memory resource. The variable @ref array_kind
  669. may be passed as the first parameter
  670. to select this overload:
  671. @par Example
  672. @code
  673. // Construct an empty array
  674. value jv( array_kind );
  675. @endcode
  676. @par Complexity
  677. Constant.
  678. @par Exception Safety
  679. No-throw guarantee.
  680. @param sp A pointer to the `boost::container::pmr::memory_resource` to
  681. use. The container will acquire shared ownership of the memory
  682. resource.
  683. @see @ref array_kind
  684. */
  685. value(
  686. array_kind_t,
  687. storage_ptr sp = {}) noexcept
  688. : arr_(std::move(sp))
  689. {
  690. }
  691. /** Construct an @ref object.
  692. The value is constructed from `other`, using the
  693. same memory resource. To transfer ownership, use `std::move`:
  694. @par Example
  695. @code
  696. object obj( {{"a",1}, {"b",2}, {"c"},3}} );
  697. // transfer ownership
  698. value jv( std::move(obj) );
  699. assert( obj.empty() );
  700. assert( *obj.storage() == *jv.storage() );
  701. @endcode
  702. @par Complexity
  703. Constant.
  704. @par Exception Safety
  705. No-throw guarantee.
  706. @param other The object to construct with.
  707. */
  708. value(object other) noexcept
  709. : obj_(std::move(other))
  710. {
  711. }
  712. /** Construct an @ref object.
  713. The value is copy constructed from `other`,
  714. using the specified memory resource.
  715. @par Complexity
  716. Linear in `other.size()`.
  717. @par Exception Safety
  718. Strong guarantee.
  719. Calls to `memory_resource::allocate` may throw.
  720. @param other The object to construct with.
  721. @param sp A pointer to the `boost::container::pmr::memory_resource` to
  722. use. The container will acquire shared ownership of the memory
  723. resource.
  724. */
  725. value(
  726. object const& other,
  727. storage_ptr sp)
  728. : obj_(
  729. other,
  730. std::move(sp))
  731. {
  732. }
  733. /** Construct an @ref object.
  734. The value is move constructed from `other`,
  735. using the specified memory resource.
  736. @par Complexity
  737. Constant or linear in `other.size()`.
  738. @par Exception Safety
  739. Strong guarantee.
  740. Calls to `memory_resource::allocate` may throw.
  741. @param other The object to construct with.
  742. @param sp A pointer to the `boost::container::pmr::memory_resource` to
  743. use. The container will acquire shared ownership of the memory
  744. resource.
  745. */
  746. value(
  747. object&& other,
  748. storage_ptr sp)
  749. : obj_(
  750. std::move(other),
  751. std::move(sp))
  752. {
  753. }
  754. /** Construct an @ref object.
  755. This is the fastest way to construct
  756. an empty object, using the specified
  757. memory resource. The variable @ref object_kind
  758. may be passed as the first parameter
  759. to select this overload:
  760. @par Example
  761. @code
  762. // Construct an empty object
  763. value jv( object_kind );
  764. @endcode
  765. @par Complexity
  766. Constant.
  767. @par Exception Safety
  768. No-throw guarantee.
  769. @param sp A pointer to the `boost::container::pmr::memory_resource` to
  770. use. The container will acquire shared ownership of the memory
  771. resource.
  772. @see @ref object_kind
  773. */
  774. value(
  775. object_kind_t,
  776. storage_ptr sp = {}) noexcept
  777. : obj_(std::move(sp))
  778. {
  779. }
  780. /** Construct from an initializer-list
  781. @li If the initializer list consists of key/value
  782. pairs, an @ref object is created; otherwise,
  783. @li if the size of the initializer list is exactly 1, the object is
  784. constructed directly from that sole element; otherwise,
  785. @li an @ref array is created.
  786. The contents of the initializer list are copied to the newly
  787. constructed value using the specified memory resource.
  788. @par Complexity
  789. Linear in `init.size()`.
  790. @par Exception Safety
  791. Strong guarantee.
  792. Calls to `memory_resource::allocate` may throw.
  793. @param init The initializer list to construct from.
  794. @param sp A pointer to the `boost::container::pmr::memory_resource` to
  795. use. The container will acquire shared ownership of the memory
  796. resource.
  797. @par Note
  798. The previous behavior of this constructor was to always
  799. construct either an @ref object or an @ref array. In practice though,
  800. several C++ implementations did not treat `value{x}` as a constructor
  801. from initializer list. This effectively resulted in different behavior
  802. on different implementations. <br>
  803. If you need the legacy behavior define macro
  804. `BOOST_JSON_LEGACY_INIT_LIST_BEHAVIOR` when you are building the
  805. library. The macro and the functionality will be deprecated in the
  806. future and then removed, so we urge you to change your code for the new
  807. behavior as soon as possible. The simplest way to create an @ref array
  808. with 1 element using an initializer list is via `array{x}`.
  809. */
  810. BOOST_JSON_DECL
  811. value(
  812. std::initializer_list<value_ref> init,
  813. storage_ptr sp = {});
  814. //------------------------------------------------------
  815. //
  816. // Assignment
  817. //
  818. //------------------------------------------------------
  819. /** Copy assignment.
  820. The contents of the value are replaced with an
  821. element-wise copy of the contents of `other`.
  822. @par Complexity
  823. Linear in the size of `*this` plus `other`.
  824. @par Exception Safety
  825. Strong guarantee.
  826. Calls to `memory_resource::allocate` may throw.
  827. @param other The value to copy.
  828. */
  829. BOOST_JSON_DECL
  830. value&
  831. operator=(value const& other);
  832. /** Move assignment.
  833. The contents of the value are replaced with the
  834. contents of `other` using move semantics:
  835. @li If `*other.storage() == *sp`, ownership of
  836. the underlying memory is transferred in constant
  837. time, with no possibility of exceptions.
  838. After assignment, the moved-from value becomes
  839. a null with its current storage pointer.
  840. @li If `*other.storage() != *sp`, an
  841. element-wise copy is performed if
  842. `other.is_structured() == true`, which may throw.
  843. In this case, the moved-from value is not
  844. changed.
  845. @par Complexity
  846. Constant, or linear in
  847. `this->size()` plus `other.size()`.
  848. @par Exception Safety
  849. Strong guarantee.
  850. Calls to `memory_resource::allocate` may throw.
  851. @param other The value to assign from.
  852. */
  853. BOOST_JSON_DECL
  854. value&
  855. operator=(value&& other);
  856. /** Assignment.
  857. Replace `*this` with the value formed by
  858. constructing from `init` and `this->storage()`.
  859. If the initializer list consists of key/value
  860. pairs, the resulting @ref object is assigned.
  861. Otherwise an @ref array is assigned. The contents
  862. of the initializer list are moved to `*this`
  863. using the existing memory resource.
  864. @par Complexity
  865. Linear in `init.size()`.
  866. @par Exception Safety
  867. Strong guarantee.
  868. Calls to `memory_resource::allocate` may throw.
  869. @param init The initializer list to assign from.
  870. */
  871. BOOST_JSON_DECL
  872. value&
  873. operator=(
  874. std::initializer_list<value_ref> init);
  875. /** Assignment.
  876. Replace `*this` with null.
  877. @par Exception Safety
  878. No-throw guarantee.
  879. @par Complexity
  880. Linear in the size of `*this`.
  881. */
  882. value&
  883. operator=(std::nullptr_t) noexcept
  884. {
  885. if(is_scalar())
  886. {
  887. sca_.k = json::kind::null;
  888. }
  889. else
  890. {
  891. ::new(&sca_) scalar(
  892. destroy());
  893. }
  894. return *this;
  895. }
  896. /** Assignment.
  897. Replace `*this` with `b`.
  898. @par Exception Safety
  899. No-throw guarantee.
  900. @par Complexity
  901. Linear in the size of `*this`.
  902. @param b The new value.
  903. */
  904. #ifdef BOOST_JSON_DOCS
  905. value& operator=(bool b) noexcept;
  906. #else
  907. template<class T
  908. ,class = typename std::enable_if<
  909. std::is_same<T, bool>::value>::type
  910. >
  911. value& operator=(T b) noexcept
  912. {
  913. if(is_scalar())
  914. {
  915. sca_.b = b;
  916. sca_.k = json::kind::bool_;
  917. }
  918. else
  919. {
  920. ::new(&sca_) scalar(
  921. b, destroy());
  922. }
  923. return *this;
  924. }
  925. #endif
  926. /** Assignment.
  927. Replace `*this` with `i`.
  928. @par Exception Safety
  929. No-throw guarantee.
  930. @par Complexity
  931. Linear in the size of `*this`.
  932. @param i The new value.
  933. */
  934. /** @{ */
  935. value& operator=(signed char i) noexcept
  936. {
  937. return operator=(
  938. static_cast<long long>(i));
  939. }
  940. value& operator=(short i) noexcept
  941. {
  942. return operator=(
  943. static_cast<long long>(i));
  944. }
  945. value& operator=(int i) noexcept
  946. {
  947. return operator=(
  948. static_cast<long long>(i));
  949. }
  950. value& operator=(long i) noexcept
  951. {
  952. return operator=(
  953. static_cast<long long>(i));
  954. }
  955. value& operator=(long long i) noexcept
  956. {
  957. if(is_scalar())
  958. {
  959. sca_.i = i;
  960. sca_.k = json::kind::int64;
  961. }
  962. else
  963. {
  964. ::new(&sca_) scalar(static_cast<
  965. std::int64_t>(i), destroy());
  966. }
  967. return *this;
  968. }
  969. /** @} */
  970. /** Assignment.
  971. Replace `*this` with `i`.
  972. @par Exception Safety
  973. No-throw guarantee.
  974. @par Complexity
  975. Linear in the size of `*this`.
  976. @param u The new value.
  977. */
  978. /** @{ */
  979. value& operator=(unsigned char u) noexcept
  980. {
  981. return operator=(static_cast<
  982. unsigned long long>(u));
  983. }
  984. value& operator=(unsigned short u) noexcept
  985. {
  986. return operator=(static_cast<
  987. unsigned long long>(u));
  988. }
  989. value& operator=(unsigned int u) noexcept
  990. {
  991. return operator=(static_cast<
  992. unsigned long long>(u));
  993. }
  994. value& operator=(unsigned long u) noexcept
  995. {
  996. return operator=(static_cast<
  997. unsigned long long>(u));
  998. }
  999. value& operator=(unsigned long long u) noexcept
  1000. {
  1001. if(is_scalar())
  1002. {
  1003. sca_.u = u;
  1004. sca_.k = json::kind::uint64;
  1005. }
  1006. else
  1007. {
  1008. ::new(&sca_) scalar(static_cast<
  1009. std::uint64_t>(u), destroy());
  1010. }
  1011. return *this;
  1012. }
  1013. /** @} */
  1014. /** Assignment.
  1015. Replace `*this` with `d`.
  1016. @par Exception Safety
  1017. No-throw guarantee.
  1018. @par Complexity
  1019. Linear in the size of `*this`.
  1020. @param d The new value.
  1021. */
  1022. value& operator=(double d) noexcept
  1023. {
  1024. if(is_scalar())
  1025. {
  1026. sca_.d = d;
  1027. sca_.k = json::kind::double_;
  1028. }
  1029. else
  1030. {
  1031. ::new(&sca_) scalar(
  1032. d, destroy());
  1033. }
  1034. return *this;
  1035. }
  1036. /** Assignment.
  1037. Replace `*this` with a copy of the string `s`.
  1038. @par Exception Safety
  1039. Strong guarantee.
  1040. Calls to `memory_resource::allocate` may throw.
  1041. @par Complexity
  1042. Linear in the sum of sizes of `*this` and `s`
  1043. @param s The new string.
  1044. */
  1045. /** @{ */
  1046. BOOST_JSON_DECL value& operator=(string_view s);
  1047. BOOST_JSON_DECL value& operator=(char const* s);
  1048. BOOST_JSON_DECL value& operator=(string const& s);
  1049. /** @} */
  1050. /** Assignment.
  1051. The contents of the value are replaced with the
  1052. contents of `s` using move semantics:
  1053. @li If `*other.storage() == *this->storage()`,
  1054. ownership of the underlying memory is transferred
  1055. in constant time, with no possibility of exceptions.
  1056. After assignment, the moved-from string becomes
  1057. empty with its current storage pointer.
  1058. @li If `*other.storage() != *this->storage()`, an
  1059. element-wise copy is performed, which may throw.
  1060. In this case, the moved-from string is not
  1061. changed.
  1062. @par Complexity
  1063. Constant, or linear in the size of `*this` plus `s.size()`.
  1064. @par Exception Safety
  1065. Strong guarantee.
  1066. Calls to `memory_resource::allocate` may throw.
  1067. @param s The string to move-assign from.
  1068. */
  1069. BOOST_JSON_DECL value& operator=(string&& s);
  1070. /** Assignment.
  1071. Replace `*this` with a copy of the array `arr`.
  1072. @par Exception Safety
  1073. Strong guarantee.
  1074. Calls to `memory_resource::allocate` may throw.
  1075. @par Complexity
  1076. Linear in the sum of sizes of `*this` and `arr`
  1077. @param arr The new array.
  1078. */
  1079. BOOST_JSON_DECL value& operator=(array const& arr);
  1080. /** Assignment.
  1081. The contents of the value are replaced with the
  1082. contents of `arr` using move semantics:
  1083. @li If `*arr.storage() == *this->storage()`,
  1084. ownership of the underlying memory is transferred
  1085. in constant time, with no possibility of exceptions.
  1086. After assignment, the moved-from array becomes
  1087. empty with its current storage pointer.
  1088. @li If `*arr.storage() != *this->storage()`, an
  1089. element-wise copy is performed, which may throw.
  1090. In this case, the moved-from array is not
  1091. changed.
  1092. @par Complexity
  1093. Constant, or linear in the size of `*this` plus `arr.size()`.
  1094. @par Exception Safety
  1095. Strong guarantee.
  1096. Calls to `memory_resource::allocate` may throw.
  1097. @param arr The array to move-assign from.
  1098. */
  1099. BOOST_JSON_DECL value& operator=(array&& arr);
  1100. /** Assignment.
  1101. Replace `*this` with a copy of the obect `obj`.
  1102. @par Exception Safety
  1103. Strong guarantee.
  1104. Calls to `memory_resource::allocate` may throw.
  1105. @par Complexity
  1106. Linear in the sum of sizes of `*this` and `obj`
  1107. @param obj The new object.
  1108. */
  1109. BOOST_JSON_DECL value& operator=(object const& obj);
  1110. /** Assignment.
  1111. The contents of the value are replaced with the
  1112. contents of `obj` using move semantics:
  1113. @li If `*obj.storage() == *this->storage()`,
  1114. ownership of the underlying memory is transferred
  1115. in constant time, with no possibility of exceptions.
  1116. After assignment, the moved-from object becomes
  1117. empty with its current storage pointer.
  1118. @li If `*obj.storage() != *this->storage()`, an
  1119. element-wise copy is performed, which may throw.
  1120. In this case, the moved-from object is not
  1121. changed.
  1122. @par Complexity
  1123. Constant, or linear in the size of `*this` plus `obj.size()`.
  1124. @par Exception Safety
  1125. Strong guarantee.
  1126. Calls to `memory_resource::allocate` may throw.
  1127. @param obj The object to move-assign from.
  1128. */
  1129. BOOST_JSON_DECL value& operator=(object&& obj);
  1130. //------------------------------------------------------
  1131. //
  1132. // Modifiers
  1133. //
  1134. //------------------------------------------------------
  1135. /** Change the kind to null, discarding the previous contents.
  1136. The value is replaced with a null,
  1137. destroying the previous contents.
  1138. @par Complexity
  1139. Linear in the size of `*this`.
  1140. @par Exception Safety
  1141. No-throw guarantee.
  1142. */
  1143. void
  1144. emplace_null() noexcept
  1145. {
  1146. *this = nullptr;
  1147. }
  1148. /** Return a reference to a `bool`, changing the kind and replacing the contents.
  1149. The value is replaced with a `bool`
  1150. initialized to `false`, destroying the
  1151. previous contents.
  1152. @par Complexity
  1153. Linear in the size of `*this`.
  1154. @par Exception Safety
  1155. No-throw guarantee.
  1156. */
  1157. bool&
  1158. emplace_bool() noexcept
  1159. {
  1160. *this = false;
  1161. return sca_.b;
  1162. }
  1163. /** Return a reference to a `std::int64_t`, changing the kind and replacing the contents.
  1164. The value is replaced with a `std::int64_t`
  1165. initialized to zero, destroying the
  1166. previous contents.
  1167. @par Complexity
  1168. Linear in the size of `*this`.
  1169. @par Exception Safety
  1170. No-throw guarantee.
  1171. */
  1172. std::int64_t&
  1173. emplace_int64() noexcept
  1174. {
  1175. *this = std::int64_t{};
  1176. return sca_.i;
  1177. }
  1178. /** Return a reference to a `std::uint64_t`, changing the kind and replacing the contents.
  1179. The value is replaced with a `std::uint64_t`
  1180. initialized to zero, destroying the
  1181. previous contents.
  1182. @par Complexity
  1183. Linear in the size of `*this`.
  1184. @par Exception Safety
  1185. No-throw guarantee.
  1186. */
  1187. std::uint64_t&
  1188. emplace_uint64() noexcept
  1189. {
  1190. *this = std::uint64_t{};
  1191. return sca_.u;
  1192. }
  1193. /** Return a reference to a `double`, changing the kind and replacing the contents.
  1194. The value is replaced with a `double`
  1195. initialized to zero, destroying the
  1196. previous contents.
  1197. @par Complexity
  1198. Linear in the size of `*this`.
  1199. @par Exception Safety
  1200. No-throw guarantee.
  1201. */
  1202. double&
  1203. emplace_double() noexcept
  1204. {
  1205. *this = double{};
  1206. return sca_.d;
  1207. }
  1208. /** Return a reference to a @ref string, changing the kind and replacing the contents.
  1209. The value is replaced with an empty @ref string
  1210. using the current memory resource, destroying the
  1211. previous contents.
  1212. @par Complexity
  1213. Linear in the size of `*this`.
  1214. @par Exception Safety
  1215. No-throw guarantee.
  1216. */
  1217. BOOST_JSON_DECL
  1218. string&
  1219. emplace_string() noexcept;
  1220. /** Return a reference to an @ref array, changing the kind and replacing the contents.
  1221. The value is replaced with an empty @ref array
  1222. using the current memory resource, destroying the
  1223. previous contents.
  1224. @par Complexity
  1225. Linear in the size of `*this`.
  1226. @par Exception Safety
  1227. No-throw guarantee.
  1228. */
  1229. BOOST_JSON_DECL
  1230. array&
  1231. emplace_array() noexcept;
  1232. /** Return a reference to an @ref object, changing the kind and replacing the contents.
  1233. The contents are replaced with an empty @ref object using the current
  1234. `boost::container::pmr::memory_resource`. All previously obtained
  1235. iterators and references obtained beforehand are invalidated.
  1236. @par Complexity
  1237. Linear in the size of `*this`.
  1238. @par Exception Safety
  1239. No-throw guarantee.
  1240. */
  1241. BOOST_JSON_DECL
  1242. object&
  1243. emplace_object() noexcept;
  1244. /** Swap the given values.
  1245. Exchanges the contents of this value with another value. Ownership of
  1246. the respective `boost::container::pmr::memory_resource` objects is not
  1247. transferred:
  1248. @li If `*other.storage() == *this->storage()`,
  1249. ownership of the underlying memory is swapped in
  1250. constant time, with no possibility of exceptions.
  1251. All iterators and references remain valid.
  1252. @li If `*other.storage() != *this->storage()`,
  1253. the contents are logically swapped by making copies,
  1254. which can throw. In this case all iterators and
  1255. references are invalidated.
  1256. @par Complexity
  1257. Constant or linear in the sum of the sizes of
  1258. the values.
  1259. @par Exception Safety
  1260. Strong guarantee.
  1261. Calls to `memory_resource::allocate` may throw.
  1262. @param other The value to swap with.
  1263. If `this == &other`, this function call has no effect.
  1264. */
  1265. BOOST_JSON_DECL
  1266. void
  1267. swap(value& other);
  1268. /** Swap the given values.
  1269. Exchanges the contents of value `lhs` with another value `rhs`.
  1270. Ownership of the respective `boost::container::pmr::memory_resource`
  1271. objects is not transferred.
  1272. @li If `*lhs.storage() == *rhs.storage()`,
  1273. ownership of the underlying memory is swapped in
  1274. constant time, with no possibility of exceptions.
  1275. All iterators and references remain valid.
  1276. @li If `*lhs.storage() != *rhs.storage`,
  1277. the contents are logically swapped by a copy,
  1278. which can throw. In this case all iterators and
  1279. references are invalidated.
  1280. @par Effects
  1281. @code
  1282. lhs.swap( rhs );
  1283. @endcode
  1284. @par Complexity
  1285. Constant or linear in the sum of the sizes of
  1286. the values.
  1287. @par Exception Safety
  1288. Strong guarantee.
  1289. Calls to `memory_resource::allocate` may throw.
  1290. @param lhs The value to exchange.
  1291. @param rhs The value to exchange.
  1292. If `&lhs == &rhs`, this function call has no effect.
  1293. @see @ref value::swap
  1294. */
  1295. friend
  1296. void
  1297. swap(value& lhs, value& rhs)
  1298. {
  1299. lhs.swap(rhs);
  1300. }
  1301. //------------------------------------------------------
  1302. //
  1303. // Observers
  1304. //
  1305. //------------------------------------------------------
  1306. /** Returns the kind of this JSON value.
  1307. This function returns the discriminating
  1308. enumeration constant of type @ref json::kind
  1309. corresponding to the underlying representation
  1310. stored in the container.
  1311. @par Complexity
  1312. Constant.
  1313. @par Exception Safety
  1314. No-throw guarantee.
  1315. */
  1316. json::kind
  1317. kind() const noexcept
  1318. {
  1319. return static_cast<json::kind>(
  1320. static_cast<unsigned char>(
  1321. sca_.k) & 0x3f);
  1322. }
  1323. /** Return `true` if this is an array
  1324. This function is used to determine if the underlying
  1325. representation is a certain kind.
  1326. @par Effects
  1327. @code
  1328. return this->kind() == kind::array;
  1329. @endcode
  1330. @par Complexity
  1331. Constant.
  1332. @par Exception Safety
  1333. No-throw guarantee.
  1334. */
  1335. bool
  1336. is_array() const noexcept
  1337. {
  1338. return kind() == json::kind::array;
  1339. }
  1340. /** Return `true` if this is an object
  1341. This function is used to determine if the underlying
  1342. representation is a certain kind.
  1343. @par Effects
  1344. @code
  1345. return this->kind() == kind::object;
  1346. @endcode
  1347. @par Complexity
  1348. Constant.
  1349. @par Exception Safety
  1350. No-throw guarantee.
  1351. */
  1352. bool
  1353. is_object() const noexcept
  1354. {
  1355. return kind() == json::kind::object;
  1356. }
  1357. /** Return `true` if this is a string
  1358. This function is used to determine if the underlying
  1359. representation is a certain kind.
  1360. @par Effects
  1361. @code
  1362. return this->kind() == kind::string;
  1363. @endcode
  1364. @par Complexity
  1365. Constant.
  1366. @par Exception Safety
  1367. No-throw guarantee.
  1368. */
  1369. bool
  1370. is_string() const noexcept
  1371. {
  1372. return kind() == json::kind::string;
  1373. }
  1374. /** Return `true` if this is a signed integer
  1375. This function is used to determine if the underlying
  1376. representation is a certain kind.
  1377. @par Effects
  1378. @code
  1379. return this->kind() == kind::int64;
  1380. @endcode
  1381. @par Complexity
  1382. Constant.
  1383. @par Exception Safety
  1384. No-throw guarantee.
  1385. */
  1386. bool
  1387. is_int64() const noexcept
  1388. {
  1389. return kind() == json::kind::int64;
  1390. }
  1391. /** Return `true` if this is a unsigned integer
  1392. This function is used to determine if the underlying
  1393. representation is a certain kind.
  1394. @par Effects
  1395. @code
  1396. return this->kind() == kind::uint64;
  1397. @endcode
  1398. @par Complexity
  1399. Constant.
  1400. @par Exception Safety
  1401. No-throw guarantee.
  1402. */
  1403. bool
  1404. is_uint64() const noexcept
  1405. {
  1406. return kind() == json::kind::uint64;
  1407. }
  1408. /** Return `true` if this is a double
  1409. This function is used to determine if the underlying
  1410. representation is a certain kind.
  1411. @par Effects
  1412. @code
  1413. return this->kind() == kind::double_;
  1414. @endcode
  1415. @par Complexity
  1416. Constant.
  1417. @par Exception Safety
  1418. No-throw guarantee.
  1419. */
  1420. bool
  1421. is_double() const noexcept
  1422. {
  1423. return kind() == json::kind::double_;
  1424. }
  1425. /** Return `true` if this is a bool
  1426. This function is used to determine if the underlying
  1427. representation is a certain kind.
  1428. @par Effects
  1429. @code
  1430. return this->kind() == kind::bool_;
  1431. @endcode
  1432. @par Complexity
  1433. Constant.
  1434. @par Exception Safety
  1435. No-throw guarantee.
  1436. */
  1437. bool
  1438. is_bool() const noexcept
  1439. {
  1440. return kind() == json::kind::bool_;
  1441. }
  1442. /** Returns true if this is a null.
  1443. This function is used to determine if the underlying
  1444. representation is a certain kind.
  1445. @par Effects
  1446. @code
  1447. return this->kind() == kind::null;
  1448. @endcode
  1449. @par Complexity
  1450. Constant.
  1451. @par Exception Safety
  1452. No-throw guarantee.
  1453. */
  1454. bool
  1455. is_null() const noexcept
  1456. {
  1457. return kind() == json::kind::null;
  1458. }
  1459. /** Returns true if this is an array or object.
  1460. This function returns `true` if
  1461. @ref kind() is either `kind::object` or
  1462. `kind::array`.
  1463. @par Complexity
  1464. Constant.
  1465. @par Exception Safety
  1466. No-throw guarantee.
  1467. */
  1468. bool
  1469. is_structured() const noexcept
  1470. {
  1471. // VFALCO Could use bit 0x20 for this
  1472. return
  1473. kind() == json::kind::object ||
  1474. kind() == json::kind::array;
  1475. }
  1476. /** Returns true if this is not an array or object.
  1477. This function returns `true` if
  1478. @ref kind() is neither `kind::object` nor
  1479. `kind::array`.
  1480. @par Complexity
  1481. Constant.
  1482. @par Exception Safety
  1483. No-throw guarantee.
  1484. */
  1485. bool
  1486. is_primitive() const noexcept
  1487. {
  1488. // VFALCO Could use bit 0x20 for this
  1489. return
  1490. sca_.k != json::kind::object &&
  1491. sca_.k != json::kind::array;
  1492. }
  1493. /** Returns true if this is a number.
  1494. This function returns `true` when
  1495. @ref kind() is one of the following values:
  1496. `kind::int64`, `kind::uint64`, or
  1497. `kind::double_`.
  1498. @par Complexity
  1499. Constant.
  1500. @par Exception Safety
  1501. No-throw guarantee.
  1502. */
  1503. bool
  1504. is_number() const noexcept
  1505. {
  1506. // VFALCO Could use bit 0x40 for this
  1507. return
  1508. kind() == json::kind::int64 ||
  1509. kind() == json::kind::uint64 ||
  1510. kind() == json::kind::double_;
  1511. }
  1512. //------------------------------------------------------
  1513. /** Return an @ref array pointer if this is an array, else return `nullptr`
  1514. If `this->kind() == kind::array`, returns a pointer
  1515. to the underlying array. Otherwise, returns `nullptr`.
  1516. @par Example
  1517. The return value is used in both a boolean context and
  1518. to assign a variable:
  1519. @code
  1520. if( auto p = jv.if_array() )
  1521. return *p;
  1522. @endcode
  1523. @par Complexity
  1524. Constant.
  1525. @par Exception Safety
  1526. No-throw guarantee.
  1527. */
  1528. array const*
  1529. if_array() const noexcept
  1530. {
  1531. if(kind() == json::kind::array)
  1532. return &arr_;
  1533. return nullptr;
  1534. }
  1535. /** Return an @ref array pointer if this is an array, else return `nullptr`
  1536. If `this->kind() == kind::array`, returns a pointer
  1537. to the underlying array. Otherwise, returns `nullptr`.
  1538. @par Example
  1539. The return value is used in both a boolean context and
  1540. to assign a variable:
  1541. @code
  1542. if( auto p = jv.if_array() )
  1543. return *p;
  1544. @endcode
  1545. @par Complexity
  1546. Constant.
  1547. @par Exception Safety
  1548. No-throw guarantee.
  1549. */
  1550. array*
  1551. if_array() noexcept
  1552. {
  1553. if(kind() == json::kind::array)
  1554. return &arr_;
  1555. return nullptr;
  1556. }
  1557. /** Return an @ref object pointer if this is an object, else return `nullptr`
  1558. If `this->kind() == kind::object`, returns a pointer
  1559. to the underlying object. Otherwise, returns `nullptr`.
  1560. @par Example
  1561. The return value is used in both a boolean context and
  1562. to assign a variable:
  1563. @code
  1564. if( auto p = jv.if_object() )
  1565. return *p;
  1566. @endcode
  1567. @par Complexity
  1568. Constant.
  1569. @par Exception Safety
  1570. No-throw guarantee.
  1571. */
  1572. object const*
  1573. if_object() const noexcept
  1574. {
  1575. if(kind() == json::kind::object)
  1576. return &obj_;
  1577. return nullptr;
  1578. }
  1579. /** Return an @ref object pointer if this is an object, else return `nullptr`
  1580. If `this->kind() == kind::object`, returns a pointer
  1581. to the underlying object. Otherwise, returns `nullptr`.
  1582. @par Example
  1583. The return value is used in both a boolean context and
  1584. to assign a variable:
  1585. @code
  1586. if( auto p = jv.if_object() )
  1587. return *p;
  1588. @endcode
  1589. @par Complexity
  1590. Constant.
  1591. @par Exception Safety
  1592. No-throw guarantee.
  1593. */
  1594. object*
  1595. if_object() noexcept
  1596. {
  1597. if(kind() == json::kind::object)
  1598. return &obj_;
  1599. return nullptr;
  1600. }
  1601. /** Return a @ref string pointer if this is a string, else return `nullptr`
  1602. If `this->kind() == kind::string`, returns a pointer
  1603. to the underlying object. Otherwise, returns `nullptr`.
  1604. @par Example
  1605. The return value is used in both a boolean context and
  1606. to assign a variable:
  1607. @code
  1608. if( auto p = jv.if_string() )
  1609. return *p;
  1610. @endcode
  1611. @par Complexity
  1612. Constant.
  1613. @par Exception Safety
  1614. No-throw guarantee.
  1615. */
  1616. string const*
  1617. if_string() const noexcept
  1618. {
  1619. if(kind() == json::kind::string)
  1620. return &str_;
  1621. return nullptr;
  1622. }
  1623. /** Return a @ref string pointer if this is a string, else return `nullptr`
  1624. If `this->kind() == kind::string`, returns a pointer
  1625. to the underlying object. Otherwise, returns `nullptr`.
  1626. @par Example
  1627. The return value is used in both a boolean context and
  1628. to assign a variable:
  1629. @code
  1630. if( auto p = jv.if_string() )
  1631. return *p;
  1632. @endcode
  1633. @par Complexity
  1634. Constant.
  1635. @par Exception Safety
  1636. No-throw guarantee.
  1637. */
  1638. string*
  1639. if_string() noexcept
  1640. {
  1641. if(kind() == json::kind::string)
  1642. return &str_;
  1643. return nullptr;
  1644. }
  1645. /** Return an `int64_t` pointer if this is a signed integer, else return `nullptr`
  1646. If `this->kind() == kind::int64`, returns a pointer
  1647. to the underlying integer. Otherwise, returns `nullptr`.
  1648. @par Example
  1649. The return value is used in both a boolean context and
  1650. to assign a variable:
  1651. @code
  1652. if( auto p = jv.if_int64() )
  1653. return *p;
  1654. @endcode
  1655. @par Complexity
  1656. Constant.
  1657. @par Exception Safety
  1658. No-throw guarantee.
  1659. */
  1660. std::int64_t const*
  1661. if_int64() const noexcept
  1662. {
  1663. if(kind() == json::kind::int64)
  1664. return &sca_.i;
  1665. return nullptr;
  1666. }
  1667. /** Return an `int64_t` pointer if this is a signed integer, else return `nullptr`
  1668. If `this->kind() == kind::int64`, returns a pointer
  1669. to the underlying integer. Otherwise, returns `nullptr`.
  1670. @par Example
  1671. The return value is used in both a boolean context and
  1672. to assign a variable:
  1673. @code
  1674. if( auto p = jv.if_int64() )
  1675. return *p;
  1676. @endcode
  1677. @par Complexity
  1678. Constant.
  1679. @par Exception Safety
  1680. No-throw guarantee.
  1681. */
  1682. std::int64_t*
  1683. if_int64() noexcept
  1684. {
  1685. if(kind() == json::kind::int64)
  1686. return &sca_.i;
  1687. return nullptr;
  1688. }
  1689. /** Return a `uint64_t` pointer if this is an unsigned integer, else return `nullptr`
  1690. If `this->kind() == kind::uint64`, returns a pointer
  1691. to the underlying unsigned integer. Otherwise, returns
  1692. `nullptr`.
  1693. @par Example
  1694. The return value is used in both a boolean context and
  1695. to assign a variable:
  1696. @code
  1697. if( auto p = jv.if_uint64() )
  1698. return *p;
  1699. @endcode
  1700. @par Complexity
  1701. Constant.
  1702. @par Exception Safety
  1703. No-throw guarantee.
  1704. */
  1705. std::uint64_t const*
  1706. if_uint64() const noexcept
  1707. {
  1708. if(kind() == json::kind::uint64)
  1709. return &sca_.u;
  1710. return nullptr;
  1711. }
  1712. /** Return a `uint64_t` pointer if this is an unsigned integer, else return `nullptr`
  1713. If `this->kind() == kind::uint64`, returns a pointer
  1714. to the underlying unsigned integer. Otherwise, returns
  1715. `nullptr`.
  1716. @par Example
  1717. The return value is used in both a boolean context and
  1718. to assign a variable:
  1719. @code
  1720. if( auto p = jv.if_uint64() )
  1721. return *p;
  1722. @endcode
  1723. @par Complexity
  1724. Constant.
  1725. @par Exception Safety
  1726. No-throw guarantee.
  1727. */
  1728. std::uint64_t*
  1729. if_uint64() noexcept
  1730. {
  1731. if(kind() == json::kind::uint64)
  1732. return &sca_.u;
  1733. return nullptr;
  1734. }
  1735. /** Return a `double` pointer if this is a double, else return `nullptr`
  1736. If `this->kind() == kind::double_`, returns a pointer
  1737. to the underlying double. Otherwise, returns
  1738. `nullptr`.
  1739. @par Example
  1740. The return value is used in both a boolean context and
  1741. to assign a variable:
  1742. @code
  1743. if( auto p = jv.if_double() )
  1744. return *p;
  1745. @endcode
  1746. @par Complexity
  1747. Constant.
  1748. @par Exception Safety
  1749. No-throw guarantee.
  1750. */
  1751. double const*
  1752. if_double() const noexcept
  1753. {
  1754. if(kind() == json::kind::double_)
  1755. return &sca_.d;
  1756. return nullptr;
  1757. }
  1758. /** Return a `double` pointer if this is a double, else return `nullptr`
  1759. If `this->kind() == kind::double_`, returns a pointer
  1760. to the underlying double. Otherwise, returns
  1761. `nullptr`.
  1762. @par Example
  1763. The return value is used in both a boolean context and
  1764. to assign a variable:
  1765. @code
  1766. if( auto p = jv.if_double() )
  1767. return *p;
  1768. @endcode
  1769. @par Complexity
  1770. Constant.
  1771. @par Exception Safety
  1772. No-throw guarantee.
  1773. */
  1774. double*
  1775. if_double() noexcept
  1776. {
  1777. if(kind() == json::kind::double_)
  1778. return &sca_.d;
  1779. return nullptr;
  1780. }
  1781. /** Return a `bool` pointer if this is a boolean, else return `nullptr`
  1782. If `this->kind() == kind::bool_`, returns a pointer
  1783. to the underlying boolean. Otherwise, returns
  1784. `nullptr`.
  1785. @par Example
  1786. The return value is used in both a boolean context and
  1787. to assign a variable:
  1788. @code
  1789. if( auto p = jv.if_bool() )
  1790. return *p;
  1791. @endcode
  1792. @par Complexity
  1793. Constant.
  1794. @par Exception Safety
  1795. No-throw guarantee.
  1796. */
  1797. bool const*
  1798. if_bool() const noexcept
  1799. {
  1800. if(kind() == json::kind::bool_)
  1801. return &sca_.b;
  1802. return nullptr;
  1803. }
  1804. /** Return a `bool` pointer if this is a boolean, else return `nullptr`
  1805. If `this->kind() == kind::bool_`, returns a pointer
  1806. to the underlying boolean. Otherwise, returns
  1807. `nullptr`.
  1808. @par Example
  1809. The return value is used in both a boolean context and
  1810. to assign a variable:
  1811. @code
  1812. if( auto p = jv.if_bool() )
  1813. return *p;
  1814. @endcode
  1815. @par Complexity
  1816. Constant.
  1817. @par Exception Safety
  1818. No-throw guarantee.
  1819. */
  1820. bool*
  1821. if_bool() noexcept
  1822. {
  1823. if(kind() == json::kind::bool_)
  1824. return &sca_.b;
  1825. return nullptr;
  1826. }
  1827. //------------------------------------------------------
  1828. /** Return the stored number cast to an arithmetic type.
  1829. This function attempts to return the stored value
  1830. converted to the arithmetic type `T` which may not
  1831. be `bool`:
  1832. @li If `T` is an integral type and the stored
  1833. value is a number which can be losslessly converted,
  1834. the conversion is performed without error and the
  1835. converted number is returned.
  1836. @li If `T` is an integral type and the stored value
  1837. is a number which cannot be losslessly converted,
  1838. then the operation fails with an error.
  1839. @li If `T` is a floating point type and the stored
  1840. value is a number, the conversion is performed
  1841. without error. The converted number is returned,
  1842. with a possible loss of precision.
  1843. @li Otherwise, if the stored value is not a number;
  1844. that is, if `this->is_number()` returns `false`, then
  1845. the operation fails with an error.
  1846. @par Constraints
  1847. @code
  1848. std::is_arithmetic< T >::value && ! std::is_same< T, bool >::value
  1849. @endcode
  1850. @par Complexity
  1851. Constant.
  1852. @par Exception Safety
  1853. No-throw guarantee.
  1854. @return The converted number.
  1855. @param ec Set to the error, if any occurred.
  1856. */
  1857. /** @{ */
  1858. template<class T>
  1859. #ifdef BOOST_JSON_DOCS
  1860. T
  1861. #else
  1862. typename std::enable_if<
  1863. std::is_arithmetic<T>::value &&
  1864. ! std::is_same<T, bool>::value,
  1865. T>::type
  1866. #endif
  1867. to_number(system::error_code& ec) const noexcept
  1868. {
  1869. error e;
  1870. auto result = to_number<T>(e);
  1871. BOOST_JSON_FAIL(ec, e);
  1872. return result;
  1873. }
  1874. template<class T>
  1875. #ifdef BOOST_JSON_DOCS
  1876. T
  1877. #else
  1878. typename std::enable_if<
  1879. std::is_arithmetic<T>::value &&
  1880. ! std::is_same<T, bool>::value,
  1881. T>::type
  1882. #endif
  1883. to_number(std::error_code& ec) const noexcept
  1884. {
  1885. system::error_code jec;
  1886. auto result = to_number<T>(jec);
  1887. ec = jec;
  1888. return result;
  1889. }
  1890. /** @} */
  1891. /** Return the stored number as `boost::system::result<T>`.
  1892. This function attempts to return the stored value converted to the
  1893. arithmetic type `T` which may not be `bool`:
  1894. @li If `T` is an integral type and the stored value is a number which
  1895. can be losslessly converted, the conversion is performed without
  1896. error and `result<T>` containing the converted number is returned.
  1897. @li If `T` is an integral type and the stored value is a number which
  1898. cannot be losslessly converted, then `result<T>` containing the
  1899. corresponding `error_code` is returned.
  1900. @li If `T` is a floating point type and the stored value is a number,
  1901. the conversion is performed without error. `result<T>` containing
  1902. the converted number, with a possible loss of precision, is
  1903. returned.
  1904. @li Otherwise, if the stored value is not a number; that is, if
  1905. `this->is_number()` returns `false`, then `result<T>` containing
  1906. the corresponding `error_code` is returned.
  1907. @par Constraints
  1908. @code
  1909. std::is_arithmetic< T >::value && ! std::is_same< T, bool >::value
  1910. @endcode
  1911. @par Complexity
  1912. Constant.
  1913. @par Exception Safety
  1914. No-throw guarantee.
  1915. @return `boost::system::result<T>` with either the converted number or
  1916. an `error_code`.
  1917. */
  1918. template<class T>
  1919. #ifdef BOOST_JSON_DOCS
  1920. system::result<T>
  1921. #else
  1922. typename std::enable_if<
  1923. std::is_arithmetic<T>::value && ! std::is_same<T, bool>::value,
  1924. system::result<T>
  1925. >::type
  1926. #endif
  1927. try_to_number() const noexcept
  1928. {
  1929. system::error_code ec;
  1930. T result = to_number<T>(ec);
  1931. if( ec )
  1932. return {system::in_place_error, ec};
  1933. return {system::in_place_value, result};
  1934. }
  1935. /** Return the stored number cast to an arithmetic type.
  1936. This function attempts to return the stored value
  1937. converted to the arithmetic type `T` which may not
  1938. be `bool`:
  1939. @li If `T` is an integral type and the stored
  1940. value is a number which can be losslessly converted,
  1941. the conversion is performed without error and the
  1942. converted number is returned.
  1943. @li If `T` is an integral type and the stored value
  1944. is a number which cannot be losslessly converted,
  1945. then the operation fails with an error.
  1946. @li If `T` is a floating point type and the stored
  1947. value is a number, the conversion is performed
  1948. without error. The converted number is returned,
  1949. with a possible loss of precision.
  1950. @li Otherwise, if the stored value is not a number;
  1951. that is, if `this->is_number()` returns `false`, then
  1952. the operation fails with an error.
  1953. @par Constraints
  1954. @code
  1955. std::is_arithmetic< T >::value && ! std::is_same< T, bool >::value
  1956. @endcode
  1957. @par Complexity
  1958. Constant.
  1959. @return The converted number.
  1960. @throw `boost::system::system_error` Thrown on error.
  1961. */
  1962. template<class T>
  1963. #ifdef BOOST_JSON_DOCS
  1964. T
  1965. #else
  1966. typename std::enable_if<
  1967. std::is_arithmetic<T>::value &&
  1968. ! std::is_same<T, bool>::value,
  1969. T>::type
  1970. #endif
  1971. to_number() const
  1972. {
  1973. return try_to_number<T>().value();
  1974. }
  1975. //------------------------------------------------------
  1976. //
  1977. // Accessors
  1978. //
  1979. //------------------------------------------------------
  1980. /** Return the associated memory resource.
  1981. This function returns the `boost::container::pmr::memory_resource` used
  1982. by the container.
  1983. @par Complexity
  1984. Constant.
  1985. @par Exception Safety
  1986. No-throw guarantee.
  1987. */
  1988. storage_ptr const&
  1989. storage() const noexcept
  1990. {
  1991. return sp_;
  1992. }
  1993. /** Return the associated allocator.
  1994. This function returns an instance of @ref allocator_type constructed
  1995. from the associated `boost::container::pmr::memory_resource`.
  1996. @par Complexity
  1997. Constant.
  1998. @par Exception Safety
  1999. No-throw guarantee.
  2000. */
  2001. allocator_type
  2002. get_allocator() const noexcept
  2003. {
  2004. return sp_.get();
  2005. }
  2006. //------------------------------------------------------
  2007. /** Return `result` with a reference to the underlying @ref array
  2008. If @ref is_array() is `true`, the result contains a reference to the
  2009. underlying @ref array, otherwise it contains an `error_code`.
  2010. @par Example
  2011. The return value can be used in both a boolean context and
  2012. to assign a variable:
  2013. @code
  2014. if( auto r = jv.try_as_array() )
  2015. return *r;
  2016. @endcode
  2017. But can also be used to throw an exception on error:
  2018. @code
  2019. return jv.try_as_array().value();
  2020. @endcode
  2021. @par Complexity
  2022. Constant.
  2023. @par Exception Safety
  2024. No-throw guarantee.
  2025. */
  2026. /** @{ */
  2027. BOOST_JSON_DECL
  2028. system::result<array&>
  2029. try_as_array() noexcept;
  2030. BOOST_JSON_DECL
  2031. system::result<array const&>
  2032. try_as_array() const noexcept;
  2033. /** @} */
  2034. /** Return `result` with a reference to the underlying @ref object
  2035. If @ref is_object() is `true`, the result contains a reference to the
  2036. underlying @ref object, otherwise it contains an `error_code`.
  2037. @par Example
  2038. The return value can be used in both a boolean context and
  2039. to assign a variable:
  2040. @code
  2041. if( auto r = jv.try_as_object() )
  2042. return *r;
  2043. @endcode
  2044. But can also be used to throw an exception on error:
  2045. @code
  2046. return jv.try_as_object().value();
  2047. @endcode
  2048. @par Complexity
  2049. Constant.
  2050. @par Exception Safety
  2051. No-throw guarantee.
  2052. */
  2053. /** @{ */
  2054. BOOST_JSON_DECL
  2055. system::result<object&>
  2056. try_as_object() noexcept;
  2057. BOOST_JSON_DECL
  2058. system::result<object const&>
  2059. try_as_object() const noexcept;
  2060. /** @} */
  2061. /** Return `result` with a reference to the underlying @ref string
  2062. If @ref is_string() is `true`, the result contains a reference to the
  2063. underlying @ref string, otherwise it contains an `error_code`.
  2064. @par Example
  2065. The return value can be used in both a boolean context and
  2066. to assign a variable:
  2067. @code
  2068. if( auto r = jv.try_as_string() )
  2069. return *r;
  2070. @endcode
  2071. But can also be used to throw an exception on error:
  2072. @code
  2073. return jv.try_as_string().value();
  2074. @endcode
  2075. @par Complexity
  2076. Constant.
  2077. @par Exception Safety
  2078. No-throw guarantee.
  2079. */
  2080. /** @{ */
  2081. BOOST_JSON_DECL
  2082. system::result<string&>
  2083. try_as_string() noexcept;
  2084. BOOST_JSON_DECL
  2085. system::result<string const&>
  2086. try_as_string() const noexcept;
  2087. /** @} */
  2088. /** Return `result` with a reference to the underlying `std::int64_t`
  2089. If @ref is_int64() is `true`, the result contains a reference to the
  2090. underlying `std::int64_t`, otherwise it contains an `error_code`.
  2091. @par Example
  2092. The return value can be used in both a boolean context and
  2093. to assign a variable:
  2094. @code
  2095. if( auto r = jv.try_as_int64() )
  2096. return *r;
  2097. @endcode
  2098. But can also be used to throw an exception on error:
  2099. @code
  2100. return jv.try_as_int64().value();
  2101. @endcode
  2102. @par Complexity
  2103. Constant.
  2104. @par Exception Safety
  2105. No-throw guarantee.
  2106. */
  2107. BOOST_JSON_DECL
  2108. system::result<std::int64_t&>
  2109. try_as_int64() noexcept;
  2110. /** Return `result` with the underlying `std::int64_t`
  2111. If @ref is_int64() is `true`, the result contains a copy of the
  2112. underlying `std::int64_t`, otherwise it contains an `error_code`.
  2113. @par Example
  2114. The return value can be used in both a boolean context and
  2115. to assign a variable:
  2116. @code
  2117. if( auto r = jv.try_as_int64() )
  2118. return *r;
  2119. @endcode
  2120. But can also be used to throw an exception on error:
  2121. @code
  2122. return jv.try_as_int64().value();
  2123. @endcode
  2124. @par Complexity
  2125. Constant.
  2126. @par Exception Safety
  2127. No-throw guarantee.
  2128. */
  2129. BOOST_JSON_DECL
  2130. system::result<std::int64_t>
  2131. try_as_int64() const noexcept;
  2132. /** Return `result` with a reference to the underlying `std::uint64_t`
  2133. If @ref is_uint64() is `true`, the result contains a reference to the
  2134. underlying `std::uint64_t`, otherwise it contains an `error_code`.
  2135. @par Example
  2136. The return value can be used in both a boolean context and
  2137. to assign a variable:
  2138. @code
  2139. if( auto r = jv.try_as_uint64() )
  2140. return *r;
  2141. @endcode
  2142. But can also be used to throw an exception on error:
  2143. @code
  2144. return jv.try_as_uint64().value();
  2145. @endcode
  2146. @par Complexity
  2147. Constant.
  2148. @par Exception Safety
  2149. No-throw guarantee.
  2150. */
  2151. BOOST_JSON_DECL
  2152. system::result<std::uint64_t&>
  2153. try_as_uint64() noexcept;
  2154. /** Return `result` with the underlying `std::uint64_t`
  2155. If @ref is_uint64() is `true`, the result contains a copy of the
  2156. underlying `std::uint64_t`, otherwise it contains an `error_code`.
  2157. @par Example
  2158. The return value can be used in both a boolean context and
  2159. to assign a variable:
  2160. @code
  2161. if( auto r = jv.try_as_uint64() )
  2162. return *r;
  2163. @endcode
  2164. But can also be used to throw an exception on error:
  2165. @code
  2166. return jv.try_as_uint64().value();
  2167. @endcode
  2168. @par Complexity
  2169. Constant.
  2170. @par Exception Safety
  2171. No-throw guarantee.
  2172. */
  2173. BOOST_JSON_DECL
  2174. system::result<std::uint64_t>
  2175. try_as_uint64() const noexcept;
  2176. /** Return `result` with a reference to the underlying `double`
  2177. If @ref is_double() is `true`, the result contains a reference to the
  2178. underlying `double`, otherwise it contains an `error_code`.
  2179. @par Example
  2180. The return value can be used in both a boolean context and
  2181. to assign a variable:
  2182. @code
  2183. if( auto r = jv.try_as_double() )
  2184. return *r;
  2185. @endcode
  2186. But can also be used to throw an exception on error:
  2187. @code
  2188. return jv.try_as_double().value();
  2189. @endcode
  2190. @par Complexity
  2191. Constant.
  2192. @par Exception Safety
  2193. No-throw guarantee.
  2194. */
  2195. BOOST_JSON_DECL
  2196. system::result<double&>
  2197. try_as_double() noexcept;
  2198. /** Return `result` with the underlying `double`
  2199. If @ref is_double() is `true`, the result contains a copy of the
  2200. underlying `double`, otherwise it contains an `error_code`.
  2201. @par Example
  2202. The return value can be used in both a boolean context and
  2203. to assign a variable:
  2204. @code
  2205. if( auto r = jv.try_as_double() )
  2206. return *r;
  2207. @endcode
  2208. But can also be used to throw an exception on error:
  2209. @code
  2210. return jv.try_as_double().value();
  2211. @endcode
  2212. @par Complexity
  2213. Constant.
  2214. @par Exception Safety
  2215. No-throw guarantee.
  2216. */
  2217. BOOST_JSON_DECL
  2218. system::result<double>
  2219. try_as_double() const noexcept;
  2220. /** Return `result` with a reference to the underlying `bool`
  2221. If @ref is_bool() is `true`, the result contains a reference to the
  2222. underlying `bool`, otherwise it contains an `error_code`.
  2223. @par Example
  2224. The return value can be used in both a boolean context and
  2225. to assign a variable:
  2226. @code
  2227. if( auto r = jv.try_as_bool() )
  2228. return *r;
  2229. @endcode
  2230. But can also be used to throw an exception on error:
  2231. @code
  2232. return jv.try_as_bool().value();
  2233. @endcode
  2234. @par Complexity
  2235. Constant.
  2236. @par Exception Safety
  2237. No-throw guarantee.
  2238. */
  2239. BOOST_JSON_DECL
  2240. system::result<bool&>
  2241. try_as_bool() noexcept;
  2242. /** Return `result` with the underlying `bool`
  2243. If @ref is_bool() is `true`, the result contains a copy of the
  2244. underlying `bool`, otherwise it contains an `error_code`.
  2245. @par Example
  2246. The return value can be used in both a boolean context and
  2247. to assign a variable:
  2248. @code
  2249. if( auto r = jv.try_as_bool() )
  2250. return *r;
  2251. @endcode
  2252. But can also be used to throw an exception on error:
  2253. @code
  2254. return jv.try_as_bool().value();
  2255. @endcode
  2256. @par Complexity
  2257. Constant.
  2258. @par Exception Safety
  2259. No-throw guarantee.
  2260. */
  2261. BOOST_JSON_DECL
  2262. system::result<bool>
  2263. try_as_bool() const noexcept;
  2264. /** Return engaged `result` if the `value` is null
  2265. If @ref is_null() is `true`, the result is engaged, otherwise it
  2266. contains an `error_code`.
  2267. @par Example
  2268. The return value can be used in both a boolean context and
  2269. to assign a variable:
  2270. @code
  2271. if( auto r = jv.try_as_null() )
  2272. return *r;
  2273. @endcode
  2274. But can also be used to throw an exception on error:
  2275. @code
  2276. return jv.try_as_null().value();
  2277. @endcode
  2278. @par Complexity
  2279. Constant.
  2280. @par Exception Safety
  2281. No-throw guarantee.
  2282. */
  2283. BOOST_JSON_DECL
  2284. system::result<std::nullptr_t>
  2285. try_as_null() const noexcept;
  2286. //------------------------------------------------------
  2287. /** Return a reference to the underlying `object`, or throw an exception.
  2288. If @ref is_object() is `true`, returns
  2289. a reference to the underlying @ref object,
  2290. otherwise throws an exception.
  2291. @par Exception Safety
  2292. Strong guarantee.
  2293. @throw `boost::system::system_error` `! this->is_object()`.
  2294. @param loc `source_location` to use in thrown exception; the source
  2295. location of the call site by default.
  2296. @par Complexity
  2297. Constant.
  2298. */
  2299. /** @{ */
  2300. object&
  2301. as_object(source_location const& loc = BOOST_CURRENT_LOCATION) &
  2302. {
  2303. auto& self = const_cast<value const&>(*this);
  2304. return const_cast<object&>( self.as_object(loc) );
  2305. }
  2306. object&&
  2307. as_object(source_location const& loc = BOOST_CURRENT_LOCATION) &&
  2308. {
  2309. return std::move( as_object(loc) );
  2310. }
  2311. BOOST_JSON_DECL
  2312. object const&
  2313. as_object(source_location const& loc = BOOST_CURRENT_LOCATION) const&;
  2314. /** @} */
  2315. /** Return a reference to the underlying @ref array, or throw an exception.
  2316. If @ref is_array() is `true`, returns
  2317. a reference to the underlying @ref array,
  2318. otherwise throws an exception.
  2319. @par Exception Safety
  2320. Strong guarantee.
  2321. @throw `boost::system::system_error` `! this->is_array()`.
  2322. @param loc `source_location` to use in thrown exception; the source
  2323. location of the call site by default.
  2324. @par Complexity
  2325. Constant.
  2326. */
  2327. /** @{ */
  2328. array&
  2329. as_array(source_location const& loc = BOOST_CURRENT_LOCATION) &
  2330. {
  2331. auto& self = const_cast<value const&>(*this);
  2332. return const_cast<array&>( self.as_array(loc) );
  2333. }
  2334. array&&
  2335. as_array(source_location const& loc = BOOST_CURRENT_LOCATION) &&
  2336. {
  2337. return std::move( as_array(loc) );
  2338. }
  2339. BOOST_JSON_DECL
  2340. array const&
  2341. as_array(source_location const& loc = BOOST_CURRENT_LOCATION) const&;
  2342. /** @} */
  2343. /** Return a reference to the underlying `string`, or throw an exception.
  2344. If @ref is_string() is `true`, returns
  2345. a reference to the underlying @ref string,
  2346. otherwise throws an exception.
  2347. @par Exception Safety
  2348. Strong guarantee.
  2349. @throw `boost::system::system_error` `! this->is_string()`.
  2350. @param loc `source_location` to use in thrown exception; the source
  2351. location of the call site by default.
  2352. @par Complexity
  2353. Constant.
  2354. */
  2355. string&
  2356. as_string(source_location const& loc = BOOST_CURRENT_LOCATION) &
  2357. {
  2358. auto& self = const_cast<value const&>(*this);
  2359. return const_cast<string&>( self.as_string(loc) );
  2360. }
  2361. /** Return a reference to the underlying `string`, or throw an exception.
  2362. If @ref is_string() is `true`, returns
  2363. a reference to the underlying @ref string,
  2364. otherwise throws an exception.
  2365. @par Exception Safety
  2366. Strong guarantee.
  2367. @throw `boost::system::system_error` `! this->is_string()`.
  2368. @param loc `source_location` to use in thrown exception; the source
  2369. location of the call site by default.
  2370. @par Complexity
  2371. Constant.
  2372. */
  2373. /** @{ */
  2374. string&&
  2375. as_string(source_location const& loc = BOOST_CURRENT_LOCATION) &&
  2376. {
  2377. return std::move( as_string(loc) );
  2378. }
  2379. BOOST_JSON_DECL
  2380. string const&
  2381. as_string(source_location const& loc = BOOST_CURRENT_LOCATION) const&;
  2382. BOOST_JSON_DECL
  2383. std::int64_t&
  2384. as_int64(source_location const& loc = BOOST_CURRENT_LOCATION);
  2385. /** @} */
  2386. /** Return the underlying `std::int64_t`, or throw an exception.
  2387. If @ref is_int64() is `true`, returns
  2388. the underlying `std::int64_t`,
  2389. otherwise throws an exception.
  2390. @par Exception Safety
  2391. Strong guarantee.
  2392. @throw `boost::system::system_error` `! this->is_int64()`.
  2393. @param loc `source_location` to use in thrown exception; the source
  2394. location of the call site by default.
  2395. @par Complexity
  2396. Constant.
  2397. @par Note
  2398. This function is the const-qualified overload of @ref as_int64, which
  2399. is intended for direct access to the underlying object, __if__ it has
  2400. the type `std::int64_t`. It does not convert the underlying object to
  2401. type `std::int64_t` even if a lossless conversion is possible. If you
  2402. are not sure which kind your `value` has, and you only care about
  2403. getting a `std::int64_t` number, consider using @ref to_number instead.
  2404. */
  2405. BOOST_JSON_DECL
  2406. std::int64_t
  2407. as_int64(source_location const& loc = BOOST_CURRENT_LOCATION) const;
  2408. /** Return a reference to the underlying `std::uint64_t`, or throw an exception.
  2409. If @ref is_uint64() is `true`, returns
  2410. a reference to the underlying `std::uint64_t`,
  2411. otherwise throws an exception.
  2412. @par Exception Safety
  2413. Strong guarantee.
  2414. @throw `boost::system::system_error` `! this->is_uint64()`.
  2415. @param loc `source_location` to use in thrown exception; the source
  2416. location of the call site by default.
  2417. @par Complexity
  2418. Constant.
  2419. @par Note
  2420. This function is intended for direct access to the underlying object,
  2421. __if__ it has the type `std::uint64_t`. It does not convert the
  2422. underlying object to type `std::uint64_t` even if a lossless conversion
  2423. is possible. If you are not sure which kind your `value` has, and you
  2424. only care about getting a `std::uint64_t` number, consider using
  2425. @ref to_number instead.
  2426. */
  2427. BOOST_JSON_DECL
  2428. std::uint64_t&
  2429. as_uint64(source_location const& loc = BOOST_CURRENT_LOCATION);
  2430. /** Return the underlying `std::uint64_t`, or throw an exception.
  2431. If @ref is_uint64() is `true`, returns
  2432. the underlying `std::uint64_t`,
  2433. otherwise throws an exception.
  2434. @par Exception Safety
  2435. Strong guarantee.
  2436. @throw `boost::system::system_error` `! this->is_uint64()`.
  2437. @param loc `source_location` to use in thrown exception; the source
  2438. location of the call site by default.
  2439. @par Complexity
  2440. Constant.
  2441. @par Note
  2442. This function is the const-qualified overload of @ref as_uint64, which
  2443. is intended for direct access to the underlying object, __if__ it has
  2444. the type `std::uint64_t`. It does not convert the underlying object to
  2445. type `std::uint64_t` even if a lossless conversion is possible. If you
  2446. are not sure which kind your `value` has, and you only care about
  2447. getting a `std::uint64_t` number, consider using
  2448. @ref to_number instead.
  2449. */
  2450. BOOST_JSON_DECL
  2451. std::uint64_t
  2452. as_uint64(source_location const& loc = BOOST_CURRENT_LOCATION) const;
  2453. /** Return a reference to the underlying `double`, or throw an exception.
  2454. If @ref is_double() is `true`, returns
  2455. a reference to the underlying `double`,
  2456. otherwise throws an exception.
  2457. @par Exception Safety
  2458. Strong guarantee.
  2459. @throw `boost::system::system_error` `! this->is_double()`.
  2460. @param loc `source_location` to use in thrown exception; the source
  2461. location of the call site by default.
  2462. @par Complexity
  2463. Constant.
  2464. @par Note
  2465. This function is intended for direct access to the underlying object,
  2466. __if__ it has the type `double`. It does not convert the underlying
  2467. object to type `double` even if a lossless conversion is possible. If
  2468. you are not sure which kind your `value` has, and you only care about
  2469. getting a `double` number, consider using @ref to_number instead.
  2470. */
  2471. BOOST_JSON_DECL
  2472. double&
  2473. as_double(source_location const& loc = BOOST_CURRENT_LOCATION);
  2474. /** Return the underlying `double`, or throw an exception.
  2475. If @ref is_double() is `true`, returns
  2476. the underlying `double`,
  2477. otherwise throws an exception.
  2478. @par Exception Safety
  2479. Strong guarantee.
  2480. @throw `boost::system::system_error` `! this->is_double()`.
  2481. @param loc `source_location` to use in thrown exception; the source
  2482. location of the call site by default.
  2483. @par Complexity
  2484. Constant.
  2485. @par Note
  2486. This function is the const-qualified overload of @ref as_double, which
  2487. is intended for direct access to the underlying object, __if__ it has
  2488. the type `double`. It does not convert the underlying object to type
  2489. `double` even if a lossless conversion is possible. If you are not sure
  2490. which kind your `value` has, and you only care about getting a `double`
  2491. number, consider using @ref to_number instead.
  2492. */
  2493. BOOST_JSON_DECL
  2494. double
  2495. as_double(source_location const& loc = BOOST_CURRENT_LOCATION) const;
  2496. /** Return a reference to the underlying `bool`, or throw an exception.
  2497. If @ref is_bool() is `true`, returns
  2498. a reference to the underlying `bool`,
  2499. otherwise throws an exception.
  2500. @par Exception Safety
  2501. Strong guarantee.
  2502. @throw `boost::system::system_error` `! this->is_bool()`.
  2503. @param loc `source_location` to use in thrown exception; the source
  2504. location of the call site by default.
  2505. @par Complexity
  2506. Constant.
  2507. */
  2508. BOOST_JSON_DECL
  2509. bool&
  2510. as_bool(source_location const& loc = BOOST_CURRENT_LOCATION);
  2511. /** Return the underlying `bool`, or throw an exception.
  2512. If @ref is_bool() is `true`, returns
  2513. the underlying `bool`,
  2514. otherwise throws an exception.
  2515. @par Exception Safety
  2516. Strong guarantee.
  2517. @throw `boost::system::system_error` `! this->is_bool()`.
  2518. @param loc `source_location` to use in thrown exception; the source
  2519. location of the call site by default.
  2520. @par Complexity
  2521. Constant.
  2522. */
  2523. BOOST_JSON_DECL
  2524. bool
  2525. as_bool(source_location const& loc = BOOST_CURRENT_LOCATION) const;
  2526. //------------------------------------------------------
  2527. /** Return a reference to the underlying `object`, without checking.
  2528. This is the fastest way to access the underlying
  2529. representation when the kind is known in advance.
  2530. @par Preconditions
  2531. @code
  2532. this->is_object()
  2533. @endcode
  2534. @par Complexity
  2535. Constant.
  2536. @par Exception Safety
  2537. No-throw guarantee.
  2538. */
  2539. /** @{ */
  2540. object&
  2541. get_object() & noexcept
  2542. {
  2543. BOOST_ASSERT(is_object());
  2544. return obj_;
  2545. }
  2546. object&&
  2547. get_object() && noexcept
  2548. {
  2549. BOOST_ASSERT(is_object());
  2550. return std::move(obj_);
  2551. }
  2552. object const&
  2553. get_object() const& noexcept
  2554. {
  2555. BOOST_ASSERT(is_object());
  2556. return obj_;
  2557. }
  2558. /** @} */
  2559. /** Return a reference to the underlying `array`, without checking.
  2560. This is the fastest way to access the underlying
  2561. representation when the kind is known in advance.
  2562. @par Preconditions
  2563. @code
  2564. this->is_array()
  2565. @endcode
  2566. @par Complexity
  2567. Constant.
  2568. @par Exception Safety
  2569. No-throw guarantee.
  2570. */
  2571. /** @{ */
  2572. array&
  2573. get_array() & noexcept
  2574. {
  2575. BOOST_ASSERT(is_array());
  2576. return arr_;
  2577. }
  2578. array&&
  2579. get_array() && noexcept
  2580. {
  2581. BOOST_ASSERT(is_array());
  2582. return std::move(arr_);
  2583. }
  2584. array const&
  2585. get_array() const& noexcept
  2586. {
  2587. BOOST_ASSERT(is_array());
  2588. return arr_;
  2589. }
  2590. /** @} */
  2591. /** Return a reference to the underlying `string`, without checking.
  2592. This is the fastest way to access the underlying
  2593. representation when the kind is known in advance.
  2594. @par Preconditions
  2595. @code
  2596. this->is_string()
  2597. @endcode
  2598. @par Complexity
  2599. Constant.
  2600. @par Exception Safety
  2601. No-throw guarantee.
  2602. */
  2603. /** @{ */
  2604. string&
  2605. get_string() & noexcept
  2606. {
  2607. BOOST_ASSERT(is_string());
  2608. return str_;
  2609. }
  2610. string&&
  2611. get_string() && noexcept
  2612. {
  2613. BOOST_ASSERT(is_string());
  2614. return std::move(str_);
  2615. }
  2616. string const&
  2617. get_string() const& noexcept
  2618. {
  2619. BOOST_ASSERT(is_string());
  2620. return str_;
  2621. }
  2622. /** @} */
  2623. /** Return a reference to the underlying `std::int64_t`, without checking.
  2624. This is the fastest way to access the underlying
  2625. representation when the kind is known in advance.
  2626. @par Preconditions
  2627. @code
  2628. this->is_int64()
  2629. @endcode
  2630. @par Complexity
  2631. Constant.
  2632. @par Exception Safety
  2633. No-throw guarantee.
  2634. */
  2635. std::int64_t&
  2636. get_int64() noexcept
  2637. {
  2638. BOOST_ASSERT(is_int64());
  2639. return sca_.i;
  2640. }
  2641. /** Return the underlying `std::int64_t`, without checking.
  2642. This is the fastest way to access the underlying
  2643. representation when the kind is known in advance.
  2644. @par Preconditions
  2645. @code
  2646. this->is_int64()
  2647. @endcode
  2648. @par Complexity
  2649. Constant.
  2650. @par Exception Safety
  2651. No-throw guarantee.
  2652. */
  2653. std::int64_t
  2654. get_int64() const noexcept
  2655. {
  2656. BOOST_ASSERT(is_int64());
  2657. return sca_.i;
  2658. }
  2659. /** Return a reference to the underlying `std::uint64_t`, without checking.
  2660. This is the fastest way to access the underlying
  2661. representation when the kind is known in advance.
  2662. @par Preconditions
  2663. @code
  2664. this->is_uint64()
  2665. @endcode
  2666. @par Complexity
  2667. Constant.
  2668. @par Exception Safety
  2669. No-throw guarantee.
  2670. */
  2671. std::uint64_t&
  2672. get_uint64() noexcept
  2673. {
  2674. BOOST_ASSERT(is_uint64());
  2675. return sca_.u;
  2676. }
  2677. /** Return the underlying `std::uint64_t`, without checking.
  2678. This is the fastest way to access the underlying
  2679. representation when the kind is known in advance.
  2680. @par Preconditions
  2681. @code
  2682. this->is_uint64()
  2683. @endcode
  2684. @par Complexity
  2685. Constant.
  2686. @par Exception Safety
  2687. No-throw guarantee.
  2688. */
  2689. std::uint64_t
  2690. get_uint64() const noexcept
  2691. {
  2692. BOOST_ASSERT(is_uint64());
  2693. return sca_.u;
  2694. }
  2695. /** Return a reference to the underlying `double`, without checking.
  2696. This is the fastest way to access the underlying
  2697. representation when the kind is known in advance.
  2698. @par Preconditions
  2699. @code
  2700. this->is_double()
  2701. @endcode
  2702. @par Complexity
  2703. Constant.
  2704. @par Exception Safety
  2705. No-throw guarantee.
  2706. */
  2707. double&
  2708. get_double() noexcept
  2709. {
  2710. BOOST_ASSERT(is_double());
  2711. return sca_.d;
  2712. }
  2713. /** Return the underlying `double`, without checking.
  2714. This is the fastest way to access the underlying
  2715. representation when the kind is known in advance.
  2716. @par Preconditions
  2717. @code
  2718. this->is_double()
  2719. @endcode
  2720. @par Complexity
  2721. Constant.
  2722. @par Exception Safety
  2723. No-throw guarantee.
  2724. */
  2725. double
  2726. get_double() const noexcept
  2727. {
  2728. BOOST_ASSERT(is_double());
  2729. return sca_.d;
  2730. }
  2731. /** Return a reference to the underlying `bool`, without checking.
  2732. This is the fastest way to access the underlying
  2733. representation when the kind is known in advance.
  2734. @par Preconditions
  2735. @code
  2736. this->is_bool()
  2737. @endcode
  2738. @par Complexity
  2739. Constant.
  2740. @par Exception Safety
  2741. No-throw guarantee.
  2742. */
  2743. bool&
  2744. get_bool() noexcept
  2745. {
  2746. BOOST_ASSERT(is_bool());
  2747. return sca_.b;
  2748. }
  2749. /** Return the underlying `bool`, without checking.
  2750. This is the fastest way to access the underlying
  2751. representation when the kind is known in advance.
  2752. @par Preconditions
  2753. @code
  2754. this->is_bool()
  2755. @endcode
  2756. @par Complexity
  2757. Constant.
  2758. @par Exception Safety
  2759. No-throw guarantee.
  2760. */
  2761. bool
  2762. get_bool() const noexcept
  2763. {
  2764. BOOST_ASSERT(is_bool());
  2765. return sca_.b;
  2766. }
  2767. //------------------------------------------------------
  2768. /** Access an element, with bounds checking.
  2769. Returns `boost::system::result` containing a reference to the element
  2770. of the underlying object, if `pos` is within its range. If `pos` is
  2771. outside of that range, or the underlying value is not an object the
  2772. result contains an `error_code`.
  2773. @par Exception Safety
  2774. No-throw guarantee.
  2775. @param key The key of the element to find.
  2776. @par Complexity
  2777. Constant.
  2778. */
  2779. /** @{ */
  2780. BOOST_JSON_DECL
  2781. boost::system::result<value&>
  2782. try_at(string_view key) noexcept;
  2783. BOOST_JSON_DECL
  2784. boost::system::result<value const&>
  2785. try_at(string_view key) const noexcept;
  2786. /** @} */
  2787. /** Access an element, with bounds checking.
  2788. This function is used to access elements of
  2789. the underlying object, or throw an exception
  2790. if the value is not an object.
  2791. @par Complexity
  2792. Constant.
  2793. @par Exception Safety
  2794. Strong guarantee.
  2795. @param key The key of the element to find.
  2796. @param loc `source_location` to use in thrown exception; the source
  2797. location of the call site by default.
  2798. @return `this->as_object(loc).at( key, loc )`.
  2799. */
  2800. /** @{ */
  2801. value&
  2802. at(string_view key, source_location const& loc = BOOST_CURRENT_LOCATION) &
  2803. {
  2804. return as_object(loc).at(key, loc);
  2805. }
  2806. value&&
  2807. at(string_view key, source_location const& loc = BOOST_CURRENT_LOCATION) &&
  2808. {
  2809. return std::move( as_object(loc) ).at(key, loc);
  2810. }
  2811. value const&
  2812. at(
  2813. string_view key,
  2814. source_location const& loc = BOOST_CURRENT_LOCATION) const&
  2815. {
  2816. return as_object(loc).at(key, loc);
  2817. }
  2818. /** @} */
  2819. /** Access an element, with bounds checking.
  2820. Returns `boost::system::result` containing a reference to the element
  2821. of the underlying array, if `pos` is within its range. If `pos` is
  2822. outside of that range, or the underlying value is not an array the
  2823. result contains an `error_code`.
  2824. @par Exception Safety
  2825. No-throw guarantee.
  2826. @param pos A zero-based array index.
  2827. @par Complexity
  2828. Constant.
  2829. */
  2830. /** @{ */
  2831. BOOST_JSON_DECL
  2832. boost::system::result<value&>
  2833. try_at(std::size_t pos) noexcept;
  2834. BOOST_JSON_DECL
  2835. boost::system::result<value const&>
  2836. try_at(std::size_t pos) const noexcept;
  2837. /** @} */
  2838. /** Access an element, with bounds checking.
  2839. This function is used to access elements of
  2840. the underlying array, or throw an exception
  2841. if the value is not an array.
  2842. @par Complexity
  2843. Constant.
  2844. @par Exception Safety
  2845. Strong guarantee.
  2846. @param pos A zero-based array index.
  2847. @param loc `source_location` to use in thrown exception; the source
  2848. location of the call site by default.
  2849. @return `this->as_array(loc).at( pos, loc )`.
  2850. */
  2851. /** @{ */
  2852. value &
  2853. at(std::size_t pos, source_location const& loc = BOOST_CURRENT_LOCATION) &
  2854. {
  2855. return as_array(loc).at(pos, loc);
  2856. }
  2857. value&&
  2858. at(std::size_t pos, source_location const& loc = BOOST_CURRENT_LOCATION) &&
  2859. {
  2860. return std::move( as_array(loc) ).at(pos, loc);
  2861. }
  2862. value const&
  2863. at(
  2864. std::size_t pos,
  2865. source_location const& loc = BOOST_CURRENT_LOCATION) const&
  2866. {
  2867. return as_array(loc).at(pos, loc);
  2868. }
  2869. /** @} */
  2870. /** Access an element via JSON Pointer.
  2871. This function is used to access a (potentially nested) element of the
  2872. value using a JSON Pointer string.
  2873. @par Complexity
  2874. Linear in the sizes of `ptr` and underlying array, object, or string.
  2875. @par Exception Safety
  2876. No-throw guarantee.
  2877. @param ptr JSON Pointer string.
  2878. @return `boost::system::result<value&>` containing either a reference
  2879. to the element identified by `ptr` or a corresponding `error_code`.
  2880. @see
  2881. [RFC 6901 - JavaScript Object Notation (JSON) Pointer](https://datatracker.ietf.org/doc/html/rfc6901).
  2882. */
  2883. BOOST_JSON_DECL
  2884. system::result<value const&>
  2885. try_at_pointer(string_view ptr) const noexcept;
  2886. /** Access an element via JSON Pointer.
  2887. This function is used to access a (potentially nested) element of the
  2888. value using a JSON Pointer string.
  2889. @par Complexity
  2890. Linear in the sizes of `ptr` and underlying array, object, or string.
  2891. @par Exception Safety
  2892. No-throw guarantee.
  2893. @param ptr JSON Pointer string.
  2894. @return `boost::system::result<value const&>` containing either a
  2895. reference to the element identified by `ptr` or a corresponding
  2896. `error_code`.
  2897. @see
  2898. [RFC 6901 - JavaScript Object Notation (JSON) Pointer](https://datatracker.ietf.org/doc/html/rfc6901).
  2899. */
  2900. BOOST_JSON_DECL
  2901. system::result<value&>
  2902. try_at_pointer(string_view ptr) noexcept;
  2903. /** Access an element via JSON Pointer.
  2904. This function is used to access a (potentially nested)
  2905. element of the value using a JSON Pointer string.
  2906. @par Complexity
  2907. Linear in the sizes of `ptr` and underlying array, object, or string.
  2908. @par Exception Safety
  2909. Strong guarantee.
  2910. @param ptr JSON Pointer string.
  2911. @param loc `source_location` to use in thrown exception; the source
  2912. location of the call site by default.
  2913. @return reference to the element identified by `ptr`.
  2914. @throw `boost::system::system_error` if an error occurs.
  2915. @see
  2916. <a href="https://datatracker.ietf.org/doc/html/rfc6901">
  2917. RFC 6901 - JavaScript Object Notation (JSON) Pointer</a>
  2918. */
  2919. /** @{ */
  2920. BOOST_JSON_DECL
  2921. value const&
  2922. at_pointer(
  2923. string_view ptr,
  2924. source_location const& loc = BOOST_CURRENT_LOCATION) const&;
  2925. inline
  2926. value&&
  2927. at_pointer(
  2928. string_view ptr,
  2929. source_location const& loc = BOOST_CURRENT_LOCATION) &&;
  2930. inline
  2931. value&
  2932. at_pointer(
  2933. string_view ptr,
  2934. source_location const& loc = BOOST_CURRENT_LOCATION) &;
  2935. /** @} */
  2936. /** Access an element via JSON Pointer.
  2937. This function is used to access a (potentially nested)
  2938. element of the value using a JSON Pointer string.
  2939. @par Complexity
  2940. Linear in the sizes of `ptr` and underlying array, object, or string.
  2941. @par Exception Safety
  2942. No-throw guarantee.
  2943. @param ptr JSON Pointer string.
  2944. @param ec Set to the error, if any occurred.
  2945. @return pointer to the element identified by `ptr`.
  2946. @see
  2947. <a href="https://datatracker.ietf.org/doc/html/rfc6901">
  2948. RFC 6901 - JavaScript Object Notation (JSON) Pointer</a>
  2949. */
  2950. /** @{ */
  2951. BOOST_JSON_DECL
  2952. value const*
  2953. find_pointer(string_view ptr, system::error_code& ec) const noexcept;
  2954. BOOST_JSON_DECL
  2955. value*
  2956. find_pointer(string_view ptr, system::error_code& ec) noexcept;
  2957. BOOST_JSON_DECL
  2958. value const*
  2959. find_pointer(string_view ptr, std::error_code& ec) const noexcept;
  2960. BOOST_JSON_DECL
  2961. value*
  2962. find_pointer(string_view ptr, std::error_code& ec) noexcept;
  2963. /** @} */
  2964. //------------------------------------------------------
  2965. /** Set an element via JSON Pointer.
  2966. This function is used to insert or assign to a potentially nested
  2967. element of the value using a JSON Pointer string. The function may
  2968. create intermediate elements corresponding to pointer segments.
  2969. <br/>
  2970. The particular conditions when and what kind of intermediate element
  2971. is created is governed by the `ptr` parameter.
  2972. Each pointer token is considered in sequence. For each token
  2973. - if the containing value is an @ref object, then a new `null`
  2974. element is created with key equal to unescaped token string;
  2975. otherwise
  2976. - if the containing value is an @ref array, and the token represents a
  2977. past-the-end marker, then a `null` element is appended to the array;
  2978. otherwise
  2979. - if the containing value is an @ref array, and the token represents a
  2980. number, then if the difference between the number and array's size
  2981. is smaller than `opts.max_created_elements`, then the size of the
  2982. array is increased, so that the number can reference an element in the
  2983. array; otherwise
  2984. - if the containing value is of different @ref kind and
  2985. `opts.replace_any_scalar` is `true`, or the value is `null`, then
  2986. - if `opts.create_arrays` is `true` and the token either represents
  2987. past-the-end marker or a number, then the value is replaced with
  2988. an empty array and the token is considered again; otherwise
  2989. - if `opts.create_objects` is `true`, then the value is replaced
  2990. with an empty object and the token is considered again; otherwise
  2991. - an error is produced.
  2992. @par Complexity
  2993. Linear in the sum of size of `ptr`, size of underlying array, object,
  2994. or string and `opts.max_created_elements`.
  2995. @par Exception Safety
  2996. Basic guarantee.
  2997. Calls to `memory_resource::allocate` may throw.
  2998. @param sv JSON Pointer string.
  2999. @param ref The value to assign to pointed element.
  3000. @param opts The options for the algorithm.
  3001. @return `boost::json::result<value&>` containing either a reference to
  3002. the element identified by `ptr` or a corresponding `error_code`.
  3003. @see
  3004. @ref set_pointer_options,
  3005. [RFC 6901 - JavaScript Object Notation (JSON) Pointer](https://datatracker.ietf.org/doc/html/rfc6901).
  3006. */
  3007. BOOST_JSON_DECL
  3008. system::result<value&>
  3009. try_set_at_pointer(
  3010. string_view sv,
  3011. value_ref ref,
  3012. set_pointer_options const& opts = {} );
  3013. /** Set an element via JSON Pointer.
  3014. This function is used to insert or assign to a potentially nested
  3015. element of the value using a JSON Pointer string. The function may
  3016. create intermediate elements corresponding to pointer segments.
  3017. <br/>
  3018. The particular conditions when and what kind of intermediate element
  3019. is created is governed by the `ptr` parameter.
  3020. Each pointer token is considered in sequence. For each token
  3021. - if the containing value is an @ref object, then a new `null`
  3022. element is created with key equal to unescaped token string; otherwise
  3023. - if the containing value is an @ref array, and the token represents a
  3024. past-the-end marker, then a `null` element is appended to the array;
  3025. otherwise
  3026. - if the containing value is an @ref array, and the token represents a
  3027. number, then if the difference between the number and array's size
  3028. is smaller than `opts.max_created_elements`, then the size of the
  3029. array is increased, so that the number can reference an element in the
  3030. array; otherwise
  3031. - if the containing value is of different @ref kind and
  3032. `opts.replace_any_scalar` is `true`, or the value is `null`, then
  3033. - if `opts.create_arrays` is `true` and the token either represents
  3034. past-the-end marker or a number, then the value is replaced with
  3035. an empty array and the token is considered again; otherwise
  3036. - if `opts.create_objects` is `true`, then the value is replaced
  3037. with an empty object and the token is considered again; otherwise
  3038. - an error is produced.
  3039. @par Complexity
  3040. Linear in the sum of size of `ptr`, size of underlying array, object,
  3041. or string and `opts.max_created_elements`.
  3042. @par Exception Safety
  3043. Basic guarantee.
  3044. Calls to `memory_resource::allocate` may throw.
  3045. @param sv JSON Pointer string.
  3046. @param ref The value to assign to pointed element.
  3047. @param opts The options for the algorithm.
  3048. @return Reference to the element identified by `ptr`.
  3049. @see @ref set_pointer_options,
  3050. <a href="https://datatracker.ietf.org/doc/html/rfc6901">
  3051. RFC 6901 - JavaScript Object Notation (JSON) Pointer</a>.
  3052. */
  3053. BOOST_JSON_DECL
  3054. value&
  3055. set_at_pointer(
  3056. string_view sv,
  3057. value_ref ref,
  3058. set_pointer_options const& opts = {} );
  3059. /** Set an element via JSON Pointer.
  3060. This function is used to insert or assign to a potentially nested
  3061. element of the value using a JSON Pointer string. The function may
  3062. create intermediate elements corresponding to pointer segments.
  3063. <br/>
  3064. The particular conditions when and what kind of intermediate element
  3065. is created is governed by the `ptr` parameter.
  3066. Each pointer token is considered in sequence. For each token
  3067. - if the containing value is an @ref object, then a new `null`
  3068. element is created with key equal to unescaped token string;
  3069. otherwise
  3070. - if the containing value is an @ref array, and the token represents a
  3071. past-the-end marker, then a `null` element is appended to the array;
  3072. otherwise
  3073. - if the containing value is an @ref array, and the token represents a
  3074. number, then if the difference between the number and array's size
  3075. is smaller than `opts.max_created_elements`, then the size of the
  3076. array is increased, so that the number can reference an element in the
  3077. array; otherwise
  3078. - if the containing value is of different @ref kind and
  3079. `opts.replace_any_scalar` is `true`, or the value is `null`, then
  3080. - if `opts.create_arrays` is `true` and the token either represents
  3081. past-the-end marker or a number, then the value is replaced with
  3082. an empty array and the token is considered again; otherwise
  3083. - if `opts.create_objects` is `true`, then the value is replaced
  3084. with an empty object and the token is considered again; otherwise
  3085. - an error is produced.
  3086. @par Complexity
  3087. Linear in the sum of size of `ptr`, size of underlying array, object,
  3088. or string and `opts.max_created_elements`.
  3089. @par Exception Safety
  3090. Basic guarantee.
  3091. Calls to `memory_resource::allocate` may throw.
  3092. @param sv JSON Pointer string.
  3093. @param ref The value to assign to pointed element.
  3094. @param ec Set to the error, if any occurred.
  3095. @param opts The options for the algorithm.
  3096. @return Pointer to the element identified by `ptr`.
  3097. @see @ref set_pointer_options,
  3098. <a href="https://datatracker.ietf.org/doc/html/rfc6901">
  3099. RFC 6901 - JavaScript Object Notation (JSON) Pointer</a>.
  3100. */
  3101. /** @{ */
  3102. BOOST_JSON_DECL
  3103. value*
  3104. set_at_pointer(
  3105. string_view sv,
  3106. value_ref ref,
  3107. system::error_code& ec,
  3108. set_pointer_options const& opts = {} );
  3109. BOOST_JSON_DECL
  3110. value*
  3111. set_at_pointer(
  3112. string_view sv,
  3113. value_ref ref,
  3114. std::error_code& ec,
  3115. set_pointer_options const& opts = {} );
  3116. /** @} */
  3117. //------------------------------------------------------
  3118. /** Return `true` if two values are equal.
  3119. Two values are equal when they are the
  3120. same kind and their referenced values
  3121. are equal, or when they are both integral
  3122. types and their integral representations
  3123. are equal.
  3124. @par Complexity
  3125. Constant or linear in the size of
  3126. the array, object, or string.
  3127. @par Exception Safety
  3128. No-throw guarantee.
  3129. */
  3130. // inline friend speeds up overload resolution
  3131. friend
  3132. bool
  3133. operator==(
  3134. value const& lhs,
  3135. value const& rhs) noexcept
  3136. {
  3137. return lhs.equal(rhs);
  3138. }
  3139. /** Return `true` if two values are not equal.
  3140. Two values are equal when they are the
  3141. same kind and their referenced values
  3142. are equal, or when they are both integral
  3143. types and their integral representations
  3144. are equal.
  3145. @par Complexity
  3146. Constant or linear in the size of
  3147. the array, object, or string.
  3148. @par Exception Safety
  3149. No-throw guarantee.
  3150. */
  3151. friend
  3152. bool
  3153. operator!=(
  3154. value const& lhs,
  3155. value const& rhs) noexcept
  3156. {
  3157. return ! (lhs == rhs);
  3158. }
  3159. /** Serialize @ref value to an output stream.
  3160. This function serializes a `value` as JSON into the output stream.
  3161. @return Reference to `os`.
  3162. @par Complexity
  3163. Constant or linear in the size of `jv`.
  3164. @par Exception Safety
  3165. Strong guarantee.
  3166. Calls to `memory_resource::allocate` may throw.
  3167. @param os The output stream to serialize to.
  3168. @param jv The value to serialize.
  3169. */
  3170. BOOST_JSON_DECL
  3171. friend
  3172. std::ostream&
  3173. operator<<(
  3174. std::ostream& os,
  3175. value const& jv);
  3176. /** Parse @ref value from an input stream.
  3177. This function parses JSON from an input stream into a `value`. If
  3178. parsing fails, `std::ios_base::failbit` will be set for `is` and
  3179. `jv` will be left unchanged. Regardless of whether `skipws` flag is set
  3180. on `is`, consumes whitespace before and after JSON, because whitespace
  3181. is considered a part of JSON. Behaves as
  3182. [_FormattedInputFunction_](https://en.cppreference.com/w/cpp/named_req/FormattedInputFunction).
  3183. Note: this operator cannot assume that the stream only contains a
  3184. single JSON document, which may result in **very underwhelming
  3185. performance**, if the stream isn't cooperative. If you know that your
  3186. input consists of a single JSON document, consider using @ref parse
  3187. function instead.
  3188. @return Reference to `is`.
  3189. @par Complexity
  3190. Linear in the size of JSON data.
  3191. @par Exception Safety
  3192. Basic guarantee.
  3193. Calls to `memory_resource::allocate` may throw.
  3194. The stream may throw as configured by
  3195. [`std::ios::exceptions`](https://en.cppreference.com/w/cpp/io/basic_ios/exceptions).
  3196. @param is The input stream to parse from.
  3197. @param jv The value to parse into.
  3198. @see @ref parse.
  3199. */
  3200. BOOST_JSON_DECL
  3201. friend
  3202. std::istream&
  3203. operator>>(
  3204. std::istream& is,
  3205. value& jv);
  3206. /** Helper for `boost::hash` support
  3207. Computes a hash value for `jv`. This function is used by
  3208. `boost::hash<value>`. Similar overloads for @ref array, @ref object,
  3209. and @ref string do not exist, because those types are supported by
  3210. `boost::hash` out of the box.
  3211. @return hash value for `jv`.
  3212. @param jv `value` for which a hash is to be computed.
  3213. @see [Boost.ContainerHash](https://boost.org/libs/container_hash).
  3214. */
  3215. #ifndef BOOST_JSON_DOCS
  3216. template<
  3217. class T,
  3218. typename std::enable_if<
  3219. std::is_same< detail::remove_cvref<T>, value >::value >::type*
  3220. = nullptr>
  3221. friend
  3222. std::size_t
  3223. hash_value( T const& jv ) noexcept
  3224. #else
  3225. friend
  3226. inline
  3227. std::size_t
  3228. hash_value( value const& jv ) noexcept
  3229. #endif
  3230. {
  3231. return detail::hash_value_impl(jv);
  3232. }
  3233. private:
  3234. static
  3235. void
  3236. relocate(
  3237. value* dest,
  3238. value const& src) noexcept
  3239. {
  3240. std::memcpy(
  3241. static_cast<void*>(dest),
  3242. &src,
  3243. sizeof(src));
  3244. }
  3245. BOOST_JSON_DECL
  3246. storage_ptr
  3247. destroy() noexcept;
  3248. BOOST_JSON_DECL
  3249. bool
  3250. equal(value const& other) const noexcept;
  3251. template<class T>
  3252. auto
  3253. to_number(error& e) const noexcept ->
  3254. typename std::enable_if<
  3255. std::is_signed<T>::value &&
  3256. ! std::is_floating_point<T>::value,
  3257. T>::type
  3258. {
  3259. if(sca_.k == json::kind::int64)
  3260. {
  3261. auto const i = sca_.i;
  3262. if( i >= (std::numeric_limits<T>::min)() &&
  3263. i <= (std::numeric_limits<T>::max)())
  3264. {
  3265. e = {};
  3266. return static_cast<T>(i);
  3267. }
  3268. e = error::not_exact;
  3269. }
  3270. else if(sca_.k == json::kind::uint64)
  3271. {
  3272. auto const u = sca_.u;
  3273. if(u <= static_cast<std::uint64_t>((
  3274. std::numeric_limits<T>::max)()))
  3275. {
  3276. e = {};
  3277. return static_cast<T>(u);
  3278. }
  3279. e = error::not_exact;
  3280. }
  3281. else if(sca_.k == json::kind::double_)
  3282. {
  3283. auto const d = sca_.d;
  3284. if( d >= static_cast<double>(
  3285. (detail::to_number_limit<T>::min)()) &&
  3286. d <= static_cast<double>(
  3287. (detail::to_number_limit<T>::max)()) &&
  3288. static_cast<T>(d) == d)
  3289. {
  3290. e = {};
  3291. return static_cast<T>(d);
  3292. }
  3293. e = error::not_exact;
  3294. }
  3295. else
  3296. {
  3297. e = error::not_number;
  3298. }
  3299. return T{};
  3300. }
  3301. template<class T>
  3302. auto
  3303. to_number(error& e) const noexcept ->
  3304. typename std::enable_if<
  3305. std::is_unsigned<T>::value &&
  3306. ! std::is_same<T, bool>::value,
  3307. T>::type
  3308. {
  3309. if(sca_.k == json::kind::int64)
  3310. {
  3311. auto const i = sca_.i;
  3312. if( i >= 0 && static_cast<std::uint64_t>(i) <=
  3313. (std::numeric_limits<T>::max)())
  3314. {
  3315. e = {};
  3316. return static_cast<T>(i);
  3317. }
  3318. e = error::not_exact;
  3319. }
  3320. else if(sca_.k == json::kind::uint64)
  3321. {
  3322. auto const u = sca_.u;
  3323. if(u <= (std::numeric_limits<T>::max)())
  3324. {
  3325. e = {};
  3326. return static_cast<T>(u);
  3327. }
  3328. e = error::not_exact;
  3329. }
  3330. else if(sca_.k == json::kind::double_)
  3331. {
  3332. auto const d = sca_.d;
  3333. if( d >= 0 &&
  3334. d <= (detail::to_number_limit<T>::max)() &&
  3335. static_cast<T>(d) == d)
  3336. {
  3337. e = {};
  3338. return static_cast<T>(d);
  3339. }
  3340. e = error::not_exact;
  3341. }
  3342. else
  3343. {
  3344. e = error::not_number;
  3345. }
  3346. return T{};
  3347. }
  3348. template<class T>
  3349. auto
  3350. to_number(error& e) const noexcept ->
  3351. typename std::enable_if<
  3352. std::is_floating_point<
  3353. T>::value, T>::type
  3354. {
  3355. if(sca_.k == json::kind::int64)
  3356. {
  3357. e = {};
  3358. return static_cast<T>(sca_.i);
  3359. }
  3360. if(sca_.k == json::kind::uint64)
  3361. {
  3362. e = {};
  3363. return static_cast<T>(sca_.u);
  3364. }
  3365. if(sca_.k == json::kind::double_)
  3366. {
  3367. e = {};
  3368. return static_cast<T>(sca_.d);
  3369. }
  3370. e = error::not_number;
  3371. return {};
  3372. }
  3373. };
  3374. // Make sure things are as big as we think they should be
  3375. #if BOOST_JSON_ARCH == 64
  3376. BOOST_STATIC_ASSERT(sizeof(value) == 24);
  3377. #elif BOOST_JSON_ARCH == 32
  3378. BOOST_STATIC_ASSERT(sizeof(value) == 16);
  3379. #else
  3380. # error Unknown architecture
  3381. #endif
  3382. //----------------------------------------------------------
  3383. /** A key/value pair.
  3384. This is the type of element used by the @ref object
  3385. container.
  3386. */
  3387. class key_value_pair
  3388. {
  3389. #ifndef BOOST_JSON_DOCS
  3390. friend struct detail::access;
  3391. using access = detail::access;
  3392. #endif
  3393. BOOST_JSON_DECL
  3394. static char const empty_[1];
  3395. inline
  3396. key_value_pair(
  3397. pilfered<json::value> k,
  3398. pilfered<json::value> v) noexcept;
  3399. public:
  3400. /// Copy assignment (deleted).
  3401. key_value_pair&
  3402. operator=(key_value_pair const&) = delete;
  3403. /** Destructor.
  3404. The value is destroyed and all internally
  3405. allocated memory is freed.
  3406. */
  3407. ~key_value_pair() noexcept
  3408. {
  3409. auto const& sp = value_.storage();
  3410. if(sp.is_not_shared_and_deallocate_is_trivial())
  3411. return;
  3412. if(key_ == empty_)
  3413. return;
  3414. sp->deallocate(const_cast<char*>(key_),
  3415. len_ + 1, alignof(char));
  3416. }
  3417. /** Copy constructor.
  3418. This constructs a key/value pair with a
  3419. copy of another key/value pair, using
  3420. the same memory resource as `other`.
  3421. @par Exception Safety
  3422. Strong guarantee.
  3423. Calls to `memory_resource::allocate` may throw.
  3424. @param other The key/value pair to copy.
  3425. */
  3426. key_value_pair(
  3427. key_value_pair const& other)
  3428. : key_value_pair(other,
  3429. other.storage())
  3430. {
  3431. }
  3432. /** Copy constructor.
  3433. This constructs a key/value pair with a
  3434. copy of another key/value pair, using
  3435. the specified memory resource.
  3436. @par Exception Safety
  3437. Strong guarantee.
  3438. Calls to `memory_resource::allocate` may throw.
  3439. @param other The key/value pair to copy.
  3440. @param sp A pointer to the `boost::container::pmr::memory_resource` to
  3441. use. The element will acquire shared ownership of the memory resource.
  3442. */
  3443. BOOST_JSON_DECL
  3444. key_value_pair(
  3445. key_value_pair const& other,
  3446. storage_ptr sp);
  3447. /** Move constructor.
  3448. The pair is constructed by acquiring
  3449. ownership of the contents of `other` and
  3450. shared ownership of `other`'s memory resource.
  3451. @note
  3452. After construction, the moved-from pair holds an
  3453. empty key, and a null value with its current
  3454. storage pointer.
  3455. @par Complexity
  3456. Constant.
  3457. @par Exception Safety
  3458. No-throw guarantee.
  3459. @param other The pair to move.
  3460. */
  3461. key_value_pair(
  3462. key_value_pair&& other) noexcept
  3463. : value_(std::move(other.value_))
  3464. , key_(detail::exchange(
  3465. other.key_, empty_))
  3466. , len_(detail::exchange(
  3467. other.len_, 0))
  3468. {
  3469. }
  3470. /** Pilfer constructor.
  3471. The pair is constructed by acquiring ownership
  3472. of the contents of `other` using pilfer semantics.
  3473. This is more efficient than move construction, when
  3474. it is known that the moved-from object will be
  3475. immediately destroyed afterwards.
  3476. @par Complexity
  3477. Constant.
  3478. @par Exception Safety
  3479. No-throw guarantee.
  3480. @param other The value to pilfer. After pilfer
  3481. construction, `other` is not in a usable state
  3482. and may only be destroyed.
  3483. @see @ref pilfer,
  3484. <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html">
  3485. Valueless Variants Considered Harmful</a>
  3486. */
  3487. key_value_pair(
  3488. pilfered<key_value_pair> other) noexcept
  3489. : value_(pilfer(other.get().value_))
  3490. , key_(detail::exchange(
  3491. other.get().key_, empty_))
  3492. , len_(detail::exchange(
  3493. other.get().len_, 0))
  3494. {
  3495. }
  3496. /** Constructor.
  3497. This constructs a key/value pair.
  3498. @par Exception Safety
  3499. Strong guarantee.
  3500. Calls to `memory_resource::allocate` may throw.
  3501. @param key The key string to use.
  3502. @param args Optional arguments forwarded to
  3503. the @ref value constructor.
  3504. */
  3505. template<class... Args>
  3506. explicit
  3507. key_value_pair(
  3508. string_view key,
  3509. Args&&... args)
  3510. : value_(std::forward<Args>(args)...)
  3511. {
  3512. if(key.size() > string::max_size())
  3513. {
  3514. BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
  3515. detail::throw_system_error( error::key_too_large, &loc );
  3516. }
  3517. auto s = reinterpret_cast<
  3518. char*>(value_.storage()->
  3519. allocate(key.size() + 1, alignof(char)));
  3520. std::memcpy(s, key.data(), key.size());
  3521. s[key.size()] = 0;
  3522. key_ = s;
  3523. len_ = static_cast<
  3524. std::uint32_t>(key.size());
  3525. }
  3526. /** Constructor.
  3527. This constructs a key/value pair. A
  3528. copy of the specified value is made,
  3529. using the specified memory resource.
  3530. @par Exception Safety
  3531. Strong guarantee.
  3532. Calls to `memory_resource::allocate` may throw.
  3533. @param p A `std::pair` with the key
  3534. string and @ref value to construct with.
  3535. @param sp A pointer to the `boost::container::pmr::memory_resource` to
  3536. use. The element will acquire shared ownership of the memory resource.
  3537. */
  3538. explicit
  3539. key_value_pair(
  3540. std::pair<
  3541. string_view,
  3542. json::value> const& p,
  3543. storage_ptr sp = {})
  3544. : key_value_pair(
  3545. p.first,
  3546. p.second,
  3547. std::move(sp))
  3548. {
  3549. }
  3550. /** Constructor.
  3551. This constructs a key/value pair.
  3552. Ownership of the specified value is
  3553. transferred by move construction.
  3554. @par Exception Safety
  3555. Strong guarantee.
  3556. Calls to `memory_resource::allocate` may throw.
  3557. @param p A `std::pair` with the key
  3558. string and @ref value to construct with.
  3559. @param sp A pointer to the `boost::container::pmr::memory_resource` to
  3560. use. The element will acquire shared ownership of the memory resource.
  3561. */
  3562. explicit
  3563. key_value_pair(
  3564. std::pair<
  3565. string_view,
  3566. json::value>&& p,
  3567. storage_ptr sp = {})
  3568. : key_value_pair(
  3569. p.first,
  3570. std::move(p).second,
  3571. std::move(sp))
  3572. {
  3573. }
  3574. /** Return the associated memory resource.
  3575. This returns a pointer to the memory
  3576. resource used to construct the value.
  3577. @par Complexity
  3578. Constant.
  3579. @par Exception Safety
  3580. No-throw guarantee.
  3581. */
  3582. storage_ptr const&
  3583. storage() const noexcept
  3584. {
  3585. return value_.storage();
  3586. }
  3587. /** Return the key of this element.
  3588. After construction, the key may
  3589. not be modified.
  3590. @par Complexity
  3591. Constant.
  3592. @par Exception Safety
  3593. No-throw guarantee.
  3594. */
  3595. string_view const
  3596. key() const noexcept
  3597. {
  3598. return { key_, len_ };
  3599. }
  3600. /** Return the key of this element as a null-terminated string.
  3601. @par Complexity
  3602. Constant.
  3603. @par Exception Safety
  3604. No-throw guarantee.
  3605. */
  3606. char const*
  3607. key_c_str() const noexcept
  3608. {
  3609. return key_;
  3610. }
  3611. /** Return the value of this element.
  3612. @par Complexity
  3613. Constant.
  3614. @par Exception Safety
  3615. No-throw guarantee.
  3616. */
  3617. /** @{ */
  3618. json::value const&
  3619. value() const& noexcept
  3620. {
  3621. return value_;
  3622. }
  3623. json::value&&
  3624. value() && noexcept
  3625. {
  3626. return std::move( value() );
  3627. }
  3628. json::value&
  3629. value() & noexcept
  3630. {
  3631. return value_;
  3632. }
  3633. /** @} */
  3634. private:
  3635. json::value value_;
  3636. char const* key_;
  3637. std::uint32_t len_;
  3638. std::uint32_t next_;
  3639. };
  3640. //----------------------------------------------------------
  3641. #ifdef BOOST_JSON_DOCS
  3642. /** Tuple-like element access.
  3643. This overload permits the key and value
  3644. of a `key_value_pair` to be accessed
  3645. by index. For example:
  3646. @code
  3647. key_value_pair kvp("num", 42);
  3648. string_view key = get<0>(kvp);
  3649. value& jv = get<1>(kvp);
  3650. @endcode
  3651. @par Structured Bindings
  3652. When using C++17 or greater, objects of type
  3653. @ref key_value_pair may be used to initialize
  3654. structured bindings:
  3655. @code
  3656. key_value_pair kvp("num", 42);
  3657. auto& [key, value] = kvp;
  3658. @endcode
  3659. Depending on the value of `I`, the return type will be:
  3660. @li `string_view const` if `I == 0`, or
  3661. @li `value&`, `value const&`, or `value&&` if `I == 1`.
  3662. Any other value for `I` is ill-formed.
  3663. @tparam I The element index to access.
  3664. @par Constraints
  3665. `std::is_same_v< std::remove_cvref_t<T>, key_value_pair >`
  3666. @return `kvp.key()` if `I == 0`, or `kvp.value()`
  3667. if `I == 1`.
  3668. @param kvp The @ref key_value_pair object
  3669. to access.
  3670. */
  3671. template<
  3672. std::size_t I,
  3673. class T>
  3674. __see_below__
  3675. get(T&& kvp) noexcept;
  3676. #else
  3677. template<std::size_t I>
  3678. auto
  3679. get(key_value_pair const&) noexcept ->
  3680. typename std::conditional<I == 0,
  3681. string_view const,
  3682. value const&>::type
  3683. {
  3684. static_assert(I == 0,
  3685. "key_value_pair index out of range");
  3686. }
  3687. template<std::size_t I>
  3688. auto
  3689. get(key_value_pair&) noexcept ->
  3690. typename std::conditional<I == 0,
  3691. string_view const,
  3692. value&>::type
  3693. {
  3694. static_assert(I == 0,
  3695. "key_value_pair index out of range");
  3696. }
  3697. template<std::size_t I>
  3698. auto
  3699. get(key_value_pair&&) noexcept ->
  3700. typename std::conditional<I == 0,
  3701. string_view const,
  3702. value&&>::type
  3703. {
  3704. static_assert(I == 0,
  3705. "key_value_pair index out of range");
  3706. }
  3707. /** Extracts a key_value_pair's key using tuple-like interface
  3708. */
  3709. template<>
  3710. inline
  3711. string_view const
  3712. get<0>(key_value_pair const& kvp) noexcept
  3713. {
  3714. return kvp.key();
  3715. }
  3716. /** Extracts a key_value_pair's key using tuple-like interface
  3717. */
  3718. template<>
  3719. inline
  3720. string_view const
  3721. get<0>(key_value_pair& kvp) noexcept
  3722. {
  3723. return kvp.key();
  3724. }
  3725. /** Extracts a key_value_pair's key using tuple-like interface
  3726. */
  3727. template<>
  3728. inline
  3729. string_view const
  3730. get<0>(key_value_pair&& kvp) noexcept
  3731. {
  3732. return kvp.key();
  3733. }
  3734. /** Extracts a key_value_pair's value using tuple-like interface
  3735. */
  3736. template<>
  3737. inline
  3738. value const&
  3739. get<1>(key_value_pair const& kvp) noexcept
  3740. {
  3741. return kvp.value();
  3742. }
  3743. /** Extracts a key_value_pair's value using tuple-like interface
  3744. */
  3745. template<>
  3746. inline
  3747. value&
  3748. get<1>(key_value_pair& kvp) noexcept
  3749. {
  3750. return kvp.value();
  3751. }
  3752. /** Extracts a key_value_pair's value using tuple-like interface
  3753. */
  3754. template<>
  3755. inline
  3756. value&&
  3757. get<1>(key_value_pair&& kvp) noexcept
  3758. {
  3759. return std::move(kvp.value());
  3760. }
  3761. #endif
  3762. } // namespace json
  3763. } // namespace boost
  3764. #ifdef __clang__
  3765. # pragma clang diagnostic push
  3766. # pragma clang diagnostic ignored "-Wmismatched-tags"
  3767. #endif
  3768. #ifndef BOOST_JSON_DOCS
  3769. namespace std {
  3770. /** Tuple-like size access for key_value_pair
  3771. */
  3772. template<>
  3773. struct tuple_size< ::boost::json::key_value_pair >
  3774. : std::integral_constant<std::size_t, 2>
  3775. {
  3776. };
  3777. /** Tuple-like access for the key type of key_value_pair
  3778. */
  3779. template<>
  3780. struct tuple_element<0, ::boost::json::key_value_pair>
  3781. {
  3782. using type = ::boost::json::string_view const;
  3783. };
  3784. /** Tuple-like access for the value type of key_value_pair
  3785. */
  3786. template<>
  3787. struct tuple_element<1, ::boost::json::key_value_pair>
  3788. {
  3789. using type = ::boost::json::value&;
  3790. };
  3791. /** Tuple-like access for the value type of key_value_pair
  3792. */
  3793. template<>
  3794. struct tuple_element<1, ::boost::json::key_value_pair const>
  3795. {
  3796. using type = ::boost::json::value const&;
  3797. };
  3798. } // std
  3799. #endif
  3800. // std::hash specialization
  3801. #ifndef BOOST_JSON_DOCS
  3802. namespace std {
  3803. template <>
  3804. struct hash< ::boost::json::value > {
  3805. BOOST_JSON_DECL
  3806. std::size_t
  3807. operator()(::boost::json::value const& jv) const noexcept;
  3808. };
  3809. } // std
  3810. #endif
  3811. #ifdef __clang__
  3812. # pragma clang diagnostic pop
  3813. #endif
  3814. // These are here because value, array,
  3815. // and object form cyclic references.
  3816. #include <boost/json/detail/impl/array.hpp>
  3817. #include <boost/json/impl/array.hpp>
  3818. #include <boost/json/impl/object.hpp>
  3819. #include <boost/json/impl/value.hpp>
  3820. // These must come after array and object
  3821. #include <boost/json/impl/value_ref.hpp>
  3822. #endif