30#define JSON_FMT_INDENT 0x01
31#define JSON_FMT_QUOTESLASH 0x02
32#define JSON_FMT_UTF8 0x04
34#define ERR_JSON_INVTYPE -1
35#define ERR_JSON_TOOMANY -2
36#define ERR_JSON_ITERTYPE -3
37#define ERR_JSON_ITERPOS -4
38#define ERR_JSON_INPUT -5
39#define ERR_JSON_SIZE -7
40#define ERR_JSON_MISSING -8
63 using pnode = std::unique_ptr<node>;
64 using nodes_map = std::map<const std::string, pnode>;
65 using nodes_array = std::vector<pnode>;
69 node (
const std::string& s);
76 node (
const std::vector<T>& vec);
79 node (
const T& t,
decltype (&T::to_json)* =
nullptr);
92 using difference_type = std::ptrdiff_t;
93 using value_type = node;
94 using reference =
typename std::conditional_t<C_, node const&, node&>;
95 using pointer =
typename std::conditional_t<C_, const node*, node*>;
97 typename std::conditional_t<C_, nodes_map::const_iterator, nodes_map::iterator>;
99 typename std::conditional_t<C_, nodes_array::const_iterator, nodes_array::iterator>;
100 using iterator_category = std::bidirectional_iterator_tag;
104 : target (other.target)
106 if (target.t == type::object)
107 new (&objit) obj_iter (other.objit);
108 else if (target.t == type::array)
109 new (&arrit) arr_iter (other.arrit);
111 at_end = other.at_end;
117 if (target.t == type::object)
118 (&objit)->~obj_iter ();
119 else if (target.t == type::array)
120 (&arrit)->~arr_iter ();
126 if (target.t == type::object)
128 if (objit == target.obj.end ())
130 return *objit->second;
132 else if (target.t == type::array)
134 if (arrit == target.arr.end ())
147 if (target.t == type::object)
149 if (objit == target.obj.end ())
151 return objit->second.get ();
153 else if (target.t == type::array)
155 if (arrit == target.arr.end ())
157 return arrit->get ();
165 const std::string&
name ()
const
167 if (target.t != type::object)
169 if (objit == target.obj.end ())
178 if (target.t == type::object)
180 else if (target.t == type::array)
192 if (target.t == type::object)
194 else if (target.t == type::array)
208 if (target.t == type::object)
210 else if (target.t == type::array)
222 if (target.t == type::object)
224 else if (target.t == type::array)
236 if (&target != &other.target)
238 else if (target.t == type::object)
239 return (objit == other.objit);
240 else if (target.t == type::array)
241 return (arrit == other.arrit);
243 return (at_end == other.at_end);
289 template <
class T,
typename B = decltype (&T::to_json)>
300 clear (type::boolean);
306 template <
typename T,
typename B = std::enable_if_t<std::is_arithmetic_v<T>>>
309 clear (type::numeric);
317 clear (type::string);
325 clear (type::string);
331 explicit operator std::string ()
const;
332 explicit operator const char* ()
const;
333 explicit operator double ()
const;
334 explicit operator float ()
const;
335 explicit operator int ()
const;
336 explicit operator bool ()
const;
338 double to_num ()
const;
339 std::string
to_str ()
const;
345 node&
at (
const std::string& name);
346 const node&
at (
const std::string& name)
const;
351 const node&
at (
size_t index)
const;
353 const_iterator
begin ()
const;
355 const_iterator
end ()
const;
365 mlib::erc write (std::ostream& os,
int flags = 0,
int spaces = 0,
int level = 0)
const;
366 mlib::erc write (std::string& s,
int flags = 0,
int spaces = 0)
const;
369 bool has (
const std::string& name)
const;
370 const node*
find (
const std::string& name)
const;
371 node*
find (
const std::string& name);
373 void erase (
const std::string& name);
424 new (&obj) nodes_array ();
425 for (
size_t i = 0; i < vec.size (); ++i)
426 arr.emplace_back (std::make_unique<node> (vec[i]));
434 new (&obj) nodes_map ();
441 if (t == type::object)
442 return const_iterator (*
this, obj.begin ());
443 else if (t == type::array)
444 return const_iterator (*
this, arr.begin ());
446 return const_iterator (*
this,
false);
452 if (t == type::object)
453 return iterator (*
this, obj.begin ());
454 else if (t == type::array)
455 return iterator (*
this, arr.begin ());
457 return iterator (*
this,
false);
463 if (t == type::object)
464 return const_iterator (*
this, obj.end ());
465 else if (t == type::array)
466 return const_iterator (*
this, arr.end ());
468 return const_iterator (*
this,
true);
474 if (t == type::object)
475 return iterator (*
this, obj.end ());
476 else if (t == type::array)
477 return iterator (*
this, arr.end ());
479 return iterator (*
this,
true);
483inline node::operator std::string ()
const
492inline node::operator
const char* ()
const
494 if (t != type::string)
500inline node::operator double ()
const
506inline node::operator float ()
const
508 return (
float)to_num ();
511inline node::operator int ()
const
513 return (
int)to_num ();
517inline node::operator bool ()
const
529 (&obj)->~nodes_map ();
532 (&arr)->~nodes_array ();
535 (&str)->~basic_string ();
544 new (&obj) nodes_map ();
547 new (&arr) nodes_array ();
550 new (&str) std::string ();
570 return (t == type::object) ? (int)obj.size ()
571 : (t == type::array) ? (
int)arr.size ()
572 : (t != type::null) ? 1
589 return const_cast<node&
> (
static_cast<const node&
> (*this).at (name));
599 return const_cast<node&
> (
static_cast<const node&
> (*this).at (index));
605 omanip (
void (*fn)(std::ios_base&,
int),
int val) : pfun(fn), arg(val) {}
606 void (* pfun)(std::ios_base&, int);
609 friend std::ostream& operator << (std::ostream& strm,
const omanip& manip) {
610 (*manip.pfun) (strm, manip.arg);
616void indenter (std::ios_base& os,
int spaces);
618inline omanip spaces (
int nspc)
620 return omanip (&indenter, nspc);
623inline std::ostream& indent (std::ostream& os)
628inline std::ostream& tabs (std::ostream& os)
634std::ostream& noindent (std::ostream& os);
636std::ostream& utf8 (std::ostream& os);
638std::ostream& noutf8 (std::ostream& os);
643std::ostream& operator<< (std::ostream& os,
const node& n);
646std::istream& operator>> (std::istream& is,
node& n);
652 n.
clear (type::array);
653 for (
int i = 0; i < vec.size (); ++i)
objects returned as a function result or thrown directly.
Definition errorcode.h:73
void raise() const
Definition errorcode.h:603
An error facility routes a group of errors handled in a similar manner.
Definition errorcode.h:141
node iterator
Definition json.h:88
pointer operator->() const
Value pointer.
Definition json.h:145
iterator_type< C_ > operator--()
Decrement operator (prefix)
Definition json.h:220
~iterator_type()
Destructor.
Definition json.h:115
reference operator*() const
Dereference value.
Definition json.h:124
iterator_type(const iterator_type &other)
Copy constructor.
Definition json.h:103
bool operator!=(const iterator_type< C_ > &other) const
Inequality operator.
Definition json.h:247
iterator_type< C_ > & operator++()
Increment operator (prefix)
Definition json.h:190
bool operator==(const iterator_type< C_ > &other) const
Equality operator.
Definition json.h:234
const std::string & name() const
Object name.
Definition json.h:165
Representation of a JSON node.
Definition json.h:61
bool operator!=(const node &other) const
inequality operator
Definition json.h:577
void erase(const std::string &name)
Erase the child with that name, if it exists.
Definition json.cpp:322
void clear(type t=type::null)
Remove previous node content.
Definition json.h:523
int size() const
Return number of direct descendants.
Definition json.h:568
bool operator==(const node &other) const
Equality operator.
Definition json.cpp:282
type kind() const
Return the type of node.
Definition json.h:562
bool has(const std::string &name) const
Return true if node is an object and has a child with that name.
Definition json.cpp:314
mlib::erc read(std::istream &s)
Deserialize the node from an input stream.
Definition json.cpp:573
bool to_bool() const
Conversion to boolean value.
Definition json.cpp:897
const node * find(const std::string &name) const
If node is an object and has a child with the given name, returns a pointer to child node.
Definition json.cpp:336
const_iterator end() const
End iterator (const variant)
Definition json.h:461
mlib::erc write(std::ostream &os, int flags=0, int spaces=0, int level=0) const
Write node to a stream.
Definition json.cpp:772
node & at(const std::string &name)
Return value of an object node element.
Definition json.h:587
const_iterator begin() const
Begin iterator (const variant)
Definition json.h:439
std::string to_str() const
String conversion function.
Definition json.cpp:882
node & operator=(const node &rhs)
Principal assignment operator.
Definition json.cpp:108
operator std::string() const
Return node value as a string (if possible)
Definition json.h:483
node & operator[](const std::string &name)
Return value of an object node element.
Definition json.cpp:155
node(type t=type::null)
Constructor for an empty node.
Definition json.cpp:34
Definition of mlib::erc and mlib::errfac classes.
mlib::errfac & Errors()
Return error facility used for JSON errors.
Definition json.cpp:21
constexpr int max_string_length
Maximum string length.
Definition json.h:27
constexpr int max_object_names
Maximum number of properties for a node.
Definition json.h:24
#define ERR_JSON_INVTYPE
invalid node type
Definition json.h:34
#define ERR_JSON_ITERTYPE
invalid iterator type
Definition json.h:36
#define ERR_JSON_ITERPOS
invalid iterator position
Definition json.h:37
void to_json(node &n, const std::vector< T > &vec)
Assign array value to a node.
Definition json.h:650
constexpr int max_array_size
Maximum number of array elements in a JSON node.
Definition json.h:21
type
JSON node types.
Definition json.h:50