value.hpp 96 KB

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