9#ifndef CLASSDESC_JSON_PACK_BASE_H
10#define CLASSDESC_JSON_PACK_BASE_H
12#define JSON5_PARSER_MVALUE_ENABLED
13#define BOOST_BIND_GLOBAL_PLACEHOLDERS
14#include <json5_parser_value.h>
15#include <json5_parser_reader_template.h>
16#include <json5_parser_writer_template.h>
23#if defined(__cplusplus) && __cplusplus<201103L
36 static const int maxchars=200;
37 char errstring[maxchars];
39 json_pack_error(
const char *fmt,...)
43 vsnprintf(errstring,maxchars,fmt,args);
46 virtual ~json_pack_error() throw() {}
47 virtual const char* what()
const throw() {
return errstring;}
52 json_object_not_found(
const string& name):
53 json_pack_error(
"json object %s not found", name.c_str()) {}
56 typedef std::map<json5_parser::Value_type,RESTProcessType::Type> RESTProcessTypeJSONMap_t;
57 const inline RESTProcessTypeJSONMap_t& RESTProcessTypeJSONMap()
59 static RESTProcessTypeJSONMap_t jsonMap;
62 jsonMap[json5_parser::obj_type]=RESTProcessType::object;
63 jsonMap[json5_parser::array_type]=RESTProcessType::array;
64 jsonMap[json5_parser::str_type]=RESTProcessType::string;
65 jsonMap[json5_parser::bool_type]=RESTProcessType::boolean;
66 jsonMap[json5_parser::int_type]=RESTProcessType::int_number;
67 jsonMap[json5_parser::real_type]=RESTProcessType::float_number;
68 jsonMap[json5_parser::null_type]=RESTProcessType::null;
76 RESTProcessTypeJSONMap_t::const_iterator r=RESTProcessTypeJSONMap().find(type);
77 if (r!=RESTProcessTypeJSONMap().end())
return r->second;
78 return RESTProcessType::null;
84 typedef std::map<RESTProcessType::Type,json5_parser::Value_type> Map;
88 const RESTProcessTypeJSONMap_t& m=RESTProcessTypeJSONMap();
89 for (RESTProcessTypeJSONMap_t::const_iterator i=m.begin(); i!=m.end(); ++i)
90 jsonMap.insert(std::make_pair(i->second,i->first));
92 Map::const_iterator r=jsonMap.find(type);
93 if (r!=jsonMap.end())
return r->second;
94 return json5_parser::null_type;
104 typedef json5_parser::mArray Array;
108 explicit json_pack_t(
const T& x,
109 typename enable_if<is_base_of<json5_parser::mValue,T>, dummy<0> >::T* d=0 ):
113 explicit json_pack_t(
const T& x,
114 typename enable_if<is_base_of<json5_parser::mArray,T>, dummy<0> >::T* d=0 ):
118 explicit json_pack_t(
const T& x,
119 typename enable_if<is_base_of<json5_parser::mObject,T>, dummy<0> >::T* d=0 ):
123 explicit json_pack_t(
const T& x,
typename enable_if<
126 Not<is_base_of<json5_parser::mValue,T> >,
127 Not<is_base_of<json5_parser::mArray,T> >
129 Not<is_base_of<json5_parser::mObject,T> >
130 >, dummy<1> >::T* d=0);
132 explicit json_pack_t(
bool x):
133 json5_parser::mValue(x),
135 explicit json_pack_t(
double x):
137 explicit json_pack_t(
const char* x):
139 explicit json_pack_t(
const string& x):
145#if defined(__cplusplus) && __cplusplus>=201103L
147 explicit json_pack_t(
const std::initializer_list<T>& x): json5_parser::mValue(json5_parser::mArray())
149 auto& arr=get_array();
150 for (
auto& i: x) arr.emplace_back(i);
154 const Array& array()
const {
return get_array();}
155 RESTProcessType::Type type()
const {
160 void objectify() {
if (type()!=RESTProcessType::object) *
this=json_pack_t(json5_parser::mObject());}
164 inline bool read(
const std::string& s, json_pack_t& value)
166 return json5_parser::read_string(s,
static_cast<json5_parser::mValue&
>(value));
169 inline bool read(std::istream& is,
json_pack_t& value)
171 return json5_parser::read_stream(is,
static_cast<json5_parser::mValue&
>(value));
174 inline void write(
const json_pack_t& value, std::ostream& os,
unsigned options=0)
176 json5_parser::write_stream(
static_cast<const json5_parser::mValue&
>(value), os, options );
179 inline std::string write(
const json_pack_t& value,
unsigned options=0)
181 return json5_parser::write_string(
static_cast<const json5_parser::mValue&
>(value), options );
184 inline void write_formatted(
const json_pack_t& value, std::ostream& os)
186 write_stream(
static_cast<const json5_parser::mValue&
>(value), os, json5_parser::pretty_print );
189 inline std::string write_formatted(
const json_pack_t& value)
191 return write_string(
static_cast<const json5_parser::mValue&
>(value), json5_parser::pretty_print );
202 template <
class T>
void json_unpack(json_unpack_t& o,
const string& d,
T& a);
207 template <
class T>
const json_unpack_t& operator>>(
const json_unpack_t& j,
T& a)
208 {json_unpack(
const_cast<json_unpack_t&
>(j),
"",a);
return j;}
210 inline const json_unpack_t& operator>>(
const json_unpack_t& j,
const char*& a)
211 {
throw json_pack_error(
"cannot unpack to char*, please use string instead");}
214 json_pack_t::json_pack_t(
const T& x,
typename enable_if<
217 Not<is_base_of<json5_parser::mValue,T> >,
218 Not<is_base_of<json5_parser::mArray,T> >
220 Not<is_base_of<json5_parser::mObject,T> >
222 json5_parser::mValue(json5_parser::mObject()),
223 throw_on_error(false), throw_on_not_found(false)
227 inline json5_parser::mValue&
228 json_find(json5_parser::mValue& x, std::string name)
230 if (name.size()==0)
return x;
231 if (name[0]==
'.') name.erase(0,1);
232 std::string::size_type p=name.find(
'.');
233 if (x.type()==json5_parser::obj_type)
235 json5_parser::mObject& xo=x.get_obj();
236 json5_parser::mObject::iterator i=xo.find(name.substr(0,p));
239 else if (p==std::string::npos)
242 return json_find(i->second,name.substr(p,std::string::npos));
249 template <
class T> json5_parser::mValue valueof(
T a)
250 {
return json5_parser::mValue(a);}
251 template <
class T>
T getValue(
const json5_parser::mValue& x)
252 {
return x.get_value<
T>();}
254 inline json5_parser::mValue valueof(
unsigned char a)
255 {
return json5_parser::mValue(
int(a));}
256 template <>
inline unsigned char getValue(
const json5_parser::mValue& x)
257 {
return x.get_value<
int>();}
259 inline json5_parser::mValue valueof(
signed char a)
260 {
return json5_parser::mValue(
int(a));}
261 template <>
inline signed char getValue(
const json5_parser::mValue& x)
262 {
return x.get_value<
int>();}
264 inline json5_parser::mValue valueof(
char a)
265 {
return json5_parser::mValue(
string()+a);}
266 template <>
inline char getValue(
const json5_parser::mValue& x)
267 {
return x.get_value<
string>()[0];}
269 inline json5_parser::mValue valueof(
unsigned short a)
270 {
return json5_parser::mValue(
int(a));}
271 template <>
inline unsigned short getValue(
const json5_parser::mValue& x)
272 {
return x.get_value<
int>();}
274 inline json5_parser::mValue valueof(
signed short a)
275 {
return json5_parser::mValue(
int(a));}
276 template <>
inline signed short getValue(
const json5_parser::mValue& x)
277 {
return x.get_value<
int>();}
279 inline json5_parser::mValue valueof(
unsigned int a)
280 {
return json5_parser::mValue(boost::uint64_t(a));}
281 template <>
inline unsigned getValue(
const json5_parser::mValue& x)
282 {
return x.get_value<boost::uint64_t>();}
284 inline json5_parser::mValue valueof(
unsigned long a)
285 {
return json5_parser::mValue(boost::uint64_t(a));}
286 template <>
inline unsigned long getValue(
const json5_parser::mValue& x)
287 {
return x.get_value<boost::uint64_t>();}
289 inline json5_parser::mValue valueof(
long a)
290 {
return json5_parser::mValue(boost::int64_t(a));}
291 template <>
inline long getValue(
const json5_parser::mValue& x)
292 {
return x.get_value<boost::int64_t>();}
295 inline json5_parser::mValue valueof(
unsigned long long a)
296 {
return json5_parser::mValue(boost::uint64_t(a));}
297 template <>
inline unsigned long long getValue(
const json5_parser::mValue& x)
298 {
return x.get_value<boost::uint64_t>();}
300 inline json5_parser::mValue valueof(
long long a)
301 {
return json5_parser::mValue(boost::int64_t(a));}
302 template <>
inline long long getValue(
const json5_parser::mValue& x)
303 {
return x.get_value<boost::int64_t>();}
306 inline json5_parser::mValue valueof(
float a)
307 {
return json5_parser::mValue(
double(a));}
309 template <>
inline float getValue(
const json5_parser::mValue& x)
312 if (x.type()==json5_parser::null_type)
return std::nan(
"");
313 return x.get_value<
double>();
316 template <>
inline double getValue(
const json5_parser::mValue& x)
319 if (x.type()==json5_parser::null_type)
return std::nan(
"");
320 return x.get_value<
double>();
324 template <
class T>
typename
326 json_packp(json_unpack_t& o,
const string& d,
const T& a,
dummy<0> dum=0)
328 using namespace json5_parser;
339 json5_parser::mValue& parent=
json_find(o,head(d));
340 if (parent.type()==obj_type)
341 parent.get_obj()[tail(d)]=valueof(a);
348 if (o.throw_on_not_found)
throw;
353 if (o.throw_on_error)
throw;
359 template <
class T>
typename
361 json_unpackp(json_unpack_t& o,
string d,
T& a,
dummy<0> dum=0)
370 if (o.throw_on_error)
throw;
374 template <
class T>
void json_pack_isarray
375 (json5_parser::mValue& jval,
const T& val, std::vector<size_t> dims)
385 size_t s=dims.back();
386 jval=json5_parser::mArray(s);
389 for (
size_t i=0; i<dims.size(); ++i) stride*=dims[i];
390 for (
size_t i=0; i<s; ++i)
391 json_pack_isarray(jval.get_array()[i],(&val)[i*stride], dims);
398 int ndims,
size_t ncopies,...)
401 va_start(ap,ncopies);
402 std::vector<size_t> dims(ndims);
403 dims[ndims-1]=ncopies;
404 for (
int i=ndims-2; i>=0; --i) dims[i]=va_arg(ap,
size_t);
408 json5_parser::mValue& parent=
json_find(o,head(d));
409 if (parent.type()!=json5_parser::obj_type)
410 throw json_pack_error(
"attempt to pack an array member into a non-object");
412 json_pack_isarray(parent.get_obj()[tail(d)],a,dims);
417 if (o.throw_on_error)
throw;
421 template <
class T>
void json_unpack_isarray
422 (
const json5_parser::mValue& jval,
T& val, std::vector<size_t> dims)
426 json_unpack_t j(jval);
427 json_unpack(j,
"",val);
431 size_t s=dims.back();
434 for (
size_t i=0; i<dims.size(); ++i) stride*=dims[i];
435 for (
size_t i=0; i<s; ++i)
436 json_unpack_isarray(jval.get_array()[i],(&val)[i*stride], dims);
441 void json_unpack(json_unpack_t& o,
const string& d,
is_array ia,
T& a,
442 int ndims,
size_t ncopies,...)
445 va_start(ap,ncopies);
446 std::vector<size_t> dims(ndims);
447 dims[ndims-1]=ncopies;
448 for (
int i=ndims-2; i>=0; --i) dims[i]=va_arg(ap,
size_t);
452 const json5_parser::mValue& v=
json_find(o,d);
453 if (v.type()!=json5_parser::array_type)
455 (
"attempt to unpack an array member from a non-object");
457 json_unpack_isarray(v,a,dims);
462 if (o.throw_on_error)
throw;
475 string tmp(
static_cast<string>(arg));
480 template <
class T>
void json_unpack(json_unpack_t& x,
const string& d,
484 json_unpack(x,d,tmp);
486 int (*isspace)(int)=std::isspace;
487 std::string::iterator end=std::remove_if(tmp.begin(),tmp.end(),isspace);
488 arg=tmp.substr(0,end-tmp.begin());
492 template <
class T>
typename
494 json_unpackp(json_unpack_t& o,
const string& d,
T& a,
dummy<1> dum=0)
498 const json5_parser::mValue& val=
json_find(o,d);
499 if (val.type()!=json5_parser::array_type)
503 const json5_parser::mArray& arr=val.get_array();
504 resize(a, arr.size());
506 for (
typename T::iterator j=a.begin(); i<arr.size() && j!=a.end(); ++i, ++j)
508 json_unpack_t jp(arr[i]);
509 json_unpack(jp,
"",*j);
515 if (o.throw_on_error)
throw;
519 template <
class T1,
class T2>
527 template <
class T1,
class T2>
528 void json_unpackp(json_unpack_t& o,
const string& d, std::pair<T1,T2>& a)
530 json_unpack(o,d+
".first",a.first);
531 json_unpack(o,d+
".second",a.second);
534 template <
class T>
typename
541 json5_parser::mValue& parent=
json_find(o,head(d));
542 if (parent.type()!=json5_parser::obj_type)
543 throw json_pack_error(
"attempt to pack an array member into a non-object");
546 json5_parser::mValue* v;
550 v=&parent.get_obj()[tail(d)];
552 json5_parser::mArray& arr=
553 (*v=json5_parser::mArray(a.size())).get_array();
554 typename T::const_iterator i=a.begin();
555 for (
size_t k=0; i!=a.end(); ++i, ++k)
565 if (o.throw_on_error)
throw;
569 template <
class T>
typename
571 json_unpackp(json_unpack_t& o,
const string& d,
T& a,
dummy<2> dum=0)
575 const json5_parser::mValue& val=
json_find(o,d);
576 if (val.type()!=json5_parser::array_type)
580 const json5_parser::mArray& arr=val.get_array();
582 for (
size_t i=0; i<arr.size(); ++i)
585#if defined(__cplusplus) && __cplusplus>=201103L
586 typename NonConstKeyValueType<typename T::value_type>::T v{};
588 typename NonConstKeyValueType<typename T::value_type>::T v;
590 json_unpack_t j(arr[i]);
598 if (o.throw_on_error)
throw;
617 json_unpack(json_unpack_t& targ,
const string& desc,
T*) {}
620 void json_unpack(json_unpack_t& targ,
const string& desc,
const T& arg) {}
626 void json_unpack(json_unpack_t& targ,
const string& desc,
Exclude<T>& arg) {}
628 template <
class T,
class U>
631 template <
class T,
class U>
632 void json_unpack(json_unpack_t& targ,
const string& desc,
T&,
is_constructor, U&) {}
635 template <
class T>
string json(
const T& x)
641 template <
class T>
void json(
T& x,
const string& s)
649 void json_pack_onbase(
json_pack_t& x,
const string& d,
T& a)
653 void json_unpack_onbase(json_unpack_t& x,
const string& d,
T& a)
658inline std::ostream& operator<<(std::ostream& o,
const json5_parser::mValue& x)
660 json5_parser::write_stream(x,o);
670#include "use_mbr_pointers.h"
671CLASSDESC_USE_OLDSTYLE_MEMBER_OBJECTS(json_pack)
672CLASSDESC_USE_OLDSTYLE_MEMBER_OBJECTS(json_unpack)
673CLASSDESC_FUNCTION_NOP(json_pack)
674CLASSDESC_FUNCTION_NOP(json_unpack)
677using classdesc::json_pack_onbase;
678using classdesc::json_unpack_onbase;
681using classdesc::json_unpack;
Definition classdesc.h:868
Definition classdesc.h:920
Definition classdesc.h:923
Definition classdesc.h:926
Definition json_pack_base.h:35
Definition json_pack_base.h:99
void objectify()
convert this to an object type (if not already)
Definition json_unpack_base.h:160
bool throw_on_not_found
enable exceptions if element not present in JSON stream
Definition json_pack_base.h:102
bool throw_on_error
enable exceptions on error conditions
Definition json_pack_base.h:101
Contains access_* structs, and nothing else. These structs are used to gain access to private members...
Definition classdesc_access.h:20
Contains definitions related to classdesc functionality.
json5_parser::mValue & json_find(json5_parser::mValue &x, std::string name)
find an object named by name within the json object x
Definition json_pack_base.h:228
string basename()
returns a valid identifier to append to the descriptor of a base class
Definition classdesc.h:1127
json5_parser::Value_type RESTProcessTypeToJson5ParserType(RESTProcessType::Type type)
convert a RESTProcessType::Type to a json5_parser::Value_type
Definition json_pack_base.h:82
void json_pack(json_pack_t &o, const string &d, T &a)
forward declare generic json operations
Definition json_pack_epilogue.h:61
RESTProcessType::Type Json5ParserTypeToRESTProcessType(json5_parser::Value_type type)
convert a json5_parser::Value_type to a RESTProcessType::Type
Definition json_pack_base.h:74
string json(const T &x)
produce json string equivalent of object x
Definition json_pack_base.h:635
Definition classdesc.h:420
Definition classdesc.h:1012
Definition classdesc.h:405
Definition classdesc.h:299
controlled template specialisation: stolen from boost::enable_if.
Definition classdesc.h:282
base class for exceptions thrown by classdesc
Definition classdesc.h:546
determines if T is a standard associative container
Definition classdesc.h:321
determines if this is a string
Definition classdesc.h:313
Definition json_pack_base.h:51
Definition json_pack_epilogue.h:92
Definition json_pack_epilogue.h:104