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 void erase (
const std::string& name);
421 new (&obj) nodes_array ();
422 for (
size_t i = 0; i < vec.size (); ++i)
423 arr.emplace_back (std::make_unique<node> (vec[i]));
431 new (&obj) nodes_map ();
438 if (t == type::object)
439 return const_iterator (*
this, obj.begin ());
440 else if (t == type::array)
441 return const_iterator (*
this, arr.begin ());
443 return const_iterator (*
this,
false);
449 if (t == type::object)
450 return iterator (*
this, obj.begin ());
451 else if (t == type::array)
452 return iterator (*
this, arr.begin ());
454 return iterator (*
this,
false);
460 if (t == type::object)
461 return const_iterator (*
this, obj.end ());
462 else if (t == type::array)
463 return const_iterator (*
this, arr.end ());
465 return const_iterator (*
this,
true);
471 if (t == type::object)
472 return iterator (*
this, obj.end ());
473 else if (t == type::array)
474 return iterator (*
this, arr.end ());
476 return iterator (*
this,
true);
480inline node::operator std::string ()
const
489inline node::operator
const char* ()
const
491 if (t != type::string)
497inline node::operator double ()
const
503inline node::operator float ()
const
505 return (
float)to_num ();
508inline node::operator int ()
const
510 return (
int)to_num ();
514inline node::operator bool ()
const
526 (&obj)->~nodes_map ();
529 (&arr)->~nodes_array ();
532 (&str)->~basic_string ();
541 new (&obj) nodes_map ();
544 new (&arr) nodes_array ();
547 new (&str) std::string ();
567 return (t == type::object) ? (int)obj.size ()
568 : (t == type::array) ? (
int)arr.size ()
569 : (t != type::null) ? 1
586 return const_cast<node&
> (
static_cast<const node&
> (*this).at (name));
596 return const_cast<node&
> (
static_cast<const node&
> (*this).at (index));
602 omanip (
void (*fn)(std::ios_base&,
int),
int val) : pfun(fn), arg(val) {}
603 void (* pfun)(std::ios_base&, int);
606 friend std::ostream&
operator << (std::ostream& strm,
const omanip& manip) {
607 (*manip.pfun) (strm, manip.arg);
613void indenter (std::ios_base& os,
int spaces);
615inline omanip spaces (
int nspc)
617 return omanip (&indenter, nspc);
620inline std::ostream& indent (std::ostream& os)
625inline std::ostream& tabs (std::ostream& os)
631std::ostream& noindent (std::ostream& os);
633std::ostream& utf8 (std::ostream& os);
635std::ostream& noutf8 (std::ostream& os);
640std::ostream& operator<< (std::ostream& os,
const node& n);
643std::istream& operator>> (std::istream& is,
node& n);
649 n.
clear (type::array);
650 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
iterator_type< C_ > operator--()
Decrement operator (prefix)
Definition json.h:220
~iterator_type()
Destructor.
Definition json.h:115
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
pointer operator->()
Value pointer.
Definition json.h:145
reference operator*()
Dereference value.
Definition json.h:124
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:574
void erase(const std::string &name)
Erase the child with that name, if it exists.
Definition json.cpp:323
void clear(type t=type::null)
Remove previous node content.
Definition json.h:520
int size() const
Return number of direct descendants.
Definition json.h:565
bool operator==(const node &other) const
Equality operator.
Definition json.cpp:283
type kind() const
Return the type of node.
Definition json.h:559
bool has(const std::string &name) const
Return true if node is an object and has a child with that name.
Definition json.cpp:315
mlib::erc read(std::istream &s)
Deserialize the node from an input stream.
Definition json.cpp:543
bool to_bool() const
Conversion to boolean value.
Definition json.cpp:875
const_iterator end() const
End iterator (const variant)
Definition json.h:458
mlib::erc write(std::ostream &os, int flags=0, int spaces=0, int level=0) const
Write node to a stream.
Definition json.cpp:742
node & at(const std::string &name)
Return value of an object node element.
Definition json.h:584
const_iterator begin() const
Begin iterator (const variant)
Definition json.h:436
std::string to_str() const
String conversion function.
Definition json.cpp:860
node & operator=(const node &rhs)
Principal assignment operator.
Definition json.cpp:109
operator std::string() const
Return node value as a string (if possible)
Definition json.h:480
node & operator[](const std::string &name)
Return value of an object node element.
Definition json.cpp:156
node(type t=type::null)
Constructor for an empty node.
Definition json.cpp:34
Definition of mlib::erc and mlib::errfac classes.
std::ostream & operator<<(std::ostream &strm, const mlib::inaddr &addr)
Serialize an address as '<hostname>:<port>'.
Definition inaddr.h:128
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:647
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