46#if __cplusplus >= 201103L
52#elif defined(__INTEL_COMPILER)
60#ifndef PICOJSON_USE_RVALUE_REFERENCE
61#if (defined(__cpp_rvalue_references) && __cpp_rvalue_references >= 200610) || (defined(_MSC_VER) && _MSC_VER >= 1600)
62#define PICOJSON_USE_RVALUE_REFERENCE 1
64#define PICOJSON_USE_RVALUE_REFERENCE 0
68#ifndef PICOJSON_NOEXCEPT
69#if PICOJSON_USE_RVALUE_REFERENCE
70#define PICOJSON_NOEXCEPT noexcept
72#define PICOJSON_NOEXCEPT throw()
77#ifdef PICOJSON_USE_INT64
78#define __STDC_FORMAT_MACROS
80#if __cplusplus >= 201103L
90#ifndef PICOJSON_USE_LOCALE
91#define PICOJSON_USE_LOCALE 1
93#if PICOJSON_USE_LOCALE
99#ifndef PICOJSON_ASSERT
100#define PICOJSON_ASSERT(e) \
103 throw std::runtime_error(#e); \
108#define SNPRINTF _snprintf_s
110#pragma warning(disable : 4244)
111#pragma warning(disable : 4127)
112#pragma warning(disable : 4702)
114#define SNPRINTF snprintf
126#ifdef PICOJSON_USE_INT64
139 typedef std::map<std::string, value>
object;
143#ifdef PICOJSON_USE_INT64
157 value(
int type,
bool);
158 explicit value(
bool b);
159#ifdef PICOJSON_USE_INT64
160 explicit value(int64_t i);
162 explicit value(
double n);
163 explicit value(
const std::string &s);
165 explicit value(
const object &o);
166#if PICOJSON_USE_RVALUE_REFERENCE
167 explicit value(std::string &&s);
169 explicit value(
object &&o);
171 explicit value(
const char *s);
172 value(
const char *s,
size_t len);
176#if PICOJSON_USE_RVALUE_REFERENCE
181 template <
typename T>
bool is()
const;
182 template <
typename T>
const T &
get()
const;
183 template <
typename T> T &
get();
184 template <
typename T>
void set(
const T &);
185#if PICOJSON_USE_RVALUE_REFERENCE
186 template <
typename T>
void set(T &&);
189 const value &
get(
const size_t idx)
const;
190 const value &
get(
const std::string &key)
const;
194 bool contains(
const size_t idx)
const;
195 bool contains(
const std::string &key)
const;
196 std::string
to_str()
const;
197 template <
typename Iter>
void serialize(Iter os,
bool prettify =
false)
const;
198 std::string
serialize(
bool prettify =
false)
const;
201 template <
typename T>
value(
const T *);
202 template <
typename Iter>
static void _indent(Iter os,
int indent);
203 template <
typename Iter>
void _serialize(Iter os,
int indent)
const;
220 INIT(boolean_,
false);
222#ifdef PICOJSON_USE_INT64
225 INIT(string_,
new std::string());
227 INIT(object_,
new object());
238#ifdef PICOJSON_USE_INT64
239inline value::value(int64_t i) : type_(int64_type), u_() {
248#elif __cplusplus >= 201103L
249 std::isnan(n) || std::isinf(n)
254 throw std::overflow_error(
"");
271#if PICOJSON_USE_RVALUE_REFERENCE
273 u_.
string_ =
new std::string(std::move(s));
336#if PICOJSON_USE_RVALUE_REFERENCE
350#define IS(ctype, jtype) \
351 template <> inline bool value::is<ctype>() const { \
352 return type_ == jtype##_type; \
356#ifdef PICOJSON_USE_INT64
359IS(std::string,
string)
363template <>
inline bool value::is<double>()
const {
365#ifdef PICOJSON_USE_INT64
366 ||
type_ == int64_type
371#define GET(ctype, var) \
372 template <> inline const ctype &value::get<ctype>() const { \
373 PICOJSON_ASSERT("type mismatch! call is<type>() before get<type>()" && is<ctype>()); \
376 template <> inline ctype &value::get<ctype>() { \
377 PICOJSON_ASSERT("type mismatch! call is<type>() before get<type>()" && is<ctype>()); \
380GET(
bool, u_.boolean_)
381GET(
std::
string, *u_.string_)
383GET(
object, *u_.object_)
384#ifdef PICOJSON_USE_INT64
386 (type_ == int64_type && (
const_cast<value *
>(
this)->type_ =
number_type,
const_cast<value *
>(
this)->u_.number_ = u_.int64_),
388GET(int64_t, u_.int64_)
390GET(
double, u_.number_)
394#define SET(ctype, jtype, setter) \
395 template <> inline void value::set<ctype>(const ctype &_val) { \
397 type_ = jtype##_type; \
400SET(
bool,
boolean, u_.boolean_ = _val;)
401SET(std::string,
string, u_.string_ =
new std::string(_val);)
403SET(
object,
object, u_.object_ =
new object(_val);)
404SET(
double, number, u_.number_ = _val;)
405#ifdef PICOJSON_USE_INT64
406SET(int64_t, int64, u_.int64_ = _val;)
410#if PICOJSON_USE_RVALUE_REFERENCE
411#define MOVESET(ctype, jtype, setter) \
412 template <> inline void value::set<ctype>(ctype && _val) { \
414 type_ = jtype##_type; \
417MOVESET(std::string,
string, u_.string_ =
new std::string(std::move(_val));)
419MOVESET(
object,
object, u_.object_ =
new object(std::move(_val));)
431#ifdef PICOJSON_USE_INT64
433 return u_.int64_ != 0;
457 object::const_iterator i =
u_.
object_->find(key);
458 return i !=
u_.
object_->end() ? i->second : s_null;
464 object::iterator i =
u_.
object_->find(key);
465 return i !=
u_.
object_->end() ? i->second : s_null;
475 object::const_iterator i =
u_.
object_->find(key);
485#ifdef PICOJSON_USE_INT64
487 char buf[
sizeof(
"-9223372036854775808")];
488 SNPRINTF(buf,
sizeof(buf),
"%" PRId64,
u_.int64_);
496#if PICOJSON_USE_LOCALE
497 char *decimal_point = localeconv()->decimal_point;
498 if (strcmp(decimal_point,
".") != 0) {
499 size_t decimal_point_len = strlen(decimal_point);
500 for (
char *p = buf; *p !=
'\0'; ++p) {
501 if (strncmp(p, decimal_point, decimal_point_len) == 0) {
502 return std::string(buf, p) +
"." + (p + decimal_point_len);
521 return std::string();
524template <
typename Iter>
void copy(
const std::string &s, Iter oi) {
525 std::copy(s.begin(), s.end(), oi);
532#define MAP(val, sym) \
546 if (
static_cast<unsigned char>(c) < 0x20 || c == 0x7f) {
548 SNPRINTF(buf,
sizeof(buf),
"\\u%04x", c & 0xff);
561 std::for_each(s.begin(), s.end(), process_char);
590 for (array::const_iterator i =
u_.
array_->begin(); i !=
u_.
array_->end(); ++i) {
597 i->_serialize(oi, indent);
625 i->second._serialize(oi, indent);
651template <
typename Iter>
class input {
691 if (!(ch ==
' ' || ch ==
'\t' || ch ==
'\n' || ch ==
'\r')) {
699 if (
getc() != expected) {
705 bool match(
const std::string &pattern) {
706 for (std::string::const_iterator pi(pattern.begin()); pi != pattern.end(); ++pi) {
718 for (
int i = 0; i < 4; i++) {
719 if ((hex = in.
getc()) == -1) {
722 if (
'0' <= hex && hex <=
'9') {
724 }
else if (
'A' <= hex && hex <=
'F') {
726 }
else if (
'a' <= hex && hex <=
'f') {
732 uni_ch = uni_ch * 16 + hex;
742 if (0xd800 <= uni_ch && uni_ch <= 0xdfff) {
743 if (0xdc00 <= uni_ch) {
748 if (in.
getc() !=
'\\' || in.
getc() !=
'u') {
753 if (!(0xdc00 <= second && second <= 0xdfff)) {
756 uni_ch = ((uni_ch - 0xd800) << 10) | ((second - 0xdc00) & 0x3ff);
760 out.push_back(
static_cast<char>(uni_ch));
762 if (uni_ch < 0x800) {
763 out.push_back(
static_cast<char>(0xc0 | (uni_ch >> 6)));
765 if (uni_ch < 0x10000) {
766 out.push_back(
static_cast<char>(0xe0 | (uni_ch >> 12)));
768 out.push_back(
static_cast<char>(0xf0 | (uni_ch >> 18)));
769 out.push_back(
static_cast<char>(0x80 | ((uni_ch >> 12) & 0x3f)));
771 out.push_back(
static_cast<char>(0x80 | ((uni_ch >> 6) & 0x3f)));
773 out.push_back(
static_cast<char>(0x80 | (uni_ch & 0x3f)));
784 }
else if (ch ==
'"') {
786 }
else if (ch ==
'\\') {
787 if ((ch = in.
getc()) == -1) {
791#define MAP(sym, val) \
793 out.push_back(val); \
813 out.push_back(
static_cast<char>(ch));
820 if (!ctx.parse_array_start()) {
825 return ctx.parse_array_stop(idx);
828 if (!ctx.parse_array_item(in, idx)) {
833 return in.
expect(
']') && ctx.parse_array_stop(idx);
837 if (!ctx.parse_object_start()) {
848 if (!ctx.parse_object_item(in, key)) {
859 if ((
'0' <= ch && ch <=
'9') || ch ==
'+' || ch ==
'-' || ch ==
'e' || ch ==
'E') {
860 num_str.push_back(
static_cast<char>(ch));
861 }
else if (ch ==
'.') {
862#if PICOJSON_USE_LOCALE
863 num_str += localeconv()->decimal_point;
865 num_str.push_back(
'.');
879#define IS(ch, text, op) \
881 if (in.match(text) && op) { \
886 IS(
'n',
"ull", ctx.set_null());
887 IS(
'f',
"alse", ctx.set_bool(
false));
888 IS(
't',
"rue", ctx.set_bool(
true));
891 return ctx.parse_string(in);
897 if ((
'0' <= ch && ch <=
'9') || ch ==
'-') {
902 if (num_str.empty()) {
905#ifdef PICOJSON_USE_INT64
908 intmax_t ival = strtoimax(num_str.c_str(), &endp, 10);
909 if (errno == 0 && std::numeric_limits<int64_t>::min() <= ival && ival <= std::numeric_limits<int64_t>::max() &&
910 endp == num_str.c_str() + num_str.size()) {
916 f = strtod(num_str.c_str(), &endp);
917 if (endp == num_str.c_str() + num_str.size()) {
937#ifdef PICOJSON_USE_INT64
938 bool set_int64(int64_t) {
980#ifdef PICOJSON_USE_INT64
981 bool set_int64(int64_t i) {
1000 a.push_back(
value());
1012 object &o =
out_->
get<
object>();
1038#ifdef PICOJSON_USE_INT64
1039 bool set_int64(int64_t) {
1054 return _parse(*
this, in);
1063 return _parse(*
this, in);
1072template <
typename Iter>
inline std::string
parse(
value &out, Iter &pos,
const Iter &last) {
1074 pos =
parse(out, pos, last, &err);
1078template <
typename Context,
typename Iter>
inline Iter
_parse(Context &ctx,
const Iter &first,
const Iter &last, std::string *err) {
1080 if (!
_parse(ctx, in) && err != NULL) {
1082 SNPRINTF(buf,
sizeof(buf),
"syntax error at line %d near: ", in.
line());
1086 if (ch == -1 || ch ==
'\n') {
1088 }
else if (ch >=
' ') {
1089 err->push_back(
static_cast<char>(ch));
1096template <
typename Iter>
inline Iter
parse(
value &out,
const Iter &first,
const Iter &last, std::string *err) {
1098 return _parse(ctx, first, last, err);
1103 parse(out, s.begin(), s.end(), &err);
1109 parse(out, std::istreambuf_iterator<char>(is.rdbuf()), std::istreambuf_iterator<char>(), &err);
1127#define PICOJSON_CMP(type) \
1129 return y.is<type>() && x.get<type>() == y.get<type>()
1148#if !PICOJSON_USE_RVALUE_REFERENCE
1161 is.setstate(std::ios::failbit);
1167 x.
serialize(std::ostream_iterator<char>(os));
default_parse_context(const default_parse_context &)
bool parse_string(input< Iter > &in)
bool parse_object_start()
bool parse_array_item(input< Iter > &in, size_t)
default_parse_context & operator=(const default_parse_context &)
bool set_number(double f)
bool parse_array_stop(size_t)
default_parse_context(value *out)
bool parse_object_item(input< Iter > &in, const std::string &key)
bool parse_object_item(input< Iter > &, const std::string &)
bool parse_string(input< Iter > &)
bool parse_object_start()
bool parse_array_stop(size_t)
bool parse_array_item(input< Iter > &, size_t)
null_parse_context(const null_parse_context &)
bool parse_array_item(input< Iter > &in, size_t)
bool parse_array_stop(size_t)
null_parse_context & operator=(const null_parse_context &)
bool parse_object_start()
bool parse_object_item(input< Iter > &in, const std::string &)
bool parse_string(input< Iter > &in)
std::string to_str() const
void serialize(Iter os, bool prettify=false) const
bool evaluate_as_boolean() const
void swap(value &x) PICOJSON_NOEXCEPT
static void _indent(Iter os, int indent)
std::map< std::string, value > object
bool contains(const size_t idx) const
value & operator=(const value &x)
std::vector< value > array
void _serialize(Iter os, int indent) const
bool _parse_codepoint(String &out, input< Iter > &in)
void serialize_str(const std::string &s, Iter oi)
std::string parse(value &out, Iter &pos, const Iter &last)
bool _parse_object(Context &ctx, input< Iter > &in)
bool operator==(const value &x, const value &y)
void set_last_error(const std::string &s)
const std::string & get_last_error()
std::string _parse_number(input< Iter > &in)
int _parse_quadhex(input< Iter > &in)
bool _parse_string(String &out, input< Iter > &in)
void copy(const std::string &s, Iter oi)
bool _parse_array(Context &ctx, input< Iter > &in)
bool operator!=(const value &x, const value &y)
bool _parse(Context &ctx, input< Iter > &in)
void swap(picojson::value &x, picojson::value &y)
#define PICOJSON_ASSERT(e)
#define SET(ctype, jtype, setter)
std::istream & operator>>(std::istream &is, picojson::value &x)
#define PICOJSON_CMP(type)
#define PICOJSON_NOEXCEPT
std::ostream & operator<<(std::ostream &os, const picojson::value &x)