19#include <initializer_list>
27using std::initializer_list;
29using std::is_convertible;
30using std::is_integral;
31using std::is_floating_point;
53 auto find(
const std::string &s) {
54 return std::find_if(std::begin(
data), std::end(
data), [&s](
const auto &
d) {
return d.first == s; });
57 auto find(
const std::string &s)
const {
58 return std::find_if(std::begin(
data), std::end(
data), [&s](
const auto &
d) {
return d.first == s; });
83 JSON &operator[](
const std::string &s) {
84 const auto itr = find(s);
85 if (itr != data.end()) {
88 data.emplace_back(s,
JSON());
89 return data.back().second;
93 JSON &at(
const std::string &s) {
94 const auto itr = find(s);
95 if (itr != data.end()) {
98 throw std::out_of_range(
"Unknown key: " + s);
102 const JSON &at(
const std::string &s)
const {
103 const auto itr = find(s);
104 if (itr != data.end()) {
107 throw std::out_of_range(
"Unknown key: " + s);
111 size_t count(
const std::string &s)
const {
112 return (find(s) != data.end())?1:0;
115 std::vector<std::pair<std::string, JSON>> data;
117 using iterator =
decltype(data)::iterator;
118 using const_iterator =
decltype(data)::const_iterator;
125 auto clone(
const std::unique_ptr<T> &ptr) {
126 if (ptr !=
nullptr) {
127 return std::make_unique<T>(*ptr);
129 return std::unique_ptr<T>(
nullptr);
139 Internal(
Class t_type) {
143 Internal(
const Internal &other)
144 : List(clone(other.List)),
145 Map(clone(other.Map)),
146 String(clone(other.String)),
154 Internal &operator=(
const Internal &other)
156 List = clone(other.List);
157 Map = clone(other.Map);
158 String = clone(other.String);
166 void set_type(
Class type ) {
176 case Class::Object: Map = std::make_unique<QuickFlatMap>();
break;
177 case Class::Array: List = std::make_unique<std::vector<JSON>>();
break;
178 case Class::String: String = std::make_unique<std::string>();
break;
188 Internal(Internal &&) =
default;
189 Internal &operator=(Internal &&) =
default;
191 std::unique_ptr<std::vector<JSON>> List;
192 std::unique_ptr<QuickFlatMap> Map;
193 std::unique_ptr<std::string> String;
205 template <
typename Container>
213 typename Container::iterator
begin() {
return object ?
object->begin() :
typename Container::iterator(); }
214 typename Container::iterator
end() {
return object ?
object->end() :
typename Container::iterator(); }
215 typename Container::const_iterator
begin()
const {
return object ?
object->begin() :
typename Container::iterator(); }
216 typename Container::const_iterator
end()
const {
return object ?
object->end() :
typename Container::iterator(); }
219 template <
typename Container>
227 typename Container::const_iterator
begin()
const {
return object ?
object->begin() :
typename Container::const_iterator(); }
228 typename Container::const_iterator
end()
const {
return object ?
object->end() :
typename Container::const_iterator(); }
239 JSON( initializer_list<JSON> list )
242 for(
auto i = list.begin(),
e = list.end(); i !=
e; ++i, ++i ) {
243 operator[]( i->to_string() ) = *std::next( i );
247 template <
typename T>
248 explicit JSON(
T b,
typename enable_if<is_same<T,bool>::value>::type* =
nullptr ) : internal( static_cast<bool>(b) ) {}
250 template <
typename T>
251 explicit JSON(
T i,
typename enable_if<is_integral<T>::value && !is_same<T,bool>::value>::type* =
nullptr ) : internal( static_cast<int64_t>(i) ) {}
253 template <
typename T>
254 explicit JSON(
T f,
typename enable_if<is_floating_point<T>::value>::type* =
nullptr ) : internal( static_cast<double>(
f) ) {}
256 template <
typename T>
257 explicit JSON(
T s,
typename enable_if<is_convertible<T,std::string>::value>::type* =
nullptr ) : internal( static_cast<
std::string>(s) ) {}
261 static JSON Load(
const std::string & );
265 return internal.Map->operator[]( key );
270 if( index >= internal.List->size() ) {
271 internal.List->resize( index + 1 );
274 return internal.List->operator[]( index );
282 const JSON &
at(
const std::string &key )
const {
283 return internal.Map->
at( key );
291 return internal.List->
at( index );
297 return static_cast<long>(internal.List->size());
303 bool has_key(
const std::string &key )
const {
305 return internal.Map->count(key) != 0;
313 return static_cast<int>(internal.Map->size());
315 return static_cast<int>(internal.List->size());
329 return ok ? *internal.String : std::string(
"");
335 return ok ? internal.Float : 0.0;
341 return ok ? internal.Int : 0;
347 return ok ? internal.Bool :
false;
383 std::string
dump(
long depth = 1, std::string tab =
" ")
const {
384 switch( internal.Type ) {
388 std::string pad =
"";
389 for(
long i = 0; i < depth; ++i, pad += tab ) { }
391 std::string s =
"{\n";
393 for(
auto &p : *internal.Map ) {
394 if( !skip ) { s +=
",\n"; }
395 s += ( pad +
"\"" + json_escape(p.first) +
"\" : " + p.second.dump( depth + 1, tab ) );
398 s += (
"\n" + pad.erase( 0, 2 ) +
"}" ) ;
404 for(
auto &p : *internal.List ) {
405 if( !skip ) { s +=
", "; }
406 s += p.dump( depth + 1, tab );
413 return "\"" + json_escape( *internal.String ) +
"\"";
415 return std::to_string( internal.Float );
417 return std::to_string( internal.Int );
419 return internal.Bool ?
"true" :
"false";
422 throw std::runtime_error(
"Unhandled JSON type");
427 static std::string json_escape(
const std::string &
str ) {
431 case '\"': output +=
"\\\"";
break;
432 case '\\': output +=
"\\\\";
break;
433 case '\b': output +=
"\\b";
break;
434 case '\f': output +=
"\\f";
break;
435 case '\n': output +=
"\\n";
break;
436 case '\r': output +=
"\\r";
break;
437 case '\t': output +=
"\\t";
break;
438 default : output += i;
break;
452#ifdef CHAISCRIPT_MSVC
455#pragma warning(disable : 6330)
457 return ::isspace(c) != 0;
458#ifdef CHAISCRIPT_MSVC
466 while(
isspace(
str.at(offset) ) && offset <=
str.size() ) { ++offset; }
474 if(
str.at(offset) ==
'}' ) {
475 ++offset;
return Object;
478 for (;offset<
str.size();) {
481 if(
str.at(offset) !=
':' ) {
482 throw std::runtime_error(std::string(
"JSON ERROR: Object: Expected colon, found '") +
str.at(offset) +
"'\n");
489 if(
str.at(offset) ==
',' ) {
492 else if(
str.at(offset) ==
'}' ) {
496 throw std::runtime_error(std::string(
"JSON ERROR: Object: Expected comma, found '") +
str.at(offset) +
"'\n");
509 if(
str.at(offset) ==
']' ) {
510 ++offset;
return Array;
513 for (;offset <
str.size();) {
517 if(
str.at(offset) ==
',' ) {
520 else if(
str.at(offset) ==
']' ) {
524 throw std::runtime_error(std::string(
"JSON ERROR: Array: Expected ',' or ']', found '") +
str.at(offset) +
"'\n");
533 for(
char c =
str.at(++offset); c !=
'\"' ; c =
str.at(++offset) ) {
535 switch(
str.at(++offset) ) {
536 case '\"': val +=
'\"';
break;
537 case '\\': val +=
'\\';
break;
538 case '/' : val +=
'/' ;
break;
539 case 'b' : val +=
'\b';
break;
540 case 'f' : val +=
'\f';
break;
541 case 'n' : val +=
'\n';
break;
542 case 'r' : val +=
'\r';
break;
543 case 't' : val +=
'\t';
break;
546 for(
size_t i = 1; i <= 4; ++i ) {
547 c =
str.at(offset+i);
548 if( (c >=
'0' && c <=
'9') || (c >=
'a' && c <=
'f') || (c >=
'A' && c <=
'F') ) {
551 throw std::runtime_error(std::string(
"JSON ERROR: String: Expected hex character in unicode escape, found '") + c +
"'");
556 default : val +=
'\\';
break;
567 std::string val, exp_str;
569 bool isDouble =
false;
570 bool isNegative =
false;
572 bool isExpNegative =
false;
573 if( offset <
str.size() &&
str.at(offset) ==
'-' ) {
577 for (; offset <
str.size() ;) {
578 c =
str.at(offset++);
579 if( c >=
'0' && c <=
'9' ) {
581 }
else if( c ==
'.' && !isDouble ) {
588 if( offset <
str.size() && (c ==
'E' || c ==
'e' )) {
589 c =
str.at(offset++);
591 isExpNegative =
true;
592 }
else if( c ==
'+' ) {
598 for (; offset <
str.size() ;) {
599 c =
str.at(offset++);
600 if( c >=
'0' && c <=
'9' ) {
602 }
else if( !
isspace( c ) && c !=
',' && c !=
']' && c !=
'}' ) {
603 throw std::runtime_error(std::string(
"JSON ERROR: Number: Expected a number for exponent, found '") + c +
"'");
611 else if( offset <
str.size() && (!
isspace( c ) && c !=
',' && c !=
']' && c !=
'}' )) {
612 throw std::runtime_error(std::string(
"JSON ERROR: Number: unexpected character '") + c +
"'");
619 if( !exp_str.empty() ) {
628 if(
str.substr( offset, 4 ) ==
"true" ) {
631 }
else if(
str.substr( offset, 5 ) ==
"false" ) {
635 throw std::runtime_error(std::string(
"JSON ERROR: Bool: Expected 'true' or 'false', found '") +
str.substr( offset, 5 ) +
"'");
640 if(
str.substr( offset, 4 ) !=
"null" ) {
641 throw std::runtime_error(std::string(
"JSON ERROR: Null: Expected 'null', found '") +
str.substr( offset, 4 ) +
"'");
650 value =
str.at(offset);
658 default :
if( ( value <=
'9' && value >=
'0' ) || value ==
'-' ) {
662 throw std::runtime_error(std::string(
"JSON ERROR: Parse: Unexpected starting character '") + value +
"'");
Env e
Definition Common.cc:2
Complex exp(Complex z, int n)
Definition GameApi_pl.cc:31416
SM String(std::string s)
Definition Language.hh:977
void * find(int i)
Definition ui.cc:347
Definition Containment.hh:34
Definition Expression.hh:105
JSONConstWrapper(std::nullptr_t)
Definition json.hpp:225
Container::const_iterator begin() const
Definition json.hpp:227
Container::const_iterator end() const
Definition json.hpp:228
JSONConstWrapper(const Container *val)
Definition json.hpp:224
JSONWrapper(std::nullptr_t)
Definition json.hpp:211
Container::const_iterator begin() const
Definition json.hpp:215
Container::const_iterator end() const
Definition json.hpp:216
Container::iterator begin()
Definition json.hpp:213
JSONWrapper(Container *val)
Definition json.hpp:210
Container::iterator end()
Definition json.hpp:214
bool has_key(const std::string &key) const
Definition json.hpp:303
std::string to_string(bool &ok) const
Definition json.hpp:327
std::string to_string() const
Definition json.hpp:326
double to_float() const
Definition json.hpp:332
bool is_null() const
Functions for getting primitives from the JSON object.
Definition json.hpp:324
JSON & at(size_t index)
Definition json.hpp:286
Class JSONType() const
Definition json.hpp:321
JSONWrapper< QuickFlatMap > object_range()
Definition json.hpp:350
JSON(Class type)
Definition json.hpp:234
JSONConstWrapper< QuickFlatMap > object_range() const
Definition json.hpp:366
JSONConstWrapper< std::vector< JSON > > array_range() const
Definition json.hpp:375
JSON(T i, typename enable_if< is_integral< T >::value &&!is_same< T, bool >::value >::type *=nullptr)
Definition json.hpp:251
std::string dump(long depth=1, std::string tab=" ") const
Definition json.hpp:383
JSON & operator[](const std::string &key)
Definition json.hpp:263
bool to_bool(bool &ok) const
Definition json.hpp:345
JSON(T s, typename enable_if< is_convertible< T, std::string >::value >::type *=nullptr)
Definition json.hpp:257
static JSON Load(const std::string &)
Definition json.hpp:667
long length() const
Definition json.hpp:295
Class
Definition json.hpp:39
@ String
Definition json.hpp:43
@ Boolean
Definition json.hpp:46
@ Array
Definition json.hpp:42
@ Object
Definition json.hpp:41
@ Integral
Definition json.hpp:45
@ Null
Definition json.hpp:40
@ Floating
Definition json.hpp:44
JSON(T b, typename enable_if< is_same< T, bool >::value >::type *=nullptr)
Definition json.hpp:248
const JSON & at(const std::string &key) const
Definition json.hpp:282
JSON & operator[](const size_t index)
Definition json.hpp:268
double to_float(bool &ok) const
Definition json.hpp:333
JSON(T f, typename enable_if< is_floating_point< T >::value >::type *=nullptr)
Definition json.hpp:254
JSON(std::nullptr_t)
Definition json.hpp:232
int64_t to_int(bool &ok) const
Definition json.hpp:339
const JSON & at(size_t index) const
Definition json.hpp:290
JSON & at(const std::string &key)
Definition json.hpp:278
bool to_bool() const
Definition json.hpp:344
JSON(initializer_list< JSON > list)
Definition json.hpp:239
JSONWrapper< std::vector< JSON > > array_range()
Definition json.hpp:358
int64_t to_int() const
Definition json.hpp:338
int size() const
Definition json.hpp:311
d
Definition meshpage.php:3895
lazy data
Definition meshpage.php:1583
str
Definition meshpage.php:1778
std::unique_ptr< B > make_unique(Arg &&... arg)
Definition chaiscript_defines.hpp:97
auto parse_num(const char *t_str) -> typename std::enable_if< std::is_integral< T >::value, T >::type
Definition chaiscript_defines.hpp:155
@ string
string value
Definition json.hpp:1223
double f(const std::string &, double, bool) noexcept
Definition profile_cpp_calls_2.cpp:4
static JSON parse_null(const std::string &str, size_t &offset)
Definition json.hpp:639
static JSON parse_next(const std::string &str, size_t &offset)
Definition json.hpp:647
static JSON parse_array(const std::string &str, size_t &offset)
Definition json.hpp:503
static JSON parse_number(const std::string &str, size_t &offset)
Definition json.hpp:566
static JSON parse_bool(const std::string &str, size_t &offset)
Definition json.hpp:627
static JSON parse_string(const std::string &str, size_t &offset)
Definition json.hpp:531
static bool isspace(const char c)
Definition json.hpp:450
static void consume_ws(const std::string &str, size_t &offset)
Definition json.hpp:465
static JSON parse_object(const std::string &str, size_t &offset)
Definition json.hpp:469