BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bdljsn_json.h
Go to the documentation of this file.
1/// @file bdljsn_json.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bdljsn_json.h -*-C++-*-
8#ifndef INCLUDED_BDLJSN_JSON
9#define INCLUDED_BDLJSN_JSON
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bdljsn_json bdljsn_json
15/// @brief Provide an in-memory representation of a JSON document.
16/// @addtogroup bdl
17/// @{
18/// @addtogroup bdljsn
19/// @{
20/// @addtogroup bdljsn_json
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bdljsn_json-purpose"> Purpose</a>
25/// * <a href="#bdljsn_json-classes"> Classes </a>
26/// * <a href="#bdljsn_json-description"> Description </a>
27/// * <a href="#bdljsn_json-reading-and-writing-a-bdljsn-json-object"> Reading and Writing a bdljsn::Json Object </a>
28/// * <a href="#bdljsn_json-all-bdljsn-json-objects-are-valid-json-documents"> All bdljsn::Json Objects are Valid JSON Documents </a>
29/// * <a href="#bdljsn_json-important-preconditions"> Important Preconditions </a>
30/// * <a href="#bdljsn_json-operator-and-the-definition-of-value"> operator== and the Definition of Value </a>
31/// * <a href="#bdljsn_json-initializer-lists"> Initializer Lists </a>
32/// * <a href="#bdljsn_json-usage"> Usage </a>
33/// * <a href="#bdljsn_json-example-1-constructor-a-basic-bdljsn-json-object"> Example 1: Constructor a Basic bdljsn::Json Object </a>
34/// * <a href="#bdljsn_json-example-2-more-efficiently-creating-a-bdljsn-json"> Example 2: More Efficiently Creating a bdljsn::Json </a>
35/// * <a href="#bdljsn_json-example-3-using-the-visit-method-to-traverse-a-json-object"> Example 3: Using the visit Method to Traverse a Json Object </a>
36///
37/// # Purpose {#bdljsn_json-purpose}
38/// Provide an in-memory representation of a JSON document.
39///
40/// # Classes {#bdljsn_json-classes}
41///
42/// - bdljsn::Json : representation of a JSON document
43/// - bdljsn::JsonArray : representation of a JSON array
44/// - bdljsn::JsonObject: representation of a JSON object
45///
46/// @see bdljsn_jsonutil, bdljsn_jsonnumber, bdljsn_jsonnull
47///
48/// # Description {#bdljsn_json-description}
49/// This component provides a value-semantic type, `bdljsn::Json`,
50/// used as an in-memory representation for a JSON document. This component
51/// also provides `bdljsn::JsonArray` and `bdljsn::JsonObject` types for
52/// representing JSON Arrays and Objects respectively.
53///
54/// `bdljsn::Json` has a close structural similarity to the JSON grammar itself,
55/// which at a high-level looks like:
56/// @code
57/// JSON ::= Object
58/// | Array
59/// | String
60/// | Number
61/// | Boolean
62/// | null
63/// @endcode
64/// Where the Object and Array alternatives can recursively contain JSON. Just
65/// like this grammar, a `bdljsn::Json` is a variant holding either an Object,
66/// Array, String, Number, Boolean, or null. These variant selections are
67/// represented by the following types:
68///
69/// * Object: `JsonObject`
70/// * Array: `JsonArray`
71/// * String: `bsl::string`
72/// * Number: `JsonNumber`
73/// * Boolean: `bool`
74/// * null: `JsonNull`
75///
76/// For more details on the JSON grammar see:
77///
78/// * website: https://www.json.org/
79/// * RFC: https://datatracker.ietf.org/doc/html/rfc8259
80///
81/// ## Reading and Writing a bdljsn::Json Object {#bdljsn_json-reading-and-writing-a-bdljsn-json-object}
82///
83///
84/// @ref bdljsn_jsonutil is the recommended facility to write and read
85/// `bdljsn::Json` objects to and from JSON document text.
86///
87/// `operator<<` overloads are available for all the types. In addition a
88/// canonical BDE print method is available for `bdljsn::Json`,
89/// `bdljsn::JsonObject`, `bdljsn::JsonArray` `bdljsn::JsonNumber` and
90/// `bdljsn::JsonNull`.
91///
92/// ## All bdljsn::Json Objects are Valid JSON Documents {#bdljsn_json-all-bdljsn-json-objects-are-valid-json-documents}
93///
94///
95/// Every `bdljsn::Json` represents a (valid) JSON document (`bdljsn::Json` does
96/// not have an "invalid" state). This means writing a `bdljsn::Json` to a
97/// string can only fail if an out-of-memory condition occurs.
98///
99/// Similarly, every JSON document has a `bdljsn::Json` representation.
100/// However, `bdljsn::JsonObject` represents Objects having only unique member
101/// names, meaning that duplicate member names in a JSON document will be
102/// ignored (see `bdljsn::JsonUtil` for more information on how duplicate names
103/// are handled when parsing a JSON document). Note that the JSON RFC says that
104/// Object member names "SHOULD be unique", and there is no standard behavior
105/// for JSON parsers where member names are not unique (typically an in-process
106/// representation with unique member names is used).
107///
108/// ### Important Preconditions {#bdljsn_json-important-preconditions}
109///
110///
111/// In order to preserve the invariant that all `bdljsn::Json` objects are valid
112/// JSON documents there are some constructors and assignment operations in
113/// `bdljsn` package that have notable preconditions:
114///
115/// * `bdljsn::JsonNumber` constructors from string require that the string
116/// conform to the JSON grammar for a number (see
117/// `bdljsn::NumberUtil::isValidNumber`).
118/// * Constructors and assignment operators from `double` or
119/// `bdldfp::Decimal64` require the value *not* be either INF or NaN
120/// * `bdljsn::Json` constructors and assignment operators require that
121/// strings contain valid UTF-8 (see `bdlde::Utf8Util::isValid`).
122///
123/// ## operator== and the Definition of Value {#bdljsn_json-operator-and-the-definition-of-value}
124///
125///
126/// `bdljsn::Json` type's definition of value (i.e., the behavior for
127/// `operator==`) mirrors comparing the text of two JSON documents where all the
128/// white-space is ignored.
129///
130/// Concretely, `bdljsn::Json` is a variant type, whose definition of equality
131/// is derived from the definition of equality of its constituent types. I.e.,
132/// two `bdljsn::Json` objects compare equal if they have the same `type` and
133/// the two objects of that `type` they contain compare equal. The definition
134/// of equality for Object, Array, Boolean, string, and `JsonNull` types are
135/// relatively self-explanatory (see respective `operator==` definitions for
136/// details). The definition of equality for `JsonNumber` is notable:
137/// `JsonNumber` objects define value in terms of the text of the JSON number
138/// string they contain. So two JSON numbers having the same numerical value
139/// may compare *unequal* (e.g., "2" and "2.0" and "20e-1" are considered
140/// different `JsonNumber` values!). Note that `bdljsn::JsonNumber::isEqual`
141/// provides a semantic comparison of two numbers (see @ref bdljsn_jsonnumber for
142/// more detail).
143///
144/// ## Initializer Lists {#bdljsn_json-initializer-lists}
145///
146///
147/// The `bdljsn::JsonArray` and `bdljsn::JsonObject` classes have constructors
148/// and assorted manipulator methods (e.g., `assign`, `insert`) that accept
149/// instances of `std::initializer_list` which are invoked when users supply
150/// braced lists of values. When values of the following types are used in
151/// those braced lists, the values are converted to `bdljsn::Json` objects
152/// (as the `JsonArray` elements or as the "value" portion of `JsonObject`
153/// members).
154///
155/// * `JsonNull`
156/// * `bool`
157/// * integral types
158/// * `float`
159/// * `double`
160/// * `bdldfp::Decimal64`
161/// * `const char *`
162/// * `bsl::string`
163/// * `std::string`
164/// * `std::pmr::string` // where available
165/// * `bsl::string_view`
166/// * `std::string_view` // where available
167/// * `JsonObject`
168/// * `JsonArray`
169/// * `JsonNumber`
170/// * `Json`
171///
172/// ## Usage {#bdljsn_json-usage}
173///
174///
175/// This section illustrates the intended use of this component.
176///
177/// ### Example 1: Constructor a Basic bdljsn::Json Object {#bdljsn_json-example-1-constructor-a-basic-bdljsn-json-object}
178///
179///
180/// Most often `bdljsn::Json` objects will be written and read from JSON text
181/// using @ref bdljsn_jsonutil . In this simple example, we demonstrate manually
182/// creating the document below and then verify the properties of the resulting
183/// object:
184/// @code
185/// {
186/// "number": 3.14,
187/// "boolean": true,
188/// "string": "text",
189/// "null": null,
190/// "array": [ "2.76", true ],
191/// "object": { "boolean": false }
192/// }
193/// @endcode
194/// First, we use `bdljsn::Json::makeObject` to configure the top level
195/// `bdljsn::Json` object to be a `bdljsn::Json` object, and use the various
196/// manipulators of `bdljsn::JsonObject` to configure its value:
197/// @code
198/// using namespace bdldfp::DecimalLiterals;
199///
200/// bdljsn::Json json;
201///
202/// json.makeObject();
203/// json["number"] = 3.14;
204/// json["boolean"] = true;
205/// json["string"] = "text";
206/// json["array"].makeArray();
207/// json["array"].theArray().pushBack(bdljsn::Json(2.76_d64));
208/// json["array"].theArray().pushBack(bdljsn::Json(true));
209/// json["object"].makeObject()["boolean"] = false;
210/// @endcode
211/// Notice that we used `operator[]` to implicitly create new members of the
212/// top-level object. Using `json.theObject().insert` would be more efficient
213/// (see example 2).
214///
215/// Finally, we validate the properties of the resulting object:
216/// @code
217/// assert(3.14 == json["number"].asDouble());
218/// assert(true == json["boolean"].theBoolean());
219/// assert("text" == json["string"].theString());
220/// assert(true == json["null"].isNull());
221/// assert(2.76_d64 == json["array"][0].asDecimal64());
222/// assert(false == json["object"]["boolean"].theBoolean());
223/// @endcode
224///
225/// ### Example 2: More Efficiently Creating a bdljsn::Json {#bdljsn_json-example-2-more-efficiently-creating-a-bdljsn-json}
226///
227///
228/// Example 1 used `operator[]` to implicitly add members to the Objects. Using
229/// `operator[]` is intuitive but not the most efficient method to add new
230/// members to a `bdljsn::JsonObject` (similar to using `operator[]` to add
231/// elements to an `unordered_map`). The following code demonstrates a more
232/// efficient way to create the same `bdljsn::Json` representation as Example 1:
233/// @code
234/// using namespace bdldfp::DecimalLiterals;
235///
236/// bdljsn::Json json;
237/// bdljsn::JsonArray subArray;
238/// bdljsn::JsonObject subObject;
239///
240/// json.makeObject();
241/// json.theObject().insert("number", bdljsn::JsonNumber(3.14));
242/// json.theObject().insert("boolean", true);
243/// json.theObject().insert("string", "text");
244/// json.theObject().insert("null", bdljsn::JsonNull());
245///
246/// subArray.pushBack(bdljsn::Json(2.76_d64));
247/// subArray.pushBack(bdljsn::Json(true));
248/// json.theObject().insert("array", bsl::move(subArray));
249///
250/// subObject.insert("boolean", false);
251/// json.theObject().insert("object", bsl::move(subObject));
252/// @endcode
253///
254/// ### Example 3: Using the visit Method to Traverse a Json Object {#bdljsn_json-example-3-using-the-visit-method-to-traverse-a-json-object}
255///
256///
257/// The `Json` class provides the (overloaded) `visit` method that invokes a
258/// user-supplied "visitor" functor according to the current `type()` of the
259/// `Json` object.
260///
261/// For example, suppose one needs to survey the structure of the `Json` object
262/// created in {Example 1} (and again in {Example 2}) and, in doing so, compile
263/// a tally of each of each of the `Json` sub-objects and their their types
264/// (i.e., object, array, string, ...).
265///
266/// First, we define a compliant visitor class, `TallyByTypeVisitor`:
267/// @code
268/// // ==================
269/// // TallyByTypeVisitor
270/// // ==================
271///
272/// class TallyByTypeVisitor {
273///
274/// int d_tally[6];
275///
276/// public:
277/// // CREATORS
278///
279/// /// Create a `TallyByTypeVisitor` object that when passed to the
280/// /// `Json::visit` method will increment the specified `tally` array
281/// /// according to `type()` and visit subordinate `Json` objects, if
282/// /// any. The behavior is undefined unless `tally` has at least
283/// /// 6 elements.
284/// explicit TallyByTypeVisitor();
285///
286/// // ACCESSORS
287///
288/// /// Increment the element corresponding to object in the tally array
289/// /// supplied at construction and visit the value of each member of
290/// /// the specified `object`.
291/// void operator()(const JsonObject& object);
292///
293/// /// Increment the element corresponding to array in the tally array
294/// /// supplied at construction and visit each element of the specified
295/// /// `array`.
296/// void operator()(const JsonArray& array);
297///
298/// /// Increment the element corresponding to
299/// /// string/number/boolean/null in the tally array supplied at
300/// /// construction. Ignore the specified
301/// /// `string`/`number`/`boolean`/`null`.
302/// void operator()(const bsl::string& string );
303/// void operator()(const JsonNumber& number );
304/// void operator()(const bool& boolean);
305/// void operator()(const JsonNull& null );
306///
307/// /// Return the address of an array of 6 elements containing the
308/// /// tally by type. The array is ordered according to
309/// /// `JsonType::Enum`.
310/// const int *tally() const;
311/// };
312/// @endcode
313/// Notice that we have no need to change the value of the examined `Json`
314/// objects so we use a set of `operator()` overloads compatible with the
315/// `visit` accessor method. Accordingly, we careful below to use this visitor
316/// only with `const`-qualified `Json` objects
317///
318/// Then, we define the constructor and the six `operator()` overloads. In each
319/// overload by type we increment the appropriate element in the user-supplied
320/// array of integers.
321/// @code
322/// // ------------------
323/// // TallyByTypeVisitor
324/// // ------------------
325///
326/// // CREATORS
327/// TallyByTypeVisitor::TallyByTypeVisitor()
328/// {
329/// d_tally[bdljsn::JsonType::e_OBJECT ] =
330/// d_tally[bdljsn::JsonType::e_ARRAY ] =
331/// d_tally[bdljsn::JsonType::e_STRING ] =
332/// d_tally[bdljsn::JsonType::e_NUMBER ] =
333/// d_tally[bdljsn::JsonType::e_BOOLEAN] =
334/// d_tally[bdljsn::JsonType::e_NULL ] = 0;
335/// }
336///
337/// // ACCESSORS
338/// void TallyByTypeVisitor::operator()(const bsl::string& string)
339/// {
340/// (void) string;
341/// ++d_tally[bdljsn::JsonType::e_STRING];
342/// }
343///
344/// void TallyByTypeVisitor::operator()(const JsonNumber& number)
345/// {
346/// (void) number;
347/// ++d_tally[bdljsn::JsonType::e_NUMBER];
348/// }
349///
350/// void TallyByTypeVisitor::operator()(const bool& boolean)
351/// {
352/// (void) boolean;
353/// ++d_tally[bdljsn::JsonType::e_BOOLEAN];
354/// }
355///
356/// void TallyByTypeVisitor::operator()(const JsonNull& null)
357/// {
358/// (void) null;
359/// ++d_tally[bdljsn::JsonType::e_NULL];
360/// }
361/// @endcode
362/// Next, we define the visitor overload for array types. After incrementing
363/// the tally array we pass this same visitor object to the `Json` object in the
364/// array so those objects are included in the tally.
365/// @code
366/// void TallyByTypeVisitor::operator()(const JsonArray& array)
367/// {
368/// ++d_tally[bdljsn::JsonType::e_ARRAY];
369///
370/// typedef JsonArray::ConstIterator ConstItr;
371///
372/// for (ConstItr cur = array.cbegin(),
373/// end = array.cend();
374/// end != cur; ++cur) {
375/// const Json constElement = *cur;
376/// constElement.visit<void>(*this);
377/// }
378/// }
379///
380/// const int *TallyByTypeVisitor::tally() const
381/// {
382/// return d_tally;
383/// }
384/// @endcode
385/// Notice that `element` is `const`-qualified so the accessor `visit` method is
386/// invoked.
387///
388/// Then, we implement the visitor overload for the object type. Examination
389/// of the object produces a sequence of name-value pairs where the `second`
390/// part is a `Json` object that we must visit.
391/// @code
392/// void TallyByTypeVisitor::operator()(const JsonObject& object)
393/// {
394/// ++d_tally[bdljsn::JsonType::e_OBJECT];
395///
396/// typedef JsonObject::ConstIterator ConstItr;
397///
398/// for (ConstItr cur = object.cbegin(),
399/// end = object.cend();
400/// end != cur; ++cur) {
401/// const bsl::pair<const bsl::string, Json> member = *cur;
402/// const Json& json = member.second;
403/// json.visit<void>(*this);
404/// }
405/// }
406/// @endcode
407/// Again, notice that this visitor is used as an argument to a
408/// `const`-qualified `Json` object.
409///
410/// Finally, we make a survey of the `Json` object created in {Example 1} (and
411/// duplicated in {Example 2}). From visual inspection of the source JSON
412/// document we expect 10 `Json` objects distributed thus:
413///
414/// - Object
415/// 1. top-level of the document is an object
416/// 2. `{"boolean": false }`, interior object
417///
418/// - Array
419/// 1. `[2.76, true]`
420///
421/// - String
422/// 1. `"text"`
423///
424/// - Number
425/// 1. `2.76`
426/// 2. `3.14`
427///
428/// - Boolean
429/// 1. `false`, from the internal object
430/// 2. `true`, from the array
431/// 3. `true`, from top-level object
432///
433/// - Null
434/// 1. `null`
435///
436/// Use of our visitor functor on `example1` confirms these observations:
437/// @code
438/// int main()
439/// {
440/// TallyByTypeVisitor visitor;
441///
442/// const Json& constExample1 = example1;
443///
444/// constExample1.visit<void>(&visitor);
445///
446/// const int *const tally = visitor.tally();
447///
448/// assert(2 == tally[bdljsn::JsonType::e_OBJECT ]);
449/// assert(1 == tally[bdljsn::JsonType::e_ARRAY ]);
450/// assert(1 == tally[bdljsn::JsonType::e_STRING ]);
451/// assert(2 == tally[bdljsn::JsonType::e_NUMBER ]);
452/// assert(3 == tally[bdljsn::JsonType::e_BOOLEAN]);
453/// assert(1 == tally[bdljsn::JsonType::e_NULL ]);
454///
455/// return 0;
456/// }
457/// @endcode
458/// @}
459/** @} */
460/** @} */
461
462/** @addtogroup bdl
463 * @{
464 */
465/** @addtogroup bdljsn
466 * @{
467 */
468/** @addtogroup bdljsn_json
469 * @{
470 */
471
472#include <bdlscm_version.h>
473
474#include <bdlb_variant.h>
475
476#include <bdlde_utf8util.h>
477
478#include <bdljsn_jsonnull.h>
479#include <bdljsn_jsonnumber.h>
480#include <bdljsn_jsontype.h>
481
483#include <bdlb_transparenthash.h>
484#include <bdldfp_decimal.h>
485
486#include <bslma_allocator.h>
487#include <bslma_bslallocator.h>
489
490#include <bslmf_assert.h>
491#include <bslmf_enableif.h>
492#include <bslmf_issame.h>
493#include <bslmf_movableref.h>
495#include <bslmf_util.h>
496
497#include <bsla_unreachable.h>
498
499#include <bsls_assert.h>
501#include <bsls_keyword.h>
502#include <bsls_types.h>
503#include <bsls_util.h>
504
505#include <bsl_exception.h> // `bsl::uncaught_exceptions`
506#include <bsl_iterator.h>
507#include <bsl_limits.h> // `bsl::numeric_limits`
508#include <bsl_span.h>
509#include <bsl_string.h>
510#include <bsl_string_view.h>
511#include <bsl_type_traits.h> // `bsl::enable_if`, `bsl::is_integral`,
512 // `bsl::is_same`, `bsl::is_signed`,
513 // `bsl::is_unsigned`, `bsl::is_convertible`,
514 // `bsl::true_type`, `bsl::false_type`.
515#include <bsl_unordered_map.h>
516#include <bsl_utility.h> // `bsl::forward`
517#include <bsl_vector.h>
518
519#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
520#include <initializer_list>
521#endif
522
523#if defined(BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY)
524#include <string_view>
525#endif
526
527
528namespace bdljsn {
529
530// FORWARD DECLARATIONS
531class Json;
532class JsonArray;
533class JsonObject;
534#ifdef BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
535class Json_Initializer;
536class JsonObject_MemberInitializer;
537#endif
538
539 // ===============
540 // class JsonArray
541 // ===============
542
543/// This type is designed to replicate much of the standard sequence
544/// container interface, eliding interfaces that are less relevant for a non-generic container.
545///
546/// \note Note that a `bsl::vector` is chosen for the
547/// implementation because our implementation permits the element type to be
548/// incomplete (when just spelling the type name).
549///
550/// See @ref bdljsn_json
552
553 private:
554 // PRIVATE CLASS METHODS
555
556 // Return `true` if `0 <= value` and `false` otherwise. This function is
557 // invoked when `t_INTEGRAL` is a signed type.
558 template <class t_INTEGRAL>
559 static bool isNonNegativeImp(t_INTEGRAL value, bsl::true_type is_signed);
560
561 // Return `true` (always). This function is invoked when `t_INTEGRAL` is
562 // an unsigned type.
563 template <class t_INTEGRAL>
564 static bool isNonNegativeImp(t_INTEGRAL value, bsl::false_type is_signed);
565
566 // Return `true` if `0 <= value` and `false` otherwise. Note that this
567 // function avoids warnings arising from checking unsigned types for
568 // negativity.
569 template <class t_INTEGRAL>
570 static bool isNonNegative(t_INTEGRAL value);
571
572 // PRIVATE TYPES
574
575 public:
576 // TYPES
579
583
586
589
590 private:
591 // DATA
592 Elements d_elements; // the underlying sequence of elements
593
594 // FRIENDS
595 friend bool operator==(const JsonArray&, const JsonArray&);
596 friend bool operator!=(const JsonArray&, const JsonArray&);
597 friend void swap(JsonArray&, JsonArray&);
598
599 public:
600 // TRAITS
604
605 // CREATORS
606
607 /// Create an empty `JsonArray`. Optionally specify a `basicAllocator`
608 /// used to supply memory. If `basicAllocator` is not specified, the
609 /// currently installed default allocator is used.
610 JsonArray();
611 explicit JsonArray(bslma::Allocator *basicAllocator);
612
613 /// Create a `JsonArray` having the same value as the specified `original`
614 /// object. Optionally specify `basicAllocator` to supply memory. If
615 /// `basicAllocator` is not specified, the allocator associated with
616 /// `original` is propagated for use in the newly-created `JsonArray`.
617 JsonArray(const JsonArray& original, bslma::Allocator *basicAllocator = 0);
618
619 /// Create a `JsonArray` having the same value as the specified `original`
620 /// object by moving (in constant time) the contents of `original` to the
621 /// new `JsonArray` object. The allocator associated with `original` is
622 /// propagated for use in the newly-created `JsonArray` object. `original`
623 /// is left in a valid but unspecified state.
625
626 /// Create a `JsonArray` having the same value as the specified `original`
627 /// object that uses the specified `basicAllocator` to supply memory. The
628 /// contents of `original` are moved (in constant time) to the new
629 /// `JsonArray` object if `basicAllocator == original.allocator()`, and are
630 /// move-inserted (in linear time) using `basicAllocator` otherwise.
631 /// `original` is left in a valid but unspecified state.
633 bslma::Allocator *basicAllocator);
634
635 /// Create a `JsonArray` and insert (in order) each `Json` object in the
636 /// range starting at the specified `first` element, and ending immediately
637 /// before the specified `last` element. Optionally specify
638 /// `basicAllocator` used to supply memory. If `basicAllocator` is not
639 /// specified, the currently installed default allocator is used. Throw
640 /// `bsl::length_error` if the number of elements in `[first .. last)`
641 /// exceeds the value returned by the method `maxSize`. The (template
642 /// parameter) type `t_INPUT_ITERATOR` shall meet the requirements of an
643 /// input iterator defined in the c++11 standard [24.2.3] providing access
644 /// to values of a type convertible to `Json`, and `Json` must be
645 /// `emplace-constructible` form `*i`, where `i` is a dereferenceable
646 /// iterator in the range `[first .. last)`.
647 ///
648 /// \pre The behavior is undefined unless `first` and `last` refer to a range of valid values where
649 /// `first` is at a position at or before `last`.
650 template <class t_INPUT_ITERATOR>
651 JsonArray(t_INPUT_ITERATOR first,
652 t_INPUT_ITERATOR last,
653 bslma::Allocator *basicAllocator = 0);
654
655#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
656 /// Create a `JsonArray` having a `Json` object for each element (in order)
657 /// of the specified `elements`. Optionally specify a `basicAllocator`
658 /// used to supply memory. If `basicAllocator` is not specified, the
659 /// currently installed default allocator is used.
660 JsonArray(std::initializer_list<Json_Initializer> elements,
661 bslma::Allocator *basicAllocator = 0);
662 // IMPLICIT
663#endif
664
665 // MANIPULATORS
666
667 /// Assign to this object the value of the specified `rhs` object, and
668 /// return a reference providing modifiable access to this object. If an
669 /// exception is thrown, `*this` is left in a valid but unspecified state.
670 JsonArray& operator=(const JsonArray& rhs);
671
672 /// Assign to this object the value of the specified `rhs` object, and
673 /// return a reference providing modifiable access to this object. The
674 /// contents of `rhs` are moved (in constant time) to this `JsonArray` if
675 /// `allocator() == rhs.allocator()`; otherwise, all elements in this
676 /// `JsonArray` are either destroyed or move-assigned to and each
677 /// additional element in `rhs` is move-inserted into this `JsonArray`.
678 /// `rhs` is left in a valid but unspecified state.
680
681#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
682 /// Assign to this array a sequence of `Json` objects, one for each element
683 /// (in order) of the specified `elements`. Previous elements of this
684 /// array, if any, are destroyed. Return a reference to `*this`. If an
685 /// exception is thrown, `*this` is left in a valid but unspecified state.
686 JsonArray& operator=(std::initializer_list<Json_Initializer> elements);
687#endif
688
689 /// Return a reference providing modifiable access to the element at the
690 /// specified `index` in this `JsonArray`.
691 ///
692 /// \pre The behavior is undefined unless `index < size()`.
693 Json& operator[](bsl::size_t index);
694
695 /// Assign to this object the value resulting from first clearing this
696 /// `JsonArray` and then inserting (in order) each `Json` object in the
697 /// range starting at the specified `first` element, and ending immediately
698 /// before the specified `last` element. Return a non-`const` reference to
699 /// this array. If an exception is thrown, `*this` is left in a valid but
700 /// unspecified state. Throw `bsl::length_error` if
701 /// `distance(first,last) > maxSize()`. The (template parameter) type
702 /// `t_INPUT_ITERATOR` shall meet the requirements of an input iterator
703 /// defined in the c++11 standard [24.2.3] providing access to values of a
704 /// type convertible to `Json`, and `Json` must be `emplace-constructible`
705 /// form `*i`, where `i` is a dereferenceable iterator in the range `[first .. last)`.
706 ///
707 /// \pre The behavior is undefined unless `first` and `last`
708 /// refer to a range of valid values where `first` is at a position at or
709 /// before `last`.
710 template <class t_INPUT_ITERATOR>
711 JsonArray& assign(t_INPUT_ITERATOR first, t_INPUT_ITERATOR last);
712
713#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
714 /// Assign to this array a sequence of `Json` objects, one for each element
715 /// (in order) of the specified `elements`. Previous elements of this
716 /// array, if any, are destroyed. Return a reference to `*this`. If an
717 /// exception is thrown, `*this` is left in a valid but unspecified state.
718 JsonArray& assign(std::initializer_list<Json_Initializer> elements);
719#endif
720
721 // BDE_VERIFY pragma: -FABC01
722
723 /// Return an iterator providing modifiable access to the first element in
724 /// this `JsonArray`, or the past-the-end iterator if this `JsonArray` is
725 /// empty.
726 Iterator begin();
727
728 /// Return the past-the-end iterator providing modifiable access to this
729 /// `JsonArray`.
730 Iterator end();
731
732 /// Return a reference providing modifiable access to the first element in this `JsonArray`.
733 ///
734 /// \pre The behavior is undefined unless this `JsonArray` is
735 /// not empty.
736 Json& front();
737
738 /// Return a reference providing modifiable access to the last element in this `JsonArray`.
739 ///
740 /// \pre The behavior is undefined unless this `JsonArray` is
741 /// not empty.
742 Json& back();
743
744 // BDE_VERIFY pragma: +FABC01
745
746 /// Remove all elements from this `JsonArray` making its size 0.
747 ///
748 /// \note Note that although this `JsonArray` is empty after this method returns, it
749 /// preserves the same capacity it had before the method was called.
750 void clear();
751
752 /// Remove from this `JsonArray` the element at the specified `index`, and
753 /// return an iterator providing modifiable access to the element
754 /// immediately following the removed element, or the position returned by
755 /// the method `end` if the removed element was the last in the sequence.
756 ///
757 /// \pre The behavior is undefined unless `index` is in the range
758 /// `[0 .. size())`.
759 Iterator erase(bsl::size_t index);
760
761 /// Remove from this `JsonArray` the element at the specified `position`,
762 /// and return an iterator providing modifiable access to the element
763 /// immediately following the removed element, or the position returned by
764 /// the method `end` if the removed element was the last in the sequence.
765 ///
766 /// \pre The behavior is undefined unless `position` is an iterator in the range
767 /// `[cbegin() .. cend())`.
768 Iterator erase(ConstIterator position);
769
770 /// Remove from this `JsonArray` the sequence of elements starting at the
771 /// specified `first` position and ending before the specified `last`
772 /// position, and return an iterator providing modifiable access to the
773 /// element immediately following the last removed element, or the position
774 /// returned by the method `end` if the removed elements were last in the sequence.
775 ///
776 /// \pre The behavior is undefined unless `first` is an iterator in
777 /// the range `[cbegin() .. cend()]` (both endpoints included) and `last`
778 /// is an iterator in the range `[first .. cend()]` (both endpoints
779 /// included).
781
782 /// Insert at the specified `index` in this JsonArray a copy of the
783 /// specified `json`, and return an iterator referring to the newly
784 /// inserted element. If an exception is thrown, `*this` is unaffected.
785 /// Throw `bsl::length_error` if `size() == maxSize()`. The (template
786 /// parameter) type `t_INDEX` must be a non-`bool` integral type.
787 ///
788 /// \pre The behavior is undefined unless `index` is in the range `[0 .. size()]`.
789 template <class t_INDEX>
792 Iterator>::type
793 insert(t_INDEX index, const Json& json);
794
795 /// Insert at the specified `index` in this JsonArray the specified
796 /// move-insertable `json`, and return an iterator referring to the newly
797 /// inserted element. `json` is left in a valid but unspecified state. If
798 /// an exception is thrown, `this` is unaffected. Throw
799 /// `bsl::length_error` if `size() == maxSize()`. The (template parameter)
800 /// type `t_INDEX` must be a non-`bool` integral type.
801 ///
802 /// \pre The behavior is undefined unless `index` is in the range `[0 .. size()]` (both
803 /// endpoints included).
804 template <class t_INDEX>
807 Iterator>::type
808 insert(t_INDEX index, bslmf::MovableRef<Json> json);
809
810 /// Insert at the specified `index` in this JsonArray the values in the
811 /// range starting at the specified `first` element, and ending immediately
812 /// before the specified `last` element. Return an iterator referring to
813 /// the first newly inserted element. If an exception is thrown, `*this`
814 /// is unaffected. Throw `bsl::length_error` if
815 /// `size() + distance(first, last) > maxSize()`. The (template parameter)
816 /// type `t_INDEX` must be a non-`bool` integral type. The (template
817 /// parameter) type `t_INPUT_ITERATOR` shall meet the requirements of an
818 /// input iterator defined in the C++11 standard [24.2.3] providing access
819 /// to values of a type convertible to `Json`, and `Json` must be
820 /// `emplace-constructible` from `*i` into this `JsonArray`, where `i` is a
821 /// dereferenceable iterator in the range `[first .. last)`.
822 ///
823 /// \pre The behavior is undefined unless `index` is in the range `[0 .. size()]` (both
824 /// endpoints included), and `first` and `last` refer to a range of valid
825 /// values where `first` is at a position at or before `last`.
826 template <class t_INDEX, class t_INPUT_ITERATOR>
829 Iterator>::type
830 insert(t_INDEX index, t_INPUT_ITERATOR first, t_INPUT_ITERATOR last);
831
832 /// Insert at the specified `position` in this `JsonArray` a copy of the
833 /// specified `json`, and return an iterator referring to the newly
834 /// inserted element. If an exception is thrown, `*this` is unaffected.
835 /// Throw `bsl::length_error` if `size() == maxSize()`.
836 ///
837 /// \pre The behavior is undefined unless `position` is an iterator in the range
838 /// `[begin() .. end()]` (both endpoints included).
839 Iterator insert(ConstIterator position, const Json& json);
840
841 /// Insert at the specified `position` in this `JsonArray` the specified
842 /// move-insertable `json`, and return an iterator referring to the newly
843 /// inserted element. `json` is left in a valid but unspecified state. If
844 /// an exception is thrown, `this` is unaffected. Throw
845 /// `bsl::length_error` if `size() == maxSize()`.
846 ///
847 /// \pre The behavior is undefined unless `position` is an iterator in the range
848 /// `[begin() .. end()]` (both endpoints included).
850
851 /// Insert at the specified `position` in this `JsonArray` the values in
852 /// the range starting at the specified `first` element, and ending
853 /// immediately before the specified `last` element. Return an iterator
854 /// referring to the first newly inserted element. If an exception is
855 /// thrown, `*this` is unaffected. Throw `bsl::length_error` if
856 /// `size() + distance(first, last) > maxSize()`. The (template parameter)
857 /// type `t_INPUT_ITERATOR` shall meet the requirements of an input
858 /// iterator defined in the C++11 standard [24.2.3] providing access to
859 /// values of a type convertible to `value_type`, and `value_type` must be
860 /// `emplace-constructible` from `*i` into this JsonArray, where `i` is a
861 /// dereferenceable iterator in the range `[first .. last)`.
862 ///
863 /// \pre The behavior is undefined unless `position` is an iterator in the range
864 /// `[begin() .. end()]` (both endpoints included), and `first` and `last`
865 /// refer to a range of valid values where `first` is at a position at or
866 /// before `last`.
867 template <class t_INPUT_ITERATOR>
869 t_INPUT_ITERATOR first,
870 t_INPUT_ITERATOR last);
871
872 /// Erase the last element from this `JsonArray`.
873 ///
874 /// \pre The behavior is undefined if this `JsonArray` is empty.
875 void popBack();
876
877 /// Append to the end of this `JsonArray` a copy of the specified
878 /// `json`/`array`/`object`/`number` and return a non-`const` reference to
879 /// this array. If an exception is thrown, `*this` is unaffected. Throw
880 /// `bsl::length_error` if `size() == maxSize()`.
881 JsonArray& pushBack(const Json& json);
882 JsonArray& pushBack(const JsonArray& array);
883 JsonArray& pushBack(const JsonObject& object);
884 JsonArray& pushBack(const JsonNumber& number);
885
886 /// Append to the end of this `JsonArray` the specified move-insertable
887 /// `json`/`array`/`object`/`number` and return a non-`const` reference to
888 /// this array. `json`/`array`/`object`/`number` is left in a valid but
889 /// unspecified state. If an exception is thrown, `*this` is unaffected.
890 /// Throw `bsl::length_error` if `size() == maxSize()`.
895
896 /// Append to the end of this `JsonArray` a copy of the specified `value`
897 /// and return a non-`const` reference to this array. If an exception is
898 /// thrown, `*this` is unaffected. Throw `bsl::length_error` if
899 /// `size() == maxSize()`.
900 JsonArray& pushBack(const JsonNull& value);
901 JsonArray& pushBack(bool value);
902 JsonArray& pushBack(int value);
903 JsonArray& pushBack(unsigned int value);
904 JsonArray& pushBack(long value);
905 JsonArray& pushBack(unsigned long value);
906 JsonArray& pushBack(long long value);
907 JsonArray& pushBack(unsigned long long value);
908 JsonArray& pushBack(float value);
909 JsonArray& pushBack(double value);
911
912 /// Append to the end of this `JsonArray` a copy of the specified `string`
913 /// and return a non-`const` reference to this array. If an exception is
914 /// thrown, `*this` is unaffected. Throw `bsl::length_error` if
915 /// `size() == maxSize()`.
916 JsonArray& pushBack(const char *string);
917 JsonArray& pushBack(const bsl::string_view& string);
918
919 /// Append to the end of this `JsonArray` an element having the value of
920 /// the specified `string` by moving (in constant time) the contents of
921 /// `string` to the new element and return a non-`const` reference to this
922 /// array. `string` is left in a valid but unspecified state. This
923 /// function does not participate in overload resolution unless the
924 /// specified `t_STRING_TYPE` is `bsl::string`.
925 ///
926 /// \pre The behavior is undefined unless `string` is valid UTF-8 (see `bdlde::Utf8Util::isValid`).
927 template <class t_STRING_TYPE>
928 typename bsl::enable_if<bsl::is_same<t_STRING_TYPE,
929 bsl::string>::value,
930 JsonArray&>::type
931 pushBack(BSLMF_MOVABLEREF_DEDUCE(t_STRING_TYPE) string);
932
933 /// Change the size of this `JsonArray` to the specified `count`. If
934 /// `count < size()`, the elements in the range `[count .. size())` are
935 /// erased, and this function does not throw. If `count > size()`, the
936 /// (newly created) elements in the range `[size() .. count)` are
937 /// default-constructed `Json` objects, and if an exception is thrown,
938 /// `*this` is unaffected. Throw `bsl::length_error` if
939 /// `count > maxSize()`.
940 void resize(bsl::size_t count);
941
942 /// Change the size of this JsonArray to the specified `count`, inserting
943 /// copies of the specified `json` at the end if `count > size()`. If
944 /// `count < size()`, the elements in the range `[count .. size())` are
945 /// erased `json` is ignored, and this method does not throw. If
946 /// `count > size()` and an exception is thrown, `*this` is unaffected.
947 /// Throw `bsl::length_error` if `count > maxSize()`.
948 void resize(bsl::size_t count, const Json& json);
949
950 // Aspects
951
952 /// Exchange the value of this object with that of the specified `other`
953 /// object. If an exception is thrown, both objects are left in valid but
954 /// unspecified states. This operation guarantees O[1] complexity.
955 ///
956 /// \pre The behavior is undefined unless this object was created with the same
957 /// allocator as `other`.
958 void swap(JsonArray& other);
959
960 // ACCESSORS
961
962 /// Return a reference providing non-modifiable access to the element at
963 /// the specified `index` in this `JsonArray`.
964 ///
965 /// \pre The behavior is undefined unless `index < size()`.
966 const Json& operator[](bsl::size_t index) const;
967
968 // BDE_VERIFY pragma: -FABC01
969
971
972 /// Return an iterator providing non-modifiable access to the first element
973 /// in this `JsonArray`, and the past-the-end iterator if this `JsonArray`
974 /// is empty.
976
978
979 /// Return the past-the-end iterator providing non-modifiable access to
980 /// this `JsonArray`.
982
983 /// Return a reference providing non-modifiable access to the first element in this `JsonArray`.
984 ///
985 /// \pre The behavior is undefined unless this `JsonArray`
986 /// is not empty.
987 const Json& front() const;
988
989 /// Return a reference providing non-modifiable access to the last element in this `JsonArray`.
990 ///
991 /// \pre The behavior is undefined unless this `JsonArray`
992 /// is not empty.
993 const Json& back() const;
994
995 // BDE_VERIFY pragma: +FABC01
996
997 /// Return `true` if this `JsonArray` has size 0, and `false` otherwise.
998 bool empty() const;
999
1000 /// Return the number of elements in this `JsonArray`.
1001 bsl::size_t size() const;
1002
1003 // Aspects
1004
1005 /// Return the allocator used by this object to allocate memory.
1006 bslma::Allocator *allocator() const BSLS_KEYWORD_NOEXCEPT;
1007
1008 /// Return a theoretical upper bound on the largest number of elements that
1009 /// this `JsonArray` could possibly hold. Requests to create a `JsonArray`
1010 /// longer than this number of elements are guaranteed to raise a `bsl::length_error` exception.
1011 ///
1012 /// \note Note that there is no guarantee that
1013 /// the `JsonArray` can successfully grow to the returned size, or even
1014 /// close to that size, without running out of resources.
1015 bsl::size_t maxSize() const BSLS_KEYWORD_NOEXCEPT;
1016
1017 /// Write the value of this object to the specified output `stream` in a
1018 /// human-readable format, and return a reference to `stream`. Optionally
1019 /// specify an initial indentation `level`, whose absolute value is
1020 /// incremented recursively for nested objects. If `level` is specified,
1021 /// optionally specify `spacesPerLevel`, whose absolute value indicates the
1022 /// number of spaces per indentation level for this and all of its nested
1023 /// objects. If `level` is negative, suppress indentation of the first
1024 /// line. If `spacesPerLevel` is negative, format the entire output on one
1025 /// line, suppressing all but the initial indentation (as governed by
1026 /// `level`). If `stream` is not valid on entry, this operation has no effect.
1027 ///
1028 /// \note Note that this human-readable format is not fully specified,
1029 /// and can change without notice.
1030 bsl::ostream& print(bsl::ostream& stream,
1031 int level = 0,
1032 int spacesPerLevel = 4) const;
1033};
1034
1035// FREE OPERATORS
1036
1037/// Write the value of the specified `object` to the specified output `stream`
1038/// in a single-line format, and return a reference to `stream`. If `stream` is not valid on entry, this operation has no effect.
1039///
1040/// \note Note that this
1041/// human-readable format is not fully specified, can change without notice,
1042/// and is logically equivalent to:
1043/// @code
1044/// print(stream, 0, -1);
1045/// @endcode
1046bsl::ostream& operator<<(bsl::ostream& stream, const JsonArray& object);
1047
1048/// Return `true` if the specified `lhs` and `rhs` objects have the same value,
1049/// and `false` otherwise. Two `JsonArray` objects `lhs` and `rhs` have the
1050/// same value if they have the same number of elements, and each element in
1051/// the ordered sequence of elements of `lhs` has the same value as the
1052/// corresponding element in the ordered sequence of elements of `rhs`.
1053bool operator==(const JsonArray& lhs, const JsonArray& rhs);
1054
1055/// Return `false` if the specified `lhs` and `rhs` objects have the same
1056/// value, and `true` otherwise. Two `JsonArray` objects `lhs` and `rhs` have
1057/// the same value if they have the same number of elements, and each element
1058/// in the ordered sequence of elements of `lhs` has the same value as the
1059/// corresponding element in the ordered sequence of elements of `rhs`.
1060bool operator!=(const JsonArray& lhs, const JsonArray& rhs);
1061
1062/// Exchange the value of the specified `a` `JsonArray` with that of the
1063/// specified `b` `JsonArray`. This function provides the no-throw
1064/// exception-safety guarantee. This operation has O[1] complexity if `a` was
1065/// created with the same allocator as `b`; otherwise, it has O[n+m]
1066/// complexity, where n and m are the number of elements in `a` and `b`,
1067/// respectively.
1069
1070 // ================
1071 // class JsonObject
1072 // ================
1073
1074/// This type is designed to replicate much of the standard associative
1075/// container interface, eliding interfaces that are less relevant for a
1076/// non-generic container, like hasher and comparator access, emplacement,
1077/// nodes, capacity management, etc.
1078///
1079/// See @ref bdljsn_json
1081
1082 private:
1083 // PRIVATE TYPES
1085 Json,
1088
1089 public:
1090 // TYPES
1091 typedef Container::value_type Member;
1092 typedef Container::const_iterator ConstIterator;
1093 typedef Container::iterator Iterator;
1095
1096 typedef Container::value_type value_type;
1099
1100 typedef Container::iterator iterator;
1101 typedef Container::const_iterator const_iterator;
1102
1105
1106 private:
1107 // DATA
1108 Container d_members; // the underlying container of element mappings
1109
1110 // FRIENDS
1111 friend bool operator==(const JsonObject&, const JsonObject&);
1112 friend bool operator!=(const JsonObject&, const JsonObject&);
1113 friend void swap(JsonObject&, JsonObject&);
1114
1115 public:
1116 // TRAITS
1120
1121 // CREATORS
1122
1123 /// Create an empty `JsonObject`. Optionally specify the `basicAllocator`
1124 /// used to supply memory. If `basicAllocator` is not specified, the
1125 /// currently installed default allocator is used to supply memory.
1126 JsonObject();
1127 explicit JsonObject(bslma::Allocator *basicAllocator);
1128
1129 /// Create a `JsonObject` having the same value as the specified
1130 /// `original`. Optionally specify the `basicAllocator` used to supply
1131 /// memory. If `basicAllocator` is not specified, the currently installed
1132 /// default allocator is used to supply memory.
1133 JsonObject(const JsonObject& original,
1134 bslma::Allocator *basicAllocator = 0);
1135
1136 /// Create a `JsonObject` having the same value as the specified `original`
1137 /// object by moving (in constant time) the contents of `original` to the
1138 /// new `JsonObject`. The allocator associated with `original` is
1139 /// propagated for use in the newly-created `JsonObject`. `original` is
1140 /// left in a valid but unspecified state.
1142
1143 /// Create a `JsonObject` having the same value as the specified
1144 /// `original`. Use the specified `basicAllocator` to supply memory. If
1145 /// `basicAllocator == original.allocator()` the value of `original` will
1146 /// be moved (in constant time) to the newly-created `JsonObject`, and
1147 /// `original` will be left in a valid but unspecified state. Otherwise,
1148 /// `original` is copied, and `basicAllocator` used to supply memory.
1150 bslma::Allocator *basicAllocator);
1151
1152 /// Create an empty `JsonObject`, and then create a `Json` object for each
1153 /// iterator in the range starting at the specified `first` iterator and
1154 /// ending immediately before the specified `last` iterator, by converting
1155 /// from the object referred to by each iterator. Insert into this
1156 /// `JsonObject` each such object, ignoring those having a key that appears
1157 /// earlier in the sequence. Optionally specify a `basicAllocator` used to
1158 /// supply memory. If `basicAllocator` is not supplied, the currently
1159 /// installed default allocator is used to supply memory. The (template
1160 /// parameter) type `t_INPUT_ITERATOR` shall meet the requirements of an
1161 /// input iterator defined in the C++11 standard [24.2.3] providing access
1162 /// to values of a type convertible to `Member`.
1163 ///
1164 /// \pre The behavior is undefined unless `first` and `last` refer to a sequence of valid values where
1165 /// `first` is at a position at or before `last`, and all keys of all
1166 /// `Member` objects inserted are valid UTF-8 (see
1167 /// `bdlde::Utf8Util::isValid`).
1168 template <class t_INPUT_ITERATOR>
1169 JsonObject(t_INPUT_ITERATOR first,
1170 t_INPUT_ITERATOR last,
1171 bslma::Allocator *basicAllocator = 0);
1172
1173#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
1174 /// Create a `JsonObject` having members created (in order) from the
1175 /// specified `memberInitializers`. Member initializers having key values
1176 /// that were previously inserted into the new object are ignored.
1177 /// Optionally specify a `basicAllocator` used to supply memory. If
1178 /// `basicAllocator` is not specified, the currently installed default allocator is used.
1179 ///
1180 /// \pre The behavior is undefined unless the key of each
1181 /// member initializer in `memberInitializers` is valid UTF-8 (see
1182 /// `bdlde::Utf8Util::isValid`).
1183 JsonObject(
1184 std::initializer_list<JsonObject_MemberInitializer> memberInitializers,
1185 bslma::Allocator *basicAllocator = 0);
1186 // IMPLICIT
1187#endif // BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
1188
1189 // MANIPULATORS
1190
1191 /// Assign to this object the value of the specified `rhs` object, and
1192 /// return a reference providing modifiable access to this object.
1193 JsonObject& operator=(const JsonObject& rhs);
1194
1195 /// Assign to this object the value of the specified `rhs` object, and
1196 /// return a reference providing modifiable access to this object. The
1197 /// contents of `rhs` are moved (in constant time) to this `JsonObject` if
1198 /// `allocator() == rhs.allocator()`; otherwise, all elements in this
1199 /// container are either destroyed or move-assigned to, and each additional
1200 /// element in `rhs`, if any, is move-inserted into this `JsonObject`.
1201 /// `rhs` is left in a valid but unspecified state.
1203
1204#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
1205 /// Assign to this `JsonObject` members created (in order) from the
1206 /// specified `memberInitializers`. List members having key values that
1207 /// were previously inserted into the this object are ignored. Previous
1208 /// members of this object, if any, are destroyed.
1209 ///
1210 /// \pre The behavior is undefined unless the key of each member in `members` is valid UTF-8
1211 /// (see `bdlde::Utf8Util::isValid`).
1212 JsonObject& operator=(std::initializer_list<
1213 JsonObject_MemberInitializer>
1214 memberInitializers);
1215#endif
1216
1217 /// Return a reference providing modifiable access to the `Json` object
1218 /// associated with the specified `key` in this `JsonObject`; if this
1219 /// `JsonObject` does not already contain a `Json` object associated with
1220 /// `key`, first insert a new default-constructed `Json` object associated with `key`.
1221 ///
1222 /// \pre The behavior is undefined unless `key` is valid UTF-8 (see
1223 /// `bdlde::Utf8Util::isValid`).
1224 Json& operator[](const bsl::string_view& key);
1225
1226 // BDE_VERIFY pragma: -FABC01
1227
1228 /// Return an iterator providing modifiable access to the first `Member`
1229 /// object in the sequence of `Member` objects maintained by this
1230 /// `JsonObject`, or the `end` iterator if this `JsonObject` is empty.
1232
1233 /// Return an iterator providing modifiable access to the past-the-end
1234 /// position in the sequence of `Member` objects maintained by this
1235 /// `JsonObject`.
1237
1238 // BDE_VERIFY pragma: +FABC01
1239
1240 /// Remove all entries from this `JsonObject`.
1241 /// \note Note that this `JsonObject`
1242 /// will be empty after calling this method, but allocated memory may be
1243 /// retained for future use.
1245
1246 /// Remove from this `JsonObject` the `Member` object having the specified
1247 /// `key`, if it exists, and return 1; otherwise (there is no object with a
1248 /// key equivalent to `key` in this `JsonObject`) return 0 with no other
1249 /// effect. This method invalidates only iterators and references to the
1250 /// removed element and previously saved values of the `end()` iterator,
1251 /// and preserves the relative order of the elements not removed.
1252 bsl::size_t erase(const bsl::string_view& key);
1253
1254 /// Remove from this unordered map the `value_type` object at the specified
1255 /// `position`, and return an iterator referring to the element immediately
1256 /// following the removed element, or to the past-the-end position if the
1257 /// removed element was the last element in the sequence of elements
1258 /// maintained by this unordered map. This method invalidates only
1259 /// iterators and references to the removed element and previously saved
1260 /// values of the `end()` iterator, and preserves the relative order of the elements not removed.
1261 ///
1262 /// \pre The behavior is undefined unless `position`
1263 /// refers to a `value_type` object in this unordered map.
1264 Iterator erase( Iterator position);
1265 Iterator erase(ConstIterator position);
1266
1267 /// Return an iterator providing modifiable access to the `Member` object
1268 /// in this `JsonObject` with a key equivalent to the specified `key`, if
1269 /// such an entry exists, and the past-the-end iterator (`end`) otherwise.
1270 Iterator find(const bsl::string_view& key);
1271
1272 /// Insert the specified `member` into this `JsonObject` if the key (the
1273 /// `first` element) of the object referred to by `value` does not already
1274 /// exist in this `JsonObject`; otherwise, this method has no effect.
1275 /// Return a `pair` whose `first` member is an iterator referring to the
1276 /// (possibly newly inserted) `value_type` object in this `JsonObject`
1277 /// whose key is equivalent to that of the object to be inserted, and whose
1278 /// `second` member is `true` if a new value was inserted, and `false` if a
1279 /// value having an equivalent key was already present.
1280 ///
1281 /// \pre The behavior is undefined unless `member.first` is valid UTF-8 (see
1282 /// `bdlde::Utf8Util::isValid`).
1283 bsl::pair<Iterator, bool> insert(const Member& member);
1284
1285 /// Insert the specified `member` into this `JsonObject` if the key (the
1286 /// `first` element) of the object referred to by `member` does not already
1287 /// exist in this `JsonObject`; otherwise, this method has no effect.
1288 /// Return a `pair` whose `first` member is an iterator referring to the
1289 /// (possibly newly inserted) `member` object in this `JsonObject` whose
1290 /// key is the equivalent to that of the object to be inserted, and whose
1291 /// `second` member is `true` if a new value was inserted, and `false` otherwise.
1292 ///
1293 /// \pre The behavior is undefined unless `member.first` is valid
1294 /// UTF-8 (see `bdlde::Utf8Util::isValid`).
1295 bsl::pair<Iterator, bool> insert(bslmf::MovableRef<Member> member);
1296
1297 /// Create a `Member` object for each iterator in the range starting at the
1298 /// specified `first` iterator and ending immediately before the specified
1299 /// `last` iterator, by converting from the object referred to by each
1300 /// iterator. Insert into this `JsonObject` each such object whose key is
1301 /// not already contained. Return a non-`const` reference to this
1302 /// `JsonObject`. The (template parameter) type `t_INPUT_ITERATOR` shall
1303 /// meet the requirements of an input iterator defined in the C++11
1304 /// standard [24.2.3] providing access to values of a type convertible to `Member`.
1305 ///
1306 /// \pre The behavior is undefined unless `first` and `last` refer to
1307 /// a sequence of value values where `first` is at a position at or before `last`.
1308 ///
1309 /// \pre The behavior is undefined unless the keys of all `Member`
1310 /// objects inserted are valid UTF-8 (see `bdlde::Utf8Util::isValid`).
1311 template <class t_INPUT_ITERATOR>
1312 typename bsl::enable_if<
1313 !bsl::is_convertible<t_INPUT_ITERATOR, bsl::string_view>::value,
1314 JsonObject&>::type
1315 insert(t_INPUT_ITERATOR first, t_INPUT_ITERATOR last);
1316
1317#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
1318 /// Insert into this `JsonObject` members created (in order) from the
1319 /// specified `members`. List members having key values already contained
1320 /// in this object are ignored. Return a non-`const` reference to this `JsonObject`.
1321 ///
1322 /// \pre The behavior is undefined unless the keys of all
1323 /// `Member` objects inserted are valid UTF-8 (see
1324 /// `bdlde::Utf8Util::isValid`).
1325 JsonObject& insert(std::initializer_list<JsonObject_MemberInitializer>
1326 memberInitializers);
1327#endif
1328
1329 /// Insert into this `JsonObject` a `Member` constructed from the specified
1330 /// `key` and the specified `value`, respectively, if `key` does not
1331 /// already exist in this `JsonObject`; otherwise, this method has no
1332 /// effect. Return a `pair` whose `first` member is an iterator referring
1333 /// to the (possibly newly inserted) `Member` object in this `JsonObject`
1334 /// whose key is the equivalent to that of the object to be inserted, and
1335 /// whose `second` member is `true` if a new value was inserted, and `false` otherwise.
1336 ///
1337 /// \pre The behavior is undefined unless `key` is valid
1338 /// UTF-8 (see `bdlde::Utf8Util::isValid`).
1339 template <class t_VALUE>
1341 const bsl::string_view& key,
1342 BSLS_COMPILERFEATURES_FORWARD_REF(t_VALUE) value);
1343
1344 /// Exchange the value of this object with that of the specified `other`
1345 /// object. If an exception is thrown, both objects are left in valid but
1346 /// unspecified states. This operation guarantees O[1] complexity.
1347 ///
1348 /// \pre The behavior is undefined unless this object was created with the same
1349 /// allocator as `other`.
1350 void swap(JsonObject& other);
1351
1352 // ACCESSORS
1353
1354 /// Return a reference providing non-modifiable access to the `Json` object
1355 /// associated with the specified `key` in this `JsonObject`.
1356 ///
1357 /// \pre The behavior is undefined unless `key` is valid UTF-8 (see
1358 /// `bdlde::Utf8Util::isValid`) and this `JsonObject` already contains a
1359 /// `Json` object associated with `key`.
1360 const Json& operator[](const bsl::string_view& key) const;
1361
1362 // BDE_VERIFY pragma: -FABC01
1363
1364 /// Return an iterator providing non-modifiable access to the first
1365 /// `Member` object in the sequence of `Member` objects maintained by this
1366 /// `JsonObject`, or the `end` iterator if this `JsonObject` is empty.
1369
1370 /// Return an iterator providing non-modifiable access to the past-the-end
1371 /// position in the sequence of `Member` objects maintained by this
1372 /// `JsonObject`.
1375
1376 // BDE_VERIFY pragma: +FABC01
1377
1378 /// Return `true` if there is a `Member` object in this `JsonObject` with a
1379 /// key equivalent to the specified `key`, and return `false` otherwise.
1380 bool contains(const bsl::string_view& key) const;
1381
1382 /// Return `true` if this `JsonObject` contains no elements, and `false`
1383 /// otherwise.
1384 bool empty() const BSLS_KEYWORD_NOEXCEPT;
1385
1386 /// Return an iterator providing non-modifiable access to the `Member`
1387 /// object in this `JsonObject` with a key equivalent to the specified
1388 /// `key`, if such an entry exists, and the past-the-end iterator (`end`)
1389 /// otherwise.
1390 ConstIterator find(const bsl::string_view& key) const;
1391
1392 /// Return the number of elements in this `JsonObject`.
1393 bsl::size_t size() const BSLS_KEYWORD_NOEXCEPT;
1394
1395 // Aspects
1396
1397 /// Return the allocator used by this object to allocate memory.
1398 bslma::Allocator *allocator() const BSLS_KEYWORD_NOEXCEPT;
1399
1400 /// Write the value of this object to the specified output `stream` in a
1401 /// human-readable format, and return a reference to `stream`. Optionally
1402 /// specify an initial indentation `level`, whose absolute value is
1403 /// incremented recursively for nested objects. If `level` is specified,
1404 /// optionally specify `spacesPerLevel`, whose absolute value indicates the
1405 /// number of spaces per indentation level for this and all of its nested
1406 /// objects. If `level` is negative, suppress indentation of the first
1407 /// line. If `spacesPerLevel` is negative, format the entire output on one
1408 /// line, suppressing all but the initial indentation (as governed by
1409 /// `level`). If `stream` is not valid on entry, this operation has no effect.
1410 ///
1411 /// \note Note that this human-readable format is not fully specified,
1412 /// and can change without notice.
1413 bsl::ostream& print(bsl::ostream& stream,
1414 int level = 0,
1415 int spacesPerLevel = 4) const;
1416};
1417
1418// FREE OPERATORS
1419
1420/// Write the value of the specified `object` to the specified output `stream`
1421/// in a single-line format, and return a reference to `stream`. If `stream` is not valid on entry, this operation has no effect.
1422///
1423/// \note Note that this
1424/// human-readable format is not fully specified, can change without notice,
1425/// and is logically equivalent to:
1426/// @code
1427/// print(stream, 0, -1);
1428/// @endcode
1429bsl::ostream& operator<<(bsl::ostream& stream, const JsonObject& object);
1430
1431/// Return `true` if the specified `lhs` and `rhs` objects have the same value,
1432/// and `false` otherwise. Two `JsonObject` objects have the same value if
1433/// they have the same number of `Member` objects, and for each `Member` object
1434/// that is contained in `lhs` there is a key-value pair contained in `rhs`
1435/// having the same value, and vice versa.
1436bool operator==(const JsonObject& lhs, const JsonObject& rhs);
1437
1438/// Return `false` if the specified `lhs` and `rhs` objects have the same
1439/// value, and `true` otherwise. Two `JsonObject` objects have the same value
1440/// if they have the same number of `Member` objects, and for each `Member`
1441/// object that is contained in `lhs` there is a key-value pair contained in
1442/// `rhs` having the same value, and vice versa.
1443bool operator!=(const JsonObject& lhs, const JsonObject& rhs);
1444
1445/// Exchange the value of the specified `a` `JsonObject` with that of the
1446/// specified `b` `JsonObject`. This function provides the no-throw
1447/// exception-safety guarantee. This operation has O[1] complexity if `a` was
1448/// created with the same allocator as `b`; otherwise, it has O[n+m]
1449/// complexity, where n and m are the number of elements in `a` and `b`,
1450/// respectively.
1452
1453 // ==========
1454 // class Json
1455 // ==========
1456
1457/// This type is designed to be a thin wrapper around a variant of the possible
1458/// JSON types, using a BDE-style variant interface.
1459///
1460/// See @ref bdljsn_json
1461class Json {
1462
1463 // PRIVATE TYPES
1464 typedef bdlb::Variant<JsonObject,
1465 JsonArray,
1467 JsonNumber,
1468 bool,
1469 JsonNull> Value;
1470
1477
1478 private:
1479 // DATA
1480 Value d_value; // the underlying variant value
1481
1482 // FRIENDS
1483 friend bool operator==(const Json&, const Json&);
1484 friend bool operator!=(const Json&, const Json&);
1485 friend void swap(Json&, Json&);
1486
1487 public:
1488 // TRAITS
1492
1493 // CREATORS
1494
1495 /// Create a `Json` object having the type (and the singleton value) of
1496 /// `JsonNull`. Optionally specify the `basicAllocator` used to supply
1497 /// memory. If `basicAllocator` is not specified, the currently installed
1498 /// default allocator is used to supply memory.
1499 Json();
1500 explicit Json(bslma::Allocator *basicAllocator);
1501
1502 /// Create a `Json` object having the same value as the specified
1503 /// `original`. Optionally specify the `basicAllocator` used to supply
1504 /// memory. If `basicAllocator` is not specified, the currently installed
1505 /// default allocator is used to supply memory.
1506 Json(const Json& original, bslma::Allocator *basicAllocator = 0);
1507
1508 /// Create a `Json` object having the same value as the specified
1509 /// `original` object by moving (in constant time) the contents of
1510 /// `original` to the new `JsonObject`. The allocator associated with
1511 /// `original` is propagated for use in the newly-created `Json` object.
1512 /// `original` is left in a valid but unspecified state.
1513 Json(bslmf::MovableRef<Json> original);
1514
1515 /// Create a `Json` object having the same value as the specified
1516 /// `original`. Use the specified `basicAllocator` to supply memory.
1517 Json(bslmf::MovableRef<Json> original, bslma::Allocator *basicAllocator);
1518
1519 /// Create a `Json` object having the type `bool` and the same value as the
1520 /// specified `boolean`. Optionally specify the `basicAllocator` used to
1521 /// supply memory. If `basicAllocator` is not specified, the currently
1522 /// installed default allocator is used to supply memory.
1523 explicit Json(bool boolean, bslma::Allocator *basicAllocator = 0);
1524
1525 /// Create a `Json` object having the type `JsonNull` and the same value as
1526 /// the specified `null`. Optionally specify the `basicAllocator` used to
1527 /// supply memory. If `basicAllocator` is not specified, the currently
1528 /// installed default allocator is used to supply memory.
1529 explicit Json(const JsonNull& null, bslma::Allocator *basicAllocator = 0);
1530
1531 /// Create a `Json` object having the type `JsonArray`/`JsonObject`/
1532 /// `JsonNumber` and the value of the specified `array`/`object`/`number`.
1533 /// Optionally specify `basicAllocator` used to supply memory. If
1534 /// `basicAllocator` is not specified, the currently installed default
1535 /// allocator is used to supply memory.
1536 Json(const JsonArray& array,
1537 bslma::Allocator *basicAllocator = 0); // IMPLICIT
1538 Json(const JsonObject& object,
1539 bslma::Allocator *basicAllocator = 0); // IMPLICIT
1540 explicit Json(const JsonNumber& number,
1541 bslma::Allocator *basicAllocator = 0);
1542
1543 /// Create a `Json` object having the type `JsonArray`/`JsonObject`/
1544 /// `JsonNumber` and the value of the specified `array`/`object`/ `number`
1545 /// object by moving the contents of `array`/`object`/`number` to the new
1546 /// object. Optionally specify `basicAllocator` used to supply memory. If
1547 /// `basicAllocator` is not specified, the allocator associated with
1548 /// `array`/`object`/`number` is propagated for use in the newly-created
1549 /// `Json` object. The allocator or `array`/`object`/ `number` is
1550 /// unchanged and is otherwise left in (valid) unspecified state.
1552 bslma::Allocator *basicAllocator = 0);
1553 // IMPLICIT
1555 bslma::Allocator *basicAllocator = 0);
1556 // IMPLICIT
1557 explicit Json(bslmf::MovableRef<JsonNumber> number,
1558 bslma::Allocator *basicAllocator = 0);
1559 // IMPLICIT
1560
1561#ifdef BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
1562
1563 /// Create a `Json` object having the same structure as the specified
1564 /// `initializer`. Optionally specify the `basicAllocator` used to supply
1565 /// memory. If `basicAllocator` is not specified, the currently installed
1566 /// default allocator is used to supply memory.
1567 template <class t_JSON_INITIALIZER>
1568 Json(const t_JSON_INITIALIZER& initializer,
1569 bslma::Allocator *basicAllocator = 0,
1570 typename bsl::enable_if<
1571 bsl::is_same<t_JSON_INITIALIZER,
1572 Json_Initializer>::value>::type * = 0);
1573 // IMPLICIT
1574#endif
1575
1576 /// Create a `Json` object having the type `JsonNumber` and the the
1577 /// specified `value`. Optionally specify the `basicAllocator` used to
1578 /// supply memory. If `basicAllocator` is not specified, the currently
1579 /// installed default allocator is used to supply memory.
1580 explicit Json(int value,
1581 bslma::Allocator *basicAllocator = 0);
1582 explicit Json(unsigned int value,
1583 bslma::Allocator *basicAllocator = 0);
1584 explicit Json(long value,
1585 bslma::Allocator *basicAllocator = 0);
1586 explicit Json(unsigned long value,
1587 bslma::Allocator *basicAllocator = 0);
1588 explicit Json(long long value,
1589 bslma::Allocator *basicAllocator = 0);
1590 explicit Json(unsigned long long value,
1591 bslma::Allocator *basicAllocator = 0);
1592 explicit Json(float value,
1593 bslma::Allocator *basicAllocator = 0);
1594 explicit Json(double value,
1595 bslma::Allocator *basicAllocator = 0);
1596 explicit Json(bdldfp::Decimal64 value,
1597 bslma::Allocator *basicAllocator = 0);
1598
1599 // BDE_VERIFY pragma: -FD06 `string` and `bsl::string` are too similar
1600 // BDE_VERIFY pragma: -FD07 `string` and `bsl::string` are too similar
1601
1602 /// Create a `Json` object having the type `bsl::string` and the same value
1603 /// as the specified `string`. Optionally specify the `basicAllocator`
1604 /// used to supply memory. If `basicAllocator` is not specified, the
1605 /// currently installed default allocator is used to supply memory.
1606 ///
1607 /// \pre The behavior is undefined unless `string` is valid UTF-8 (see
1608 /// `bdlde::Utf8Util::isValid`).
1609 explicit Json(const char *string,
1610 bslma::Allocator *basicAllocator = 0);
1611 explicit Json(const bsl::string_view& string,
1612 bslma::Allocator *basicAllocator = 0);
1613
1614 // BDE_VERIFY pragma: -IND01 DEDUCE macro confuses bde_verify
1615
1616 /// Create a `Json` object having the type `bsl::string` and the same value
1617 /// as the specified `string` by moving (in constant time) the contents of
1618 /// `string` to the new `Json` object. Optionally specify the
1619 /// `basicAllocator` used to supply memory. If `basicAllocator` is not
1620 /// specified, the allocator associated with `string` is propagated for use
1621 /// in the newly-created `Json` object. `string` is left in a valid but
1622 /// unspecified state. This function does not participate in overload
1623 /// resolution unless the specified `t_STRING_TYPE` is `bsl::string`.
1624 ///
1625 /// \pre The behavior is undefined unless `string` is valid UTF-8 (see
1626 /// `bdlde::Utf8Util::isValid`).
1627 template <class t_STRING_TYPE>
1628 Json(BSLMF_MOVABLEREF_DEDUCE(t_STRING_TYPE) string,
1629 bslma::Allocator *basicAllocator = 0,
1630 typename bsl::enable_if<
1631 bsl::is_same<t_STRING_TYPE,
1632 bsl::string>::value>::type * = 0);
1633 // IMPLICIT
1634
1635 // BDE_VERIFY pragma: +IND01 DEDUCE macro confuses bde_verify
1636 // BDE_VERIFY pragma: +FD06 `string` and `bsl::string` are too similar
1637 // BDE_VERIFY pragma: +FD07 `string` and `bsl::string` are too similar
1638
1639 // MANIPULATORS
1640
1641 /// Assign to this object the value of the specified `rhs` object, and
1642 /// return a reference providing modifiable access to this object. The
1643 /// value currently held by this variant is destroyed if that value's type
1644 /// is not the same as the type held by the `rhs` object.
1645 Json& operator=(const Json& rhs);
1646
1647 /// Assign to this object the value of the specified `rhs` object, and
1648 /// return a reference providing modifiable access to this object. The
1649 /// contents of `rhs` are moved (in constant time) to this `Json` object if
1650 /// `allocator() == rhs.allocator()`; otherwise they are copied. `rhs` is
1651 /// left in a valid but unspecified state.
1653
1654 /// Assign to this object a value of type `JsonNumber` initialized from the
1655 /// specified `rhs`, and return a reference providing modifiable access to
1656 /// this object. The value currently held by this object (if any) is
1657 /// destroyed if that value's type is not `JsonNumber`.
1658 Json& operator=(const JsonNumber& rhs);
1659 Json& operator=(int rhs);
1660 Json& operator=(unsigned int rhs);
1661 Json& operator=(long rhs);
1662 Json& operator=(unsigned long rhs);
1663 Json& operator=(long long rhs);
1664 Json& operator=(unsigned long long rhs);
1665 Json& operator=(float rhs);
1666 Json& operator=(double rhs);
1668
1669 /// Assign to this object the value of the specified `rhs` object, and
1670 /// return a reference providing modifiable access to this object. The
1671 /// contents of `rhs` are moved (in constant time) to this `Json` object if
1672 /// `allocator() == rhs.allocator()`; otherwise, they are copied. `rhs` is
1673 /// left in a valid but unspecified state. The value currently held by
1674 /// this object (if any) is destroyed if that value's type is not
1675 /// `JsonNumber`.
1677
1678 /// Assign to this object a value of type `bsl::string` initialized from
1679 /// the specified `rhs`, and return a reference providing modifiable access
1680 /// to this object. The value currently held by this object (if any) is
1681 /// destroyed if that value's type is not `bsl::string`.
1682 ///
1683 /// \pre The behavior is undefined unless `rhs` is valid UTF-8 (see `bdlde::Utf8Util::isValid`).
1684 Json& operator=(const char *rhs);
1685 Json& operator=(const bsl::string_view& rhs);
1686
1687 /// Assign to this object the value of the specified `rhs` object, and
1688 /// return a reference providing modifiable access to this object. The
1689 /// contents of `rhs` are moved (in constant time) to this `Json` object if
1690 /// `allocator() == rhs.allocator()`; otherwise, they are copied. `rhs` is
1691 /// left in a valid but unspecified state. The value currently held by
1692 /// this object (if any) is destroyed if that value's type is not
1693 /// `bsl::string`. This function does not participate in overload
1694 /// resolution unless the specified `t_STRING_TYPE` is `bsl::string`.
1695 ///
1696 /// \pre The behavior is undefined unless `rhs` is valid UTF-8 (see
1697 /// `bdlde::Utf8Util::isValid`).
1698 template <class t_STRING_TYPE>
1700 Json>::type&
1701 operator=(BSLMF_MOVABLEREF_DEDUCE(t_STRING_TYPE) rhs);
1702
1703 /// Assign to this object a value of type `bool` initialized from the
1704 /// specified `rhs`, and return a reference providing modifiable access to
1705 /// this object. The value currently held by this object (if any) is
1706 /// destroyed if that value's type is not `bool`.
1707 Json& operator=(bool rhs);
1708
1709 /// Assign to this object a value of type `JsonObject` initialized from the
1710 /// specified `rhs`, and return a reference providing modifiable access to
1711 /// this object. The value currently held by this object (if any) is
1712 /// destroyed if that value's type is not `JsonObject`.
1713 Json& operator=(const JsonObject& rhs);
1714
1715 /// Assign to this object the value of the specified `rhs` object, and
1716 /// return a reference providing modifiable access to this object. The
1717 /// contents of `rhs` are moved (in constant time) to this `Json` object if
1718 /// `allocator() == rhs.allocator()`; otherwise, they are copied. `rhs` is
1719 /// left in a valid but unspecified state. The value currently held by
1720 /// this object (if any) is destroyed if that value's type is not
1721 /// `JsonObject`.
1723
1724 /// Assign to this object a value of type `JsonArray` initialized from the
1725 /// specified `rhs`, and return a reference providing modifiable access to
1726 /// this object. The value currently held by this object (if any) is
1727 /// destroyed if that value's type is not `JsonArray`.
1728 Json& operator=(const JsonArray& rhs);
1729
1730 /// Assign to this object the value of the specified `rhs` object, and
1731 /// return a reference providing modifiable access to this object. The
1732 /// contents of `rhs` are moved (in constant time) to this `Json` object if
1733 /// `allocator() == rhs.allocator()`; otherwise, they are copied. `rhs` is
1734 /// left in a valid but unspecified state. The value currently held by
1735 /// this object (if any) is destroyed if that value's type is not
1736 /// `JsonArray`.
1738
1739 /// Assign to this object the singleton value of type `JsonNull`, and
1740 /// return a reference providing modifiable access to this object. The
1741 /// value currently held by this object (if any) is destroyed if that
1742 /// value's type is not `JsonNull`.
1743 Json& operator=(const JsonNull& );
1744
1745 /// Assign to this object the singleton value of type `JsonNull`, and
1746 /// return a reference providing modifiable access to this object. `rhs`
1747 /// is left in a valid but unspecified state. The value currently held by
1748 /// this object (if any) is destroyed if that value's type is not
1749 /// `JsonNull`.
1751
1752 /// Create an instance of type `JsonArray` in this object, using the
1753 /// allocator currently held by this object to supply memory, and return a
1754 /// reference providing modifiable access to the created instance.
1755 /// Optionally specify `array` to initialize the `JsonArray` created. This
1756 /// method first destroys the current value held by this object (even if
1757 /// the type currently held is `JsonArray`).
1758 JsonArray& makeArray();
1759 JsonArray& makeArray(const JsonArray& array);
1760 JsonArray& makeArray(bslmf::MovableRef<JsonArray> array);
1761
1762 /// Create an instance of type `bool` in this object and return a reference
1763 /// providing modifiable access to the created instance. Optionally
1764 /// specify `boolean` to initialize the `bool` created. This method first
1765 /// destroys the current value held by this object.
1766 bool& makeBoolean();
1767 bool& makeBoolean(bool boolean);
1768
1769 /// Create an instance of type `JsonNull` in this object. This method
1770 /// first destroys the current value held by this object.
1771 void makeNull();
1772
1773 /// Create an instance of type `JsonNumber` in this object, using the
1774 /// allocator currently held by this object to supply memory, and return a
1775 /// reference providing modifiable access to the created instance.
1776 /// Optionally specify `number` to initialize the `JsonNumber` created.
1777 /// This method first destroys the current value held by this object (even
1778 /// if the type currently held is `JsonNumber`).
1779 JsonNumber& makeNumber();
1780 JsonNumber& makeNumber(const JsonNumber& number);
1781 JsonNumber& makeNumber(bslmf::MovableRef<JsonNumber> number);
1782
1783 /// Create an instance of type `JsonObject` in this object, using the
1784 /// allocator currently held by this object to supply memory, and return a
1785 /// reference providing modifiable access to the created instance.
1786 /// Optionally specify `object` to initialize the `JsonObject` created.
1787 /// This method first destroys the current value held by this object (even
1788 /// if the type currently held is `JsonObject`).
1789 JsonObject& makeObject();
1790 JsonObject& makeObject(const JsonObject& object);
1791 JsonObject& makeObject(bslmf::MovableRef<JsonObject> object);
1792
1793 // BDE_VERIFY pragma: -FD06 `string` and `bsl::string` are too similar
1794 // BDE_VERIFY pragma: -FD07 `string` and `bsl::string` are too similar
1795
1796 /// Create an instance of type `bsl::string` in this object, using the
1797 /// allocator currently held by this object to supply memory. Optionally
1798 /// specify `string` to initialize the `bsl::string` created. This method
1799 /// first destroys the current value held by this object (even if the type currently held is `bsl::string`).
1800 ///
1801 /// \pre The behavior is undefined unless
1802 /// `string` is valid UTF-8 (see `bdlde::Utf8Util::isValid`).
1803 void makeString(const char *string);
1804 void makeString(const bsl::string_view& string);
1805
1806 /// Create an instance of type `bsl::string` in this object, using the
1807 /// allocator currently held by this object to supply memory. Optionally
1808 /// specify `string` to initialize the `bsl::string` created. This method
1809 /// first destroys the current value held by this object (even if the type
1810 /// currently held is `bsl::string`). This function does not participate
1811 /// in overload resolution unless the specified `t_STRING_TYPE` is `bsl::string`.
1812 ///
1813 /// \pre The behavior is undefined unless `string` is valid
1814 /// UTF-8 (see `bdlde::Utf8Util::isValid`).
1815 template <class t_STRING_TYPE>
1816 typename bsl::enable_if<bsl::is_same<t_STRING_TYPE,
1817 bsl::string>::value>::type
1818 makeString(BSLMF_MOVABLEREF_DEDUCE(t_STRING_TYPE) string);
1819
1820 // BDE_VERIFY pragma: +FD06 `string` and `bsl::string` are too similar
1821 // BDE_VERIFY pragma: +FD07 `string` and `bsl::string` are too similar
1822
1823 /// Return a reference providing modifiable access to the value of type `JsonArray` held by this object.
1824 ///
1825 /// \pre The behavior is undefined unless
1826 /// `isArray()` returns true.
1827 JsonArray& theArray();
1828
1829 /// Return a reference providing modifiable access to the value of type `boolean` held by this object.
1830 ///
1831 /// \pre The behavior is undefined unless
1832 /// `isBoolean()` returns true.
1833 bool& theBoolean();
1834
1835 /// Return a reference providing modifiable access to the value of type `JsonNull` held by this object.
1836 ///
1837 /// \pre The behavior is undefined unless
1838 /// `isNull()` returns true.
1839 JsonNull& theNull();
1840
1841 /// Return a reference providing modifiable access to the value of type `JsonNumber` held by this object.
1842 ///
1843 /// \pre The behavior is undefined unless
1844 /// `isNumber()` returns true.
1845 JsonNumber& theNumber();
1846
1847 /// Return a reference providing modifiable access to the value of type `JsonObject` held by this object.
1848 ///
1849 /// \pre The behavior is undefined unless
1850 /// `isObject()` returns true.
1851 JsonObject& theObject();
1852
1853#if defined(BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT)
1854 /// Return a reference providing modifiable access to the value of type `JsonArray` held by this object.
1855 ///
1856 /// \pre The behavior is undefined unless
1857 /// `isArray()` returns true.
1858 explicit operator JsonArray &();
1859
1860 /// Return a reference providing modifiable access to the value of type `boolean` held by this object.
1861 ///
1862 /// \pre The behavior is undefined unless
1863 /// `isBoolean()` returns true.
1864 explicit operator bool &();
1865
1866 /// Return a reference providing modifiable access to the value of type `JsonNull` held by this object.
1867 ///
1868 /// \pre The behavior is undefined unless
1869 /// `isNull()` returns true.
1870 explicit operator JsonNull &();
1871
1872 /// Return a reference providing modifiable access to the value of type `JsonNumber` held by this object.
1873 ///
1874 /// \pre The behavior is undefined unless
1875 /// `isNumber()` returns true.
1876 explicit operator JsonNumber &();
1877
1878 /// Return a reference providing modifiable access to the value of type `JsonObject` held by this object.
1879 ///
1880 /// \pre The behavior is undefined unless
1881 /// `isObject()` returns true.
1882 explicit operator JsonObject &();
1883#endif
1884
1885 /// Return a reference providing modifiable access to the `Json` object
1886 /// associated with the specified `key` in the `JsonObject` held by this
1887 /// object. If `isNull()`, then type is changed to object. If the
1888 /// `JsonObject` does not already contain a `Json` object associated with
1889 /// `key`, first insert a new default-constructed `Json` object associated with `key`.
1890 ///
1891 /// \pre The behavior is undefined unless `isObject()` or
1892 /// `isNull()`.
1893 Json& operator[](const bsl::string_view& key);
1894
1895 /// Return a reference providing modifiable access to the element at the
1896 /// specified `index` in the `JsonArray` held by this object.
1897 ///
1898 /// \pre The behavior is undefined unless `isArray()` returns true and
1899 /// `index < theArray().size()`.
1900 Json& operator[](bsl::size_t index);
1901
1902// BDE_VERIFY pragma: -FABC01 // not in order
1903
1904 // `JsonObject::insert` methods
1905
1906 /// Insert the specified `member` into the `JsonObject` held by this object
1907 /// if the key of `member` does not already exist; otherwise, this method
1908 /// has no effect. Return a `pair` whose `first` member is an iterator
1909 /// referring to the (possibly newly inserted) `Member` object whose key
1910 /// matches, and whose `second` member is `true` if a new value was
1911 /// inserted, and `false` otherwise. If `isNull()`, then the type is changed to object.
1912 ///
1913 /// \pre The behavior is undefined unless `isObject()` or
1914 /// `isNull()`, and unless `member.first` is valid UTF-8 (see
1915 /// `bdlde::Utf8Util::isValid`).
1917 const JsonObject::Member& member);
1918
1919 /// Insert the specified move-insertable `member` into the `JsonObject`
1920 /// held by this object if the key of `member` does not already exist;
1921 /// otherwise, this method has no effect. Return a `pair` whose `first`
1922 /// member is an iterator referring to the (possibly newly inserted)
1923 /// `Member` object whose key matches, and whose `second` member is `true`
1924 /// if a new value was inserted, and `false` otherwise. `member` is left
1925 /// in a valid but unspecified state. If `isNull()`, then the type is changed to object.
1926 ///
1927 /// \pre The behavior is undefined unless `isObject()` or
1928 /// `isNull()`, and unless `member.first` is valid UTF-8 (see
1929 /// `bdlde::Utf8Util::isValid`).
1932 member);
1933
1934 /// Insert into the `JsonObject` held by this object each `Member` in the
1935 /// range `[first, last)` whose key is not already present. Return a
1936 /// non-`const` reference to this object. If `isNull()`, then the type is changed to object.
1937 ///
1938 /// \pre The behavior is undefined unless `isObject()` or
1939 /// `isNull()`, `first` and `last` refer to a valid sequence, and the keys
1940 /// of all members are valid UTF-8 (see `bdlde::Utf8Util::isValid`).
1941 template <class t_INPUT_ITERATOR>
1942 typename bsl::enable_if<!bsl::is_convertible<t_INPUT_ITERATOR,
1943 bsl::string_view>::value,
1944 Json&>::type
1945 insert(t_INPUT_ITERATOR first, t_INPUT_ITERATOR last);
1946
1947#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
1948 /// Insert into the `JsonObject` held by this object members created from
1949 /// the specified `memberInitializers`, ignoring those whose keys already
1950 /// exist. Return a non-`const` reference to this object. If `isNull()`, then the type is changed to object.
1951 ///
1952 /// \pre The behavior is undefined unless
1953 /// `isObject()` or `isNull()`, and unless the keys of all members are
1954 /// valid UTF-8 (see `bdlde::Utf8Util::isValid`).
1955 Json& insert(std::initializer_list<JsonObject_MemberInitializer>
1956 memberInitializers);
1957#endif
1958
1959 /// Insert into the `JsonObject` held by this object a `Member` constructed
1960 /// from the specified `key` and `value` if `key` does not already exist;
1961 /// otherwise, this method has no effect. Return a `pair` whose `first`
1962 /// member is an iterator referring to the (possibly newly inserted)
1963 /// `Member` object whose key matches, and whose `second` member is `true`
1964 /// if a new value was inserted, and `false` otherwise. If `isNull()`,
1965 /// then the type is changed to object. The (template parameter) type
1966 /// `t_STRING_VIEW` must be convertible to `bsl::string_view`.
1967 ///
1968 /// \pre The behavior is undefined unless `isObject()` or `isNull()`, and unless
1969 /// `key` is valid UTF-8 (see `bdlde::Utf8Util::isValid`).
1970 template <class t_VALUE, class t_STRING_VIEW>
1972 && bsl::is_convertible<t_STRING_VIEW,
1973 bsl::string_view>::value,
1975 insert(const t_STRING_VIEW& key,
1976 BSLS_COMPILERFEATURES_FORWARD_REF(t_VALUE) value);
1977
1978 // `JsonArray::insert` methods
1979
1980 /// Insert into the `JsonArray` held by this object at the specified
1981 /// `index` a copy of the specified `json`, and return an iterator
1982 /// referring to the newly inserted element. If `isNull()`, then the type
1983 /// is changed to array and `index` must be `0`. If an exception is
1984 /// thrown, `*this` is unaffected. Throw `bsl::length_error` if
1985 /// `size() == maxSize()`. The (template parameter) type `t_INDEX` must be a non-`bool` integral type.
1986 ///
1987 /// \pre The behavior is undefined unless
1988 /// `isArray()` or `isNull()`, and unless `index` is in the range
1989 /// `[0 .. size()]`.
1990 template <class t_INDEX>
1993 JsonArray::Iterator>::type
1994 insert(t_INDEX index, const Json& json);
1995
1996 /// Insert into the `JsonArray` held by this object at the specified
1997 /// `index` the specified move-insertable `json`, and return an iterator
1998 /// referring to the newly inserted element. `json` is left in a valid but
1999 /// unspecified state. If `isNull()`, then the type is changed to array
2000 /// and `index` must be `0`. If an exception is thrown, `*this` is
2001 /// unaffected. Throw `bsl::length_error` if `size() == maxSize()`. The
2002 /// (template parameter) type `t_INDEX` must be a non-`bool` integral type.
2003 ///
2004 /// \pre The behavior is undefined unless `isArray()` or `isNull()`, and unless
2005 /// `index` is in the range `[0 .. size()]`.
2006 template <class t_INDEX>
2009 JsonArray::Iterator>::type
2010 insert(t_INDEX index, bslmf::MovableRef<Json> json);
2011
2012 /// Insert into the `JsonArray` held by this object at the specified
2013 /// `index` the values in the range `[first, last)`, and return an iterator
2014 /// referring to the first newly inserted element. If `isNull()`, then the
2015 /// type is changed to array and `index` must be `0`. If an exception is
2016 /// thrown, `*this` is unaffected. Throw `bsl::length_error` if
2017 /// `size() + distance(first, last) > maxSize()`. The (template parameter)
2018 /// type `t_INDEX` must be a non-`bool` integral type.
2019 ///
2020 /// \pre The behavior is undefined unless `isArray()` or `isNull()`, and unless `index` is in
2021 /// the range `[0 .. size()]`.
2022 template <class t_INDEX, class t_INPUT_ITERATOR>
2025 JsonArray::Iterator>::type
2026 insert(t_INDEX index,
2027 t_INPUT_ITERATOR first,
2028 t_INPUT_ITERATOR last);
2029
2030 /// Insert into the `JsonArray` held by this object at the specified
2031 /// `position` a copy of the specified `json`, and return an iterator
2032 /// referring to the newly inserted element. If an exception is thrown,
2033 /// `*this` is unaffected. Throw `bsl::length_error` if `size() == maxSize()`.
2034 ///
2035 /// \pre The behavior is undefined unless `isArray()`
2036 /// and `position` is in the range
2037 /// `[theArray().begin() .. theArray().end()]`.
2039 const Json& json);
2040
2041 /// Insert into the `JsonArray` held by this object at the specified
2042 /// `position` the specified move-insertable `json`, and return an iterator
2043 /// referring to the newly inserted element. `json` is left in a valid but
2044 /// unspecified state. If an exception is thrown, `*this` is unaffected.
2045 /// Throw `bsl::length_error` if `size() == maxSize()`.
2046 ///
2047 /// \pre The behavior is undefined unless `isArray()` and `position` is in the range
2048 /// `[theArray().begin() .. theArray().end()]`.
2051
2052 /// Insert into the `JsonArray` held by this object at the specified
2053 /// `position` the values in the range `[first, last)`, and return an
2054 /// iterator referring to the first newly inserted element. If an
2055 /// exception is thrown, `*this` is unaffected. Throw `bsl::length_error`
2056 /// if `size() + distance(first, last) > maxSize()`.
2057 ///
2058 /// \pre The behavior is undefined unless `isArray()` and `position` is in the range
2059 /// `[theArray().begin() .. theArray().end()]`.
2060 template <class t_INPUT_ITERATOR>
2062 t_INPUT_ITERATOR first,
2063 t_INPUT_ITERATOR last);
2064
2065 // `JsonArray::pushBack` methods
2066
2067 /// Append to the end of this `Json` object's array a copy of the specified
2068 /// `json`/`array`/`object`/`number` and return a non-`const` reference to
2069 /// this object. If `isNull()`, then the type is changed to array. If an
2070 /// exception is thrown, `*this` is unaffected. Throw `bsl::length_error` if `size() == maxSize()`.
2071 ///
2072 /// \pre The behavior is undefined unless `isArray()`
2073 /// or `isNull()`.
2074 Json& pushBack(const Json& json);
2075 Json& pushBack(const JsonArray& array);
2076 Json& pushBack(const JsonObject& object);
2077 Json& pushBack(const JsonNumber& number);
2078
2079 /// Append to the end of this `Json` object's array the specified
2080 /// move-insertable `json`/`array`/`object`/`number` and return a
2081 /// non-`const` reference to this object. `json`/`array`/`object`/`number`
2082 /// is left in a valid but unspecified state. If `isNull`, then the type
2083 /// is changed to array. If an exception is thrown, `*this` is unaffected.
2084 /// Throw `bsl::length_error` if `size() == maxSize()`.
2085 ///
2086 /// \pre The behavior is undefined unless `isArray()` or `isNull()`.
2091
2092 /// Append to the end of this `Json` object's array a copy of the specified
2093 /// `value` and return a non-`const` reference to this object. If
2094 /// `isNull()`, then type is changed to array. If an exception is thrown,
2095 /// `*this` is unaffected. Throw `bsl::length_error` if `size() == maxSize()`.
2096 ///
2097 /// \pre The behavior is undefined unless `isArray()` or
2098 /// `isNull()`.
2099 Json& pushBack(const JsonNull& value);
2100 Json& pushBack(bool value);
2101 Json& pushBack(int value);
2102 Json& pushBack(unsigned int value);
2103 Json& pushBack(long value);
2104 Json& pushBack(unsigned long value);
2105 Json& pushBack(long long value);
2106 Json& pushBack(unsigned long long value);
2107 Json& pushBack(float value);
2108 Json& pushBack(double value);
2110
2111 /// Append to the end of this `Json` object's array a copy of the specified
2112 /// `string` and return a non-`const` reference to this object. If
2113 /// `isNull`, then type is changed to array. If an exception is thrown,
2114 /// `*this` is unaffected. Throw `bsl::length_error` if `size() == maxSize()`.
2115 ///
2116 /// \pre The behavior is undefined unless `isArray()` or
2117 /// `isNull()`.
2118 Json& pushBack(const char *string);
2119 Json& pushBack(const bsl::string_view& string);
2120
2121 /// Append to the end of this `Json` object's array an element having value
2122 /// of the specified `string` by moving (in constant time) the contents of
2123 /// `string` to the new element and return a non-`const` reference to this
2124 /// object. If `isNull()`, then the type is changed to array. `string` is
2125 /// left in a valid but unspecified state. This function does not
2126 /// participate in overload resolution unless the specified `t_STRING_TYPE` is `bsl::string`.
2127 ///
2128 /// \pre The behavior is undefined unless `string` is valid
2129 /// UTF-8 (see `bdlde::Utf8Util::isValid`).
2130 ///
2131 /// \pre The behavior is undefined unless `isArray()` or `isNull()`.
2132 template <class t_STRING_TYPE>
2133 typename bsl::enable_if<bsl::is_same<t_STRING_TYPE,
2134 bsl::string>::value,
2135 Json&>::type
2136 pushBack(BSLMF_MOVABLEREF_DEDUCE(t_STRING_TYPE) string);
2137
2138 /// Return the result (having `RETURN_TYPE`) of invoking the specified
2139 /// `visitor` (callable) object on this `Json` object. `visitor` must be
2140 /// callable as if it provides the following overloads of `operator()`:
2141 /// @code
2142 /// RETURN_TYPE operator()(JsonObject *object );
2143 /// RETURN_TYPE operator()(JsonArray *array );
2144 /// RETURN_TYPE operator()(bsl::string *string );
2145 /// RETURN_TYPE operator()(JsonNumber *number );
2146 /// RETURN_TYPE operator()(bool *boolean);
2147 /// RETURN_TYPE operator()(JsonNull *null );
2148 /// @endcode
2149 /// The overload corresponding to the current `type()` of this `Json`
2150 /// object is invoked. For C++03 `visitor` must be `const` qualified.
2151 ///
2152 /// \pre The behavior is undefined unless all of these six overloads are
2153 /// defined.
2154 /// \pre The behavior is undefined if the `string` overload leaves
2155 /// this `Json` object with a string that is not valid UTF-8.
2156 ///
2157 /// \note Note that overloads that are not applicable in a given application need not do
2158 /// anything other than return. Also note that if `visitor` is `const`
2159 /// qualified then each of its `operator()` overloads must also be
2160 /// `const` qualified.
2161 template <class RETURN_TYPE, class VISITOR>
2162 RETURN_TYPE visit(BSLS_COMPILERFEATURES_FORWARD_REF(VISITOR) visitor);
2163
2164#ifdef BSLS_LIBRARYFEATURES_HAS_CPP14_BASELINE_LIBRARY
2165 /// Return the result (having a deduced type) of invoking the specified
2166 /// `visitor` (callable) object on this `Json` object. `visitor` must be
2167 /// callable as if it provides the following overloads of `operator()`, any
2168 /// of which can have deduced return types:
2169 /// @code
2170 /// decltype(auto) operator()(JsonObject *object );
2171 /// decltype(auto) operator()(JsonArray *array );
2172 /// decltype(auto) operator()(bsl::string *string );
2173 /// decltype(auto) operator()(JsonNumber *number );
2174 /// decltype(auto) operator()(bool *boolean);
2175 /// decltype(auto) operator()(JsonNull *null );
2176 /// @endcode
2177 /// The overload corresponding to the current `type()` of this `Json` object is invoked.
2178 ///
2179 /// \pre The behavior is undefined unless all of these
2180 /// six overloads are defined *and* each has the same return type.
2181 ///
2182 /// \pre The behavior is undefined if the `string` overload leaves this `Json` object with a string that is not valid UTF-8.
2183 ///
2184 /// \note Note that overloads
2185 /// that are not applicable in a given application need not do anything
2186 /// other than return. Also note that if `visitor` is `const` qualified
2187 /// then each of its `operator()` overloads must also be `const`
2188 /// qualified.
2189 template <class VISITOR>
2190 decltype(auto) visit(BSLS_COMPILERFEATURES_FORWARD_REF(VISITOR) visitor);
2191#endif
2192
2193 // Aspects
2194
2195 /// Exchange the value of this with that of the specified `other`. If an
2196 /// exception is thrown, both objects are left in valid but unspecified
2197 /// states. This operation guarantees O[1] complexity.
2198 ///
2199 /// \pre The behavior is undefined unless this object was created with the same allocator as
2200 /// `other`.
2201 void swap(Json& other);
2202
2203 // ACCESSORS
2204
2205 /// Load into the specified `result` the integer value of the value of type
2206 /// `JsonNumber` held by this object. Return 0 on success,
2207 /// `JsonNumber::k_OVERFLOW` if `value` is larger than can be represented
2208 /// by `result`, `JsonNumber::k_UNDERFLOW` if `value` is smaller than can
2209 /// be represented by `result`, and `JsonNumber::k_NOT_INTEGRAL` if `value`
2210 /// is not an integral number (i.e., there is a fractional part). For
2211 /// underflow, `result` will be loaded with the minimum representable
2212 /// value, for overflow, `result` will be loaded with the maximum
2213 /// representable value, for non-integral values `result` will be loaded
2214 /// with the integer part of `value` (truncating the value to the nearest
2215 /// integer). If the result is not an integer and also either overflows or
2216 /// underflows, it is treated as an overflow or underflow (respectively).
2217 ///
2218 /// \note Note that this operation returns a status value (unlike similar
2219 /// floating point conversions) because typically it is an error if a
2220 /// conversion to an integer results in an inexact value.
2221 ///
2222 /// \pre The behavior is undefined unless `isNumber()` returns true. Also note that on all
2223 /// supported platforms `bsls::Types::Int64` and `bsls::Types::Uint64` are,
2224 /// respectively, aliases for `long long` and `unsigned long long`.
2225 int asShort (short *result) const;
2226 int asInt (int *result) const;
2227 int asLong (long *result) const;
2228 int asLonglong (long long *result) const;
2229 int asInt64 (bsls::Types::Int64 *result) const;
2230 int asUshort (unsigned short *result) const;
2231 int asUint (unsigned int *result) const;
2232 int asUlong (unsigned long *result) const;
2233 int asUlonglong(unsigned long long *result) const;
2234 int asUint64 (bsls::Types::Uint64 *result) const;
2235
2236 /// Return the closest floating point representation to the value of the
2237 /// type `JsonNumber` held by this object. If this number is outside the
2238 /// representable range, return +INF or -INF (as appropriate).
2239 ///
2240 /// \pre The behavior is undefined unless `isNumber()` returns true.
2241 float asFloat() const;
2242 double asDouble() const;
2243 bdldfp::Decimal64 asDecimal64() const;
2244
2245// BDE_VERIFY pragma: +FABC01 // not in order
2246
2247 /// Load the specified `result` with the closest floating point
2248 /// representation to the value of type `JsonNumber` held by this object,
2249 /// even if a non-zero status is returned. Return 0 if this number can be
2250 /// represented exactly, and return `JsonNumber::k_INEXACT` if `value`
2251 /// cannot be represented exactly. If this number is outside the
2252 /// representable range, load `result` with +INF or -INF (as appropriate).
2253 /// A number can be represented exactly as a `Decimal64` if, for the
2254 /// significand and exponent, `abs(significand) <= 9,999,999,999,999,999` and `-398 <= exponent <= 369`.
2255 ///
2256 /// \pre The behavior is undefined unless
2257 /// `isNumber()` returns `true`;
2258 int asDecimal64Exact(bdldfp::Decimal64 *result) const;
2259
2260 /// Return true if the value held by this object is of type `JsonArray`,
2261 /// and false otherwise.
2262 bool isArray() const;
2263
2264 /// Return true if the value held by this object is of type `bool`, and
2265 /// false otherwise.
2266 bool isBoolean() const;
2267
2268 /// Return true if the value held by this object is of type `JsonNull`, and
2269 /// false otherwise.
2270 bool isNull() const;
2271
2272 /// Return true if the value held by this object is of type `JsonNumber`,
2273 /// and false otherwise.
2274 bool isNumber() const;
2275
2276 /// Return true if the value held by this object is of type `JsonObject`,
2277 /// and false otherwise.
2278 bool isObject() const;
2279
2280 /// Return true if the value held by this object is of type `bsl::string`,
2281 /// and false otherwise.
2282 bool isString() const;
2283
2284 /// Return a reference providing non-modifiable access to the value of type `JsonArray` held by this object.
2285 ///
2286 /// \pre The behavior is undefined unless
2287 /// `isArray()` returns true.
2288 const JsonArray& theArray() const;
2289
2290 /// Return a reference providing non-modifiable access to the value of type `boolean` held by this object.
2291 ///
2292 /// \pre The behavior is undefined unless
2293 /// `isBoolean()` returns true.
2294 const bool& theBoolean() const;
2295
2296 /// Return a reference providing non-modifiable access to the value of type `JsonNull` held by this object.
2297 ///
2298 /// \pre The behavior is undefined unless
2299 /// `isNull()` returns true.
2300 const JsonNull& theNull() const;
2301
2302 /// Return a reference providing non-modifiable access to the value of type `JsonNumber` held by this object.
2303 ///
2304 /// \pre The behavior is undefined unless
2305 /// `isNumber()` returns true.
2306 const JsonNumber& theNumber() const;
2307
2308 /// Return a reference providing non-modifiable access to the value of type `JsonObject` held by this object.
2309 ///
2310 /// \pre The behavior is undefined unless
2311 /// `isObject()` returns true.
2312 const JsonObject& theObject() const;
2313
2314 /// Return a reference providing non-modifiable access to the value of type `JsonString` held by this object.
2315 ///
2316 /// \pre The behavior is undefined unless
2317 /// `isString()` returns true.
2318 const bsl::string& theString() const;
2319
2320 /// Return the type of this `Json` value.
2322
2323 /// Return a reference providing non-modifiable access to the `Json` object
2324 /// associated with the specified `key` in this `JsonObject`.
2325 ///
2326 /// \pre The behavior is undefined unless `key` is valid UTF-8 (see
2327 /// `bdlde::Utf8Util::isValid`) and this `JsonObject` already contains a
2328 /// `Json` object associated with `key`.
2329 const Json& operator[](const bsl::string_view& key) const;
2330
2331 /// Return a reference providing non-modifiable access to the element at
2332 /// the specified `index` in the `JsonArray` held by this object.
2333 ///
2334 /// \pre The behavior is undefined unless `isArray()` returns true and
2335 /// `index < theArray().size()`.
2336 const Json& operator[](bsl::size_t index) const;
2337
2338#if defined(BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT)
2339 /// Return a reference providing non-modifiable access to the value of type `JsonArray` held by this object.
2340 ///
2341 /// \pre The behavior is undefined unless
2342 /// `isArray()` returns true.
2343 explicit operator const JsonArray &() const;
2344
2345 /// Return a reference providing non-modifiable access to the value of type `boolean` held by this object.
2346 ///
2347 /// \pre The behavior is undefined unless
2348 /// `isBoolean()` returns true.
2349 explicit operator const bool &() const;
2350
2351 /// Return a reference providing non-modifiable access to the value of type `JsonNull` held by this object.
2352 ///
2353 /// \pre The behavior is undefined unless
2354 /// `isNull()` returns true.
2355 explicit operator const JsonNull &() const;
2356
2357 /// Return a reference providing non-modifiable access to the value of type `JsonNumber` held by this object.
2358 ///
2359 /// \pre The behavior is undefined unless
2360 /// `isNumber()` returns true.
2361 explicit operator const JsonNumber &() const;
2362
2363 /// Return a reference providing non-modifiable access to the value of type `JsonObject` held by this object.
2364 ///
2365 /// \pre The behavior is undefined unless
2366 /// `isObject()` returns true.
2367 explicit operator const JsonObject &() const;
2368
2369 /// Return a reference providing non-modifiable access to the value of type `JsonString` held by this object.
2370 ///
2371 /// \pre The behavior is undefined unless
2372 /// `isString()` returns true.
2373 explicit operator const bsl::string &() const;
2374#endif
2375
2376 /// Return the number of elements in the `JsonObject` or `JsonArray` held by this object.
2377 ///
2378 /// \pre The behavior is undefined unless
2379 /// `isArray() || isObject()` evaluates to true.
2380 bsl::size_t size() const;
2381
2382 /// Return `true` if the `JsonObject` held by this `Json` object contains a
2383 /// member whose key is equivalent to the specified `key`, and return `false` otherwise.
2384 ///
2385 /// \pre The behavior is undefined unless
2386 /// `true == isObject()`.
2387 bool contains(const bsl::string_view& key) const;
2388
2389 /// Return the result (having `RETURN_TYPE`) of invoking the specified
2390 /// `visitor` (callable) object on this `Json` object. `visitor` must be
2391 /// callable as if it provides the following overloads of `operator()`:
2392 /// @code
2393 /// RETURN_TYPE operator()(const JsonObject& object );
2394 /// RETURN_TYPE operator()(const JsonArray& array );
2395 /// RETURN_TYPE operator()(const bsl::string& string );
2396 /// RETURN_TYPE operator()(const JsonNumber& number );
2397 /// RETURN_TYPE operator()(const bool& boolean);
2398 /// RETURN_TYPE operator()(const JsonNull& null );
2399 /// @endcode
2400 /// The overload corresponding to the current `type()` of this `Json`
2401 /// object is invoked. For C++03 `visitor` must be `const`-qualified.
2402 ///
2403 /// \pre The behavior is undefined unless all of these six overloads are defined.
2404 ///
2405 /// \note Note that overloads that are not applicable in a given application need
2406 /// not do anything other than return. Also note that if `visitor` is
2407 /// `const` qualified then each of its `operator()` overloads must also be
2408 /// `const` qualified.
2409 template <class RETURN_TYPE, class VISITOR>
2410 RETURN_TYPE visit(BSLS_COMPILERFEATURES_FORWARD_REF(VISITOR) visitor)
2411 const;
2412
2413#ifdef BSLS_LIBRARYFEATURES_HAS_CPP14_BASELINE_LIBRARY
2414 /// Return the result (having a deduced type) of invoking the specified
2415 /// `visitor` (callable) object on this `Json` object. `visitor` must be
2416 /// callable as if it provides the following overloads of `operator()`, any
2417 /// of which can have deduced return types:
2418 /// @code
2419 /// decltype(auto) operator()(const JsonObject& object );
2420 /// decltype(auto) operator()(const JsonArray& array );
2421 /// decltype(auto) operator()(const bsl::string& string );
2422 /// decltype(auto) operator()(const JsonNumber& number );
2423 /// decltype(auto) operator()(const bool& boolean);
2424 /// decltype(auto) operator()(const JsonNull& null );
2425 /// @endcode
2426 /// The overload corresponding to the current `type()` of this `Json` object is invoked.
2427 ///
2428 /// \pre The behavior is undefined unless all of these six
2429 /// overloads are defined *and* each has the same return type.
2430 ///
2431 /// \note Note that overloads that are not applicable in a given application need not do
2432 /// anything other than return. Also note that if `visitor` is `const`
2433 /// qualified then each of its `operator()` overloads must also be `const`
2434 /// qualified.
2435 template <class VISITOR>
2436 decltype(auto) visit(BSLS_COMPILERFEATURES_FORWARD_REF(VISITOR) visitor)
2437 const;
2438#endif
2439
2440 // Aspects
2441
2442 /// Return the allocator used by this object to allocate memory.
2444
2445 /// Write the value of this object to the specified output `stream` in a
2446 /// human-readable format, and return a reference to `stream`. Optionally
2447 /// specify an initial indentation `level`, whose absolute value is
2448 /// incremented recursively for nested objects. If `level` is specified,
2449 /// optionally specify `spacesPerLevel`, whose absolute value indicates the
2450 /// number of spaces per indentation level for this and all of its nested
2451 /// objects. If `level` is negative, suppress indentation of the first
2452 /// line. If `spacesPerLevel` is negative, format the entire output on one
2453 /// line, suppressing all but the initial indentation (as governed by
2454 /// `level`). If `stream` is not valid on entry, this operation has no effect.
2455 ///
2456 /// \note Note that this human-readable format is not fully specified,
2457 /// and can change without notice.
2458 bsl::ostream& print(bsl::ostream& stream,
2459 int level = 0,
2460 int spacesPerLevel = 4) const;
2461};
2462
2463// FREE OPERATORS
2464
2465/// Write the value of the specified `object` to the specified output `stream`
2466/// in a single-line format, and return a reference to `stream`. If `stream` is not valid on entry, this operation has no effect.
2467///
2468/// \note Note that this
2469/// human-readable format is not fully specified, can change without notice,
2470/// and is logically equivalent to:
2471/// @code
2472/// print(stream, 0, -1);
2473/// @endcode
2474bsl::ostream& operator<<(bsl::ostream& stream, const Json& object);
2475
2476/// Return `true` if the specified `lhs` and `rhs` objects have the same value,
2477/// and `false` otherwise. Two `Json` objects `lhs` and `rhs` have the same
2478/// value if they hold objects of the same type, and those objects have the
2479/// same value.
2480bool operator==(const Json& lhs, const Json& rhs);
2481
2482/// Return `false` if the specified `lhs` and `rhs` objects have the same
2483/// value, and `true` otherwise. Two `Json` objects `lhs` and `rhs` have the
2484/// same value if they hold objects of the same type, and those objects have
2485/// the same value.
2486bool operator!=(const Json& lhs, const Json& rhs);
2487
2488/// Return `true` if the specified `lhs` and `rhs` arguments have the same
2489/// value, and `false` otherwise. Two arguments have the same value if the
2490/// `Json` object has the same value as a `Json` object constructed from the
2491/// other argument.
2492bool operator==(const JsonArray& lhs, const Json& rhs);
2493bool operator==(const JsonObject& lhs, const Json& rhs);
2494bool operator==(const JsonNumber& lhs, const Json& rhs);
2495bool operator==(const JsonNull& lhs, const Json& rhs);
2496bool operator==(bool lhs, const Json& rhs);
2497bool operator==(int lhs, const Json& rhs);
2498bool operator==(unsigned int lhs, const Json& rhs);
2499bool operator==(long lhs, const Json& rhs);
2500bool operator==(unsigned long lhs, const Json& rhs);
2501bool operator==(long long lhs, const Json& rhs);
2502bool operator==(unsigned long long lhs, const Json& rhs);
2503bool operator==(float lhs, const Json& rhs);
2504bool operator==(double lhs, const Json& rhs);
2505bool operator==(bdldfp::Decimal64 lhs, const Json& rhs);
2506bool operator==(const char *lhs, const Json& rhs);
2507bool operator==(const bsl::string_view& lhs, const Json& rhs);
2508bool operator==(const Json& lhs, const JsonArray& rhs);
2509bool operator==(const Json& lhs, const JsonObject& rhs);
2510bool operator==(const Json& lhs, const JsonNumber& rhs);
2511bool operator==(const Json& lhs, const JsonNull& rhs);
2512bool operator==(const Json& lhs, bool rhs);
2513bool operator==(const Json& lhs, int rhs);
2514bool operator==(const Json& lhs, unsigned int rhs);
2515bool operator==(const Json& lhs, long rhs);
2516bool operator==(const Json& lhs, unsigned long rhs);
2517bool operator==(const Json& lhs, long long rhs);
2518bool operator==(const Json& lhs, unsigned long long rhs);
2519bool operator==(const Json& lhs, float rhs);
2520bool operator==(const Json& lhs, double rhs);
2521bool operator==(const Json& lhs, bdldfp::Decimal64 rhs);
2522bool operator==(const Json& lhs, const char *rhs);
2523bool operator==(const Json& lhs, const bsl::string_view& rhs);
2524
2525/// Return `true` if the specified `lhs` and `rhs` arguments do not have the
2526/// same value, and `false` otherwise. Two arguments do not have the same
2527/// value if the `Json` object does not have the same value as a `Json` object
2528/// constructed from the other argument.
2529bool operator!=(const JsonArray& lhs, const Json& rhs);
2530bool operator!=(const JsonObject& lhs, const Json& rhs);
2531bool operator!=(const JsonNumber& lhs, const Json& rhs);
2532bool operator!=(const JsonNull& lhs, const Json& rhs);
2533bool operator!=(bool lhs, const Json& rhs);
2534bool operator!=(int lhs, const Json& rhs);
2535bool operator!=(unsigned int lhs, const Json& rhs);
2536bool operator!=(long lhs, const Json& rhs);
2537bool operator!=(unsigned long lhs, const Json& rhs);
2538bool operator!=(long long lhs, const Json& rhs);
2539bool operator!=(unsigned long long lhs, const Json& rhs);
2540bool operator!=(float lhs, const Json& rhs);
2541bool operator!=(double lhs, const Json& rhs);
2542bool operator!=(bdldfp::Decimal64 lhs, const Json& rhs);
2543bool operator!=(const char *lhs, const Json& rhs);
2544bool operator!=(const bsl::string_view& lhs, const Json& rhs);
2545bool operator!=(const Json& lhs, const JsonArray& rhs);
2546bool operator!=(const Json& lhs, const JsonObject& rhs);
2547bool operator!=(const Json& lhs, const JsonNumber& rhs);
2548bool operator!=(const Json& lhs, const JsonNull& rhs);
2549bool operator!=(const Json& lhs, bool rhs);
2550bool operator!=(const Json& lhs, int rhs);
2551bool operator!=(const Json& lhs, unsigned int rhs);
2552bool operator!=(const Json& lhs, long rhs);
2553bool operator!=(const Json& lhs, unsigned long rhs);
2554bool operator!=(const Json& lhs, long long rhs);
2555bool operator!=(const Json& lhs, unsigned long long rhs);
2556bool operator!=(const Json& lhs, float rhs);
2557bool operator!=(const Json& lhs, double rhs);
2558bool operator!=(const Json& lhs, bdldfp::Decimal64 rhs);
2559bool operator!=(const Json& lhs, const char *rhs);
2560bool operator!=(const Json& lhs, const bsl::string_view& rhs);
2561
2562/// Exchange the value of the specified `a` `Json` object with that of the
2563/// specified `b` `Json` object. If an exception is thrown, both objects are
2564/// left in valid but unspecified states. This operation guarantees O[1] complexity.
2565///
2566/// \pre The behavior is undefined unless `a` was created with the same
2567/// allocator as `b`.
2568void swap(Json& a, Json& b);
2569
2570// ============================================================================
2571// INLINE DEFINITIONS
2572// ============================================================================
2573
2574#ifdef BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
2575
2576 // ======================
2577 // class Json_Initializer
2578 // ======================
2579
2580/// This component-private class is designed capture a set of values that can
2581/// be used to initialize a `Json` object, or an element in a `JsonArray`, or
2582/// the "value" portion of a `JsonObject` member. This class is not
2583/// modifiable, and (except for small types like `int`) does not own the
2584/// objects that it holds. The purpose here is to enable list-initialization
2585/// (including nested lists) of `Json`, `JsonArray`, and `JsonObject` objects.
2586/// The lifetime of a `Json_Initializer` object should not exceed that of
2587/// list-initialization expression because pointers held here would no longer
2588/// be valid.
2589///
2590/// See @ref bdljsn_json
2591class Json_Initializer {
2592
2593 public:
2594 // PUBLIC TYPES
2595 typedef bdlb::Variant<JsonNull,
2596 bool,
2597 long long,
2598 unsigned long long,
2599 double,
2602 bsl::span<const Json_Initializer>,
2603 const JsonObject *,
2604 const JsonArray *,
2605 const JsonNumber *,
2606 const Json *> Storage;
2607
2608 private:
2609 // DATA
2610 Storage d_storage;
2611
2612 public:
2613 // CREATORS
2614
2615 /// Create a `Json_Initializer` object containing a `JsonNull` in the
2616 /// internal variant.
2617 Json_Initializer();
2618 Json_Initializer(const JsonNull& ); // IMPLICIT
2619
2620 /// Create a `Json_Initializer` object containing the boolean value of the specified `value` in the internal variant.
2621 ///
2622 /// \note Note that (template
2623 /// parameter) `t_BOOL` must be `bool`; types that convert to `bool` (e.g.,
2624 /// pointers) are disallowed.
2625 template <class t_BOOL>
2626 Json_Initializer(t_BOOL value, typename bsl::enable_if<
2628 bool>::type * = 0);
2629 // IMPLICIT
2630
2631 /// Create a `Json_Initializer` object containing the value of the
2632 /// specified `value` in the internal variant. If `value` is a signed
2633 /// integral type, then the value is stored as a `long long`. If `value`
2634 /// is an unsigned integral type, then the value is stored as an
2635 /// `unsigned long long`.
2636 template <class t_INTEGRAL>
2637 Json_Initializer(t_INTEGRAL value, typename bsl::enable_if<
2640 int >::type * = 0);
2641 // IMPLICIT
2642
2643 /// Create a `Json_Initializer` object containing the specified `value`.
2644 Json_Initializer(float value); // IMPLICIT
2645
2646 /// Create a `Json_Initializer` object containing the specified `value`.
2647 Json_Initializer(double value); // IMPLICIT
2648
2649 /// Create a `Json_Initializer` object containing the specified `value`.
2650 Json_Initializer(bdldfp::Decimal64 value); // IMPLICIT
2651
2652 /// Create a `Json_Initializer` object containing a @ref string_view referring
2653 /// to the null-terminated sequence pointed to by the specified `string`.
2654 Json_Initializer(const char *string); // IMPLICIT
2655
2656 /// Create a `Json_Initializer` object containing a @ref string_view referring
2657 /// to the contents of the specified `string`.
2658 Json_Initializer(const bsl::string& string); // IMPLICIT
2659 Json_Initializer(const std::string& string); // IMPLICIT
2660#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR_STRING
2661 Json_Initializer(const std::pmr::string& string); // IMPLICIT
2662#endif
2663
2664 /// Create a `Json_Initializer` object containing a @ref string_view
2665 /// containing the specified `sv`.
2666 Json_Initializer(const bsl::string_view& sv); // IMPLICIT
2667
2668#ifdef BSLSTL_STRING_VIEW_AND_STD_STRING_VIEW_COEXIST
2669 /// Create a `Json_Initializer` object containing a @ref string_view
2670 /// containing the specified `sv`.
2671 Json_Initializer(const std::string_view& sv); // IMPLICIT
2672#endif
2673
2674 /// Create a `Json_Initializer` object containing an initializer list with
2675 /// the value of the specified `il`.
2676 Json_Initializer(std::initializer_list<Json_Initializer> il); // IMPLICIT
2677
2678 /// Create a `Json_Initializer` object containing a pointer to the
2679 /// specified `jObj`.
2680 Json_Initializer(const JsonObject& jObj); // IMPLICIT
2681
2682 /// Create a `Json_Initializer` object containing a pointer to the
2683 /// specified `jArr`.
2684 Json_Initializer(const JsonArray& jArr); // IMPLICIT
2685
2686 /// Create a `Json_Initializer` object containing a pointer to the
2687 /// specified `jNum`.
2688 Json_Initializer(const JsonNumber& jNum); // IMPLICIT
2689
2690 /// Create a `Json_Initializer` object containing a pointer to the
2691 /// specified `json`.
2692 Json_Initializer(const Json& json); // IMPLICIT
2693
2694 // ACCESSORS
2695
2696 /// Return a reference providing non-modifiable access to the internal
2697 /// variant.
2698 const Storage& get_storage() const;
2699};
2700
2701 // ----------------------
2702 // class Json_Initializer
2703 // ----------------------
2704
2705// CREATORS
2706inline
2707Json_Initializer::Json_Initializer()
2708: d_storage(JsonNull())
2709{
2710}
2711
2712inline
2713Json_Initializer::Json_Initializer(const JsonNull &)
2714: d_storage(JsonNull())
2715{
2716}
2717
2718template <class t_BOOL>
2719Json_Initializer::Json_Initializer(t_BOOL value, typename bsl::enable_if<
2721 bool>::type *)
2722: d_storage(value)
2723{
2724}
2725
2726template <class t_INTEGRAL>
2727Json_Initializer::Json_Initializer(t_INTEGRAL value, typename bsl::enable_if<
2730 int >::type *)
2731{
2732 BSLMF_ASSERT(bsl::is_unsigned<t_INTEGRAL>::value
2733 || bsl:: is_signed<t_INTEGRAL>::value);
2734
2735 if (bsl::is_unsigned<t_INTEGRAL>::value) {
2736 d_storage = static_cast<unsigned long long>(value);
2737 } else {
2738 d_storage = static_cast< long long>(value);
2739 }
2740}
2741
2742inline
2743Json_Initializer::Json_Initializer(float value)
2744: d_storage(static_cast<double>(value))
2745{
2746}
2747
2748inline
2749Json_Initializer::Json_Initializer(double value)
2750: d_storage(value)
2751{
2752}
2753
2754inline
2755Json_Initializer::Json_Initializer(bdldfp::Decimal64 value)
2756: d_storage(value)
2757{
2758}
2759
2760inline
2761Json_Initializer::Json_Initializer(const char *string)
2762: d_storage(bsl::string_view(string))
2763{
2764}
2765
2766inline
2767Json_Initializer::Json_Initializer(const bsl::string& string)
2768: d_storage(bsl::string_view(string))
2769{
2770}
2771
2772inline
2773Json_Initializer::Json_Initializer(const std::string& string)
2774: d_storage(bsl::string_view(string))
2775{
2776}
2777
2778#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR_STRING
2779inline
2780Json_Initializer::Json_Initializer(const std::pmr::string& string)
2781: d_storage(bsl::string_view(string))
2782{
2783}
2784#endif
2785
2786inline
2787Json_Initializer::Json_Initializer(const bsl::string_view& sv)
2788: d_storage(sv)
2789{
2790}
2791
2792#ifdef BSLSTL_STRING_VIEW_AND_STD_STRING_VIEW_COEXIST
2793inline
2794Json_Initializer::Json_Initializer(const std::string_view& sv)
2795: d_storage(bsl::string_view(sv))
2796{
2797}
2798#endif
2799
2800inline
2801Json_Initializer::Json_Initializer(std::initializer_list<Json_Initializer> il)
2802: d_storage(bsl::span<const Json_Initializer>(il.begin(), il.end()))
2803{
2804}
2805
2806inline
2807Json_Initializer::Json_Initializer(const JsonObject& jObj)
2808: d_storage(&jObj)
2809{
2810}
2811
2812inline
2813Json_Initializer::Json_Initializer(const JsonArray& jArr)
2814: d_storage(&jArr)
2815{
2816}
2817
2818inline
2819Json_Initializer::Json_Initializer(const JsonNumber& jNum)
2820: d_storage(&jNum)
2821{
2822}
2823
2824inline
2825Json_Initializer::Json_Initializer(const Json& json)
2826: d_storage(&json)
2827{
2828}
2829
2830// ACCESSORS
2831inline
2832const Json_Initializer::Storage&
2833Json_Initializer::get_storage() const
2834{
2835 return d_storage;
2836}
2837
2838 // ===========================
2839 // class Json_ConstructVisitor
2840 // ===========================
2841
2842/// This component-private class is used to construct a `Json` object from a
2843/// `Json_Initializer` object. `Json_Initializer` is a variant class defined
2844/// below.
2845///
2846/// See @ref bdljsn_json
2847class Json_ConstructVisitor {
2848 Json *d_this_p;
2849
2850 public:
2851 /// Create a `Json_ConstructVisitor` object configured write into the
2852 /// specified `json`.
2853 explicit Json_ConstructVisitor(Json *json);
2854
2855 /// Store the specified `jNull` into the `Json` object pointed to by
2856 /// `d_this_p`.
2857 void operator()(const JsonNull& jNull) const;
2858
2859 /// Store the specified `b` into the `Json` object pointed to by
2860 /// `d_this_p`.
2861 void operator()(bool b) const;
2862
2863 /// Store the specified `ll` into the `Json` object pointed to by
2864 /// `d_this_p`.
2865 void operator()(long long ll) const;
2866
2867 /// Store the specified `ull` into the `Json` object pointed to by
2868 /// `d_this_p`.
2869 void operator()(unsigned long long ull) const;
2870
2871 /// Store the specified `d` into the `Json` object pointed to by
2872 /// `d_this_p`.
2873 void operator()(double d) const;
2874
2875 /// Store the specified `value` into the `Json` object pointed to by
2876 /// `d_this_p`.
2877 void operator()(bdldfp::Decimal64 value) const;
2878
2879 /// Store the specified `sv` into the `Json` object pointed to by
2880 /// `d_this_p`.
2881 void operator()(const bsl::string_view& sv) const;
2882
2883 /// Store the object pointed to by the specified `jObj` to the `Json`
2884 /// object pointed to by `d_this_p`.
2885 void operator()(const JsonObject *jObj) const;
2886
2887 /// Store the object pointed to by the specified `jArr` to the `Json`
2888 /// object pointed to by `d_this_p`.
2889 void operator()(const JsonArray *jArr) const;
2890
2891 /// Store the object pointed to by the specified `jNum` to the `Json`
2892 /// object pointed to by `d_this_p`.
2893 void operator()(const JsonNumber *jNum) const;
2894
2895 /// Store the object pointed to by the specified `json` to the `Json`
2896 /// object pointed to by `d_this_p`.
2897 void operator()(const Json *json) const;
2898
2899 /// Store a `JsonArray` containing the elements of the specified `il` into
2900 /// the `Json` object pointed to by `d_this_p`.
2901 void operator()(bsl::span<const Json_Initializer> il) const;
2902
2903 ///
2904 /// \pre The behavior is undefined when this method is called.
2905 void operator()(bslmf::Nil) const;
2906};
2907
2908 // ---------------------------
2909 // class Json_ConstructVisitor
2910 // ---------------------------
2911
2912inline
2913Json_ConstructVisitor::Json_ConstructVisitor(Json *json)
2914: d_this_p(json)
2915{
2916}
2917
2918inline
2919void Json_ConstructVisitor::operator()(const JsonNull &jNull) const
2920{
2921 (void)jNull;
2922}
2923
2924inline
2925void Json_ConstructVisitor::operator()(bool b) const
2926{
2927 d_this_p->makeBoolean(b);
2928}
2929
2930inline
2931void Json_ConstructVisitor::operator()(long long ll) const
2932{
2933 d_this_p->makeNumber(JsonNumber(ll));
2934}
2935
2936inline
2937void Json_ConstructVisitor::operator()(unsigned long long ull) const
2938{
2939 d_this_p->makeNumber(JsonNumber(ull));
2940}
2941
2942inline
2943void Json_ConstructVisitor::operator()(double d) const
2944{
2945 d_this_p->makeNumber(JsonNumber(d));
2946}
2947
2948inline
2949void Json_ConstructVisitor::operator()(bdldfp::Decimal64 value) const
2950{
2951 d_this_p->makeNumber(JsonNumber(value));
2952}
2953
2954inline
2955void Json_ConstructVisitor::operator()(const bsl::string_view& sv) const
2956{
2957 d_this_p->makeString(sv);
2958}
2959
2960inline
2961void Json_ConstructVisitor::operator()(const JsonObject *jObj) const
2962{
2963 d_this_p->makeObject(*jObj);
2964}
2965
2966inline
2967void Json_ConstructVisitor::operator()(const JsonArray *jArr) const
2968{
2969 d_this_p->makeArray(*jArr);
2970}
2971
2972inline
2973void Json_ConstructVisitor::operator()(const JsonNumber *jNum) const
2974{
2975 d_this_p->makeNumber(*jNum);
2976}
2977
2978inline
2979void Json_ConstructVisitor::operator()(const Json *json) const
2980{
2981 *d_this_p = *json;
2982}
2983
2984inline
2985void Json_ConstructVisitor::operator()(bsl::span<const Json_Initializer> sp)
2986 const
2987{
2988 JsonArray arr(sp.begin(), sp.end(), d_this_p->allocator());
2989 d_this_p->makeArray(bslmf::MovableRefUtil::move(arr));
2990}
2991
2992inline
2993void Json_ConstructVisitor::operator()(bslmf::Nil) const
2994{
2996 BSLS_ASSERT_INVOKE_NORETURN("Unreachable");
2997}
2998
2999 // ==================================
3000 // class JsonObject_MemberInitializer
3001 // ==================================
3002
3003/// This component-private class is designed capture a set of values that can
3004/// be used to initialize an element in a `JsonObject`. The purpose here is to
3005/// enable list-initialization (including nested lists) of JSON objects.
3006///
3007/// See @ref bdljsn_json
3008class JsonObject_MemberInitializer {
3009
3010 private:
3011 // DATA
3012 bsl::string_view d_first;
3013 Json_Initializer d_second;
3014
3015 public:
3016// BDE_VERIFY pragma: push
3017// BDE_VERIFY pragma: -IEC01 // implicit conversions is the reason we exist
3018
3019 // CREATORS
3020
3021 /// Create a `JsonObject_MemberInitializer` object a key whose value is
3022 /// equal to the specified `s` and whose value is equal to the specified
3023 /// `ji`.
3024 JsonObject_MemberInitializer(const char *s,
3025 const Json_Initializer& ji);
3026 JsonObject_MemberInitializer(const bsl::string& s,
3027 const Json_Initializer& ji);
3028 JsonObject_MemberInitializer(const std::string& s,
3029 const Json_Initializer& ji);
3030#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR_STRING
3031 JsonObject_MemberInitializer(const std::pmr::string& s,
3032 const Json_Initializer& ji);
3033#endif
3034
3035 /// Create a `JsonObject_MemberInitializer` object a key whose value is
3036 /// equal to the specified `sv` and whose value is equal to the specified
3037 /// `ji`.
3038 JsonObject_MemberInitializer(const bsl::string_view& sv,
3039 const Json_Initializer& ji);
3040
3041#ifdef BSLSTL_STRING_VIEW_AND_STD_STRING_VIEW_COEXIST
3042 /// Create a `JsonObject_MemberInitializer` object a key whose value is
3043 /// equal to the specified `sv` and whose value is equal to the specified
3044 /// `ji`.
3045 JsonObject_MemberInitializer(const std::string_view& sv,
3046 const Json_Initializer& ji);
3047#endif
3048
3049 // ACCESSORS
3050
3051 /// Return the key that the object was created with.
3052 bsl::string_view key() const;
3053
3054 /// Return a reference providing non-modifiable access to the value that
3055 /// the object was created with.
3056 const Json_Initializer& value() const;
3057
3058// BDE_VERIFY pragma: pop
3059};
3060
3061 // ----------------------------------
3062 // class JsonObject_MemberInitializer
3063 // ----------------------------------
3064
3065// CREATORS
3066inline
3067JsonObject_MemberInitializer::JsonObject_MemberInitializer(
3068 const char *s,
3069 const Json_Initializer& ji)
3070: d_first(s)
3071, d_second(ji)
3072{
3073}
3074
3075inline
3076JsonObject_MemberInitializer::JsonObject_MemberInitializer(
3077 const bsl::string& s,
3078 const Json_Initializer& ji)
3079: d_first(s)
3080, d_second(ji)
3081{
3082}
3083
3084inline
3085JsonObject_MemberInitializer::JsonObject_MemberInitializer(
3086 const std::string& s,
3087 const Json_Initializer& ji)
3088: d_first(s)
3089, d_second(ji)
3090{
3091}
3092
3093#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR_STRING
3094inline
3095JsonObject_MemberInitializer::JsonObject_MemberInitializer(
3096 const std::pmr::string& s,
3097 const Json_Initializer& ji)
3098: d_first(s)
3099, d_second(ji)
3100{
3101}
3102#endif
3103
3104inline
3105JsonObject_MemberInitializer::JsonObject_MemberInitializer(
3106 const bsl::string_view& sv,
3107 const Json_Initializer& ji)
3108: d_first(sv)
3109, d_second(ji)
3110{
3111}
3112
3113#ifdef BSLSTL_STRING_VIEW_AND_STD_STRING_VIEW_COEXIST
3114inline
3115JsonObject_MemberInitializer::JsonObject_MemberInitializer(
3116 const std::string_view& sv,
3117 const Json_Initializer& ji)
3118: d_first(sv)
3119, d_second(ji)
3120{
3121}
3122#endif
3123
3124// ACCESSORS
3125inline
3126bsl::string_view JsonObject_MemberInitializer::key() const
3127{
3128 return d_first;
3129}
3130
3131inline
3132const Json_Initializer& JsonObject_MemberInitializer::value() const
3133{
3134 return d_second;
3135}
3136
3137#endif // BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
3138
3139 // =====================
3140 // struct Json_VisitUtil
3141 // =====================
3142
3144
3145 // CLASS METHODS
3146
3147 /// Invoke the specified `visitor` (callable object) with the specified
3148 /// `argument` and return the computed value of (template parameter) the `RETURN_TYPE`.
3149 ///
3150 /// \note Note that in typical use, `argument` has the current
3151 /// value and type of a `Json` object.
3152 template <class RETURN_TYPE,
3153 class VISITOR,
3154 class ARGUMENT>
3155 static
3156 RETURN_TYPE invokeVisitor(VISITOR *visitor,
3157 const ARGUMENT& argument);
3158 template <class RETURN_TYPE,
3159 class VISITOR,
3160 class ARGUMENT>
3161 static
3162 RETURN_TYPE invokeVisitor(VISITOR& visitor,
3163 const ARGUMENT& argument);
3164 template <class RETURN_TYPE,
3165 class VISITOR,
3166 class ARGUMENT>
3167 static
3168 RETURN_TYPE invokeVisitor(const VISITOR& visitor,
3169 const ARGUMENT& argument);
3170 template <class RETURN_TYPE,
3171 class VISITOR,
3172 class ARGUMENT>
3173 static
3174 RETURN_TYPE invokeVisitor(BSLMF_MOVABLEREF_DEDUCE(VISITOR) visitor,
3175 const ARGUMENT& argument);
3176#ifdef BSLS_LIBRARYFEATURES_HAS_CPP14_BASELINE_LIBRARY
3177 template <class VISITOR,
3178 class ARGUMENT>
3179 static
3180 decltype(auto) invokeVisitor(const VISITOR& visitor,
3181 const ARGUMENT& argument);
3182 template <class VISITOR,
3183 class ARGUMENT>
3184 static
3185 decltype(auto) invokeVisitor(BSLMF_MOVABLEREF_DEDUCE(VISITOR) visitor,
3186 const ARGUMENT& argument);
3187#endif
3188};
3189
3190 // ---------------------
3191 // struct Json_VisitUtil
3192 // ---------------------
3193
3194template <class RETURN_TYPE,
3195 class VISITOR,
3196 class ARGUMENT>
3197RETURN_TYPE Json_VisitUtil::invokeVisitor(VISITOR *visitor,
3198 const ARGUMENT& argument)
3199{
3200 BSLS_ASSERT(visitor);
3201 return (*visitor)(argument);
3202}
3203
3204template <class RETURN_TYPE,
3205 class VISITOR,
3206 class ARGUMENT>
3207RETURN_TYPE Json_VisitUtil::invokeVisitor(VISITOR& visitor,
3208 const ARGUMENT& argument)
3209{
3210 return visitor(argument);
3211}
3212
3213template <class RETURN_TYPE,
3214 class VISITOR,
3215 class ARGUMENT>
3216RETURN_TYPE Json_VisitUtil::invokeVisitor(const VISITOR& visitor,
3217 const ARGUMENT& argument)
3218{
3219 return visitor(argument);
3220}
3221
3222template <class RETURN_TYPE,
3223 class VISITOR,
3224 class ARGUMENT>
3225RETURN_TYPE Json_VisitUtil::invokeVisitor(
3226 BSLMF_MOVABLEREF_DEDUCE(VISITOR) visitor,
3227 const ARGUMENT& argument)
3228{
3229#ifdef BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES
3230 return (bsl::forward<VISITOR>(visitor))(argument);
3231#else
3232 return (bslmf::MovableRefUtil::access(visitor))(argument);
3233#endif
3234}
3235
3236#ifdef BSLS_LIBRARYFEATURES_HAS_CPP14_BASELINE_LIBRARY
3237template <class VISITOR,
3238 class ARGUMENT>
3239decltype(auto) Json_VisitUtil::invokeVisitor(const VISITOR& visitor,
3240 const ARGUMENT& argument)
3241{
3242 return visitor(argument);
3243}
3244
3245template <class VISITOR,
3246 class ARGUMENT>
3247decltype(auto) Json_VisitUtil::invokeVisitor(
3248 BSLMF_MOVABLEREF_DEDUCE(VISITOR) visitor,
3249 const ARGUMENT& argument)
3250{
3251#ifdef BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES
3252 return (bsl::forward<VISITOR>(visitor))(argument);
3253#else
3254 return (bslmf::MovableRefUtil::access(visitor))(argument);
3255#endif
3256}
3257#endif
3258 // ===============================
3259 // class Json_StringInvariantGuard
3260 // ===============================
3261
3262/// This is a component-private guard class.
3263///
3264/// See @ref bdljsn_json
3266
3267 // DATA
3268 bsl::string *d_string_p;
3269
3270 public:
3271 // CREATORS
3272
3273 /// Create an object that guards the invariant (valid UTF-8) of the JSON
3274 /// string at the specified `string`.
3275 explicit Json_StringInvariantGuard(bsl::string *string);
3276
3277 /// Validate the JSON string specified on construction using `BSLS_ASSERT`
3278 /// and destroy this guard object.
3280};
3281
3282 // -------------------------------
3283 // class Json_StringInvariantGuard
3284 // -------------------------------
3285
3286// CREATORS
3287inline
3288Json_StringInvariantGuard::Json_StringInvariantGuard(bsl::string *string)
3289: d_string_p(string)
3290{
3291 BSLS_ASSERT(string);
3292}
3293
3294inline
3297{
3298 if (0 == bsl::uncaught_exceptions()) {
3299 if (false == bdlde::Utf8Util::isValid(*d_string_p)) {
3301 "false == bdlde::Utf8Util::isValid(*d_string_p)");
3302 }
3303 }
3304}
3305
3306 // ---------------
3307 // class JsonArray
3308 // ---------------
3309
3310// PRIVATE CLASS METHODS
3311
3312template <class t_INTEGRAL>
3313bool JsonArray::isNonNegativeImp(t_INTEGRAL value, bsl::true_type )
3314{
3315 return 0 <= value;
3316}
3317
3318template <class t_INTEGRAL>
3319bool JsonArray::isNonNegativeImp(t_INTEGRAL , bsl::false_type )
3320{
3321 return true;
3322}
3323
3324template <class t_INTEGRAL>
3325bool JsonArray::isNonNegative(t_INTEGRAL value)
3326{
3327 return isNonNegativeImp(
3328 value,
3330 bsl::numeric_limits<t_INTEGRAL>::is_signed>());
3331}
3332
3333// CREATORS
3334inline
3336: d_elements()
3337{
3338}
3339
3340inline
3342: d_elements(basicAllocator)
3343{
3344}
3345
3346inline
3348 bslma::Allocator *basicAllocator)
3349: d_elements(original.d_elements, basicAllocator)
3350{
3351}
3352
3353inline
3360
3361inline
3363 bslma::Allocator *basicAllocator)
3364: d_elements(basicAllocator)
3365{
3366 JsonArray& originalAsLvalue = bslmf::MovableRefUtil::access(original);
3367
3368 if (basicAllocator == originalAsLvalue.allocator()) {
3369 d_elements = bslmf::MovableRefUtil::move(originalAsLvalue.d_elements);
3370 }
3371 else {
3372 d_elements = originalAsLvalue.d_elements;
3373 }
3374}
3375
3376template <class t_INPUT_ITERATOR>
3377inline
3378JsonArray::JsonArray(t_INPUT_ITERATOR first,
3379 t_INPUT_ITERATOR last,
3380 bslma::Allocator *basicAllocator)
3381: d_elements(first, last, basicAllocator)
3382{
3383}
3384
3385#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
3386inline
3387JsonArray::JsonArray(std::initializer_list<Json_Initializer> elements,
3388 bslma::Allocator *basicAllocator)
3389: d_elements(elements.begin(), elements.end(), basicAllocator)
3390{
3391}
3392
3393#endif
3394
3395// MANIPULATORS
3396inline
3398{
3399 d_elements = rhs.d_elements;
3400 return *this;
3401}
3402
3403inline
3405{
3406 d_elements = bslmf::MovableRefUtil::move(
3407 bslmf::MovableRefUtil::access(rhs).d_elements);
3408 return *this;
3409}
3410
3411#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
3412inline
3413JsonArray& JsonArray::operator=(std::initializer_list<Json_Initializer>
3414 elements)
3415{
3416 assign(elements);
3417 return *this;
3418}
3419#endif
3420
3421inline
3422Json& JsonArray::operator[](bsl::size_t index)
3423{
3424 BSLS_ASSERT(index < d_elements.size());
3425 return d_elements[index];
3426}
3427
3428template <class t_INPUT_ITERATOR>
3429inline
3430JsonArray& JsonArray::assign(t_INPUT_ITERATOR first, t_INPUT_ITERATOR last)
3431{
3432 d_elements.assign(first, last);
3433 return *this;
3434}
3435
3436#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
3437inline
3438JsonArray& JsonArray::assign(std::initializer_list<Json_Initializer> elements)
3439{
3440 d_elements.assign(elements.begin(), elements.end());
3441 return *this;
3442}
3443#endif
3444
3445inline
3447{
3448 return d_elements.back();
3449}
3450
3451inline
3453{
3454 return d_elements.begin();
3455}
3456
3457inline
3459{
3460 d_elements.clear();
3461}
3462
3463inline
3465{
3466 return d_elements.end();
3467}
3468
3469inline
3471{
3472 return d_elements.erase(d_elements.begin() + index);
3473}
3474
3475inline
3477{
3478 return d_elements.erase(position);
3479}
3480
3481inline
3483{
3484 return d_elements.erase(first, last);
3485}
3486
3487inline
3489{
3490 return d_elements.front();
3491}
3492
3493template <class t_INDEX>
3494inline
3497 JsonArray::Iterator>::type
3498JsonArray::insert(t_INDEX index, const Json& json)
3499{
3500 BSLS_ASSERT(isNonNegative(index));
3501
3502 return d_elements.insert(d_elements.begin() + index, json);
3503}
3504
3505template <class t_INDEX>
3506inline
3509 JsonArray::Iterator>::type
3511{
3512 BSLS_ASSERT(isNonNegative(index));
3513
3514 return d_elements.insert(d_elements.begin() + index,
3516}
3517
3518template <class t_INDEX, class t_INPUT_ITERATOR>
3519inline
3522 JsonArray::Iterator>::type
3523JsonArray::insert(t_INDEX index,
3524 t_INPUT_ITERATOR first,
3525 t_INPUT_ITERATOR last)
3526{
3527 BSLS_ASSERT(isNonNegative(index));
3528
3529 return d_elements.insert(d_elements.begin() + index, first, last);
3530}
3531
3532inline
3534{
3535 return d_elements.insert(position, json);
3536}
3537
3538inline
3541{
3542 return d_elements.insert(position, bslmf::MovableRefUtil::move(json));
3543}
3544
3545template <class t_INPUT_ITERATOR>
3546inline
3548 t_INPUT_ITERATOR first,
3549 t_INPUT_ITERATOR last)
3550{
3551 return d_elements.insert(position, first, last);
3552}
3553
3554inline
3556{
3557 d_elements.pop_back();
3558}
3559
3560inline
3562{
3563 d_elements.push_back(json);
3564 return *this;
3565}
3566
3567inline
3569{
3570 d_elements.push_back(bslmf::MovableRefUtil::move(json));
3571 return *this;
3572}
3573
3574inline
3576{
3577 d_elements.emplace_back(array);
3578 return *this;
3579}
3580
3581inline
3583{
3584 d_elements.emplace_back(object);
3585 return *this;
3586}
3587
3588inline
3590{
3591 d_elements.emplace_back(number);
3592 return *this;
3593}
3594
3595inline
3597{
3598 d_elements.emplace_back(bslmf::MovableRefUtil::move(array));
3599 return *this;
3600}
3601
3602inline
3604{
3605 d_elements.emplace_back(bslmf::MovableRefUtil::move(object));
3606 return *this;
3607}
3608
3609inline
3611{
3612 d_elements.emplace_back(bslmf::MovableRefUtil::move(number));
3613 return *this;
3614}
3615
3616inline
3618{
3619 d_elements.emplace_back(value);
3620 return *this;
3621}
3622
3623inline
3625{
3626 d_elements.emplace_back(value);
3627 return *this;
3628}
3629
3630inline
3632{
3633 d_elements.emplace_back(value);
3634 return *this;
3635}
3636
3637inline
3638JsonArray& JsonArray::pushBack(unsigned int value)
3639{
3640 d_elements.emplace_back(value);
3641 return *this;
3642}
3643
3644inline
3646{
3647 d_elements.emplace_back(value);
3648 return *this;
3649}
3650
3651inline
3652JsonArray& JsonArray::pushBack(unsigned long value)
3653{
3654 d_elements.emplace_back(value);
3655 return *this;
3656}
3657
3658inline
3660{
3661 d_elements.emplace_back(value);
3662 return *this;
3663}
3664
3665inline
3666JsonArray& JsonArray::pushBack(unsigned long long value)
3667{
3668 d_elements.emplace_back(value);
3669 return *this;
3670}
3671
3672inline
3674{
3675 d_elements.emplace_back(value);
3676 return *this;
3677}
3678
3679inline
3681{
3682 d_elements.emplace_back(value);
3683 return *this;
3684}
3685
3686inline
3688{
3689 d_elements.emplace_back(value);
3690 return *this;
3691}
3692
3693inline
3694JsonArray& JsonArray::pushBack(const char *string)
3695{
3696 BSLS_ASSERT(string);
3697
3698 d_elements.emplace_back(string);
3699 return *this;
3700}
3701
3702inline
3704{
3705 d_elements.emplace_back(string);
3706 return *this;
3707}
3708
3709template <class t_STRING_TYPE>
3710inline
3711typename bsl::enable_if<bsl::is_same<t_STRING_TYPE,
3712 bsl::string>::value,
3713 JsonArray&>::type
3715{
3718
3719 d_elements.emplace_back(bslmf::MovableRefUtil::move(string));
3720 return *this;
3721}
3722
3723inline
3724void JsonArray::resize(bsl::size_t count)
3725{
3726 d_elements.resize(count);
3727}
3728
3729inline
3730void JsonArray::resize(bsl::size_t count, const Json& json)
3731{
3732 d_elements.resize(count, json);
3733}
3734
3735inline
3737{
3738 BSLS_ASSERT(allocator() == other.allocator());
3739 d_elements.swap(other.d_elements);
3740}
3741
3742// ACCESSORS
3743inline
3744const Json& JsonArray::operator[](bsl::size_t index) const
3745{
3746 BSLS_ASSERT(index < d_elements.size());
3747 return d_elements[index];
3748}
3749
3750inline
3752{
3753 return d_elements.get_allocator().mechanism();
3754}
3755
3756inline
3757const Json& JsonArray::back() const
3758{
3759 return d_elements.back();
3760}
3761
3762inline
3764{
3765 return d_elements.begin();
3766}
3767
3768inline
3770{
3771 return d_elements.begin();
3772}
3773
3774inline
3776{
3777 return d_elements.end();
3778}
3779
3780inline
3782{
3783 return d_elements.empty();
3784}
3785
3786inline
3788{
3789 return d_elements.end();
3790}
3791
3792inline
3794{
3795 return d_elements.front();
3796}
3797
3798inline
3800{
3801 return d_elements.max_size();
3802}
3803
3804inline
3805bsl::size_t JsonArray::size() const
3806{
3807 return d_elements.size();
3808}
3809
3810 // ----------------
3811 // class JsonObject
3812 // ----------------
3813
3814// CREATORS
3815inline
3817: d_members()
3818{
3819}
3820
3821inline
3823: d_members(basicAllocator)
3824{
3825}
3826
3827inline
3829 bslma::Allocator *basicAllocator)
3830: d_members(original.d_members, basicAllocator)
3831{
3832}
3833
3834inline
3841
3842inline
3844 bslma::Allocator *basicAllocator)
3845: d_members(basicAllocator)
3846{
3847 JsonObject& originalAsLvalue = bslmf::MovableRefUtil::access(original);
3848
3849 if (basicAllocator == originalAsLvalue.allocator()) {
3850 d_members = bslmf::MovableRefUtil::move(originalAsLvalue.d_members);
3851 }
3852 else {
3853 d_members = originalAsLvalue.d_members;
3854 }
3855}
3856
3857template <class t_INPUT_ITERATOR>
3858inline
3859JsonObject::JsonObject(t_INPUT_ITERATOR first,
3860 t_INPUT_ITERATOR last,
3861 bslma::Allocator *basicAllocator)
3862: d_members(first, last, basicAllocator)
3863{
3864#ifdef BSLS_ASSERT_IS_ACTIVE
3865 for (Container::const_iterator itr = d_members.begin(),
3866 end = d_members.end();
3867 end != itr; ++itr) {
3869 }
3870#endif
3871}
3872
3873#ifdef BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
3874inline
3876 std::initializer_list<JsonObject_MemberInitializer>
3877 memberInitializers,
3878 bslma::Allocator *basicAllocator)
3879: d_members(basicAllocator)
3880{
3881 d_members.reserve(memberInitializers.size());
3882
3883 for (const JsonObject_MemberInitializer& memberInitializer :
3884 memberInitializers) {
3885 BSLS_ASSERT(bdlde::Utf8Util::isValid(memberInitializer.key()));
3886
3887 d_members.emplace(memberInitializer.key(),
3888 memberInitializer.value());
3889 }
3890}
3891#endif // BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
3892
3893// MANIPULATORS
3894inline
3896{
3897 d_members = rhs.d_members;
3898 return *this;
3899}
3900
3901inline
3903{
3904 // Implementation Note: We test allocators here per {DRQS 143521386<GO>}.
3905
3906 Container& rhsMembers = bslmf::MovableRefUtil::access(rhs).d_members;
3907 if (d_members.get_allocator() == rhsMembers.get_allocator()) {
3908 d_members = bslmf::MovableRefUtil::move(rhsMembers);
3909 }
3910 else {
3911 d_members = rhsMembers;
3912 }
3913 return *this;
3914}
3915
3916#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
3917inline
3919 std::initializer_list<JsonObject_MemberInitializer> memberInitializers)
3920{
3921 Container newContainer(d_members.get_allocator());
3922 newContainer.reserve(memberInitializers.size());
3923
3924 for (const JsonObject_MemberInitializer& memberInitializer :
3925 memberInitializers) {
3926 BSLS_ASSERT(bdlde::Utf8Util::isValid(memberInitializer.key()));
3927
3928 newContainer.emplace(memberInitializer.key(),
3929 memberInitializer.value());
3930 }
3931 d_members = bslmf::MovableRefUtil::move(newContainer);
3932 return *this;
3933}
3934#endif
3935
3936inline
3938{
3940
3941 return d_members[key];
3942}
3943
3944inline
3949
3950inline
3952{
3953 d_members.clear();
3954}
3955
3956inline
3958{
3959 return d_members.end();
3960}
3961
3962inline
3964{
3965 Iterator it = d_members.find(key);
3966 if (it == d_members.end()) {
3967 return 0; // RETURN
3968 }
3969 d_members.erase(it);
3970 return 1;
3971}
3972
3973inline
3975{
3976 return d_members.erase(position);
3977}
3978
3979inline
3981{
3982 return d_members.erase(position);
3983}
3984
3985inline
3987{
3988 return d_members.find(key);
3989}
3990
3991inline
3993{
3994 return d_members.insert(member);
3995}
3996
3997inline
4000{
4001#ifdef BSLS_ASSERT_IS_ACTIVE
4002 const bsl::string& key = bslmf::MovableRefUtil::access(member).first;
4004#endif
4005 return d_members.insert(bslmf::MovableRefUtil::move(member));
4006}
4007
4008template <class t_INPUT_ITERATOR>
4009inline
4010typename bsl::enable_if<
4012 JsonObject&>::type
4013JsonObject::insert(t_INPUT_ITERATOR first, t_INPUT_ITERATOR last)
4014{
4015#ifdef BSLS_ASSERT_IS_ACTIVE
4016 for (Container::const_iterator itr = d_members.begin(),
4017 end = d_members.end();
4018 end != itr; ++itr) {
4020 }
4021#endif
4022 d_members.insert(first, last);
4023 return *this;
4024}
4025
4026#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
4027inline
4028JsonObject& JsonObject::insert(std::initializer_list<
4029 JsonObject_MemberInitializer>
4030 memberInitializers)
4031{
4032 for (const JsonObject_MemberInitializer& memberInitializer :
4033 memberInitializers) {
4034 BSLS_ASSERT(bdlde::Utf8Util::isValid(memberInitializer.key()));
4035
4036 d_members.emplace(memberInitializer.key(), memberInitializer.value());
4037 }
4038 return *this;
4039}
4040#endif
4041
4042template <class t_VALUE>
4044 const bsl::string_view& key,
4045 BSLS_COMPILERFEATURES_FORWARD_REF(t_VALUE) value)
4046{
4048
4049 return d_members.emplace(key,
4050 BSLS_COMPILERFEATURES_FORWARD(t_VALUE, value));
4051}
4052
4053inline
4055{
4056 BSLS_ASSERT(allocator() == other.allocator());
4057 d_members.swap(other.d_members);
4058}
4059
4060// ACCESSORS
4061inline
4063{
4064 ConstIterator it = d_members.find(key);
4065 BSLS_ASSERT(it != d_members.end());
4066 return it->second;
4067}
4068
4069inline
4071{
4072 return d_members.get_allocator().mechanism();
4073}
4074
4075inline
4077{
4078 return d_members.begin();
4079}
4080
4081inline
4086
4087inline
4089{
4090 return d_members.cend();
4091}
4092
4093inline
4095{
4096 return d_members.find(key) != d_members.end();
4097}
4098
4099inline
4101{
4102 return d_members.empty();
4103}
4104
4105inline
4107{
4108 return d_members.end();
4109}
4110
4111inline
4113{
4114 return d_members.find(key);
4115}
4116
4117inline
4119{
4120 return d_members.size();
4121}
4122 // ----------
4123 // class Json
4124 // ----------
4125
4126// CREATORS
4127inline
4129: d_value(JsonNull())
4130{
4131}
4132
4133inline
4135: d_value(JsonNull(), basicAllocator)
4136{
4137}
4138
4139inline
4140Json::Json(const Json& original, bslma::Allocator *basicAllocator)
4141: d_value(original.d_value, basicAllocator)
4142{
4143}
4144
4145inline
4147: d_value(bslmf::MovableRefUtil::move(
4148 bslmf::MovableRefUtil::access(original).d_value))
4149{
4150}
4151
4152inline
4154: d_value(bslmf::MovableRefUtil::move(
4155 bslmf::MovableRefUtil::access(original).d_value),
4156 basicAllocator)
4157{
4158}
4159
4160inline
4161Json::Json(bool boolean, bslma::Allocator *basicAllocator)
4162: d_value(boolean, basicAllocator)
4163{
4164}
4165
4166inline
4167Json::Json(const JsonNull& null, bslma::Allocator *basicAllocator)
4168: d_value(null, basicAllocator)
4169{
4170}
4171
4172inline
4173Json::Json(const JsonArray& array, bslma::Allocator *basicAllocator)
4174: d_value(array, basicAllocator)
4175{
4176}
4177
4178inline
4179Json::Json(const JsonObject& object, bslma::Allocator *basicAllocator)
4180: d_value(object, basicAllocator)
4181{
4182}
4183
4184inline
4185Json::Json(const JsonNumber& number, bslma::Allocator *basicAllocator)
4186: d_value(number, basicAllocator)
4187{
4188}
4189
4190inline
4192 bslma::Allocator *basicAllocator)
4193: d_value(bslmf::MovableRefUtil::move(array), basicAllocator)
4194{
4195}
4196
4197inline
4199 bslma::Allocator *basicAllocator)
4200: d_value(bslmf::MovableRefUtil::move(object), basicAllocator)
4201{
4202}
4203
4204inline
4206 bslma::Allocator *basicAllocator)
4207: d_value(bslmf::MovableRefUtil::move(number), basicAllocator)
4208{
4209}
4210
4211#ifdef BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
4212template <class t_JSON_INITIALIZER>
4213Json::Json(const t_JSON_INITIALIZER& initializer,
4214 bslma::Allocator *basicAllocator,
4215 typename bsl::enable_if<
4216 bsl::is_same<t_JSON_INITIALIZER,
4217 Json_Initializer>::value>::type *)
4218: d_value(JsonNull(), basicAllocator)
4219{
4220 initializer.get_storage().apply(Json_ConstructVisitor(this));
4221}
4222#endif
4223
4224inline
4225Json::Json(int value, bslma::Allocator *basicAllocator)
4226: d_value(JsonNumber(value), basicAllocator)
4227{
4228}
4229
4230inline
4231Json::Json(unsigned int value, bslma::Allocator *basicAllocator)
4232: d_value(JsonNumber(value), basicAllocator)
4233{
4234}
4235
4236inline
4237Json::Json(long value, bslma::Allocator *basicAllocator)
4238: d_value(JsonNumber(value), basicAllocator)
4239{
4240}
4241
4242inline
4243Json::Json(unsigned long value, bslma::Allocator *basicAllocator)
4244: d_value(JsonNumber(value), basicAllocator)
4245{
4246}
4247
4248inline
4250: d_value(JsonNumber(value), basicAllocator)
4251{
4252}
4253
4254inline
4256: d_value(JsonNumber(value), basicAllocator)
4257{
4258}
4259
4260inline
4261Json::Json(float value, bslma::Allocator *basicAllocator)
4262: d_value(JsonNumber(value), basicAllocator)
4263{
4264}
4265
4266inline
4267Json::Json(double value, bslma::Allocator *basicAllocator)
4268: d_value(JsonNumber(value), basicAllocator)
4269{
4270}
4271
4272inline
4274: d_value(JsonNumber(value), basicAllocator)
4275{
4276}
4277
4278inline
4279Json::Json(const char *string, bslma::Allocator *basicAllocator)
4280: d_value(basicAllocator)
4281{
4283 d_value.createInPlace<bsl::string>(string);
4284}
4285
4286inline
4287Json::Json(const bsl::string_view& string, bslma::Allocator *basicAllocator)
4288: d_value(basicAllocator)
4289{
4291 d_value.createInPlace<bsl::string>(string);
4292}
4293
4294template <class t_STRING_TYPE>
4295inline
4297 bslma::Allocator *basicAllocator,
4298 typename bsl::enable_if<
4300: d_value(bslmf::MovableRefUtil::move(string), basicAllocator)
4301{
4304}
4305
4306// MANIPULATORS
4307inline
4309{
4310 d_value = rhs.d_value;
4311 return *this;
4312}
4313
4314inline
4316{
4317 Json& rhsRef = bslmf::MovableRefUtil::access(rhs);
4318 d_value = bslmf::MovableRefUtil::move(rhsRef.d_value);
4319 return *this;
4320}
4321
4322inline
4324{
4325 d_value.createInPlace<JsonNumber>(rhs);
4326 return *this;
4327}
4328
4329inline
4331{
4332 d_value.createInPlace<JsonNumber>(rhs);
4333 return *this;
4334}
4335
4336inline
4338{
4339 d_value.createInPlace<JsonNumber>(rhs);
4340 return *this;
4341}
4342
4343inline
4345{
4346 d_value.createInPlace<JsonNumber>(rhs);
4347 return *this;
4348}
4349
4350inline
4351Json& Json::operator=(unsigned int rhs)
4352{
4353 d_value.createInPlace<JsonNumber>(rhs);
4354 return *this;
4355}
4356
4357inline
4359{
4360 d_value.createInPlace<JsonNumber>(rhs);
4361 return *this;
4362}
4363
4364inline
4365Json& Json::operator=(unsigned long rhs)
4366{
4367 d_value.createInPlace<JsonNumber>(rhs);
4368 return *this;
4369}
4370
4371inline
4372Json& Json::operator=(long long rhs)
4373{
4374 d_value.createInPlace<JsonNumber>(rhs);
4375 return *this;
4376}
4377
4378inline
4379Json& Json::operator=(unsigned long long rhs)
4380{
4381 d_value.createInPlace<JsonNumber>(rhs);
4382 return *this;
4383}
4384
4385inline
4387{
4388 d_value.createInPlace<JsonNumber>(rhs);
4389 return *this;
4390}
4391
4392inline
4394{
4395 d_value = bslmf::MovableRefUtil::move(rhs);
4396 return *this;
4397}
4398
4399inline
4400Json& Json::operator=(const char *rhs)
4401{
4402 makeString(rhs);
4403 return *this;
4404}
4405
4406inline
4408{
4409 makeString(rhs);
4410 return *this;
4411}
4412
4413template <class t_STRING_TYPE>
4415 Json>::type&
4417{
4419 return *this;
4420}
4421
4422inline
4424{
4425 makeBoolean(rhs);
4426 return *this;
4427}
4428
4429inline
4431{
4432 makeObject(rhs);
4433 return *this;
4434}
4435
4436inline
4442
4443inline
4445{
4446 makeArray(rhs);
4447 return *this;
4448}
4449
4450inline
4456
4457inline
4459{
4460 makeNull();
4461 return *this;
4462}
4463
4464inline
4466{
4467 makeNull();
4468 return *this;
4469}
4470
4471inline
4473{
4474 return d_value.createInPlace<JsonArray>();
4475}
4476
4477inline
4479{
4480 d_value = array;
4481 return d_value.the<JsonArray>();
4482}
4483
4484inline
4486{
4487 d_value = bslmf::MovableRefUtil::move(array);
4488 return d_value.the<JsonArray>();
4489}
4490
4491inline
4493{
4494 return d_value.createInPlace<bool>();
4495}
4496
4497inline
4498bool& Json::makeBoolean(bool boolean)
4499{
4500 d_value = boolean;
4501 return d_value.the<bool>();
4502}
4503
4504inline
4506{
4507 d_value.createInPlace<JsonNull>();
4508}
4509
4510inline
4512{
4513 return d_value.createInPlace<JsonNumber>();
4514}
4515
4516inline
4518{
4519 d_value = number;
4520 return d_value.the<JsonNumber>();
4521}
4522
4523inline
4525{
4526 d_value = bslmf::MovableRefUtil::move(number);
4527 return d_value.the<JsonNumber>();
4528}
4529
4530inline
4532{
4533 return d_value.createInPlace<JsonObject>();
4534}
4535
4536inline
4538{
4539 d_value = object;
4540 return d_value.the<JsonObject>();
4541}
4542
4543inline
4545{
4546 d_value = bslmf::MovableRefUtil::move(object);
4547 return d_value.the<JsonObject>();
4548}
4549
4550inline
4551void Json::makeString(const char *string)
4552{
4554 d_value.createInPlace<bsl::string>(string);
4555}
4556
4557inline
4559{
4560 BSLS_ASSERT(bdlde::Utf8Util::isValid(string.data(), string.size()));
4561 d_value.createInPlace<bsl::string>(string);
4562}
4563
4564template <class t_STRING_TYPE>
4565inline
4573
4574 // `JsonObject::insert` methods
4575
4576inline
4578 const JsonObject::Member& member)
4579{
4580 BSLS_ASSERT(isObject() || isNull());
4581 if (isNull()) {
4582 makeObject();
4583 }
4584 return theObject().insert(member);
4585}
4586
4587inline
4598
4599template <class t_INPUT_ITERATOR>
4600inline
4601typename bsl::enable_if<!bsl::is_convertible<t_INPUT_ITERATOR,
4602 bsl::string_view>::value,
4603 Json&>::type
4604Json::insert(t_INPUT_ITERATOR first, t_INPUT_ITERATOR last)
4605{
4606 BSLS_ASSERT(isObject() || isNull());
4607 if (isNull()) {
4608 makeObject();
4609 }
4610 theObject().insert(first, last);
4611 return *this;
4612}
4613
4614#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
4615inline
4616Json& Json::insert(std::initializer_list<JsonObject_MemberInitializer>
4617 memberInitializers)
4618{
4619 BSLS_ASSERT(isObject() || isNull());
4620 if (isNull()) {
4621 makeObject();
4622 }
4623 theObject().insert(memberInitializers);
4624 return *this;
4625}
4626#endif
4627
4628template <class t_VALUE, class t_STRING_VIEW>
4629inline
4631 && bsl::is_convertible<t_STRING_VIEW,
4632 bsl::string_view>::value,
4634Json::insert(const t_STRING_VIEW& key,
4635 BSLS_COMPILERFEATURES_FORWARD_REF(t_VALUE) value)
4636{
4637 BSLS_ASSERT(isObject() || isNull());
4638 if (isNull()) {
4639 makeObject();
4640 }
4641 return theObject().insert(key,
4642 BSLS_COMPILERFEATURES_FORWARD(t_VALUE, value));
4643}
4644
4645 // `JsonArray::insert` methods
4646
4647template <class t_INDEX>
4648inline
4651 JsonArray::Iterator>::type
4652Json::insert(t_INDEX index, const Json& json)
4653{
4654 BSLS_ASSERT(isArray() || isNull());
4655
4656 if (isNull()) {
4657 makeArray();
4658 }
4659 return theArray().insert(index, json);
4660}
4661
4662template <class t_INDEX>
4663inline
4666 JsonArray::Iterator>::type
4668{
4669 BSLS_ASSERT(isArray() || isNull());
4670
4671 if (isNull()) {
4672 makeArray();
4673 }
4674 return theArray().insert(index, bslmf::MovableRefUtil::move(json));
4675}
4676
4677template <class t_INDEX, class t_INPUT_ITERATOR>
4678inline
4681 JsonArray::Iterator>::type
4682Json::insert(t_INDEX index,
4683 t_INPUT_ITERATOR first,
4684 t_INPUT_ITERATOR last)
4685{
4686 BSLS_ASSERT(isArray() || isNull());
4687
4688 if (isNull()) {
4689 makeArray();
4690 }
4691 return theArray().insert(index, first, last);
4692}
4693
4694inline
4696 const Json& json)
4697{
4699 return theArray().insert(position, json);
4700}
4701
4702inline
4709
4710template <class t_INPUT_ITERATOR>
4711inline
4713 t_INPUT_ITERATOR first,
4714 t_INPUT_ITERATOR last)
4715{
4717 return theArray().insert(position, first, last);
4718}
4719
4720 // `JsonArray::pushBack` methods
4721
4722inline
4724{
4725 BSLS_ASSERT(isArray() || isNull());
4726 if (isNull()) {
4727 makeArray();
4728 }
4729 theArray().pushBack(json);
4730 return *this;
4731}
4732
4733inline
4735{
4736 BSLS_ASSERT(isArray() || isNull());
4737 if (isNull()) {
4738 makeArray();
4739 }
4740 theArray().pushBack(array);
4741 return *this;
4742}
4743
4744inline
4746{
4747 BSLS_ASSERT(isArray() || isNull());
4748 if (isNull()) {
4749 makeArray();
4750 }
4751 theArray().pushBack(object);
4752 return *this;
4753}
4754
4755inline
4757{
4758 BSLS_ASSERT(isArray() || isNull());
4759 if (isNull()) {
4760 makeArray();
4761 }
4762 theArray().pushBack(number);
4763 return *this;
4764}
4765
4766inline
4768{
4769 BSLS_ASSERT(isArray() || isNull());
4770 if (isNull()) {
4771 makeArray();
4772 }
4774 return *this;
4775}
4776
4777inline
4779{
4780 BSLS_ASSERT(isArray() || isNull());
4781 if (isNull()) {
4782 makeArray();
4783 }
4785 return *this;
4786}
4787
4788inline
4790{
4791 BSLS_ASSERT(isArray() || isNull());
4792 if (isNull()) {
4793 makeArray();
4794 }
4796 return *this;
4797}
4798
4799inline
4801{
4802 BSLS_ASSERT(isArray() || isNull());
4803 if (isNull()) {
4804 makeArray();
4805 }
4807 return *this;
4808}
4809
4810inline
4812{
4813 BSLS_ASSERT(isArray() || isNull());
4814 if (isNull()) {
4815 makeArray();
4816 }
4817 theArray().pushBack(value);
4818 return *this;
4819}
4820
4821inline
4823{
4824 BSLS_ASSERT(isArray() || isNull());
4825 if (isNull()) {
4826 makeArray();
4827 }
4828 theArray().pushBack(value);
4829 return *this;
4830}
4831
4832inline
4834{
4835 BSLS_ASSERT(isArray() || isNull());
4836 if (isNull()) {
4837 makeArray();
4838 }
4839 theArray().pushBack(value);
4840 return *this;
4841}
4842
4843inline
4844Json& Json::pushBack(unsigned int value)
4845{
4846 BSLS_ASSERT(isArray() || isNull());
4847 if (isNull()) {
4848 makeArray();
4849 }
4850 theArray().pushBack(value);
4851 return *this;
4852}
4853
4854inline
4856{
4857 BSLS_ASSERT(isArray() || isNull());
4858 if (isNull()) {
4859 makeArray();
4860 }
4861 theArray().pushBack(value);
4862 return *this;
4863}
4864
4865inline
4866Json& Json::pushBack(unsigned long value)
4867{
4868 BSLS_ASSERT(isArray() || isNull());
4869 if (isNull()) {
4870 makeArray();
4871 }
4872 theArray().pushBack(value);
4873 return *this;
4874}
4875
4876inline
4877Json& Json::pushBack(long long value)
4878{
4879 BSLS_ASSERT(isArray() || isNull());
4880 if (isNull()) {
4881 makeArray();
4882 }
4883 theArray().pushBack(value);
4884 return *this;
4885}
4886
4887inline
4888Json& Json::pushBack(unsigned long long value)
4889{
4890 BSLS_ASSERT(isArray() || isNull());
4891 if (isNull()) {
4892 makeArray();
4893 }
4894 theArray().pushBack(value);
4895 return *this;
4896}
4897
4898inline
4900{
4901 BSLS_ASSERT(isArray() || isNull());
4902 if (isNull()) {
4903 makeArray();
4904 }
4905 theArray().pushBack(value);
4906 return *this;
4907}
4908
4909inline
4910Json& Json::pushBack(double value)
4911{
4912 BSLS_ASSERT(isArray() || isNull());
4913 if (isNull()) {
4914 makeArray();
4915 }
4916 theArray().pushBack(value);
4917 return *this;
4918}
4919
4920inline
4922{
4923 BSLS_ASSERT(isArray() || isNull());
4924 if (isNull()) {
4925 makeArray();
4926 }
4927 theArray().pushBack(value);
4928 return *this;
4929}
4930
4931inline
4932Json& Json::pushBack(const char *string)
4933{
4934 BSLS_ASSERT(string);
4935 BSLS_ASSERT(isArray() || isNull());
4936 if (isNull()) {
4937 makeArray();
4938 }
4939 theArray().pushBack(string);
4940 return *this;
4941}
4942
4943inline
4945{
4946 BSLS_ASSERT(isArray() || isNull());
4947 if (isNull()) {
4948 makeArray();
4949 }
4950 theArray().pushBack(string);
4951 return *this;
4952}
4953
4954template <class t_STRING_TYPE>
4955inline
4956typename bsl::enable_if<bsl::is_same<t_STRING_TYPE,
4957 bsl::string>::value,
4958 Json&>::type
4960{
4961 BSLS_ASSERT(isArray() || isNull());
4962 if (isNull()) {
4963 makeArray();
4964 }
4966 return *this;
4967}
4968
4969template <class RETURN_TYPE, class VISITOR>
4971{
4972 typedef Json_VisitUtil Util;
4973
4974 switch (type()) {
4975 case JsonType::e_OBJECT : {
4976 return Util::invokeVisitor<RETURN_TYPE>(visitor, &theObject());
4977 // RETURN
4978 } break;
4979 case JsonType::e_ARRAY : {
4980 return Util::invokeVisitor<RETURN_TYPE>(visitor, &theArray());
4981 // RETURN
4982 } break;
4983 case JsonType::e_STRING : {
4984#ifdef BSLS_ASSERT_IS_ACTIVE
4985 Json_StringInvariantGuard guard(&d_value.the<bsl::string>());
4986#endif
4987 return Util::invokeVisitor<RETURN_TYPE>(visitor,
4988 &d_value.the<bsl::string>());
4989 // RETURN
4990 } break;
4991 case JsonType::e_NUMBER : {
4992 return Util::invokeVisitor<RETURN_TYPE>(visitor, &theNumber());
4993 // RETURN
4994 } break;
4995 case JsonType::e_BOOLEAN: {
4996 return Util::invokeVisitor<RETURN_TYPE>(visitor, &theBoolean());
4997 // RETURN
4998 } break;
4999 case JsonType::e_NULL : {
5000 return Util::invokeVisitor<RETURN_TYPE>(visitor, &theNull());
5001 // RETURN
5002 } break;
5003 default: {
5004 BSLS_ASSERT_OPT(false && "reachable");
5005 } break;
5006 }
5008}
5009
5010#ifdef BSLS_LIBRARYFEATURES_HAS_CPP14_BASELINE_LIBRARY
5011template <class VISITOR>
5012decltype(auto) Json::visit(BSLS_COMPILERFEATURES_FORWARD_REF(VISITOR) visitor)
5013{
5014 using Util = Json_VisitUtil;
5015
5016 switch (type()) {
5017 case JsonType::e_OBJECT : {
5018 return Util::invokeVisitor(visitor, &theObject()); // RETURN
5019 } break;
5020 case JsonType::e_ARRAY : {
5021 return Util::invokeVisitor(visitor, &theArray()); // RETURN
5022 } break;
5023 case JsonType::e_STRING : {
5024#ifdef BSLS_ASSERT_IS_ACTIVE
5025 Json_StringInvariantGuard guard(&d_value.the<bsl::string>());
5026#endif
5027 return Util::invokeVisitor(visitor, &d_value.the<bsl::string>());
5028 // RETURN
5029 } break;
5030 case JsonType::e_NUMBER : {
5031 return Util::invokeVisitor(visitor, &theNumber()); // RETURN
5032 } break;
5033 case JsonType::e_BOOLEAN: {
5034 return Util::invokeVisitor(visitor, &theBoolean()); // RETURN
5035 } break;
5036 case JsonType::e_NULL : {
5037 return Util::invokeVisitor(visitor, &theNull()); // RETURN
5038 } break;
5039 default: {
5040 BSLS_ASSERT_OPT_UNREACHABLE("Invalid Json type in `visit()`");
5041 } break;
5042 }
5044}
5045#endif
5046
5047 // Aspects
5048
5049inline
5050void Json::swap(Json& other)
5051{
5052 BSLS_ASSERT(allocator() == other.allocator());
5053 d_value.swap(other.d_value);
5054}
5055
5056// ACCESSORS
5057inline
5058bool Json::isArray() const
5059{
5060 return type() == JsonType::e_ARRAY;
5061}
5062
5063inline
5065{
5066 return type() == JsonType::e_BOOLEAN;
5067}
5068
5069inline
5070bool Json::isNull() const
5071{
5072 return type() == JsonType::e_NULL;
5073}
5074
5075inline
5076bool Json::isNumber() const
5077{
5078 return type() == JsonType::e_NUMBER;
5079}
5080
5081inline
5082bool Json::isObject() const
5083{
5084 return type() == JsonType::e_OBJECT;
5085}
5086
5087inline
5088bool Json::isString() const
5089{
5090 return type() == JsonType::e_STRING;
5091}
5092
5093inline
5095{
5096 return d_value.the<JsonArray>();
5097}
5098
5099inline
5101{
5102 return d_value.the<bool>();
5103}
5104
5105inline
5107{
5108 return d_value.the<JsonNull>();
5109}
5110
5111inline
5113{
5114 return d_value.the<JsonNumber>();
5115}
5116
5117inline
5119{
5120 return d_value.the<JsonObject>();
5121}
5122
5123#if defined(BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT)
5124inline
5125Json::operator JsonArray &()
5126{
5127 return theArray();
5128}
5129
5130inline
5131Json::operator bool &()
5132{
5133 return theBoolean();
5134}
5135
5136inline
5137Json::operator JsonNull &()
5138{
5139 return theNull();
5140}
5141
5142inline
5143Json::operator JsonNumber &()
5144{
5145 return theNumber();
5146}
5147
5148inline
5149Json::operator JsonObject &()
5150{
5151 return theObject();
5152}
5153#endif
5154
5155inline
5157{
5158 BSLS_ASSERT(isObject() || isNull());
5159 if (isNull()) {
5160 makeObject();
5161 }
5162 return theObject()[key];
5163}
5164
5165inline
5166Json& Json::operator[](bsl::size_t index)
5167{
5168 BSLS_ASSERT(d_value.is<JsonArray>());
5169 return theArray()[index];
5170}
5171
5172// ACCESSORS
5173inline
5174bsl::size_t Json::size() const
5175{
5177 return isArray() ? theArray().size() : theObject().size();
5178}
5179
5180inline
5181bool Json::contains(const bsl::string_view& key) const
5182{
5184 return theObject().contains(key);
5185}
5186
5187// BDE_VERIFY pragma: -FABC01 // not in order
5188
5189inline
5191{
5193 return theNumber().asDecimal64();
5194}
5195
5196inline
5198{
5200 return theNumber().asDecimal64Exact(result);
5201}
5202
5203inline
5204double Json::asDouble() const
5205{
5207 return theNumber().asDouble();
5208}
5209
5210inline
5211float Json::asFloat() const
5212{
5214 return theNumber().asFloat();
5215}
5216
5217inline
5218int Json::asShort(short *result) const
5219{
5221 return theNumber().asShort(result);
5222}
5223
5224inline
5225int Json::asInt(int *result) const
5226{
5228 return theNumber().asInt(result);
5229}
5230
5231inline
5232int Json::asLong(long *result) const
5233{
5235 return theNumber().asLong(result);
5236}
5237
5238inline
5239int Json::asLonglong(long long *result) const
5240{
5242 return theNumber().asLonglong(result);
5243}
5244
5245inline
5247{
5249 return theNumber().asInt64(result);
5250}
5251
5252inline
5253int Json::asUshort(unsigned short *result) const
5254{
5256 return theNumber().asUshort(result);
5257}
5258
5259inline
5260int Json::asUint(unsigned int *result) const
5261{
5263 return theNumber().asUint(result);
5264}
5265
5266inline
5267int Json::asUlong(unsigned long *result) const
5268{
5270 return theNumber().asUlong(result);
5271}
5272
5273inline
5274int Json::asUlonglong(unsigned long long *result) const
5275{
5277 return theNumber().asUlonglong(result);
5278}
5279
5280inline
5282{
5284 return theNumber().asUint64(result);
5285}
5286
5287// BDE_VERIFY pragma: +FABC01 // not in order
5288
5289inline
5291{
5292 return d_value.the<JsonArray>();
5293}
5294
5295inline
5296const bool& Json::theBoolean() const
5297{
5298 return d_value.the<bool>();
5299}
5300
5301inline
5303{
5304 return d_value.the<JsonNull>();
5305}
5306
5307inline
5309{
5310 return d_value.the<JsonNumber>();
5311}
5312
5313inline
5315{
5316 return d_value.the<JsonObject>();
5317}
5318
5319inline
5321{
5322 return d_value.the<bsl::string>();
5323}
5324
5325inline
5327{
5328 return static_cast<JsonType::Enum>(d_value.typeIndex() - 1);
5329}
5330inline
5332{
5333 BSLS_ASSERT(d_value.is<JsonObject>());
5334 return theObject()[key];
5335}
5336
5337inline
5338const Json& Json::operator[](bsl::size_t index) const
5339{
5340 BSLS_ASSERT(d_value.is<JsonArray>());
5341 return theArray()[index];
5342}
5343
5344#if defined(BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT)
5345inline
5346Json::operator const JsonArray &() const
5347{
5348 return theArray();
5349}
5350
5351inline
5352Json::operator const bool &() const
5353{
5354 return theBoolean();
5355}
5356
5357inline
5358Json::operator const JsonNull &() const
5359{
5360 return theNull();
5361}
5362
5363inline
5364Json::operator const JsonNumber &() const
5365{
5366 return theNumber();
5367}
5368
5369inline
5370Json::operator const JsonObject &() const
5371{
5372 return theObject();
5373}
5374
5375inline
5376Json::operator const bsl::string &() const
5377{
5378 return theString();
5379}
5380#endif
5381
5382template <class RETURN_TYPE, class VISITOR>
5384 const
5385{
5386 typedef Json_VisitUtil Util;
5387
5388 switch (type()) {
5389 case JsonType::e_OBJECT : {
5390 return Util::invokeVisitor<RETURN_TYPE>(visitor, theObject());
5391 // RETURN
5392 } break;
5393 case JsonType::e_ARRAY : {
5394 return Util::invokeVisitor<RETURN_TYPE>(visitor, theArray());
5395 // RETURN
5396 } break;
5397 case JsonType::e_STRING : {
5398 return Util::invokeVisitor<RETURN_TYPE>(visitor, theString());
5399 // RETURN
5400 } break;
5401 case JsonType::e_NUMBER : {
5402 return Util::invokeVisitor<RETURN_TYPE>(visitor, theNumber());
5403 // RETURN
5404 } break;
5405 case JsonType::e_BOOLEAN: {
5406 return Util::invokeVisitor<RETURN_TYPE>(visitor, theBoolean());
5407 // RETURN
5408 } break;
5409 case JsonType::e_NULL : {
5410 return Util::invokeVisitor<RETURN_TYPE>(visitor, theNull()); // RETURN
5411 } break;
5412 default: {
5413 BSLS_ASSERT_OPT(false && "reachable");
5414 } break;
5415 }
5417}
5418
5419#ifdef BSLS_LIBRARYFEATURES_HAS_CPP14_BASELINE_LIBRARY
5420template <class VISITOR>
5421decltype(auto) Json::visit(BSLS_COMPILERFEATURES_FORWARD_REF(VISITOR) visitor)
5422 const
5423{
5424 using Util = Json_VisitUtil;
5425
5426 switch (type()) {
5427 case JsonType::e_OBJECT : {
5428 return Util::invokeVisitor(visitor, theObject()); // RETURN
5429 } break;
5430 case JsonType::e_ARRAY : {
5431 return Util::invokeVisitor(visitor, theArray()); // RETURN
5432 } break;
5433 case JsonType::e_STRING : {
5434 return Util::invokeVisitor(visitor, theString()); // RETURN
5435 } break;
5436 case JsonType::e_NUMBER : {
5437 return Util::invokeVisitor(visitor, theNumber()); // RETURN
5438 } break;
5439 case JsonType::e_BOOLEAN: {
5440 return Util::invokeVisitor(visitor, theBoolean()); // RETURN
5441 } break;
5442 case JsonType::e_NULL : {
5443 return Util::invokeVisitor(visitor, theNull()); // RETURN
5444 } break;
5445 default: {
5446 BSLS_ASSERT_OPT(false && "reachable");
5447 } break;
5448 }
5450}
5451#endif
5452 // Aspects
5453
5454inline
5456{
5457 return d_value.getAllocator();
5458}
5459
5460} // close package namespace
5461
5462// FREE OPERATORS
5463inline
5464bsl::ostream& bdljsn::operator<<(bsl::ostream& stream,
5465 const bdljsn::JsonArray& object)
5466{
5467 return object.print(stream, 0, -1);
5468}
5469
5470inline
5472 const bdljsn::JsonArray& rhs)
5473{
5474 return lhs.d_elements == rhs.d_elements;
5475}
5476
5477inline
5479 const bdljsn::JsonArray& rhs)
5480{
5481 return lhs.d_elements != rhs.d_elements;
5482}
5483
5484inline
5486{
5487 bslalg::SwapUtil::swap(&a.d_elements, &b.d_elements);
5488}
5489
5490inline
5491bsl::ostream& bdljsn::operator<<(bsl::ostream& stream,
5492 const bdljsn::JsonObject& object)
5493{
5494 return object.print(stream, 0, -1);
5495}
5496
5497inline
5499 const bdljsn::JsonObject& rhs)
5500{
5501 return lhs.d_members == rhs.d_members;
5502}
5503
5504inline
5506 const bdljsn::JsonObject& rhs)
5507{
5508 return lhs.d_members != rhs.d_members;
5509}
5510
5511inline
5513{
5514 if (a.allocator() == b.allocator()) {
5515 bslalg::SwapUtil::swap(&a.d_members, &b.d_members);
5516 }
5517 else {
5518 bslma::Allocator *const allocA = a.allocator();
5519 bslma::Allocator *const allocB = b.allocator();
5520 JsonObject ta(b, allocA);
5521 JsonObject tb(a, allocB);
5522 swap(a, ta);
5523 swap(b, tb);
5524 }
5525}
5526
5527inline
5528bsl::ostream& bdljsn::operator<<(bsl::ostream& stream,
5529 const bdljsn::Json& object)
5530{
5531 return object.print(stream, 0, -1);
5532}
5533
5534inline
5535bool bdljsn::operator==(const bdljsn::Json& lhs, const bdljsn::Json& rhs)
5536{
5537 return lhs.d_value == rhs.d_value;
5538}
5539
5540inline
5541bool bdljsn::operator!=(const bdljsn::Json& lhs, const bdljsn::Json& rhs)
5542{
5543 return lhs.d_value != rhs.d_value;
5544}
5545
5546inline
5547bool bdljsn::operator==(const JsonArray& lhs, const Json& rhs)
5548{
5549 return rhs.isArray() && rhs.theArray() == lhs;
5550}
5551
5552inline
5553bool bdljsn::operator==(const JsonObject& lhs, const Json& rhs)
5554{
5555 return rhs.isObject() && rhs.theObject() == lhs;
5556}
5557
5558inline
5559bool bdljsn::operator==(const JsonNumber& lhs, const Json& rhs)
5560{
5561 return rhs.isNumber() && rhs.theNumber() == lhs;
5562}
5563
5564inline
5565bool bdljsn::operator==(const JsonNull& , const Json& rhs)
5566{
5567 return rhs.isNull();
5568}
5569
5570inline
5571bool bdljsn::operator==(bool lhs, const Json& rhs)
5572{
5573 return rhs.isBoolean() && rhs.theBoolean() == lhs;
5574}
5575
5576inline
5577bool bdljsn::operator==(int lhs, const Json& rhs)
5578{
5579 return rhs.isNumber() && rhs.theNumber() == JsonNumber(lhs);
5580}
5581
5582inline
5583bool bdljsn::operator==(unsigned int lhs, const Json& rhs)
5584{
5585 return rhs.isNumber() && rhs.theNumber() == JsonNumber(lhs);
5586}
5587
5588inline
5589bool bdljsn::operator==(long lhs, const Json& rhs)
5590{
5591 return rhs.isNumber() && rhs.theNumber() == JsonNumber(lhs);
5592}
5593
5594inline
5595bool bdljsn::operator==(unsigned long lhs, const Json& rhs)
5596{
5597 return rhs.isNumber() && rhs.theNumber() == JsonNumber(lhs);
5598}
5599
5600inline
5601bool bdljsn::operator==(long long lhs, const Json& rhs)
5602{
5603 return rhs.isNumber() && rhs.theNumber() == JsonNumber(lhs);
5604}
5605
5606inline
5607bool bdljsn::operator==(unsigned long long lhs, const Json& rhs)
5608{
5609 return rhs.isNumber() && rhs.theNumber() == JsonNumber(lhs);
5610}
5611
5612inline
5613bool bdljsn::operator==(float lhs, const Json& rhs)
5614{
5615 return rhs.isNumber() && rhs.theNumber() == JsonNumber(lhs);
5616}
5617
5618inline
5619bool bdljsn::operator==(double lhs, const Json& rhs)
5620{
5621 return rhs.isNumber() && rhs.theNumber() == JsonNumber(lhs);
5622}
5623
5624inline
5625bool bdljsn::operator==(bdldfp::Decimal64 lhs, const Json& rhs)
5626{
5627 return rhs.isNumber() && rhs.theNumber() == JsonNumber(lhs);
5628}
5629
5630inline
5631bool bdljsn::operator==(const char *lhs, const Json& rhs)
5632{
5633 BSLS_ASSERT(lhs);
5634 return rhs.isString() && rhs.theString() == lhs;
5635}
5636
5637inline
5638bool bdljsn::operator==(const bsl::string_view& lhs, const Json& rhs)
5639{
5640 return rhs.isString() && rhs.theString() == lhs;
5641}
5642
5643inline
5644bool bdljsn::operator==(const Json& lhs, const JsonArray& rhs)
5645{
5646 return lhs.isArray() && lhs.theArray() == rhs;
5647}
5648
5649inline
5650bool bdljsn::operator==(const Json& lhs, const JsonObject& rhs)
5651{
5652 return lhs.isObject() && lhs.theObject() == rhs;
5653}
5654
5655inline
5656bool bdljsn::operator==(const Json& lhs, const JsonNumber& rhs)
5657{
5658 return lhs.isNumber() && lhs.theNumber() == rhs;
5659}
5660
5661inline
5662bool bdljsn::operator==(const Json& lhs, const JsonNull& )
5663{
5664 return lhs.isNull();
5665}
5666
5667inline
5668bool bdljsn::operator==(const Json& lhs, bool rhs)
5669{
5670 return lhs.isBoolean() && lhs.theBoolean() == rhs;
5671}
5672
5673inline
5674bool bdljsn::operator==(const Json& lhs, int rhs)
5675{
5676 return lhs.isNumber() && lhs.theNumber() == JsonNumber(rhs);
5677}
5678
5679inline
5680bool bdljsn::operator==(const Json& lhs, unsigned int rhs)
5681{
5682 return lhs.isNumber() && lhs.theNumber() == JsonNumber(rhs);
5683}
5684
5685inline
5686bool bdljsn::operator==(const Json& lhs, long rhs)
5687{
5688 return lhs.isNumber() && lhs.theNumber() == JsonNumber(rhs);
5689}
5690
5691inline
5692bool bdljsn::operator==(const Json& lhs, unsigned long rhs)
5693{
5694 return lhs.isNumber() && lhs.theNumber() == JsonNumber(rhs);
5695}
5696
5697inline
5698bool bdljsn::operator==(const Json& lhs, long long rhs)
5699{
5700 return lhs.isNumber() && lhs.theNumber() == JsonNumber(rhs);
5701}
5702
5703inline
5704bool bdljsn::operator==(const Json& lhs, unsigned long long rhs)
5705{
5706 return lhs.isNumber() && lhs.theNumber() == JsonNumber(rhs);
5707}
5708
5709inline
5710bool bdljsn::operator==(const Json& lhs, float rhs)
5711{
5712 return lhs.isNumber() && lhs.theNumber() == JsonNumber(rhs);
5713}
5714
5715inline
5716bool bdljsn::operator==(const Json& lhs, double rhs)
5717{
5718 return lhs.isNumber() && lhs.theNumber() == JsonNumber(rhs);
5719}
5720
5721inline
5722bool bdljsn::operator==(const Json& lhs, bdldfp::Decimal64 rhs)
5723{
5724 return lhs.isNumber() && lhs.theNumber() == JsonNumber(rhs);
5725}
5726
5727inline
5728bool bdljsn::operator==(const Json& lhs, const char *rhs)
5729{
5730 BSLS_ASSERT(rhs);
5731 return lhs.isString() && lhs.theString() == rhs;
5732}
5733
5734inline
5735bool bdljsn::operator==(const Json& lhs, const bsl::string_view& rhs)
5736{
5737 return lhs.isString() && lhs.theString() == rhs;
5738}
5739
5740inline
5741bool bdljsn::operator!=(const JsonArray& lhs, const Json& rhs)
5742{
5743 return !rhs.isArray() || rhs.theArray() != lhs;
5744}
5745
5746inline
5747bool bdljsn::operator!=(const JsonObject& lhs, const Json& rhs)
5748{
5749 return !rhs.isObject() || rhs.theObject() != lhs;
5750}
5751
5752inline
5753bool bdljsn::operator!=(const JsonNumber& lhs, const Json& rhs)
5754{
5755 return !rhs.isNumber() || rhs.theNumber() != lhs;
5756}
5757
5758inline
5759bool bdljsn::operator!=(const JsonNull& , const Json& rhs)
5760{
5761 return !rhs.isNull();
5762}
5763
5764inline
5765bool bdljsn::operator!=(bool lhs, const Json& rhs)
5766{
5767 return !rhs.isBoolean() || rhs.theBoolean() != lhs;
5768}
5769
5770inline
5771bool bdljsn::operator!=(int lhs, const Json& rhs)
5772{
5773 return !rhs.isNumber() || rhs.theNumber() != JsonNumber(lhs);
5774}
5775
5776inline
5777bool bdljsn::operator!=(unsigned int lhs, const Json& rhs)
5778{
5779 return !rhs.isNumber() || rhs.theNumber() != JsonNumber(lhs);
5780}
5781
5782inline
5783bool bdljsn::operator!=(long lhs, const Json& rhs)
5784{
5785 return !rhs.isNumber() || rhs.theNumber() != JsonNumber(lhs);
5786}
5787
5788inline
5789bool bdljsn::operator!=(unsigned long lhs, const Json& rhs)
5790{
5791 return !rhs.isNumber() || rhs.theNumber() != JsonNumber(lhs);
5792}
5793
5794inline
5795bool bdljsn::operator!=(long long lhs, const Json& rhs)
5796{
5797 return !rhs.isNumber() || rhs.theNumber() != JsonNumber(lhs);
5798}
5799
5800inline
5801bool bdljsn::operator!=(unsigned long long lhs, const Json& rhs)
5802{
5803 return !rhs.isNumber() || rhs.theNumber() != JsonNumber(lhs);
5804}
5805
5806inline
5807bool bdljsn::operator!=(float lhs, const Json& rhs)
5808{
5809 return !rhs.isNumber() || rhs.theNumber() != JsonNumber(lhs);
5810}
5811
5812inline
5813bool bdljsn::operator!=(double lhs, const Json& rhs)
5814{
5815 return !rhs.isNumber() || rhs.theNumber() != JsonNumber(lhs);
5816}
5817
5818inline
5819bool bdljsn::operator!=(bdldfp::Decimal64 lhs, const Json& rhs)
5820{
5821 return !rhs.isNumber() || rhs.theNumber() != JsonNumber(lhs);
5822}
5823
5824inline
5825bool bdljsn::operator!=(const char *lhs, const Json& rhs)
5826{
5827 BSLS_ASSERT(lhs);
5828 return !rhs.isString() || rhs.theString() != lhs;
5829}
5830
5831inline
5832bool bdljsn::operator!=(const bsl::string_view& lhs, const Json& rhs)
5833{
5834 return !rhs.isString() || rhs.theString() != lhs;
5835}
5836
5837inline
5838bool bdljsn::operator!=(const Json& lhs, const JsonArray& rhs)
5839{
5840 return !lhs.isArray() || lhs.theArray() != rhs;
5841}
5842
5843inline
5844bool bdljsn::operator!=(const Json& lhs, const JsonObject& rhs)
5845{
5846 return !lhs.isObject() || lhs.theObject() != rhs;
5847}
5848
5849inline
5850bool bdljsn::operator!=(const Json& lhs, const JsonNumber& rhs)
5851{
5852 return !lhs.isNumber() || lhs.theNumber() != rhs;
5853}
5854
5855inline
5856bool bdljsn::operator!=(const Json& lhs, const JsonNull& )
5857{
5858 return !lhs.isNull();
5859}
5860
5861inline
5862bool bdljsn::operator!=(const Json& lhs, bool rhs)
5863{
5864 return !lhs.isBoolean() || lhs.theBoolean() != rhs;
5865}
5866
5867inline
5868bool bdljsn::operator!=(const Json& lhs, int rhs)
5869{
5870 return !lhs.isNumber() || lhs.theNumber() != JsonNumber(rhs);
5871}
5872
5873inline
5874bool bdljsn::operator!=(const Json& lhs, unsigned int rhs)
5875{
5876 return !lhs.isNumber() || lhs.theNumber() != JsonNumber(rhs);
5877}
5878
5879inline
5880bool bdljsn::operator!=(const Json& lhs, long rhs)
5881{
5882 return !lhs.isNumber() || lhs.theNumber() != JsonNumber(rhs);
5883}
5884
5885inline
5886bool bdljsn::operator!=(const Json& lhs, unsigned long rhs)
5887{
5888 return !lhs.isNumber() || lhs.theNumber() != JsonNumber(rhs);
5889}
5890
5891inline
5892bool bdljsn::operator!=(const Json& lhs, long long rhs)
5893{
5894 return !lhs.isNumber() || lhs.theNumber() != JsonNumber(rhs);
5895}
5896
5897inline
5898bool bdljsn::operator!=(const Json& lhs, unsigned long long rhs)
5899{
5900 return !lhs.isNumber() || lhs.theNumber() != JsonNumber(rhs);
5901}
5902
5903inline
5904bool bdljsn::operator!=(const Json& lhs, float rhs)
5905{
5906 return !lhs.isNumber() || lhs.theNumber() != JsonNumber(rhs);
5907}
5908
5909inline
5910bool bdljsn::operator!=(const Json& lhs, double rhs)
5911{
5912 return !lhs.isNumber() || lhs.theNumber() != JsonNumber(rhs);
5913}
5914
5915inline
5916bool bdljsn::operator!=(const Json& lhs, bdldfp::Decimal64 rhs)
5917{
5918 return !lhs.isNumber() || lhs.theNumber() != JsonNumber(rhs);
5919}
5920
5921inline
5922bool bdljsn::operator!=(const Json& lhs, const char *rhs)
5923{
5924 BSLS_ASSERT(rhs);
5925 return !lhs.isString() || lhs.theString() != rhs;
5926}
5927
5928inline
5929bool bdljsn::operator!=(const Json& lhs, const bsl::string_view& rhs)
5930{
5931 return !lhs.isString() || lhs.theString() != rhs;
5932}
5933
5934inline
5936{
5937 bslalg::SwapUtil::swap(&a.d_value, &b.d_value);
5938}
5939
5940
5941
5942#endif // INCLUDED_BDLJSN_JSON
5943
5944// ----------------------------------------------------------------------------
5945// Copyright 2022 Bloomberg Finance L.P.
5946//
5947// Licensed under the Apache License, Version 2.0 (the "License");
5948// you may not use this file except in compliance with the License.
5949// You may obtain a copy of the License at
5950//
5951// http://www.apache.org/licenses/LICENSE-2.0
5952//
5953// Unless required by applicable law or agreed to in writing, software
5954// distributed under the License is distributed on an "AS IS" BASIS,
5955// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5956// See the License for the specific language governing permissions and
5957// limitations under the License.
5958// ----------------------------- END-OF-FILE ----------------------------------
5959
5960/** @} */
5961/** @} */
5962/** @} */
bool is() const
Definition bdlb_variant.h:7725
int typeIndex() const
Definition bdlb_variant.h:7766
bsl::enable_if< Variant_ReturnValueHelper< VISITOR >::value==1, typenameVISITOR::ResultType >::type apply(VISITOR &visitor)
Definition bdlb_variant.h:1544
TYPE & createInPlace(ARGS &&... arguments)
Definition bdlb_variant.h:7574
TYPE & the()
Definition bdlb_variant.h:7637
void swap(VariantImp &other)
Definition bdlb_variant.h:7602
bsl::ostream & print(bsl::ostream &stream, int level=0, int spacesPerLevel=4) const
Definition bdlb_variant.h:7739
Definition bdlb_variant.h:2389
Definition bdldfp_decimal.h:1890
Definition bdljsn_json.h:551
void resize(bsl::size_t count)
Definition bdljsn_json.h:3724
bsl::size_t size() const
Return the number of elements in this JsonArray.
Definition bdljsn_json.h:3805
JsonArray & pushBack(const Json &json)
Definition bdljsn_json.h:3561
friend bool operator==(const JsonArray &, const JsonArray &)
Json & back()
Definition bdljsn_json.h:3446
Elements::size_type size_type
Definition bdljsn_json.h:588
BSLMF_NESTED_TRAIT_DECLARATION(JsonArray, bslma::UsesBslmaAllocator)
Json & front()
Definition bdljsn_json.h:3488
Iterator end()
Definition bdljsn_json.h:3464
Elements::const_reference const_reference
Definition bdljsn_json.h:582
Elements::iterator iterator
Definition bdljsn_json.h:584
bslma::Allocator * allocator() const BSLS_KEYWORD_NOEXCEPT
Return the allocator used by this object to allocate memory.
Definition bdljsn_json.h:3751
BSLMF_NESTED_TRAIT_DECLARATION(JsonArray, bdlb::HasPrintMethod)
Iterator begin()
Definition bdljsn_json.h:3452
void popBack()
Definition bdljsn_json.h:3555
bool empty() const
Return true if this JsonArray has size 0, and false otherwise.
Definition bdljsn_json.h:3781
JsonArray & assign(t_INPUT_ITERATOR first, t_INPUT_ITERATOR last)
Definition bdljsn_json.h:3430
Iterator erase(bsl::size_t index)
Definition bdljsn_json.h:3470
Elements::iterator Iterator
Definition bdljsn_json.h:577
Elements::const_iterator ConstIterator
Definition bdljsn_json.h:578
void clear()
Definition bdljsn_json.h:3458
ConstIterator cend() const BSLS_KEYWORD_NOEXCEPT
Definition bdljsn_json.h:3775
Elements::value_type value_type
Definition bdljsn_json.h:580
BSLMF_NESTED_TRAIT_DECLARATION(JsonArray, bslmf::IsBitwiseMoveable)
friend bool operator!=(const JsonArray &, const JsonArray &)
Elements::difference_type difference_type
Definition bdljsn_json.h:587
JsonArray & operator=(const JsonArray &rhs)
Definition bdljsn_json.h:3397
friend void swap(JsonArray &, JsonArray &)
bsl::size_t maxSize() const BSLS_KEYWORD_NOEXCEPT
Definition bdljsn_json.h:3799
Json & operator[](bsl::size_t index)
Definition bdljsn_json.h:3422
JsonArray()
Definition bdljsn_json.h:3335
ConstIterator cbegin() const BSLS_KEYWORD_NOEXCEPT
Definition bdljsn_json.h:3769
Elements::const_iterator const_iterator
Definition bdljsn_json.h:585
bsl::enable_if< bsl::is_integral< t_INDEX >::value &&!bsl::is_same< t_INDEX, bool >::value, Iterator >::type insert(t_INDEX index, const Json &json)
Definition bdljsn_json.h:3498
Elements::reference reference
Definition bdljsn_json.h:581
Definition bdljsn_jsonnull.h:121
Definition bdljsn_jsonnumber.h:412
int asUshort(unsigned short *result) const
Definition bdljsn_jsonnumber.h:1051
int asUlong(unsigned long *result) const
Definition bdljsn_jsonnumber.h:1063
int asUlonglong(unsigned long long *result) const
Definition bdljsn_jsonnumber.h:1069
int asUint64(bsls::Types::Uint64 *result) const
Definition bdljsn_jsonnumber.h:1075
int asInt(int *result) const
Definition bdljsn_jsonnumber.h:1027
int asDecimal64Exact(bdldfp::Decimal64 *result) const
Definition bdljsn_jsonnumber.h:1101
float asFloat() const
Definition bdljsn_jsonnumber.h:1081
int asShort(short *result) const
Definition bdljsn_jsonnumber.h:1021
int asInt64(bsls::Types::Int64 *result) const
Definition bdljsn_jsonnumber.h:1045
int asLong(long *result) const
Definition bdljsn_jsonnumber.h:1033
bdldfp::Decimal64 asDecimal64() const
Definition bdljsn_jsonnumber.h:1093
int asUint(unsigned int *result) const
Definition bdljsn_jsonnumber.h:1057
double asDouble() const
Definition bdljsn_jsonnumber.h:1087
int asLonglong(long long *result) const
Definition bdljsn_jsonnumber.h:1039
Definition bdljsn_json.h:1080
Container::value_type Member
Definition bdljsn_json.h:1091
bslma::Allocator * allocator() const BSLS_KEYWORD_NOEXCEPT
Return the allocator used by this object to allocate memory.
Definition bdljsn_json.h:4070
Json & operator[](const bsl::string_view &key)
Definition bdljsn_json.h:3937
void clear() BSLS_KEYWORD_NOEXCEPT
Definition bdljsn_json.h:3951
bsl::size_t size() const BSLS_KEYWORD_NOEXCEPT
Return the number of elements in this JsonObject.
Definition bdljsn_json.h:4118
Iterator find(const bsl::string_view &key)
Definition bdljsn_json.h:3986
bool empty() const BSLS_KEYWORD_NOEXCEPT
Definition bdljsn_json.h:4100
Container::const_reference const_reference
Definition bdljsn_json.h:1098
friend bool operator==(const JsonObject &, const JsonObject &)
Iterator end() BSLS_KEYWORD_NOEXCEPT
Definition bdljsn_json.h:3957
Container::const_iterator const_iterator
Definition bdljsn_json.h:1101
friend void swap(JsonObject &, JsonObject &)
bsl::pair< Iterator, bool > IteratorAndStatus
Definition bdljsn_json.h:1094
BSLMF_NESTED_TRAIT_DECLARATION(JsonObject, bslmf::IsBitwiseMoveable)
Container::size_type size_type
Definition bdljsn_json.h:1104
JsonObject()
Definition bdljsn_json.h:3816
BSLMF_NESTED_TRAIT_DECLARATION(JsonObject, bdlb::HasPrintMethod)
Container::reference reference
Definition bdljsn_json.h:1097
bsl::size_t erase(const bsl::string_view &key)
Definition bdljsn_json.h:3963
JsonObject & operator=(const JsonObject &rhs)
Definition bdljsn_json.h:3895
bool contains(const bsl::string_view &key) const
Definition bdljsn_json.h:4094
Container::const_iterator ConstIterator
Definition bdljsn_json.h:1092
ConstIterator cbegin() const BSLS_KEYWORD_NOEXCEPT
Definition bdljsn_json.h:4082
Container::iterator iterator
Definition bdljsn_json.h:1100
bsl::pair< Iterator, bool > insert(const Member &member)
Definition bdljsn_json.h:3992
BSLMF_NESTED_TRAIT_DECLARATION(JsonObject, bslma::UsesBslmaAllocator)
Container::difference_type difference_type
Definition bdljsn_json.h:1103
friend bool operator!=(const JsonObject &, const JsonObject &)
Container::value_type value_type
Definition bdljsn_json.h:1096
Container::iterator Iterator
Definition bdljsn_json.h:1093
Iterator begin() BSLS_KEYWORD_NOEXCEPT
Definition bdljsn_json.h:3945
ConstIterator cend() const BSLS_KEYWORD_NOEXCEPT
Definition bdljsn_json.h:4088
Definition bdljsn_json.h:3265
~Json_StringInvariantGuard() BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(false)
Definition bdljsn_json.h:3295
Definition bdljsn_json.h:1461
bool isBoolean() const
Definition bdljsn_json.h:5064
int asLonglong(long long *result) const
Definition bdljsn_json.h:5239
BSLMF_NESTED_TRAIT_DECLARATION(Json, bdlb::HasPrintMethod)
int asInt(int *result) const
Definition bdljsn_json.h:5225
bool isObject() const
Definition bdljsn_json.h:5082
int asShort(short *result) const
Definition bdljsn_json.h:5218
JsonNumber & makeNumber()
Definition bdljsn_json.h:4511
int asUlonglong(unsigned long long *result) const
Definition bdljsn_json.h:5274
int asUint(unsigned int *result) const
Definition bdljsn_json.h:5260
BSLMF_NESTED_TRAIT_DECLARATION(Json, bslma::UsesBslmaAllocator)
bool isArray() const
Definition bdljsn_json.h:5058
int asUint64(bsls::Types::Uint64 *result) const
Definition bdljsn_json.h:5281
int asUshort(unsigned short *result) const
Definition bdljsn_json.h:5253
Json & pushBack(const Json &json)
Definition bdljsn_json.h:4723
int asUlong(unsigned long *result) const
Definition bdljsn_json.h:5267
BSLMF_NESTED_TRAIT_DECLARATION(Json, bslmf::IsBitwiseMoveable)
JsonNull & theNull()
Definition bdljsn_json.h:5106
bool contains(const bsl::string_view &key) const
Definition bdljsn_json.h:5181
bdldfp::Decimal64 asDecimal64() const
Definition bdljsn_json.h:5190
void makeString(const char *string)
Definition bdljsn_json.h:4551
double asDouble() const
Definition bdljsn_json.h:5204
friend bool operator==(const Json &, const Json &)
bool isNumber() const
Definition bdljsn_json.h:5076
JsonArray & theArray()
Definition bdljsn_json.h:5094
bool isString() const
Definition bdljsn_json.h:5088
int asDecimal64Exact(bdldfp::Decimal64 *result) const
Definition bdljsn_json.h:5197
friend void swap(Json &, Json &)
JsonNumber & theNumber()
Definition bdljsn_json.h:5112
JsonObject & makeObject()
Definition bdljsn_json.h:4531
bool & makeBoolean()
Definition bdljsn_json.h:4492
Json & operator=(const Json &rhs)
Definition bdljsn_json.h:4308
friend bool operator!=(const Json &, const Json &)
bool isNull() const
Definition bdljsn_json.h:5070
JsonObject & theObject()
Definition bdljsn_json.h:5118
bool & theBoolean()
Definition bdljsn_json.h:5100
bsl::size_t size() const
Definition bdljsn_json.h:5174
JsonType::Enum type() const BSLS_KEYWORD_NOEXCEPT
Return the type of this Json value.
Definition bdljsn_json.h:5326
void makeNull()
Definition bdljsn_json.h:4505
int asLong(long *result) const
Definition bdljsn_json.h:5232
JsonArray & makeArray()
Definition bdljsn_json.h:4472
RETURN_TYPE visit(BSLS_COMPILERFEATURES_FORWARD_REF(VISITOR) visitor)
Definition bdljsn_json.h:4970
float asFloat() const
Definition bdljsn_json.h:5211
const bsl::string & theString() const
Definition bdljsn_json.h:5320
Json()
Definition bdljsn_json.h:4128
int asInt64(bsls::Types::Int64 *result) const
Definition bdljsn_json.h:5246
bsl::pair< JsonObject::Iterator, bool > insert(const JsonObject::Member &member)
Definition bdljsn_json.h:4577
bslma::Allocator * allocator() const BSLS_KEYWORD_NOEXCEPT
Return the allocator used by this object to allocate memory.
Definition bdljsn_json.h:5455
Json & operator[](const bsl::string_view &key)
Definition bdljsn_json.h:5156
Definition bslstl_stringview.h:471
Definition bslstl_string.h:1252
Definition bslstl_pair.h:1280
Definition bslstl_unorderedmap.h:1123
enable_if< BloombergLP::bslmf::IsTransparentPredicate< HASH, LOOKUP_KEY >::value &&BloombergLP::bslmf::IsTransparentPredicate< EQUAL, LOOKUP_KEY >::value, iterator >::type find(const LOOKUP_KEY &key)
Definition bslstl_unorderedmap.h:1860
const_iterator cbegin() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_unorderedmap.h:3886
size_type size() const BSLS_KEYWORD_NOEXCEPT
Return the number of elements in this unordered map.
Definition bslstl_unorderedmap.h:4078
AllocatorTraits::size_type size_type
Definition bslstl_unorderedmap.h:1227
iterator end() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_unorderedmap.h:3386
allocator_type get_allocator() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_unorderedmap.h:4037
void reserve(size_type numElements)
Definition bslstl_unorderedmap.h:3694
pair< iterator, bool > insert(const value_type &value)
Definition bslstl_unorderedmap.h:3543
iterator erase(const_iterator position)
Definition bslstl_unorderedmap.h:3466
pair< iterator, bool > emplace(Args &&... args)
const value_type & const_reference
Definition bslstl_unorderedmap.h:1225
const_iterator cend() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_unorderedmap.h:3895
void clear() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_unorderedmap.h:3414
AllocatorTraits::difference_type difference_type
Definition bslstl_unorderedmap.h:1228
iterator begin() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_unorderedmap.h:3377
BloombergLP::bslstl::HashTableIterator< const value_type, difference_type > const_iterator
Definition bslstl_unorderedmap.h:1235
bool empty() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_unorderedmap.h:3996
size_type size() const BSLS_KEYWORD_NOEXCEPT
Return the number of elements in this vector.
Definition bslstl_vector.h:3019
iterator begin() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_vector.h:2866
reference back()
Definition bslstl_vector.h:2932
VALUE_TYPE const * const_iterator
Definition bslstl_vector.h:944
iterator end() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_vector.h:2874
bool empty() const BSLS_KEYWORD_NOEXCEPT
Return true if this vector has size 0, and false otherwise.
Definition bslstl_vector.h:3034
reference front()
Definition bslstl_vector.h:2922
Definition bslstl_vector.h:1120
Json & reference
Definition bslstl_vector.h:1144
const Json & const_reference
Definition bslstl_vector.h:1145
allocator_type get_allocator() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_vector.h:4621
Json value_type
Definition bslstl_vector.h:1142
iterator insert(const_iterator position, const VALUE_TYPE &value)
Definition bslstl_vector.h:4386
AllocatorTraits::size_type size_type
Definition bslstl_vector.h:1147
VALUE_TYPE & emplace_back(Args &&... arguments)
Definition bslstl_vector.h:4324
void push_back(const VALUE_TYPE &value)
Definition bslstl_vector.h:4343
Json * iterator
Definition bslstl_vector.h:1152
AllocatorTraits::difference_type difference_type
Definition bslstl_vector.h:1148
iterator erase(const_iterator position)
Definition bslstl_vector.h:4538
size_type max_size() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_vector.h:4631
void swap(vector &other) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(AllocatorTraits void clear() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_vector.h:1938
void resize(size_type newSize)
Definition bslstl_vector.h:4189
void pop_back()
Definition bslstl_vector.h:4375
vector &operator=(BloombergLP::bslmf::MovableRef< vector< VALUE_TYPE, ALLOCATOR > > rhs) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(AllocatorTraits void assign(INPUT_ITER first, INPUT_ITER last)
static void swap(T *a, T *b)
Definition bslalg_swaputil.h:182
Definition bslma_allocator.h:545
Definition bslmf_movableref.h:752
#define BSLA_UNREACHABLE
Definition bsla_unreachable.h:159
#define BSLMF_ASSERT(expr)
Definition bslmf_assert.h:231
#define BSLMF_MOVABLEREF_DEDUCE(...)
Definition bslmf_movableref.h:691
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1976
#define BSLS_ASSERT_OPT(X)
Definition bsls_assert.h:2045
#define BSLS_ASSERT_OPT_UNREACHABLE(X)
Definition bsls_assert.h:2065
#define BSLS_ASSERT_INVOKE_NORETURN(X)
Definition bsls_assert.h:2101
#define BSLS_COMPILERFEATURES_FORWARD_REF(T)
Definition bsls_compilerfeatures.h:2343
#define BSLS_COMPILERFEATURES_FORWARD(T, V)
Definition bsls_compilerfeatures.h:2349
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
#define BSLS_KEYWORD_NOEXCEPT
Definition bsls_keyword.h:674
#define BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(...)
Definition bsls_keyword.h:676
void swap(OptionValue &a, OptionValue &b)
Definition bdldfp_decimal.h:747
Decimal_Type64 Decimal64
Definition bdldfp_decimal.h:750
Definition bdljsn_error.h:142
bool operator!=(const Error &lhs, const Error &rhs)
void swap(Error &a, Error &b)
bool operator==(const Error &lhs, const Error &rhs)
bsl::ostream & operator<<(bsl::ostream &stream, const Error &object)
Definition bdlat_valuetypefunctions.h:939
int uncaught_exceptions()
basic_string_view< char > string_view
Definition bslstl_stringview.h:1253
ALLOCATOR const STRING_VIEW_LIKE_TYPE & rhs
Definition bslstl_string.h:3918
T::iterator begin(T &container)
Definition bslstl_iterator.h:1593
ALLOCATOR & lhs
Definition bslstl_string.h:3917
T::iterator end(T &container)
Definition bslstl_iterator.h:1621
basic_string< char > string
Definition bslstl_string.h:844
Definition baljsn_encoder_testtypes.h:76
Definition bdlbb_blob.h:579
Definition bdlb_printmethods.h:306
Definition bdlb_transparentequalto.h:127
Definition bdlb_transparenthash.h:167
static bool isValid(const char *string)
Definition bdlde_utf8util.h:1069
Enum
Definition bdljsn_jsontype.h:129
@ e_STRING
Definition bdljsn_jsontype.h:132
@ e_BOOLEAN
Definition bdljsn_jsontype.h:134
@ e_ARRAY
Definition bdljsn_jsontype.h:131
@ e_NULL
Definition bdljsn_jsontype.h:135
@ e_OBJECT
Definition bdljsn_jsontype.h:130
@ e_NUMBER
Definition bdljsn_jsontype.h:133
Definition bdljsn_json.h:3143
Definition bslmf_enableif.h:530
Definition bslmf_isconvertible.h:875
Definition bslmf_isintegral.h:140
Definition bslmf_issame.h:146
Definition bslma_usesbslmaallocator.h:344
Definition bslmf_isbitwisemoveable.h:718
static MovableRef< t_TYPE > move(t_TYPE &reference) BSLS_KEYWORD_NOEXCEPT
Definition bslmf_movableref.h:1067
static t_TYPE & access(t_TYPE &ref) BSLS_KEYWORD_NOEXCEPT
Definition bslmf_movableref.h:1039
Definition bslmf_nil.h:133
unsigned long long Uint64
Definition bsls_types.h:139
long long Int64
Definition bsls_types.h:134