2 * Eddie Kohler, Yandong Mao, Robert Morris
3 * Copyright (c) 2012-2014 President and Fellows of Harvard College
4 * Copyright (c) 2012-2014 Massachusetts Institute of Technology
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, subject to the conditions
9 * listed in the Masstree LICENSE file. These conditions include: you must
10 * preserve this copyright notice, and you cannot mention the copyright
11 * holders in advertising related to the Software without their permission.
12 * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This
13 * notice is a summary of the Masstree LICENSE file; the license in that file
16 // -*- c-basic-offset: 4 -*-
19 #include "straccum.hh"
26 template <typename P> class Json_proxy_base;
27 template <typename T> class Json_object_proxy;
28 template <typename T> class Json_object_str_proxy;
29 template <typename T> class Json_array_proxy;
32 template <typename T, size_t S = sizeof(String::rep_type) - sizeof(T)>
34 template <typename T> struct Json_rep_item<T, 4> {
38 template <typename T> struct Json_rep_item<T, 8> {
45 enum json_type { // order matters
46 j_string = -1, j_null = 0,
47 j_array = 1, j_object = 2,
48 j_int = 3, j_unsigned = 4, j_double = 5, j_bool = 6
53 inline constexpr null_t() { }
55 static const null_t null;
56 static const Json null_json;
58 typedef int size_type;
60 typedef std::pair<const String, Json> object_value_type;
61 class object_iterator;
62 class const_object_iterator;
64 typedef Json array_value_type;
66 class const_array_iterator;
71 typedef bool (Json::*unspecified_bool_type)() const;
72 class unparse_manipulator;
73 class streaming_parser;
77 inline Json(const Json& x);
78 template <typename P> inline Json(const Json_proxy_base<P>& x);
79 #if HAVE_CXX_RVALUE_REFERENCES
80 inline Json(Json&& x);
82 inline Json(const null_t& x);
84 inline Json(unsigned x);
86 inline Json(unsigned long x);
87 inline Json(long long x);
88 inline Json(unsigned long long x);
89 inline Json(double x);
91 inline Json(const String& x);
93 inline Json(const char* x);
94 template <typename T> inline Json(const std::vector<T>& x);
95 template <typename T> inline Json(T first, T last);
98 static inline const Json& make_null();
99 static inline Json make_array();
100 static inline Json make_array_reserve(int n);
101 template <typename... Args>
102 static inline Json array(Args&&... rest);
103 static inline Json make_object();
104 template <typename... Args>
105 static inline Json object(Args&&... rest);
106 static inline Json make_string(const String& x);
107 static inline Json make_string(const char* s, int len);
110 inline bool truthy() const;
111 inline bool falsy() const;
112 inline operator unspecified_bool_type() const;
113 inline bool operator!() const;
115 inline bool is_null() const;
116 inline bool is_int() const;
117 inline bool is_i() const;
118 inline bool is_unsigned() const;
119 inline bool is_u() const;
120 inline bool is_signed() const;
121 inline bool is_nonnegint() const;
122 inline bool is_double() const;
123 inline bool is_d() const;
124 inline bool is_number() const;
125 inline bool is_n() const;
126 inline bool is_bool() const;
127 inline bool is_b() const;
128 inline bool is_string() const;
129 inline bool is_s() const;
130 inline bool is_array() const;
131 inline bool is_a() const;
132 inline bool is_object() const;
133 inline bool is_o() const;
134 inline bool is_primitive() const;
136 inline bool empty() const;
137 inline size_type size() const;
138 inline bool shared() const;
142 // Primitive extractors
143 inline int64_t to_i() const;
144 inline uint64_t to_u() const;
145 inline uint64_t to_u64() const;
146 inline bool to_i(int& x) const;
147 inline bool to_i(unsigned& x) const;
148 inline bool to_i(long& x) const;
149 inline bool to_i(unsigned long& x) const;
150 inline bool to_i(long long& x) const;
151 inline bool to_i(unsigned long long& x) const;
152 inline int64_t as_i() const;
153 inline int64_t as_i(int64_t default_value) const;
154 inline uint64_t as_u() const;
155 inline uint64_t as_u(uint64_t default_value) const;
157 inline double to_d() const;
158 inline bool to_d(double& x) const;
159 inline double as_d() const;
160 inline double as_d(double default_value) const;
162 inline bool to_b() const;
163 inline bool to_b(bool& x) const;
164 inline bool as_b() const;
165 inline bool as_b(bool default_value) const;
167 inline String to_s() const;
168 inline bool to_s(Str& x) const;
169 inline bool to_s(String& x) const;
170 inline String& as_s();
171 inline const String& as_s() const;
172 inline const String& as_s(const String& default_value) const;
175 inline size_type count(Str key) const;
176 inline const Json& get(Str key) const;
177 inline Json& get_insert(const String& key);
178 inline Json& get_insert(Str key);
179 inline Json& get_insert(const char* key);
181 inline long get_i(Str key) const;
182 inline double get_d(Str key) const;
183 inline bool get_b(Str key) const;
184 inline String get_s(Str key) const;
186 inline const Json_get_proxy get(Str key, Json& x) const;
187 inline const Json_get_proxy get(Str key, int& x) const;
188 inline const Json_get_proxy get(Str key, unsigned& x) const;
189 inline const Json_get_proxy get(Str key, long& x) const;
190 inline const Json_get_proxy get(Str key, unsigned long& x) const;
191 inline const Json_get_proxy get(Str key, long long& x) const;
192 inline const Json_get_proxy get(Str key, unsigned long long& x) const;
193 inline const Json_get_proxy get(Str key, double& x) const;
194 inline const Json_get_proxy get(Str key, bool& x) const;
195 inline const Json_get_proxy get(Str key, Str& x) const;
196 inline const Json_get_proxy get(Str key, String& x) const;
198 const Json& operator[](Str key) const;
199 inline Json_object_proxy<Json> operator[](const String& key);
200 inline Json_object_str_proxy<Json> operator[](Str key);
201 inline Json_object_str_proxy<Json> operator[](const char* key);
203 inline const Json& at(Str key) const;
204 inline Json& at_insert(const String& key);
205 inline Json& at_insert(Str key);
206 inline Json& at_insert(const char* key);
208 inline Json& set(const String& key, Json value);
209 template <typename P>
210 inline Json& set(const String& key, const Json_proxy_base<P>& value);
211 inline Json& unset(Str key);
213 inline Json& set_list();
214 template <typename T, typename... Args>
215 inline Json& set_list(const String& key, T value, Args&&... rest);
217 inline std::pair<object_iterator, bool> insert(const object_value_type& x);
218 inline object_iterator insert(object_iterator position,
219 const object_value_type& x);
220 inline object_iterator erase(object_iterator it);
221 inline size_type erase(Str key);
223 inline Json& merge(const Json& x);
224 template <typename P> inline Json& merge(const Json_proxy_base<P>& x);
227 inline const Json& get(size_type x) const;
228 inline Json& get_insert(size_type x);
230 inline const Json& operator[](size_type x) const;
231 inline Json_array_proxy<Json> operator[](size_type x);
233 inline const Json& at(size_type x) const;
234 inline Json& at_insert(size_type x);
236 inline const Json& back() const;
239 inline Json& push_back(Json x);
240 template <typename P> inline Json& push_back(const Json_proxy_base<P>& x);
241 inline void pop_back();
243 inline Json& push_back_list();
244 template <typename T, typename... Args>
245 inline Json& push_back_list(T first, Args&&... rest);
247 inline array_iterator insert(array_iterator position, Json x);
248 template <typename P>
249 inline array_iterator insert(array_iterator position, const Json_proxy_base<P>& x);
250 array_iterator erase(array_iterator first, array_iterator last);
251 inline array_iterator erase(array_iterator position);
253 void reserve(size_type n);
254 void resize(size_type n);
256 inline Json* array_data();
257 inline const Json* array_data() const;
258 inline const Json* array_cdata() const;
259 inline Json* end_array_data();
260 inline const Json* end_array_data() const;
261 inline const Json* end_array_cdata() const;
264 inline const_object_iterator obegin() const;
265 inline const_object_iterator oend() const;
266 inline object_iterator obegin();
267 inline object_iterator oend();
268 inline const_object_iterator cobegin() const;
269 inline const_object_iterator coend() const;
271 inline const_array_iterator abegin() const;
272 inline const_array_iterator aend() const;
273 inline array_iterator abegin();
274 inline array_iterator aend();
275 inline const_array_iterator cabegin() const;
276 inline const_array_iterator caend() const;
278 inline const_iterator begin() const;
279 inline const_iterator end() const;
280 inline iterator begin();
281 inline iterator end();
282 inline const_iterator cbegin() const;
283 inline const_iterator cend() const;
286 static inline unparse_manipulator indent_depth(int x);
287 static inline unparse_manipulator tab_width(int x);
288 static inline unparse_manipulator newline_terminator(bool x);
289 static inline unparse_manipulator space_separator(bool x);
291 inline String unparse() const;
292 inline String unparse(const unparse_manipulator& m) const;
293 inline void unparse(StringAccum& sa) const;
294 inline void unparse(StringAccum& sa, const unparse_manipulator& m) const;
297 inline bool assign_parse(const String& str);
298 inline bool assign_parse(const char* first, const char* last);
300 static inline Json parse(const String& str);
301 static inline Json parse(const char* first, const char* last);
304 inline Json& operator=(const Json& x);
305 #if HAVE_CXX_RVALUE_REFERENCES
306 inline Json& operator=(Json&& x);
308 inline Json& operator=(int x);
309 inline Json& operator=(unsigned x);
310 inline Json& operator=(long x);
311 inline Json& operator=(unsigned long x);
312 inline Json& operator=(long long x);
313 inline Json& operator=(unsigned long long x);
314 inline Json& operator=(double x);
315 inline Json& operator=(bool x);
316 inline Json& operator=(const String& x);
317 template <typename P> inline Json& operator=(const Json_proxy_base<P>& x);
319 inline Json& operator++();
320 inline void operator++(int);
321 inline Json& operator--();
322 inline void operator--(int);
323 inline Json& operator+=(int x);
324 inline Json& operator+=(unsigned x);
325 inline Json& operator+=(long x);
326 inline Json& operator+=(unsigned long x);
327 inline Json& operator+=(long long x);
328 inline Json& operator+=(unsigned long long x);
329 inline Json& operator+=(double x);
330 inline Json& operator+=(const Json& x);
331 inline Json& operator-=(int x);
332 inline Json& operator-=(unsigned x);
333 inline Json& operator-=(long x);
334 inline Json& operator-=(unsigned long x);
335 inline Json& operator-=(long long x);
336 inline Json& operator-=(unsigned long long x);
337 inline Json& operator-=(double x);
338 inline Json& operator-=(const Json& x);
340 friend bool operator==(const Json& a, const Json& b);
342 inline void swap(Json& x);
346 st_initial = 0, st_array_initial = 1, st_array_delim = 2,
347 st_array_value = 3, st_object_initial = 4, st_object_delim = 5,
348 st_object_key = 6, st_object_colon = 7, st_object_value = 8,
359 inline void deref(json_type j);
361 ComplexJson(const ComplexJson& x); // does not exist
369 Json_rep_item<int64_t> i;
370 Json_rep_item<uint64_t> u;
371 Json_rep_item<double> d;
372 String::rep_type str;
373 Json_rep_item<ArrayJson*> a;
374 Json_rep_item<ObjectJson*> o;
375 Json_rep_item<ComplexJson*> x;
380 inline ObjectJson* ojson() const;
381 inline ArrayJson* ajson() const;
383 int64_t hard_to_i() const;
384 uint64_t hard_to_u() const;
385 double hard_to_d() const;
386 bool hard_to_b() const;
387 String hard_to_s() const;
388 inline void force_number();
389 inline void force_double();
390 inline Json& add(double x);
391 template <typename T> inline Json& add(T x);
392 inline Json& subtract(double x);
393 template <typename T> inline Json& subtract(T x);
395 const Json& hard_get(Str key) const;
396 const Json& hard_get(size_type x) const;
397 Json& hard_get_insert(size_type x);
399 inline void uniqueify_object(bool convert);
400 void hard_uniqueify_object(bool convert);
401 inline void uniqueify_array(bool convert, int ncap);
402 void hard_uniqueify_array(bool convert, int ncap);
403 void* uniqueify_array_insert(bool convert, size_type pos);
405 static unparse_manipulator default_manipulator;
406 bool unparse_is_complex() const;
407 static void unparse_indent(StringAccum &sa, const unparse_manipulator &m, int depth);
408 void hard_unparse(StringAccum &sa, const unparse_manipulator &m, int depth) const;
410 bool assign_parse(const char* first, const char* last, const String &str);
412 friend class object_iterator;
413 friend class const_object_iterator;
414 friend class array_iterator;
415 friend class const_array_iterator;
416 friend Json operator+(Json);
417 friend Json operator-(Json);
421 struct Json::ArrayJson : public ComplexJson {
425 inline ArrayJson(int cap)
429 static ArrayJson* make(int n);
430 static void destroy(ArrayJson* a);
433 struct Json::ObjectItem {
434 std::pair<const String, Json> v_;
436 explicit ObjectItem(const String &key, const Json& value, int next)
437 : v_(key, value), next_(next) {
441 struct Json::ObjectJson : public ComplexJson {
445 std::vector<int> hash_;
447 : os_(), n_(0), capacity_(0) {
450 ObjectJson(const ObjectJson& x);
452 void grow(bool copy);
453 int bucket(const char* s, int len) const {
454 return String::hashcode(s, s + len) & (hash_.size() - 1);
456 ObjectItem& item(int p) const {
459 int find(const char* s, int len) const {
461 int p = hash_[bucket(s, len)];
463 ObjectItem &oi = item(p);
464 if (oi.v_.first.equals(s, len))
471 int find_insert(const String& key, const Json& value);
472 inline Json& get_insert(const String& key) {
473 int p = find_insert(key, make_null());
474 return item(p).v_.second;
476 Json& get_insert(Str key);
478 size_type erase(Str key);
482 inline const Json& Json::make_null() {
486 inline void Json::ComplexJson::ref() {
491 inline void Json::ComplexJson::deref(json_type j) {
492 if (refcount >= 1 && --refcount == 0) {
494 delete static_cast<ObjectJson*>(this);
496 ArrayJson::destroy(static_cast<ArrayJson*>(this));
500 inline Json::ArrayJson* Json::ajson() const {
501 precondition(u_.x.type == j_null || u_.x.type == j_array);
505 inline Json::ObjectJson* Json::ojson() const {
506 precondition(u_.x.type == j_null || u_.x.type == j_object);
510 inline void Json::uniqueify_array(bool convert, int ncap) {
511 if (u_.x.type != j_array || !u_.a.x || u_.a.x->refcount != 1
512 || (ncap > 0 && ncap > u_.a.x->capacity))
513 hard_uniqueify_array(convert, ncap);
516 inline void Json::uniqueify_object(bool convert) {
517 if (u_.x.type != j_object || !u_.o.x || u_.o.x->refcount != 1)
518 hard_uniqueify_object(convert);
522 class Json::const_object_iterator { public:
523 typedef std::pair<const String, Json> value_type;
524 typedef const value_type* pointer_type;
525 typedef const value_type& reference_type;
526 typedef std::forward_iterator_tag iterator_category;
528 const_object_iterator() {
530 typedef bool (const_object_iterator::*unspecified_bool_type)() const;
531 operator unspecified_bool_type() const {
532 return live() ? &const_object_iterator::live : 0;
537 const value_type& operator*() const {
538 return j_->ojson()->item(i_).v_;
540 const value_type* operator->() const {
543 const String& key() const {
544 return (**this).first;
546 const Json& value() const {
547 return (**this).second;
553 void operator++(int) {
559 const_object_iterator(const Json* j, int i)
565 ObjectJson* oj = j_->ojson();
567 if (!oj || i_ >= oj->n_)
569 else if (oj->item(i_).next_ == -2) {
575 friend bool operator==(const const_object_iterator&, const const_object_iterator&);
578 class Json::object_iterator : public const_object_iterator { public:
579 typedef value_type* pointer_type;
580 typedef value_type& reference_type;
584 value_type& operator*() const {
585 const_cast<Json*>(j_)->uniqueify_object(false);
586 return j_->ojson()->item(i_).v_;
588 value_type* operator->() const {
591 Json& value() const {
592 return (**this).second;
595 object_iterator(Json* j, int i)
596 : const_object_iterator(j, i) {
601 inline bool operator==(const Json::const_object_iterator& a, const Json::const_object_iterator& b) {
602 return a.j_ == b.j_ && a.i_ == b.i_;
605 inline bool operator!=(const Json::const_object_iterator& a, const Json::const_object_iterator& b) {
609 class Json::const_array_iterator { public:
610 typedef Json::size_type difference_type;
611 typedef Json value_type;
612 typedef const Json* pointer_type;
613 typedef const Json& reference_type;
614 typedef std::random_access_iterator_tag iterator_category;
616 const_array_iterator() {
618 typedef bool (const_array_iterator::*unspecified_bool_type)() const;
619 operator unspecified_bool_type() const {
620 return live() ? &const_array_iterator::live : 0;
623 ArrayJson* aj = j_->ajson();
624 return aj && i_ < aj->size;
626 const Json& operator*() const {
627 return j_->ajson()->a[i_];
629 const Json& operator[](difference_type i) const {
630 return j_->ajson()->a[i_ + i];
632 const Json* operator->() const {
635 const Json& value() const {
638 void operator++(int) {
644 void operator--(int) {
650 const_array_iterator& operator+=(difference_type x) {
654 const_array_iterator& operator-=(difference_type x) {
661 const_array_iterator(const Json* j, int i)
665 friend class Json::array_iterator;
666 friend bool operator==(const const_array_iterator&, const const_array_iterator&);
667 friend bool operator<(const const_array_iterator&, const const_array_iterator&);
668 friend difference_type operator-(const const_array_iterator&, const const_array_iterator&);
671 class Json::array_iterator : public const_array_iterator { public:
672 typedef const Json* pointer_type;
673 typedef const Json& reference_type;
677 Json& operator*() const {
678 const_cast<Json*>(j_)->uniqueify_array(false, 0);
679 return j_->ajson()->a[i_];
681 Json& operator[](difference_type i) const {
682 const_cast<Json*>(j_)->uniqueify_array(false, 0);
683 return j_->ajson()->a[i_ + i];
685 Json* operator->() const {
688 Json& value() const {
691 array_iterator& operator+=(difference_type x) {
695 array_iterator& operator-=(difference_type x) {
700 array_iterator(Json* j, int i)
701 : const_array_iterator(j, i) {
706 inline bool operator==(const Json::const_array_iterator& a, const Json::const_array_iterator& b) {
707 return a.j_ == b.j_ && a.i_ == b.i_;
710 inline bool operator<(const Json::const_array_iterator& a, const Json::const_array_iterator& b) {
711 return a.j_ < b.j_ || (a.j_ == b.j_ && a.i_ < b.i_);
714 inline bool operator!=(const Json::const_array_iterator& a, const Json::const_array_iterator& b) {
718 inline bool operator<=(const Json::const_array_iterator& a, const Json::const_array_iterator& b) {
722 inline bool operator>(const Json::const_array_iterator& a, const Json::const_array_iterator& b) {
726 inline bool operator>=(const Json::const_array_iterator& a, const Json::const_array_iterator& b) {
730 inline Json::const_array_iterator operator+(Json::const_array_iterator a, Json::const_array_iterator::difference_type i) {
733 inline Json::array_iterator operator+(Json::array_iterator a, Json::array_iterator::difference_type i) {
737 inline Json::const_array_iterator operator-(Json::const_array_iterator a, Json::const_array_iterator::difference_type i) {
740 inline Json::array_iterator operator-(Json::array_iterator a, Json::array_iterator::difference_type i) {
744 inline Json::const_array_iterator::difference_type operator-(const Json::const_array_iterator& a, const Json::const_array_iterator& b) {
745 precondition(a.j_ == b.j_);
749 class Json::const_iterator { public:
750 typedef std::pair<const String, Json&> value_type;
751 typedef const value_type* pointer_type;
752 typedef const value_type& reference_type;
753 typedef std::forward_iterator_tag iterator_category;
756 : value_(String(), *(Json*) 0) {
758 typedef bool (const_iterator::*unspecified_bool_type)() const;
759 operator unspecified_bool_type() const {
760 return live() ? &const_iterator::live : 0;
765 const value_type& operator*() const {
768 const value_type* operator->() const {
771 const String& key() const {
772 return (**this).first;
774 const Json& value() const {
775 return (**this).second;
781 void operator++(int) {
788 const_iterator(const Json* j, int i)
789 : j_(j), i_(i), value_(String(), *(Json*) 0) {
794 if (j_->u_.x.type == j_object) {
795 ObjectJson* oj = j_->ojson();
797 if (!oj || i_ >= oj->n_)
799 else if (oj->item(i_).next_ == -2) {
804 new((void *) &value_) value_type(oj->item(i_).v_.first,
805 oj->item(i_).v_.second);
808 ArrayJson *aj = j_->ajson();
809 if (!aj || unsigned(i_) >= unsigned(aj->size))
813 new((void *) &value_) value_type(String(i_), aj->a[i_]);
818 friend bool operator==(const const_iterator &, const const_iterator &);
821 class Json::iterator : public const_iterator { public:
822 typedef value_type* pointer_type;
823 typedef value_type& reference_type;
827 value_type& operator*() const {
828 if (j_->u_.x.x->refcount != 1)
830 return const_cast<value_type&>(const_iterator::operator*());
832 value_type* operator->() const {
835 Json& value() const {
836 return (**this).second;
839 iterator(Json *j, int i)
840 : const_iterator(j, i) {
842 void uniqueify() const {
843 if (j_->u_.x.type == j_object)
844 const_cast<Json*>(j_)->hard_uniqueify_object(false);
846 const_cast<Json*>(j_)->hard_uniqueify_array(false, 0);
847 const_cast<iterator*>(this)->fix();
852 inline bool operator==(const Json::const_iterator& a, const Json::const_iterator& b) {
853 return a.j_ == b.j_ && a.i_ == b.i_;
856 inline bool operator!=(const Json::const_iterator& a, const Json::const_iterator& b) {
861 template <typename P>
862 class Json_proxy_base {
864 const Json& cvalue() const {
865 return static_cast<const P *>(this)->cvalue();
868 return static_cast<P *>(this)->value();
870 operator const Json&() const {
876 bool truthy() const {
877 return cvalue().truthy();
880 return cvalue().falsy();
882 operator Json::unspecified_bool_type() const {
885 bool operator!() const {
888 bool is_null() const {
889 return cvalue().is_null();
891 bool is_int() const {
892 return cvalue().is_int();
895 return cvalue().is_i();
897 bool is_unsigned() const {
898 return cvalue().is_unsigned();
901 return cvalue().is_u();
903 bool is_signed() const {
904 return cvalue().is_signed();
906 bool is_nonnegint() const {
907 return cvalue().is_nonnegint();
909 bool is_double() const {
910 return cvalue().is_double();
913 return cvalue().is_d();
915 bool is_number() const {
916 return cvalue().is_number();
919 return cvalue().is_n();
921 bool is_bool() const {
922 return cvalue().is_bool();
925 return cvalue().is_b();
927 bool is_string() const {
928 return cvalue().is_string();
931 return cvalue().is_s();
933 bool is_array() const {
934 return cvalue().is_array();
937 return cvalue().is_a();
939 bool is_object() const {
940 return cvalue().is_object();
943 return cvalue().is_o();
945 bool is_primitive() const {
946 return cvalue().is_primitive();
949 return cvalue().empty();
951 Json::size_type size() const {
952 return cvalue().size();
954 int64_t to_i() const {
955 return cvalue().to_i();
957 uint64_t to_u() const {
958 return cvalue().to_u();
960 uint64_t to_u64() const {
961 return cvalue().to_u64();
963 bool to_i(int& x) const {
964 return cvalue().to_i(x);
966 bool to_i(unsigned& x) const {
967 return cvalue().to_i(x);
969 bool to_i(long& x) const {
970 return cvalue().to_i(x);
972 bool to_i(unsigned long& x) const {
973 return cvalue().to_i(x);
975 bool to_i(long long& x) const {
976 return cvalue().to_i(x);
978 bool to_i(unsigned long long& x) const {
979 return cvalue().to_i(x);
981 int64_t as_i() const {
982 return cvalue().as_i();
984 int64_t as_i(int64_t default_value) const {
985 return cvalue().as_i(default_value);
987 uint64_t as_u() const {
988 return cvalue().as_u();
990 uint64_t as_u(uint64_t default_value) const {
991 return cvalue().as_u(default_value);
993 double to_d() const {
994 return cvalue().to_d();
996 bool to_d(double& x) const {
997 return cvalue().to_d(x);
999 double as_d() const {
1000 return cvalue().as_d();
1002 double as_d(double default_value) const {
1003 return cvalue().as_d(default_value);
1006 return cvalue().to_b();
1008 bool to_b(bool& x) const {
1009 return cvalue().to_b(x);
1012 return cvalue().as_b();
1014 bool as_b(bool default_value) const {
1015 return cvalue().as_b(default_value);
1017 String to_s() const {
1018 return cvalue().to_s();
1020 bool to_s(Str& x) const {
1021 return cvalue().to_s(x);
1023 bool to_s(String& x) const {
1024 return cvalue().to_s(x);
1026 const String& as_s() const {
1027 return cvalue().as_s();
1029 const String& as_s(const String& default_value) const {
1030 return cvalue().as_s(default_value);
1032 Json::size_type count(Str key) const {
1033 return cvalue().count(key);
1035 const Json& get(Str key) const {
1036 return cvalue().get(key);
1038 Json& get_insert(const String& key) {
1039 return value().get_insert(key);
1041 Json& get_insert(Str key) {
1042 return value().get_insert(key);
1044 Json& get_insert(const char* key) {
1045 return value().get_insert(key);
1047 long get_i(Str key) const {
1048 return cvalue().get_i(key);
1050 double get_d(Str key) const {
1051 return cvalue().get_d(key);
1053 bool get_b(Str key) const {
1054 return cvalue().get_b(key);
1056 String get_s(Str key) const {
1057 return cvalue().get_s(key);
1059 inline const Json_get_proxy get(Str key, Json& x) const;
1060 inline const Json_get_proxy get(Str key, int& x) const;
1061 inline const Json_get_proxy get(Str key, unsigned& x) const;
1062 inline const Json_get_proxy get(Str key, long& x) const;
1063 inline const Json_get_proxy get(Str key, unsigned long& x) const;
1064 inline const Json_get_proxy get(Str key, long long& x) const;
1065 inline const Json_get_proxy get(Str key, unsigned long long& x) const;
1066 inline const Json_get_proxy get(Str key, double& x) const;
1067 inline const Json_get_proxy get(Str key, bool& x) const;
1068 inline const Json_get_proxy get(Str key, Str& x) const;
1069 inline const Json_get_proxy get(Str key, String& x) const;
1070 const Json& operator[](Str key) const {
1071 return cvalue().get(key);
1073 Json_object_proxy<P> operator[](const String& key) {
1074 return Json_object_proxy<P>(*static_cast<P*>(this), key);
1076 Json_object_str_proxy<P> operator[](Str key) {
1077 return Json_object_str_proxy<P>(*static_cast<P*>(this), key);
1079 Json_object_str_proxy<P> operator[](const char* key) {
1080 return Json_object_str_proxy<P>(*static_cast<P*>(this), key);
1082 const Json& at(Str key) const {
1083 return cvalue().at(key);
1085 Json& at_insert(const String& key) {
1086 return value().at_insert(key);
1088 Json& at_insert(Str key) {
1089 return value().at_insert(key);
1091 Json& at_insert(const char* key) {
1092 return value().at_insert(key);
1094 inline Json& set(const String& key, Json value) {
1095 return this->value().set(key, value);
1097 template <typename Q>
1098 inline Json& set(const String& key, const Json_proxy_base<Q>& value) {
1099 return this->value().set(key, value);
1101 Json& unset(Str key) {
1102 return value().unset(key);
1104 template <typename... Args>
1105 inline Json& set_list(Args&&... args) {
1106 return value().set_list(std::forward<Args>(args)...);
1108 std::pair<Json::object_iterator, bool> insert(const Json::object_value_type &x) {
1109 return value().insert(x);
1111 Json::object_iterator insert(Json::object_iterator position, const Json::object_value_type &x) {
1112 return value().insert(position, x);
1114 Json::object_iterator erase(Json::object_iterator it) {
1115 return value().erase(it);
1117 Json::size_type erase(Str key) {
1118 return value().erase(key);
1120 Json& merge(const Json& x) {
1121 return value().merge(x);
1123 template <typename P2> Json& merge(const Json_proxy_base<P2>& x) {
1124 return value().merge(x.cvalue());
1126 const Json& get(Json::size_type x) const {
1127 return cvalue().get(x);
1129 Json& get_insert(Json::size_type x) {
1130 return value().get_insert(x);
1132 const Json& operator[](int key) const {
1133 return cvalue().at(key);
1135 Json_array_proxy<P> operator[](int key) {
1136 return Json_array_proxy<P>(*static_cast<P*>(this), key);
1138 const Json& at(Json::size_type x) const {
1139 return cvalue().at(x);
1141 Json& at_insert(Json::size_type x) {
1142 return value().at_insert(x);
1144 const Json& back() const {
1145 return cvalue().back();
1148 return value().back();
1150 Json& push_back(Json x) {
1151 return value().push_back(std::move(x));
1153 template <typename Q> Json& push_back(const Json_proxy_base<Q>& x) {
1154 return value().push_back(x);
1159 template <typename... Args> Json& push_back_list(Args&&... args) {
1160 return value().push_back_list(std::forward<Args>(args)...);
1162 Json::array_iterator insert(Json::array_iterator position, Json x) {
1163 return value().insert(position, std::move(x));
1165 template <typename Q> Json::array_iterator insert(Json::array_iterator position, const Json_proxy_base<Q>& x) {
1166 return value().insert(position, x);
1168 Json::array_iterator erase(Json::array_iterator first, Json::array_iterator last) {
1169 return value().erase(first, last);
1171 Json::array_iterator erase(Json::array_iterator position) {
1172 return value().erase(position);
1174 void resize(Json::size_type n) {
1177 void unparse(StringAccum& sa) const {
1178 return cvalue().unparse(sa);
1180 void unparse(StringAccum& sa, const Json::unparse_manipulator& m) const {
1181 return cvalue().unparse(sa, m);
1183 String unparse() const {
1184 return cvalue().unparse();
1186 String unparse(const Json::unparse_manipulator& m) const {
1187 return cvalue().unparse(m);
1189 bool assign_parse(const String& str) {
1190 return value().assign_parse(str);
1192 bool assign_parse(const char* first, const char* last) {
1193 return value().assign_parse(first, last);
1195 void swap(Json& x) {
1198 Json& operator++() {
1201 void operator++(int) {
1204 Json& operator--() {
1207 void operator--(int) {
1210 Json& operator+=(int x) {
1211 return value() += x;
1213 Json& operator+=(unsigned x) {
1214 return value() += x;
1216 Json& operator+=(long x) {
1217 return value() += x;
1219 Json& operator+=(unsigned long x) {
1220 return value() += x;
1222 Json& operator+=(long long x) {
1223 return value() += x;
1225 Json& operator+=(unsigned long long x) {
1226 return value() += x;
1228 Json& operator+=(double x) {
1229 return value() += x;
1231 Json& operator+=(const Json& x) {
1232 return value() += x;
1234 Json& operator-=(int x) {
1235 return value() -= x;
1237 Json& operator-=(unsigned x) {
1238 return value() -= x;
1240 Json& operator-=(long x) {
1241 return value() -= x;
1243 Json& operator-=(unsigned long x) {
1244 return value() -= x;
1246 Json& operator-=(long long x) {
1247 return value() -= x;
1249 Json& operator-=(unsigned long long x) {
1250 return value() -= x;
1252 Json& operator-=(double x) {
1253 return value() -= x;
1255 Json& operator-=(const Json& x) {
1256 return value() -= x;
1258 Json::const_object_iterator obegin() const {
1259 return cvalue().obegin();
1261 Json::const_object_iterator oend() const {
1262 return cvalue().oend();
1264 Json::object_iterator obegin() {
1265 return value().obegin();
1267 Json::object_iterator oend() {
1268 return value().oend();
1270 Json::const_object_iterator cobegin() const {
1271 return cvalue().cobegin();
1273 Json::const_object_iterator coend() const {
1274 return cvalue().coend();
1276 Json::const_array_iterator abegin() const {
1277 return cvalue().abegin();
1279 Json::const_array_iterator aend() const {
1280 return cvalue().aend();
1282 Json::array_iterator abegin() {
1283 return value().abegin();
1285 Json::array_iterator aend() {
1286 return value().aend();
1288 Json::const_array_iterator cabegin() const {
1289 return cvalue().cabegin();
1291 Json::const_array_iterator caend() const {
1292 return cvalue().caend();
1294 Json::const_iterator begin() const {
1295 return cvalue().begin();
1297 Json::const_iterator end() const {
1298 return cvalue().end();
1300 Json::iterator begin() {
1301 return value().begin();
1303 Json::iterator end() {
1304 return value().end();
1306 Json::const_iterator cbegin() const {
1307 return cvalue().cbegin();
1309 Json::const_iterator cend() const {
1310 return cvalue().cend();
1314 template <typename T>
1315 class Json_object_proxy : public Json_proxy_base<Json_object_proxy<T> > {
1317 const Json& cvalue() const {
1318 return base_.get(key_);
1321 return base_.get_insert(key_);
1323 Json& operator=(const Json& x) {
1326 #if HAVE_CXX_RVALUE_REFERENCES
1327 Json& operator=(Json&& x) {
1328 return value() = std::move(x);
1331 Json& operator=(const Json_object_proxy<T>& x) {
1332 return value() = x.cvalue();
1334 template <typename P> Json& operator=(const Json_proxy_base<P>& x) {
1335 return value() = x.cvalue();
1337 Json_object_proxy(T& ref, const String& key)
1338 : base_(ref), key_(key) {
1344 template <typename T>
1345 class Json_object_str_proxy : public Json_proxy_base<Json_object_str_proxy<T> > {
1347 const Json& cvalue() const {
1348 return base_.get(key_);
1351 return base_.get_insert(key_);
1353 Json& operator=(const Json& x) {
1356 #if HAVE_CXX_RVALUE_REFERENCES
1357 Json& operator=(Json&& x) {
1358 return value() = std::move(x);
1361 Json& operator=(const Json_object_str_proxy<T>& x) {
1362 return value() = x.cvalue();
1364 template <typename P> Json& operator=(const Json_proxy_base<P>& x) {
1365 return value() = x.cvalue();
1367 Json_object_str_proxy(T& ref, Str key)
1368 : base_(ref), key_(key) {
1374 template <typename T>
1375 class Json_array_proxy : public Json_proxy_base<Json_array_proxy<T> > {
1377 const Json& cvalue() const {
1378 return base_.get(key_);
1381 return base_.get_insert(key_);
1383 Json& operator=(const Json& x) {
1386 #if HAVE_CXX_RVALUE_REFERENCES
1387 Json& operator=(Json&& x) {
1388 return value() = std::move(x);
1391 Json& operator=(const Json_array_proxy<T>& x) {
1392 return value() = x.cvalue();
1394 template <typename P> Json& operator=(const Json_proxy_base<P>& x) {
1395 return value() = x.cvalue();
1397 Json_array_proxy(T& ref, int key)
1398 : base_(ref), key_(key) {
1404 class Json_get_proxy : public Json_proxy_base<Json_get_proxy> {
1406 const Json& cvalue() const {
1409 operator Json::unspecified_bool_type() const {
1410 return status_ ? &Json::is_null : 0;
1412 bool operator!() const {
1415 bool status() const {
1418 const Json_get_proxy& status(bool& x) const {
1422 Json_get_proxy(const Json& ref, bool status)
1423 : base_(ref), status_(status) {
1428 Json_get_proxy& operator=(const Json_get_proxy& x);
1431 template <typename T>
1432 inline const Json_get_proxy Json_proxy_base<T>::get(Str key, Json& x) const {
1433 return cvalue().get(key, x);
1435 template <typename T>
1436 inline const Json_get_proxy Json_proxy_base<T>::get(Str key, int& x) const {
1437 return cvalue().get(key, x);
1439 template <typename T>
1440 inline const Json_get_proxy Json_proxy_base<T>::get(Str key, unsigned& x) const {
1441 return cvalue().get(key, x);
1443 template <typename T>
1444 inline const Json_get_proxy Json_proxy_base<T>::get(Str key, long& x) const {
1445 return cvalue().get(key, x);
1447 template <typename T>
1448 inline const Json_get_proxy Json_proxy_base<T>::get(Str key, unsigned long& x) const {
1449 return cvalue().get(key, x);
1451 template <typename T>
1452 inline const Json_get_proxy Json_proxy_base<T>::get(Str key, long long& x) const {
1453 return cvalue().get(key, x);
1455 template <typename T>
1456 inline const Json_get_proxy Json_proxy_base<T>::get(Str key, unsigned long long& x) const {
1457 return cvalue().get(key, x);
1459 template <typename T>
1460 inline const Json_get_proxy Json_proxy_base<T>::get(Str key, double& x) const {
1461 return cvalue().get(key, x);
1463 template <typename T>
1464 inline const Json_get_proxy Json_proxy_base<T>::get(Str key, bool& x) const {
1465 return cvalue().get(key, x);
1467 template <typename T>
1468 inline const Json_get_proxy Json_proxy_base<T>::get(Str key, Str& x) const {
1469 return cvalue().get(key, x);
1471 template <typename T>
1472 inline const Json_get_proxy Json_proxy_base<T>::get(Str key, String& x) const {
1473 return cvalue().get(key, x);
1477 /** @brief Construct a null Json. */
1478 inline Json::Json() {
1479 memset(&u_, 0, sizeof(u_));
1481 /** @brief Construct a null Json. */
1482 inline Json::Json(const null_t&) {
1483 memset(&u_, 0, sizeof(u_));
1485 /** @brief Construct a Json copy of @a x. */
1486 inline Json::Json(const Json& x)
1490 if (u_.x.x && (u_.x.type == j_array || u_.x.type == j_object))
1494 template <typename P> inline Json::Json(const Json_proxy_base<P>& x)
1495 : u_(x.cvalue().u_) {
1498 if (u_.x.x && (u_.x.type == j_array || u_.x.type == j_object))
1501 #if HAVE_CXX_RVALUE_REFERENCES
1503 inline Json::Json(Json&& x)
1504 : u_(std::move(x.u_)) {
1505 memset(&x, 0, sizeof(x));
1508 /** @brief Construct simple Json values. */
1509 inline Json::Json(int x) {
1513 inline Json::Json(unsigned x) {
1515 u_.u.type = j_unsigned;
1517 inline Json::Json(long x) {
1521 inline Json::Json(unsigned long x) {
1523 u_.u.type = j_unsigned;
1525 inline Json::Json(long long x) {
1529 inline Json::Json(unsigned long long x) {
1531 u_.u.type = j_unsigned;
1533 inline Json::Json(double x) {
1535 u_.d.type = j_double;
1537 inline Json::Json(bool x) {
1541 inline Json::Json(const String& x) {
1542 u_.str = x.internal_rep();
1545 inline Json::Json(Str x) {
1550 inline Json::Json(const char* x) {
1555 /** @brief Construct an array Json containing the elements of @a x. */
1556 template <typename T>
1557 inline Json::Json(const std::vector<T> &x) {
1558 u_.a.type = j_array;
1559 u_.a.x = ArrayJson::make(int(x.size()));
1560 for (typename std::vector<T>::const_iterator it = x.begin();
1561 it != x.end(); ++it) {
1562 new((void*) &u_.a.x->a[u_.a.x->size]) Json(*it);
1567 template <typename T> struct Json_iterator_initializer {
1568 template <typename I>
1569 static inline void run(Json& j, I first, I last) {
1570 for (j = Json::make_array(); first != last; ++first)
1571 j.push_back(Json(*first));
1574 template <typename T, typename U>
1575 struct Json_iterator_initializer<std::pair<T, U> > {
1576 template <typename I>
1577 static inline void run(Json& j, I first, I last) {
1578 for (j = Json::make_object(); first != last; ++first)
1579 j.set((*first).first, (*first).second);
1583 /** @brief Construct an array Json containing the elements in [@a first,
1585 template <typename T>
1586 inline Json::Json(T first, T last) {
1588 Json_iterator_initializer<typename std::iterator_traits<T>::value_type>::run(*this, first, last);
1592 inline void Json::deref() {
1595 else if (u_.x.x && unsigned(u_.x.type - j_array) < 2)
1596 u_.x.x->deref(json_type(u_.x.type));
1598 /** @endcond never */
1600 inline Json::~Json() {
1604 /** @brief Return an empty array-valued Json. */
1605 inline Json Json::make_array() {
1607 j.u_.x.type = j_array;
1610 /** @brief Return an array-valued Json containing @a args. */
1611 template <typename... Args>
1612 inline Json Json::array(Args&&... args) {
1614 j.u_.x.type = j_array;
1615 j.reserve(sizeof...(args));
1616 j.push_back_list(std::forward<Args>(args)...);
1619 /** @brief Return an empty array-valued Json with reserved space for @a n items. */
1620 inline Json Json::make_array_reserve(int n) {
1622 j.u_.a.type = j_array;
1623 j.u_.a.x = n ? ArrayJson::make(n) : 0;
1626 /** @brief Return an empty object-valued Json. */
1627 inline Json Json::make_object() {
1629 j.u_.o.type = j_object;
1632 /** @brief Return an empty object-valued Json. */
1633 template <typename... Args>
1634 inline Json Json::object(Args&&... rest) {
1636 j.u_.o.type = j_object;
1637 j.set_list(std::forward<Args>(rest)...);
1640 /** @brief Return a string-valued Json. */
1641 inline Json Json::make_string(const String &x) {
1645 inline Json Json::make_string(const char *s, int len) {
1646 return Json(String(s, len));
1649 /** @brief Test if this Json is truthy. */
1650 inline bool Json::truthy() const {
1651 return (u_.x.x ? u_.x.type >= 0 || u_.str.length
1652 : (unsigned) (u_.x.type - 1) < (unsigned) (j_int - 1));
1654 /** @brief Test if this Json is falsy. */
1655 inline bool Json::falsy() const {
1658 /** @brief Test if this Json is truthy.
1660 inline Json::operator unspecified_bool_type() const {
1661 return truthy() ? &Json::is_null : 0;
1663 /** @brief Return true if this Json is falsy. */
1664 inline bool Json::operator!() const {
1668 /** @brief Test this Json's type. */
1669 inline bool Json::is_null() const {
1670 return !u_.x.x && u_.x.type == j_null;
1672 inline bool Json::is_int() const {
1673 return unsigned(u_.x.type - j_int) <= unsigned(j_unsigned - j_int);
1675 inline bool Json::is_i() const {
1678 inline bool Json::is_unsigned() const {
1679 return u_.x.type == j_unsigned;
1681 inline bool Json::is_u() const {
1682 return is_unsigned();
1684 inline bool Json::is_signed() const {
1685 return u_.x.type == j_int;
1687 inline bool Json::is_nonnegint() const {
1688 return u_.x.type == j_unsigned
1689 || (u_.x.type == j_int && u_.i.x >= 0);
1691 inline bool Json::is_double() const {
1692 return u_.x.type == j_double;
1694 inline bool Json::is_d() const {
1697 inline bool Json::is_number() const {
1698 return unsigned(u_.x.type - j_int) <= unsigned(j_double - j_int);
1700 inline bool Json::is_n() const {
1703 inline bool Json::is_bool() const {
1704 return u_.x.type == j_bool;
1706 inline bool Json::is_b() const {
1709 inline bool Json::is_string() const {
1710 return u_.x.x && u_.x.type <= 0;
1712 inline bool Json::is_s() const {
1715 inline bool Json::is_array() const {
1716 return u_.x.type == j_array;
1718 inline bool Json::is_a() const {
1721 inline bool Json::is_object() const {
1722 return u_.x.type == j_object;
1724 inline bool Json::is_o() const {
1727 /** @brief Test if this Json is a primitive value, not including null. */
1728 inline bool Json::is_primitive() const {
1729 return u_.x.type >= j_int || (u_.x.x && u_.x.type <= 0);
1732 /** @brief Return true if this Json is null, an empty array, or an empty
1734 inline bool Json::empty() const {
1735 return unsigned(u_.x.type) < unsigned(j_int)
1736 && (!u_.x.x || u_.x.x->size == 0);
1738 /** @brief Return the number of elements in this complex Json.
1739 @pre is_array() || is_object() || is_null() */
1740 inline Json::size_type Json::size() const {
1741 precondition(unsigned(u_.x.type) < unsigned(j_int));
1742 return u_.x.x ? u_.x.x->size : 0;
1744 /** @brief Test if this complex Json is shared. */
1745 inline bool Json::shared() const {
1746 return u_.x.x && (u_.x.type == j_array || u_.x.type == j_object)
1747 && u_.x.x->refcount != 1;
1750 // Primitive methods
1752 /** @brief Return this Json converted to an integer.
1754 Converts any Json to an integer value. Numeric Jsons convert as you'd
1755 expect. Null Jsons convert to 0; false boolean Jsons to 0 and true
1756 boolean Jsons to 1; string Jsons to a number parsed from their initial
1757 portions; and array and object Jsons to size().
1759 inline int64_t Json::to_i() const {
1766 inline uint64_t Json::to_u() const {
1773 /** @brief Extract this integer Json's value into @a x.
1774 @param[out] x value storage
1775 @return True iff this Json stores an integer value.
1777 If false is returned (!is_number() or the number is not parseable as a
1778 pure integer), @a x remains unchanged. */
1779 inline bool Json::to_i(int& x) const {
1783 } else if (is_double() && u_.d.x == double(int(u_.d.x))) {
1791 inline bool Json::to_i(unsigned& x) const {
1795 } else if (is_double() && u_.d.x == double(unsigned(u_.d.x))) {
1796 x = unsigned(u_.d.x);
1803 inline bool Json::to_i(long& x) const {
1807 } else if (is_double() && u_.d.x == double(long(u_.d.x))) {
1815 inline bool Json::to_i(unsigned long& x) const {
1819 } else if (is_double() && u_.d.x == double((unsigned long) u_.d.x)) {
1820 x = (unsigned long) u_.d.x;
1827 inline bool Json::to_i(long long& x) const {
1831 } else if (is_double() && u_.d.x == double((long long) u_.d.x)) {
1832 x = (long long) u_.d.x;
1839 inline bool Json::to_i(unsigned long long& x) const {
1843 } else if (is_double() && u_.d.x == double((unsigned long long) u_.d.x)) {
1844 x = (unsigned long long) u_.d.x;
1850 /** @brief Return this Json converted to a 64-bit unsigned integer.
1852 See to_i() for the conversion rules. */
1853 inline uint64_t Json::to_u64() const {
1857 /** @brief Return the integer value of this numeric Json.
1860 inline int64_t Json::as_i() const {
1861 precondition(is_int() || is_double());
1862 return is_int() ? u_.i.x : int64_t(u_.d.x);
1865 /** @brief Return the integer value of this numeric Json or @a default_value. */
1866 inline int64_t Json::as_i(int64_t default_value) const {
1867 if (is_int() || is_double())
1870 return default_value;
1873 /** @brief Return the unsigned integer value of this numeric Json.
1876 inline uint64_t Json::as_u() const {
1877 precondition(is_int() || is_double());
1878 return is_int() ? u_.u.x : uint64_t(u_.d.x);
1881 /** @brief Return the integer value of this numeric Json or @a default_value. */
1882 inline uint64_t Json::as_u(uint64_t default_value) const {
1883 if (is_int() || is_double())
1886 return default_value;
1889 /** @brief Return this Json converted to a double.
1891 Converts any Json to an integer value. Numeric Jsons convert as you'd
1892 expect. Null Jsons convert to 0; false boolean Jsons to 0 and true
1893 boolean Jsons to 1; string Jsons to a number parsed from their initial
1894 portions; and array and object Jsons to size().
1896 inline double Json::to_d() const {
1903 /** @brief Extract this numeric Json's value into @a x.
1904 @param[out] x value storage
1905 @return True iff is_number().
1907 If !is_number(), @a x remains unchanged. */
1908 inline bool Json::to_d(double& x) const {
1909 if (is_double() || is_int()) {
1916 /** @brief Return the double value of this numeric Json.
1919 inline double Json::as_d() const {
1920 precondition(is_double() || is_int());
1923 else if (u_.x.type == j_int)
1929 /** @brief Return the double value of this numeric Json or @a default_value. */
1930 inline double Json::as_d(double default_value) const {
1931 if (!is_double() && !is_int())
1932 return default_value;
1937 /** @brief Return this Json converted to a boolean.
1939 Converts any Json to a boolean value. Boolean Jsons convert as you'd
1940 expect. Null Jsons convert to false; zero-valued numeric Jsons to false,
1941 and other numeric Jsons to true; empty string Jsons to false, and other
1942 string Jsons to true; and array and object Jsons to !empty().
1944 inline bool Json::to_b() const {
1951 /** @brief Extract this boolean Json's value into @a x.
1952 @param[out] x value storage
1953 @return True iff is_bool().
1955 If !is_bool(), @a x remains unchanged. */
1956 inline bool Json::to_b(bool& x) const {
1964 /** @brief Return the value of this boolean Json.
1967 inline bool Json::as_b() const {
1968 precondition(is_bool());
1972 /** @brief Return the boolean value of this numeric Json or @a default_value. */
1973 inline bool Json::as_b(bool default_value) const {
1977 return default_value;
1980 /** @brief Return this Json converted to a string.
1982 Converts any Json to a string value. String Jsons convert as you'd expect.
1983 Null Jsons convert to the empty string; numeric Jsons to their string
1984 values; boolean Jsons to "false" or "true"; and array and object Jsons to
1985 "[Array]" and "[Object]", respectively.
1987 inline String Json::to_s() const {
1988 if (u_.x.type <= 0 && u_.x.x)
1989 return String(u_.str);
1994 /** @brief Extract this string Json's value into @a x.
1995 @param[out] x value storage
1996 @return True iff is_string().
1998 If !is_string(), @a x remains unchanged. */
1999 inline bool Json::to_s(Str& x) const {
2000 if (u_.x.type <= 0 && u_.x.x) {
2001 x.assign(u_.str.data, u_.str.length);
2007 /** @brief Extract this string Json's value into @a x.
2008 @param[out] x value storage
2009 @return True iff is_string().
2011 If !is_string(), @a x remains unchanged. */
2012 inline bool Json::to_s(String& x) const {
2013 if (u_.x.type <= 0 && u_.x.x) {
2020 /** @brief Return the value of this string Json.
2023 inline const String& Json::as_s() const {
2024 precondition(u_.x.type <= 0 && u_.x.x);
2025 return reinterpret_cast<const String&>(u_.str);
2029 inline String& Json::as_s() {
2030 precondition(u_.x.type <= 0 && u_.x.x);
2031 return reinterpret_cast<String&>(u_.str);
2034 /** @brief Return the value of this string Json or @a default_value. */
2035 inline const String& Json::as_s(const String& default_value) const {
2036 if (u_.x.type > 0 || !u_.x.x)
2037 return default_value;
2042 inline void Json::force_number() {
2043 precondition((u_.x.type == j_null && !u_.x.x) || u_.x.type == j_int || u_.x.type == j_double);
2044 if (u_.x.type == j_null && !u_.x.x)
2048 inline void Json::force_double() {
2049 precondition((u_.x.type == j_null && !u_.x.x) || u_.x.type == j_int || u_.x.type == j_double);
2050 if (u_.x.type == j_null && !u_.x.x)
2051 u_.x.type = j_double;
2052 else if (u_.x.type == j_int) {
2054 u_.d.type = j_double;
2055 } else if (u_.x.type == j_unsigned) {
2057 u_.d.type = j_double;
2064 /** @brief Return 1 if this object Json contains @a key, 0 otherwise.
2066 Returns 0 if this is not an object Json. */
2067 inline Json::size_type Json::count(Str key) const {
2068 precondition(u_.x.type == j_null || u_.x.type == j_object);
2069 return u_.o.x ? ojson()->find(key.data(), key.length()) >= 0 : 0;
2072 /** @brief Return the value at @a key in an object or array Json.
2074 If this is an array Json, and @a key is the simplest base-10
2075 representation of an integer <em>i</em>, then returns get(<em>i</em>). If
2076 this is neither an array nor an object, returns a null Json. */
2077 inline const Json& Json::get(Str key) const {
2080 if (is_object() && (oj = ojson())
2081 && (i = oj->find(key.data(), key.length())) >= 0)
2082 return oj->item(i).v_.second;
2084 return hard_get(key);
2087 /** @brief Return a reference to the value of @a key in an object Json.
2089 This Json is first converted to an object. Arrays are converted to objects
2090 with numeric keys. Other types of Json are converted to empty objects.
2091 If !count(@a key), then a null Json is inserted at @a key. */
2092 inline Json& Json::get_insert(const String &key) {
2093 uniqueify_object(true);
2094 return ojson()->get_insert(key);
2098 inline Json& Json::get_insert(Str key) {
2099 uniqueify_object(true);
2100 return ojson()->get_insert(key);
2104 inline Json& Json::get_insert(const char *key) {
2105 uniqueify_object(true);
2106 return ojson()->get_insert(Str(key));
2109 /** @brief Return get(@a key).to_i(). */
2110 inline long Json::get_i(Str key) const {
2111 return get(key).to_i();
2114 /** @brief Return get(@a key).to_d(). */
2115 inline double Json::get_d(Str key) const {
2116 return get(key).to_d();
2119 /** @brief Return get(@a key).to_b(). */
2120 inline bool Json::get_b(Str key) const {
2121 return get(key).to_b();
2124 /** @brief Return get(@a key).to_s(). */
2125 inline String Json::get_s(Str key) const {
2126 return get(key).to_s();
2129 /** @brief Extract this object Json's value at @a key into @a x.
2130 @param[out] x value storage
2131 @return proxy for *this
2133 @a x is assigned iff count(@a key). The return value is a proxy
2134 object that mostly behaves like *this. However, the proxy is "truthy"
2135 iff count(@a key) and @a x was assigned. The proxy also has status()
2136 methods that return the extraction status. For example:
2139 Json j = Json::parse("{\"a\":1,\"b\":2}"), x;
2140 assert(j.get("a", x)); // extraction succeeded
2141 assert(x == Json(1));
2142 assert(!j.get("c", x)); // no "c" key
2143 assert(x == Json(1)); // x remains unchanged
2144 assert(!j.get("c", x).status()); // can use ".status()" for clarity
2146 // Can chain .get() methods to extract multiple values
2148 j.get("a", a).get("b", b);
2149 assert(a == Json(1) && b == Json(2));
2151 // Use .status() to return or assign extraction status
2152 bool a_status, b_status, c_status;
2153 j.get("a", a).status(a_status)
2154 .get("b", b).status(b_status)
2155 .get("c", c).status(c_status);
2156 assert(a_status && b_status && !c_status);
2159 Overloaded versions of @a get() can extract integer, double, boolean,
2160 and string values for specific keys. These versions succeed iff
2161 count(@a key) and the corresponding value has the expected type. For
2165 Json j = Json::parse("{\"a\":1,\"b\":\"\"}");
2167 bool a_status, b_status;
2168 j.get("a", a).status(a_status).get("b", b).status(b_status);
2169 assert(a_status && a == 1 && !b_status);
2171 inline const Json_get_proxy Json::get(Str key, Json& x) const {
2174 if (is_object() && (oj = ojson())
2175 && (i = oj->find(key.data(), key.length())) >= 0) {
2176 x = oj->item(i).v_.second;
2177 return Json_get_proxy(*this, true);
2179 return Json_get_proxy(*this, false);
2183 inline const Json_get_proxy Json::get(Str key, int &x) const {
2184 return Json_get_proxy(*this, get(key).to_i(x));
2188 inline const Json_get_proxy Json::get(Str key, unsigned& x) const {
2189 return Json_get_proxy(*this, get(key).to_i(x));
2193 inline const Json_get_proxy Json::get(Str key, long& x) const {
2194 return Json_get_proxy(*this, get(key).to_i(x));
2198 inline const Json_get_proxy Json::get(Str key, unsigned long& x) const {
2199 return Json_get_proxy(*this, get(key).to_i(x));
2203 inline const Json_get_proxy Json::get(Str key, long long& x) const {
2204 return Json_get_proxy(*this, get(key).to_i(x));
2208 inline const Json_get_proxy Json::get(Str key, unsigned long long& x) const {
2209 return Json_get_proxy(*this, get(key).to_i(x));
2213 inline const Json_get_proxy Json::get(Str key, double& x) const {
2214 return Json_get_proxy(*this, get(key).to_d(x));
2218 inline const Json_get_proxy Json::get(Str key, bool& x) const {
2219 return Json_get_proxy(*this, get(key).to_b(x));
2223 inline const Json_get_proxy Json::get(Str key, Str& x) const {
2224 return Json_get_proxy(*this, get(key).to_s(x));
2228 inline const Json_get_proxy Json::get(Str key, String& x) const {
2229 return Json_get_proxy(*this, get(key).to_s(x));
2233 /** @brief Return the value at @a key in an object or array Json.
2235 inline const Json& Json::operator[](Str key) const {
2239 /** @brief Return a proxy reference to the value at @a key in an object Json.
2241 Returns the current @a key value if it exists. Otherwise, returns a proxy
2242 that acts like a null Json. If this proxy is assigned, this Json is
2243 converted to an object as by get_insert(), and then extended as necessary
2244 to contain the new value. */
2245 inline Json_object_proxy<Json> Json::operator[](const String& key) {
2246 return Json_object_proxy<Json>(*this, key);
2250 inline Json_object_str_proxy<Json> Json::operator[](Str key) {
2251 return Json_object_str_proxy<Json>(*this, key);
2255 inline Json_object_str_proxy<Json> Json::operator[](const char* key) {
2256 return Json_object_str_proxy<Json>(*this, key);
2259 /** @brief Return the value at @a key in an object Json.
2260 @pre is_object() && count(@a key) */
2261 inline const Json& Json::at(Str key) const {
2262 precondition(is_object() && u_.o.x);
2263 ObjectJson *oj = ojson();
2264 int i = oj->find(key.data(), key.length());
2265 precondition(i >= 0);
2266 return oj->item(i).v_.second;
2269 /** @brief Return a reference to the value at @a key in an object Json.
2272 Returns a newly-inserted null Json if !count(@a key). */
2273 inline Json& Json::at_insert(const String &key) {
2274 precondition(is_object());
2275 return get_insert(key);
2279 inline Json& Json::at_insert(Str key) {
2280 precondition(is_object());
2281 return get_insert(key);
2285 inline Json& Json::at_insert(const char *key) {
2286 precondition(is_object());
2287 return get_insert(Str(key));
2290 /** @brief Set the value of @a key to @a value in this object Json.
2293 An array Json is converted to an object Json with numeric keys. Other
2294 non-object Jsons are converted to empty objects. */
2295 inline Json& Json::set(const String& key, Json value) {
2296 uniqueify_object(true);
2297 ojson()->get_insert(key) = std::move(value);
2302 template <typename P>
2303 inline Json& Json::set(const String& key, const Json_proxy_base<P>& value) {
2304 uniqueify_object(true);
2305 ojson()->get_insert(key) = value.cvalue();
2309 /** @brief Remove the value of @a key from an object Json.
2312 inline Json& Json::unset(Str key) {
2314 uniqueify_object(true);
2315 ojson()->erase(key);
2320 /** @brief Add the key-value pairs [key, value, ...] to the object.
2323 An array Json is converted to an object Json with numeric keys. Other
2324 non-object Jsons are converted to empty objects. */
2325 template <typename T, typename... Args>
2326 inline Json& Json::set_list(const String& key, T value, Args&&... rest) {
2327 set(key, std::move(value));
2328 set_list(std::forward<Args>(rest)...);
2333 inline Json& Json::set_list() {
2337 /** @brief Insert element @a x in this object Json.
2338 @param x Pair of key and value.
2339 @return Pair of iterator pointing to key's value and bool indicating
2340 whether the value is newly inserted.
2343 An existing element with key @a x.first is not replaced. */
2344 inline std::pair<Json::object_iterator, bool> Json::insert(const object_value_type& x) {
2345 precondition(is_object());
2346 uniqueify_object(false);
2347 ObjectJson *oj = ojson();
2348 int n = oj->n_, i = oj->find_insert(x.first, x.second);
2349 return std::make_pair(object_iterator(this, i), i == n);
2352 /** @brief Insert element @a x in this object Json.
2353 @param position Ignored.
2354 @param x Pair of key and value.
2355 @return Pair of iterator pointing to key's value and bool indicating
2356 whether the value is newly inserted.
2359 An existing element with key @a x.first is not replaced. */
2360 inline Json::object_iterator Json::insert(object_iterator position, const object_value_type& x) {
2362 return insert(x).first;
2365 /** @brief Remove the value pointed to by @a it from an object Json.
2367 @return Next iterator */
2368 inline Json::object_iterator Json::erase(Json::object_iterator it) {
2369 precondition(is_object() && it.live() && it.j_ == this);
2370 uniqueify_object(false);
2371 ojson()->erase(it.i_);
2376 /** @brief Remove the value of @a key from an object Json.
2378 @return Number of items removed */
2379 inline Json::size_type Json::erase(Str key) {
2380 precondition(is_object());
2381 uniqueify_object(false);
2382 return ojson()->erase(key);
2385 /** @brief Merge the values of object Json @a x into this object Json.
2386 @pre (is_object() || is_null()) && (x.is_object() || x.is_null())
2389 The key-value pairs in @a x are assigned to this Json. Null Jsons are
2390 silently converted to empty objects, except that if @a x and this Json are
2391 both null, then this Json is left as null. */
2392 inline Json& Json::merge(const Json& x) {
2393 precondition(is_object() || is_null());
2394 precondition(x.is_object() || x.is_null());
2396 uniqueify_object(false);
2397 ObjectJson *oj = ojson(), *xoj = x.ojson();
2398 const ObjectItem *xb = xoj->os_, *xe = xb + xoj->n_;
2399 for (; xb != xe; ++xb)
2401 oj->get_insert(xb->v_.first) = xb->v_.second;
2407 template <typename U>
2408 inline Json& Json::merge(const Json_proxy_base<U>& x) {
2409 return merge(x.cvalue());
2411 /** @endcond never */
2416 /** @brief Return the @a x th array element.
2418 If @a x is out of range of this array, returns a null Json. If this is an
2419 object Json, then returns get(String(@a x)). If this is neither an object
2420 nor an array, returns a null Json. */
2421 inline const Json& Json::get(size_type x) const {
2423 if (u_.x.type == j_array && (aj = ajson()) && unsigned(x) < unsigned(aj->size))
2429 /** @brief Return a reference to the @a x th array element.
2431 If this Json is an object, returns get_insert(String(x)). Otherwise this
2432 Json is first converted to an array; non-arrays are converted to empty
2433 arrays. The array is extended if @a x is out of range. */
2434 inline Json& Json::get_insert(size_type x) {
2436 if (u_.x.type == j_array && (aj = ajson()) && aj->refcount == 1
2437 && unsigned(x) < unsigned(aj->size))
2440 return hard_get_insert(x);
2443 /** @brief Return the @a x th element in an array Json.
2446 A null Json is treated like an empty array. */
2447 inline const Json& Json::at(size_type x) const {
2448 precondition(is_array());
2452 /** @brief Return a reference to the @a x th element in an array Json.
2455 The array is extended if @a x is out of range. */
2456 inline Json& Json::at_insert(size_type x) {
2457 precondition(is_array());
2458 return get_insert(x);
2461 /** @brief Return the @a x th array element.
2463 If @a x is out of range of this array, returns a null Json. If this is an
2464 object Json, then returns get(String(@a x)). If this is neither an object
2465 nor an array, returns a null Json. */
2466 inline const Json& Json::operator[](size_type x) const {
2470 /** @brief Return a proxy reference to the @a x th array element.
2472 If this Json is an object, returns operator[](String(x)). If this Json is
2473 an array and @a x is in range, returns that element. Otherwise, returns a
2474 proxy that acts like a null Json. If this proxy is assigned, this Json is
2475 converted to an array, and then extended as necessary to contain the new
2477 inline Json_array_proxy<Json> Json::operator[](size_type x) {
2478 return Json_array_proxy<Json>(*this, x);
2481 /** @brief Return the last array element.
2482 @pre is_array() && !empty() */
2483 inline const Json& Json::back() const {
2484 precondition(is_array() && u_.a.x && u_.a.x->size > 0);
2485 return u_.a.x->a[u_.a.x->size - 1];
2488 /** @brief Return a reference to the last array element.
2489 @pre is_array() && !empty() */
2490 inline Json& Json::back() {
2491 precondition(is_array() && u_.a.x && u_.a.x->size > 0);
2492 uniqueify_array(false, 0);
2493 return u_.a.x->a[u_.a.x->size - 1];
2496 /** @brief Push an element onto the back of the array.
2497 @pre is_array() || is_null()
2500 A null Json is promoted to an array. */
2501 inline Json& Json::push_back(Json x) {
2502 new(uniqueify_array_insert(false, -1)) Json(std::move(x));
2507 template <typename P> inline Json& Json::push_back(const Json_proxy_base<P>& x) {
2508 new(uniqueify_array_insert(false, -1)) Json(x.cvalue());
2512 /** @brief Remove the last element from an array.
2513 @pre is_array() && !empty() */
2514 inline void Json::pop_back() {
2515 precondition(is_array() && u_.a.x && u_.a.x->size > 0);
2516 uniqueify_array(false, 0);
2518 u_.a.x->a[u_.a.x->size].~Json();
2521 inline Json& Json::push_back_list() {
2525 /** @brief Insert the items [first, rest...] onto the back of this array.
2526 @pre is_array() || is_null()
2529 A null Json is promoted to an array. */
2530 template <typename T, typename... Args>
2531 inline Json& Json::push_back_list(T first, Args&&... rest) {
2532 push_back(std::move(first));
2533 push_back_list(std::forward<Args>(rest)...);
2538 /** @brief Insert an element into the array.
2539 @pre is_array() || is_null()
2542 A null Json is promoted to an array. */
2543 inline Json::array_iterator Json::insert(array_iterator position, Json x) {
2544 precondition(position >= abegin() && position <= aend());
2545 size_type pos = position - abegin();
2546 new(uniqueify_array_insert(false, pos)) Json(std::move(x));
2547 return abegin() + pos;
2551 template <typename P> inline Json::array_iterator Json::insert(array_iterator position, const Json_proxy_base<P>& x) {
2552 precondition(position >= abegin() && position <= aend());
2553 size_type pos = position - abegin();
2554 new(uniqueify_array_insert(false, pos)) Json(x.cvalue());
2555 return abegin() + pos;
2558 inline Json::array_iterator Json::erase(array_iterator position) {
2559 return erase(position, position + 1);
2563 inline Json* Json::array_data() {
2564 precondition(is_null() || is_array());
2565 uniqueify_array(false, 0);
2566 return u_.a.x ? u_.a.x->a : 0;
2569 inline const Json* Json::array_data() const {
2570 precondition(is_null() || is_array());
2571 return u_.a.x ? u_.a.x->a : 0;
2574 inline const Json* Json::array_cdata() const {
2575 precondition(is_null() || is_array());
2576 return u_.a.x ? u_.a.x->a : 0;
2579 inline Json* Json::end_array_data() {
2580 precondition(is_null() || is_array());
2581 uniqueify_array(false, 0);
2582 return u_.a.x ? u_.a.x->a + u_.a.x->size : 0;
2585 inline const Json* Json::end_array_data() const {
2586 precondition(is_null() || is_array());
2587 return u_.a.x ? u_.a.x->a + u_.a.x->size : 0;
2590 inline const Json* Json::end_array_cdata() const {
2591 precondition(is_null() || is_array());
2592 return u_.a.x ? u_.a.x->a + u_.a.x->size : 0;
2596 inline Json::const_object_iterator Json::cobegin() const {
2597 precondition(is_null() || is_object());
2598 return const_object_iterator(this, 0);
2601 inline Json::const_object_iterator Json::coend() const {
2602 precondition(is_null() || is_object());
2603 return const_object_iterator(this, -1);
2606 inline Json::const_object_iterator Json::obegin() const {
2610 inline Json::const_object_iterator Json::oend() const {
2614 inline Json::object_iterator Json::obegin() {
2615 precondition(is_null() || is_object());
2616 return object_iterator(this, 0);
2619 inline Json::object_iterator Json::oend() {
2620 precondition(is_null() || is_object());
2621 return object_iterator(this, -1);
2624 inline Json::const_array_iterator Json::cabegin() const {
2625 precondition(is_null() || is_array());
2626 return const_array_iterator(this, 0);
2629 inline Json::const_array_iterator Json::caend() const {
2630 precondition(is_null() || is_array());
2631 ArrayJson *aj = ajson();
2632 return const_array_iterator(this, aj ? aj->size : 0);
2635 inline Json::const_array_iterator Json::abegin() const {
2639 inline Json::const_array_iterator Json::aend() const {
2643 inline Json::array_iterator Json::abegin() {
2644 precondition(is_null() || is_array());
2645 return array_iterator(this, 0);
2648 inline Json::array_iterator Json::aend() {
2649 precondition(is_null() || is_array());
2650 ArrayJson *aj = ajson();
2651 return array_iterator(this, aj ? aj->size : 0);
2654 inline Json::const_iterator Json::cbegin() const {
2655 return const_iterator(this, 0);
2658 inline Json::const_iterator Json::cend() const {
2659 return const_iterator(this, -1);
2662 inline Json::iterator Json::begin() {
2663 return iterator(this, 0);
2666 inline Json::iterator Json::end() {
2667 return iterator(this, -1);
2670 inline Json::const_iterator Json::begin() const {
2674 inline Json::const_iterator Json::end() const {
2680 class Json::unparse_manipulator {
2682 unparse_manipulator()
2683 : indent_depth_(0), tab_width_(0), newline_terminator_(false),
2684 space_separator_(false) {
2686 int indent_depth() const {
2687 return indent_depth_;
2689 unparse_manipulator indent_depth(int x) const {
2690 unparse_manipulator m(*this);
2691 m.indent_depth_ = x;
2694 int tab_width() const {
2697 unparse_manipulator tab_width(int x) const {
2698 unparse_manipulator m(*this);
2702 bool newline_terminator() const {
2703 return newline_terminator_;
2705 unparse_manipulator newline_terminator(bool x) const {
2706 unparse_manipulator m(*this);
2707 m.newline_terminator_ = x;
2710 bool space_separator() const {
2711 return space_separator_;
2713 unparse_manipulator space_separator(bool x) const {
2714 unparse_manipulator m(*this);
2715 m.space_separator_ = x;
2718 bool empty() const {
2719 return !indent_depth_ && !newline_terminator_ && !space_separator_;
2724 bool newline_terminator_;
2725 bool space_separator_;
2728 inline Json::unparse_manipulator Json::indent_depth(int x) {
2729 return unparse_manipulator().indent_depth(x);
2731 inline Json::unparse_manipulator Json::tab_width(int x) {
2732 return unparse_manipulator().tab_width(x);
2734 inline Json::unparse_manipulator Json::newline_terminator(bool x) {
2735 return unparse_manipulator().newline_terminator(x);
2737 inline Json::unparse_manipulator Json::space_separator(bool x) {
2738 return unparse_manipulator().space_separator(x);
2741 /** @brief Return the string representation of this Json. */
2742 inline String Json::unparse() const {
2744 hard_unparse(sa, default_manipulator, 0);
2745 return sa.take_string();
2748 /** @brief Return the string representation of this Json.
2749 @param add_newline If true, add a final newline. */
2750 inline String Json::unparse(const unparse_manipulator &m) const {
2752 hard_unparse(sa, m, 0);
2753 return sa.take_string();
2756 /** @brief Unparse the string representation of this Json into @a sa. */
2757 inline void Json::unparse(StringAccum &sa) const {
2758 hard_unparse(sa, default_manipulator, 0);
2761 /** @brief Unparse the string representation of this Json into @a sa. */
2762 inline void Json::unparse(StringAccum &sa, const unparse_manipulator &m) const {
2763 hard_unparse(sa, m, 0);
2769 class Json::streaming_parser {
2771 inline streaming_parser();
2772 inline void reset();
2774 inline bool done() const;
2775 inline bool success() const;
2776 inline bool error() const;
2778 inline size_t consume(const char* first, size_t length,
2779 const String& str = String(),
2780 bool complete = false);
2781 inline const char* consume(const char* first, const char* last,
2782 const String& str = String(),
2783 bool complete = false);
2784 const uint8_t* consume(const uint8_t* first, const uint8_t* last,
2785 const String& str = String(),
2786 bool complete = false);
2788 inline Json& result();
2789 inline const Json& result() const;
2793 st_final = -2, st_error = -1,
2794 st_partlenmask = 0x0F, st_partmask = 0xFF,
2795 st_stringpart = 0x10, st_primitivepart = 0x20, st_numberpart = 0x40,
2798 st_array_initial = 0x100,
2799 st_array_value = 0x200,
2800 st_object_value = 0x300,
2802 st_array_delim = 0x400,
2803 st_object_delim = 0x500,
2804 st_object_initial = 0x600,
2805 st_object_key = 0x700,
2806 st_object_colon = 0x800,
2812 std::vector<Json*> stack_;
2816 inline Json* current();
2817 const uint8_t* error_at(const uint8_t* here);
2818 const uint8_t* consume_string(const uint8_t* first, const uint8_t* last, const String& str);
2819 const uint8_t* consume_backslash(StringAccum& sa, const uint8_t* first, const uint8_t* last);
2820 const uint8_t* consume_stringpart(StringAccum& sa, const uint8_t* first, const uint8_t* last);
2821 const uint8_t* consume_primitive(const uint8_t* first, const uint8_t* last, Json& j);
2822 const uint8_t* consume_number(const uint8_t* first, const uint8_t* last, const String& str, bool complete, Json& j);
2825 inline Json::streaming_parser::streaming_parser()
2826 : state_(st_initial) {
2829 inline void Json::streaming_parser::reset() {
2830 state_ = st_initial;
2834 inline bool Json::streaming_parser::done() const {
2838 inline bool Json::streaming_parser::success() const {
2839 return state_ == st_final;
2842 inline bool Json::streaming_parser::error() const {
2843 return state_ == st_error;
2846 inline size_t Json::streaming_parser::consume(const char* first, size_t length,
2849 const uint8_t* ufirst = reinterpret_cast<const uint8_t*>(first);
2850 return consume(ufirst, ufirst + length, str, complete) - ufirst;
2853 inline const char* Json::streaming_parser::consume(const char* first,
2857 return reinterpret_cast<const char*>
2858 (consume(reinterpret_cast<const uint8_t*>(first),
2859 reinterpret_cast<const uint8_t*>(last), str, complete));
2862 inline Json& Json::streaming_parser::result() {
2866 inline const Json& Json::streaming_parser::result() const {
2871 /** @brief Parse @a str as UTF-8 JSON into this Json object.
2872 @return true iff the parse succeeded.
2874 An unsuccessful parse does not modify *this. */
2875 inline bool Json::assign_parse(const String &str) {
2876 return assign_parse(str.begin(), str.end(), str);
2879 /** @brief Parse [@a first, @a last) as UTF-8 JSON into this Json object.
2880 @return true iff the parse succeeded.
2882 An unsuccessful parse does not modify *this. */
2883 inline bool Json::assign_parse(const char *first, const char *last) {
2884 return assign_parse(first, last, String());
2887 /** @brief Return @a str parsed as UTF-8 JSON.
2889 Returns a null JSON object if the parse fails. */
2890 inline Json Json::parse(const String &str) {
2892 (void) j.assign_parse(str);
2896 /** @brief Return [@a first, @a last) parsed as UTF-8 JSON.
2898 Returns a null JSON object if the parse fails. */
2899 inline Json Json::parse(const char *first, const char *last) {
2901 (void) j.assign_parse(first, last);
2908 inline Json& Json::operator=(const Json& x) {
2909 if (x.u_.x.type < 0)
2911 else if (x.u_.x.x && (x.u_.x.type == j_array || x.u_.x.type == j_object))
2918 #if HAVE_CXX_RVALUE_REFERENCES
2919 inline Json& Json::operator=(Json&& x) {
2927 template <typename U>
2928 inline Json& Json::operator=(const Json_proxy_base<U> &x) {
2929 return *this = x.cvalue();
2932 inline Json& Json::operator=(int x) {
2939 inline Json& Json::operator=(unsigned x) {
2942 u_.u.type = j_unsigned;
2946 inline Json& Json::operator=(long x) {
2953 inline Json& Json::operator=(unsigned long x) {
2956 u_.u.type = j_unsigned;
2960 inline Json& Json::operator=(long long x) {
2967 inline Json& Json::operator=(unsigned long long x) {
2970 u_.u.type = j_unsigned;
2974 inline Json& Json::operator=(double x) {
2977 u_.d.type = j_double;
2981 inline Json& Json::operator=(bool x) {
2988 inline Json& Json::operator=(const String& x) {
2990 u_.str = x.internal_rep();
2994 /** @endcond never */
2996 inline Json& Json::operator++() {
2999 inline void Json::operator++(int) {
3002 inline Json& Json::operator--() {
3005 inline void Json::operator--(int) {
3008 inline Json& Json::add(double x) {
3013 template <typename T>
3014 inline Json& Json::add(T x) {
3022 inline Json& Json::subtract(double x) {
3027 template <typename T>
3028 inline Json& Json::subtract(T x) {
3036 inline Json& Json::operator+=(int x) {
3039 inline Json& Json::operator+=(unsigned x) {
3042 inline Json& Json::operator+=(long x) {
3045 inline Json& Json::operator+=(unsigned long x) {
3048 inline Json& Json::operator+=(long long x) {
3051 inline Json& Json::operator+=(unsigned long long x) {
3054 inline Json& Json::operator+=(double x) {
3057 inline Json& Json::operator-=(int x) {
3060 inline Json& Json::operator-=(unsigned x) {
3063 inline Json& Json::operator-=(long x) {
3066 inline Json& Json::operator-=(unsigned long x) {
3069 inline Json& Json::operator-=(long long x) {
3072 inline Json& Json::operator-=(unsigned long long x) {
3075 inline Json& Json::operator-=(double x) {
3078 inline Json& Json::operator+=(const Json& x) {
3080 // XXX what if both are integers
3082 u_.d.x = as_d() + x.as_d();
3083 u_.d.type = j_double;
3087 inline Json& Json::operator-=(const Json& x) {
3089 // XXX what if both are integers
3091 u_.d.x = as_d() - x.as_d();
3092 u_.d.type = j_double;
3096 inline Json operator+(Json x) {
3100 inline Json operator-(Json x) {
3103 x.u_.u.x = -x.u_.u.x;
3105 x.u_.d.x = -x.u_.d.x;
3109 /** @brief Swap this Json with @a x. */
3110 inline void Json::swap(Json& x) {
3116 inline StringAccum &operator<<(StringAccum &sa, const Json& json) {
3121 template <typename P>
3122 inline StringAccum &operator<<(StringAccum &sa, const Json_proxy_base<P> &json) {
3123 return (sa << json.cvalue());
3126 inline std::ostream &operator<<(std::ostream& f, const Json& json) {
3129 return f.write(sa.data(), sa.length());
3132 template <typename P>
3133 inline std::ostream &operator<<(std::ostream& f, const Json_proxy_base<P>& json) {
3134 return (f << json.cvalue());
3137 bool operator==(const Json& a, const Json& b);
3139 template <typename T>
3140 inline bool operator==(const Json_proxy_base<T>& a, const Json& b) {
3141 return a.cvalue() == b;
3144 template <typename T>
3145 inline bool operator==(const Json& a, const Json_proxy_base<T>& b) {
3146 return a == b.cvalue();
3149 template <typename T, typename U>
3150 inline bool operator==(const Json_proxy_base<T>& a,
3151 const Json_proxy_base<U>& b) {
3152 return a.cvalue() == b.cvalue();
3155 inline bool operator!=(const Json& a, const Json& b) {
3159 template <typename T>
3160 inline bool operator!=(const Json_proxy_base<T>& a, const Json& b) {
3164 template <typename T>
3165 inline bool operator!=(const Json& a, const Json_proxy_base<T>& b) {
3169 template <typename T, typename U>
3170 inline bool operator!=(const Json_proxy_base<T>& a,
3171 const Json_proxy_base<U>& b) {
3175 inline void swap(Json& a, Json& b) {