gmsh-TingyuanDoc  0.1
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
picojson.h
Go to the documentation of this file.
1 /*
2  * Copyright 2009-2010 Cybozu Labs, Inc.
3  * Copyright 2011-2014 Kazuho Oku
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright notice,
10  * this list of conditions and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above copyright notice,
13  * this list of conditions and the following disclaimer in the documentation
14  * and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  */
28 #ifndef picojson_h
29 #define picojson_h
30 
31 #include <algorithm>
32 #include <cstdio>
33 #include <cstdlib>
34 #include <cstring>
35 #include <cstddef>
36 #include <iostream>
37 #include <iterator>
38 #include <limits>
39 #include <map>
40 #include <stdexcept>
41 #include <string>
42 #include <vector>
43 #include <utility>
44 
45 // for isnan/isinf
46 #if __cplusplus >= 201103L
47 #include <cmath>
48 #else
49 extern "C" {
50 #ifdef _MSC_VER
51 #include <float.h>
52 #elif defined(__INTEL_COMPILER)
53 #include <mathimf.h>
54 #else
55 #include <math.h>
56 #endif
57 }
58 #endif
59 
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
63 #else
64 #define PICOJSON_USE_RVALUE_REFERENCE 0
65 #endif
66 #endif // PICOJSON_USE_RVALUE_REFERENCE
67 
68 // experimental support for int64_t (see README.mkdn for detail)
69 #ifdef PICOJSON_USE_INT64
70 #define __STDC_FORMAT_MACROS
71 #include <errno.h>
72 #include <inttypes.h>
73 #endif
74 
75 // to disable the use of localeconv(3), set PICOJSON_USE_LOCALE to 0
76 #ifndef PICOJSON_USE_LOCALE
77 #define PICOJSON_USE_LOCALE 1
78 #endif
79 #if PICOJSON_USE_LOCALE
80 extern "C" {
81 #include <locale.h>
82 }
83 #endif
84 
85 #ifndef PICOJSON_ASSERT
86 #define PICOJSON_ASSERT(e) \
87  do { \
88  if (!(e)) \
89  throw std::runtime_error(#e); \
90  } while (0)
91 #endif
92 
93 #ifdef _MSC_VER
94 #define SNPRINTF _snprintf_s
95 #pragma warning(push)
96 #pragma warning(disable : 4244) // conversion from int to char
97 #pragma warning(disable : 4127) // conditional expression is constant
98 #pragma warning(disable : 4702) // unreachable code
99 #else
100 #define SNPRINTF snprintf
101 #endif
102 
103 namespace picojson {
104 
105 enum {
112 #ifdef PICOJSON_USE_INT64
113  ,
114  int64_type
115 #endif
116 };
117 
118 enum { INDENT_WIDTH = 2 };
119 
120 struct null {};
121 
122 class value {
123 public:
124  typedef std::vector<value> array;
125  typedef std::map<std::string, value> object;
126  union _storage {
127  bool boolean_;
128  double number_;
129 #ifdef PICOJSON_USE_INT64
130  int64_t int64_;
131 #endif
132  std::string *string_;
134  object *object_;
135  };
136 
137 protected:
138  int type_;
140 
141 public:
142  value();
143  value(int type, bool);
144  explicit value(bool b);
145 #ifdef PICOJSON_USE_INT64
146  explicit value(int64_t i);
147 #endif
148  explicit value(double n);
149  explicit value(const std::string &s);
150  explicit value(const array &a);
151  explicit value(const object &o);
152 #if PICOJSON_USE_RVALUE_REFERENCE
153  explicit value(std::string &&s);
154  explicit value(array &&a);
155  explicit value(object &&o);
156 #endif
157  explicit value(const char *s);
158  value(const char *s, size_t len);
159  ~value();
160  value(const value &x);
161  value &operator=(const value &x);
162 #if PICOJSON_USE_RVALUE_REFERENCE
163  value(value &&x) throw();
164  value &operator=(value &&x) throw();
165 #endif
166  void swap(value &x) throw();
167  template <typename T> bool is() const;
168  template <typename T> const T &get() const;
169  template <typename T> T &get();
170  template <typename T> void set(const T &);
171 #if PICOJSON_USE_RVALUE_REFERENCE
172  template <typename T> void set(T &&);
173 #endif
174  bool evaluate_as_boolean() const;
175  const value &get(const size_t idx) const;
176  const value &get(const std::string &key) const;
177  value &get(const size_t idx);
178  value &get(const std::string &key);
179 
180  bool contains(const size_t idx) const;
181  bool contains(const std::string &key) const;
182  std::string to_str() const;
183  template <typename Iter> void serialize(Iter os, bool prettify = false) const;
184  std::string serialize(bool prettify = false) const;
185 
186 private:
187  template <typename T> value(const T *); // intentionally defined to block implicit conversion of pointer to bool
188  template <typename Iter> static void _indent(Iter os, int indent);
189  template <typename Iter> void serialize_(Iter os, int indent) const;
190  std::string serialize_(int indent) const;
191  void clear();
192 };
193 
196 
197 inline value::value() : type_(null_type), u_() {
198 }
199 
200 inline value::value(int type, bool) : type_(type), u_() {
201  switch (type) {
202 #define INIT(p, v) \
203  case p##type: \
204  u_.p = v; \
205  break
206  INIT(boolean_, false);
207  INIT(number_, 0.0);
208 #ifdef PICOJSON_USE_INT64
209  INIT(int64_, 0);
210 #endif
211  INIT(string_, new std::string());
212  INIT(array_, new array());
213  INIT(object_, new object());
214 #undef INIT
215  default:
216  break;
217  }
218 }
219 
220 inline value::value(bool b) : type_(boolean_type), u_() {
221  u_.boolean_ = b;
222 }
223 
224 #ifdef PICOJSON_USE_INT64
225 inline value::value(int64_t i) : type_(int64_type), u_() {
226  u_.int64_ = i;
227 }
228 #endif
229 
230 inline value::value(double n) : type_(number_type), u_() {
231  if (
232 #ifdef _MSC_VER
233  !_finite(n)
234 #elif __cplusplus >= 201103L
235  std::isnan(n) || std::isinf(n)
236 #else
237  isnan(n) || isinf(n)
238 #endif
239  ) {
240  throw std::overflow_error("");
241  }
242  u_.number_ = n;
243 }
244 
245 inline value::value(const std::string &s) : type_(string_type), u_() {
246  u_.string_ = new std::string(s);
247 }
248 
249 inline value::value(const array &a) : type_(array_type), u_() {
250  u_.array_ = new array(a);
251 }
252 
253 inline value::value(const object &o) : type_(object_type), u_() {
254  u_.object_ = new object(o);
255 }
256 
257 #if PICOJSON_USE_RVALUE_REFERENCE
258 inline value::value(std::string &&s) : type_(string_type), u_() {
259  u_.string_ = new std::string(std::move(s));
260 }
261 
262 inline value::value(array &&a) : type_(array_type), u_() {
263  u_.array_ = new array(std::move(a));
264 }
265 
266 inline value::value(object &&o) : type_(object_type), u_() {
267  u_.object_ = new object(std::move(o));
268 }
269 #endif
270 
271 inline value::value(const char *s) : type_(string_type), u_() {
272  u_.string_ = new std::string(s);
273 }
274 
275 inline value::value(const char *s, size_t len) : type_(string_type), u_() {
276  u_.string_ = new std::string(s, len);
277 }
278 
279 inline void value::clear() {
280  switch (type_) {
281 #define DEINIT(p) \
282  case p##type: \
283  delete u_.p; \
284  break
285  DEINIT(string_);
286  DEINIT(array_);
287  DEINIT(object_);
288 #undef DEINIT
289  default:
290  break;
291  }
292 }
293 
294 inline value::~value() {
295  clear();
296 }
297 
298 inline value::value(const value &x) : type_(x.type_), u_() {
299  switch (type_) {
300 #define INIT(p, v) \
301  case p##type: \
302  u_.p = v; \
303  break
304  INIT(string_, new std::string(*x.u_.string_));
305  INIT(array_, new array(*x.u_.array_));
306  INIT(object_, new object(*x.u_.object_));
307 #undef INIT
308  default:
309  u_ = x.u_;
310  break;
311  }
312 }
313 
314 inline value &value::operator=(const value &x) {
315  if (this != &x) {
316  value t(x);
317  swap(t);
318  }
319  return *this;
320 }
321 
322 #if PICOJSON_USE_RVALUE_REFERENCE
323 inline value::value(value &&x) throw() : type_(null_type), u_() {
324  swap(x);
325 }
326 inline value &value::operator=(value &&x) throw() {
327  swap(x);
328  return *this;
329 }
330 #endif
331 inline void value::swap(value &x) throw() {
332  std::swap(type_, x.type_);
333  std::swap(u_, x.u_);
334 }
335 
336 #define IS(ctype, jtype) \
337  template <> inline bool value::is<ctype>() const { \
338  return type_ == jtype##_type; \
339  }
340 IS(null, null)
341 IS(bool, boolean)
342 #ifdef PICOJSON_USE_INT64
343 IS(int64_t, int64)
344 #endif
345 IS(std::string, string)
346 IS(array, array)
347 IS(object, object)
348 #undef IS
349 template <> inline bool value::is<double>() const {
350  return type_ == number_type
351 #ifdef PICOJSON_USE_INT64
352  || type_ == int64_type
353 #endif
354  ;
355 }
356 
357 #define GET(ctype, var) \
358  template <> inline const ctype &value::get<ctype>() const { \
359  PICOJSON_ASSERT("type mismatch! call is<type>() before get<type>()" && is<ctype>()); \
360  return var; \
361  } \
362  template <> inline ctype &value::get<ctype>() { \
363  PICOJSON_ASSERT("type mismatch! call is<type>() before get<type>()" && is<ctype>()); \
364  return var; \
365  }
366 GET(bool, u_.boolean_)
367 GET(std::string, *u_.string_)
368 GET(array, *u_.array_)
369 GET(object, *u_.object_)
370 #ifdef PICOJSON_USE_INT64
371 GET(double,
372  (type_ == int64_type && (const_cast<value *>(this)->type_ = number_type, const_cast<value *>(this)->u_.number_ = u_.int64_),
373  u_.number_))
374 GET(int64_t, u_.int64_)
375 #else
376 GET(double, u_.number_)
377 #endif
378 #undef GET
379 
380 #define SET(ctype, jtype, setter) \
381  template <> inline void value::set<ctype>(const ctype &_val) { \
382  clear(); \
383  type_ = jtype##_type; \
384  setter \
385  }
386 SET(bool, boolean, u_.boolean_ = _val;)
387 SET(std::string, string, u_.string_ = new std::string(_val);)
388 SET(array, array, u_.array_ = new array(_val);)
389 SET(object, object, u_.object_ = new object(_val);)
390 SET(double, number, u_.number_ = _val;)
391 #ifdef PICOJSON_USE_INT64
392 SET(int64_t, int64, u_.int64_ = _val;)
393 #endif
394 #undef SET
395 
396 #if PICOJSON_USE_RVALUE_REFERENCE
397 #define MOVESET(ctype, jtype, setter) \
398  template <> inline void value::set<ctype>(ctype && _val) { \
399  clear(); \
400  type_ = jtype##_type; \
401  setter \
402  }
403 MOVESET(std::string, string, u_.string_ = new std::string(std::move(_val));)
404 MOVESET(array, array, u_.array_ = new array(std::move(_val));)
405 MOVESET(object, object, u_.object_ = new object(std::move(_val));)
406 #undef MOVESET
407 #endif
408 
409 inline bool value::evaluate_as_boolean() const {
410  switch (type_) {
411  case null_type:
412  return false;
413  case boolean_type:
414  return u_.boolean_;
415  case number_type:
416  return u_.number_ != 0;
417 #ifdef PICOJSON_USE_INT64
418  case int64_type:
419  return u_.int64_ != 0;
420 #endif
421  case string_type:
422  return !u_.string_->empty();
423  default:
424  return true;
425  }
426 }
427 
428 inline const value &value::get(const size_t idx) const {
429  static value s_null;
430  PICOJSON_ASSERT(is<array>());
431  return idx < u_.array_->size() ? (*u_.array_)[idx] : s_null;
432 }
433 
434 inline value &value::get(const size_t idx) {
435  static value s_null;
436  PICOJSON_ASSERT(is<array>());
437  return idx < u_.array_->size() ? (*u_.array_)[idx] : s_null;
438 }
439 
440 inline const value &value::get(const std::string &key) const {
441  static value s_null;
442  PICOJSON_ASSERT(is<object>());
443  object::const_iterator i = u_.object_->find(key);
444  return i != u_.object_->end() ? i->second : s_null;
445 }
446 
447 inline value &value::get(const std::string &key) {
448  static value s_null;
449  PICOJSON_ASSERT(is<object>());
450  auto i = u_.object_->find(key);
451  return i != u_.object_->end() ? i->second : s_null;
452 }
453 
454 inline bool value::contains(const size_t idx) const {
455  PICOJSON_ASSERT(is<array>());
456  return idx < u_.array_->size();
457 }
458 
459 inline bool value::contains(const std::string &key) const {
460  PICOJSON_ASSERT(is<object>());
461  object::const_iterator i = u_.object_->find(key);
462  return i != u_.object_->end();
463 }
464 
465 inline std::string value::to_str() const {
466  switch (type_) {
467  case null_type:
468  return "null";
469  case boolean_type:
470  return u_.boolean_ ? "true" : "false";
471 #ifdef PICOJSON_USE_INT64
472  case int64_type: {
473  char buf[sizeof("-9223372036854775808")];
474  SNPRINTF(buf, sizeof(buf), "%" PRId64, u_.int64_);
475  return buf;
476  }
477 #endif
478  case number_type: {
479  char buf[256];
480  double tmp;
481  SNPRINTF(buf, sizeof(buf), fabs(u_.number_) < (1ULL << 53) && modf(u_.number_, &tmp) == 0 ? "%.f" : "%.17g", u_.number_);
482 #if PICOJSON_USE_LOCALE
483  char *decimal_point = localeconv()->decimal_point;
484  if (strcmp(decimal_point, ".") != 0) {
485  size_t decimal_point_len = strlen(decimal_point);
486  for (char *p = buf; *p != '\0'; ++p) {
487  if (strncmp(p, decimal_point, decimal_point_len) == 0) {
488  return std::string(buf, p) + "." + (p + decimal_point_len);
489  }
490  }
491  }
492 #endif
493  return buf;
494  }
495  case string_type:
496  return *u_.string_;
497  case array_type:
498  return "array";
499  case object_type:
500  return "object";
501  default:
502  PICOJSON_ASSERT(0);
503 #ifdef _MSC_VER
504  __assume(0);
505 #endif
506  }
507  return std::string();
508 }
509 
510 template <typename Iter> void copy(const std::string &s, Iter oi) {
511  std::copy(s.begin(), s.end(), oi);
512 }
513 
514 template <typename Iter> struct serialize_str_char {
515  Iter oi;
516  void operator()(char c) {
517  switch (c) {
518 #define MAP(val, sym) \
519  case val: \
520  copy(sym, oi); \
521  break
522  MAP('"', "\\\"");
523  MAP('\\', "\\\\");
524  MAP('/', "\\/");
525  MAP('\b', "\\b");
526  MAP('\f', "\\f");
527  MAP('\n', "\\n");
528  MAP('\r', "\\r");
529  MAP('\t', "\\t");
530 #undef MAP
531  default:
532  if (static_cast<unsigned char>(c) < 0x20 || c == 0x7f) {
533  char buf[7];
534  SNPRINTF(buf, sizeof(buf), "\\u%04x", c & 0xff);
535  copy(buf, buf + 6, oi);
536  } else {
537  *oi++ = c;
538  }
539  break;
540  }
541  }
542 };
543 
544 template <typename Iter> void serialize_str(const std::string &s, Iter oi) {
545  *oi++ = '"';
546  serialize_str_char<Iter> process_char = {oi};
547  std::for_each(s.begin(), s.end(), process_char);
548  *oi++ = '"';
549 }
550 
551 template <typename Iter> void value::serialize(Iter oi, bool prettify) const {
552  return serialize_(oi, prettify ? 0 : -1);
553 }
554 
555 inline std::string value::serialize(bool prettify) const {
556  return serialize_(prettify ? 0 : -1);
557 }
558 
559 template <typename Iter> void value::_indent(Iter oi, int indent) {
560  *oi++ = '\n';
561  for (int i = 0; i < indent * INDENT_WIDTH; ++i) {
562  *oi++ = ' ';
563  }
564 }
565 
566 template <typename Iter> void value::serialize_(Iter oi, int indent) const {
567  switch (type_) {
568  case string_type:
569  serialize_str(*u_.string_, oi);
570  break;
571  case array_type: {
572  *oi++ = '[';
573  if (indent != -1) {
574  ++indent;
575  }
576  for (array::const_iterator i = u_.array_->begin(); i != u_.array_->end(); ++i) {
577  if (i != u_.array_->begin()) {
578  *oi++ = ',';
579  }
580  if (indent != -1) {
581  _indent(oi, indent);
582  }
583  i->serialize_(oi, indent);
584  }
585  if (indent != -1) {
586  --indent;
587  if (!u_.array_->empty()) {
588  _indent(oi, indent);
589  }
590  }
591  *oi++ = ']';
592  break;
593  }
594  case object_type: {
595  *oi++ = '{';
596  if (indent != -1) {
597  ++indent;
598  }
599  for (object::const_iterator i = u_.object_->begin(); i != u_.object_->end(); ++i) {
600  if (i != u_.object_->begin()) {
601  *oi++ = ',';
602  }
603  if (indent != -1) {
604  _indent(oi, indent);
605  }
606  serialize_str(i->first, oi);
607  *oi++ = ':';
608  if (indent != -1) {
609  *oi++ = ' ';
610  }
611  i->second.serialize_(oi, indent);
612  }
613  if (indent != -1) {
614  --indent;
615  if (!u_.object_->empty()) {
616  _indent(oi, indent);
617  }
618  }
619  *oi++ = '}';
620  break;
621  }
622  default:
623  copy(to_str(), oi);
624  break;
625  }
626  if (indent == 0) {
627  *oi++ = '\n';
628  }
629 }
630 
631 inline std::string value::serialize_(int indent) const {
632  std::string s;
633  serialize_(std::back_inserter(s), indent);
634  return s;
635 }
636 
637 template <typename Iter> class input {
638 protected:
639  Iter cur_, end_;
640  bool consumed_;
641  int line_;
642 
643 public:
644  input(const Iter &first, const Iter &last) : cur_(first), end_(last), consumed_(false), line_(1) {
645  }
646  int getc() {
647  if (consumed_) {
648  if (*cur_ == '\n') {
649  ++line_;
650  }
651  ++cur_;
652  }
653  if (cur_ == end_) {
654  consumed_ = false;
655  return -1;
656  }
657  consumed_ = true;
658  return *cur_ & 0xff;
659  }
660  void ungetc() {
661  consumed_ = false;
662  }
663  Iter cur() const {
664  if (consumed_) {
665  input<Iter> *self = const_cast<input<Iter> *>(this);
666  self->consumed_ = false;
667  ++self->cur_;
668  }
669  return cur_;
670  }
671  int line() const {
672  return line_;
673  }
674  void skip_ws() {
675  while (1) {
676  int ch = getc();
677  if (!(ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r')) {
678  ungetc();
679  break;
680  }
681  }
682  }
683  bool expect(const int expected) {
684  skip_ws();
685  if (getc() != expected) {
686  ungetc();
687  return false;
688  }
689  return true;
690  }
691  bool match(const std::string &pattern) {
692  for (std::string::const_iterator pi(pattern.begin()); pi != pattern.end(); ++pi) {
693  if (getc() != *pi) {
694  ungetc();
695  return false;
696  }
697  }
698  return true;
699  }
700 };
701 
702 template <typename Iter> inline int _parse_quadhex(input<Iter> &in) {
703  int uni_ch = 0, hex;
704  for (int i = 0; i < 4; i++) {
705  if ((hex = in.getc()) == -1) {
706  return -1;
707  }
708  if ('0' <= hex && hex <= '9') {
709  hex -= '0';
710  } else if ('A' <= hex && hex <= 'F') {
711  hex -= 'A' - 0xa;
712  } else if ('a' <= hex && hex <= 'f') {
713  hex -= 'a' - 0xa;
714  } else {
715  in.ungetc();
716  return -1;
717  }
718  uni_ch = uni_ch * 16 + hex;
719  }
720  return uni_ch;
721 }
722 
723 template <typename String, typename Iter> inline bool _parse_codepoint(String &out, input<Iter> &in) {
724  int uni_ch;
725  if ((uni_ch = _parse_quadhex(in)) == -1) {
726  return false;
727  }
728  if (0xd800 <= uni_ch && uni_ch <= 0xdfff) {
729  if (0xdc00 <= uni_ch) {
730  // a second 16-bit of a surrogate pair appeared
731  return false;
732  }
733  // first 16-bit of surrogate pair, get the next one
734  if (in.getc() != '\\' || in.getc() != 'u') {
735  in.ungetc();
736  return false;
737  }
738  int second = _parse_quadhex(in);
739  if (!(0xdc00 <= second && second <= 0xdfff)) {
740  return false;
741  }
742  uni_ch = ((uni_ch - 0xd800) << 10) | ((second - 0xdc00) & 0x3ff);
743  uni_ch += 0x10000;
744  }
745  if (uni_ch < 0x80) {
746  out.push_back(static_cast<char>(uni_ch));
747  } else {
748  if (uni_ch < 0x800) {
749  out.push_back(static_cast<char>(0xc0 | (uni_ch >> 6)));
750  } else {
751  if (uni_ch < 0x10000) {
752  out.push_back(static_cast<char>(0xe0 | (uni_ch >> 12)));
753  } else {
754  out.push_back(static_cast<char>(0xf0 | (uni_ch >> 18)));
755  out.push_back(static_cast<char>(0x80 | ((uni_ch >> 12) & 0x3f)));
756  }
757  out.push_back(static_cast<char>(0x80 | ((uni_ch >> 6) & 0x3f)));
758  }
759  out.push_back(static_cast<char>(0x80 | (uni_ch & 0x3f)));
760  }
761  return true;
762 }
763 
764 template <typename String, typename Iter> inline bool _parse_string(String &out, input<Iter> &in) {
765  while (1) {
766  int ch = in.getc();
767  if (ch < ' ') {
768  in.ungetc();
769  return false;
770  } else if (ch == '"') {
771  return true;
772  } else if (ch == '\\') {
773  if ((ch = in.getc()) == -1) {
774  return false;
775  }
776  switch (ch) {
777 #define MAP(sym, val) \
778  case sym: \
779  out.push_back(val); \
780  break
781  MAP('"', '\"');
782  MAP('\\', '\\');
783  MAP('/', '/');
784  MAP('b', '\b');
785  MAP('f', '\f');
786  MAP('n', '\n');
787  MAP('r', '\r');
788  MAP('t', '\t');
789 #undef MAP
790  case 'u':
791  if (!_parse_codepoint(out, in)) {
792  return false;
793  }
794  break;
795  default:
796  return false;
797  }
798  } else {
799  out.push_back(static_cast<char>(ch));
800  }
801  }
802  return false;
803 }
804 
805 template <typename Context, typename Iter> inline bool _parse_array(Context &ctx, input<Iter> &in) {
806  if (!ctx.parse_array_start()) {
807  return false;
808  }
809  size_t idx = 0;
810  if (in.expect(']')) {
811  return ctx.parse_array_stop(idx);
812  }
813  do {
814  if (!ctx.parse_array_item(in, idx)) {
815  return false;
816  }
817  idx++;
818  } while (in.expect(','));
819  return in.expect(']') && ctx.parse_array_stop(idx);
820 }
821 
822 template <typename Context, typename Iter> inline bool _parse_object(Context &ctx, input<Iter> &in) {
823  if (!ctx.parse_object_start()) {
824  return false;
825  }
826  if (in.expect('}')) {
827  return true;
828  }
829  do {
830  std::string key;
831  if (!in.expect('"') || !_parse_string(key, in) || !in.expect(':')) {
832  return false;
833  }
834  if (!ctx.parse_object_item(in, key)) {
835  return false;
836  }
837  } while (in.expect(','));
838  return in.expect('}');
839 }
840 
841 template <typename Iter> inline std::string _parse_number(input<Iter> &in) {
842  std::string num_str;
843  while (1) {
844  int ch = in.getc();
845  if (('0' <= ch && ch <= '9') || ch == '+' || ch == '-' || ch == 'e' || ch == 'E') {
846  num_str.push_back(static_cast<char>(ch));
847  } else if (ch == '.') {
848 #if PICOJSON_USE_LOCALE
849  num_str += localeconv()->decimal_point;
850 #else
851  num_str.push_back('.');
852 #endif
853  } else {
854  in.ungetc();
855  break;
856  }
857  }
858  return num_str;
859 }
860 
861 template <typename Context, typename Iter> inline bool _parse(Context &ctx, input<Iter> &in) {
862  in.skip_ws();
863  int ch = in.getc();
864  switch (ch) {
865 #define IS(ch, text, op) \
866  case ch: \
867  if (in.match(text) && op) { \
868  return true; \
869  } else { \
870  return false; \
871  }
872  IS('n', "ull", ctx.set_null());
873  IS('f', "alse", ctx.set_bool(false));
874  IS('t', "rue", ctx.set_bool(true));
875 #undef IS
876  case '"':
877  return ctx.parse_string(in);
878  case '[':
879  return _parse_array(ctx, in);
880  case '{':
881  return _parse_object(ctx, in);
882  default:
883  if (('0' <= ch && ch <= '9') || ch == '-') {
884  double f;
885  char *endp;
886  in.ungetc();
887  std::string num_str(_parse_number(in));
888  if (num_str.empty()) {
889  return false;
890  }
891 #ifdef PICOJSON_USE_INT64
892  {
893  errno = 0;
894  intmax_t ival = strtoimax(num_str.c_str(), &endp, 10);
895  if (errno == 0 && std::numeric_limits<int64_t>::min() <= ival && ival <= std::numeric_limits<int64_t>::max() &&
896  endp == num_str.c_str() + num_str.size()) {
897  ctx.set_int64(ival);
898  return true;
899  }
900  }
901 #endif
902  f = strtod(num_str.c_str(), &endp);
903  if (endp == num_str.c_str() + num_str.size()) {
904  ctx.set_number(f);
905  return true;
906  }
907  return false;
908  }
909  break;
910  }
911  in.ungetc();
912  return false;
913 }
914 
916 public:
917  bool set_null() {
918  return false;
919  }
920  bool set_bool(bool) {
921  return false;
922  }
923 #ifdef PICOJSON_USE_INT64
924  bool set_int64(int64_t) {
925  return false;
926  }
927 #endif
928  bool set_number(double) {
929  return false;
930  }
931  template <typename Iter> bool parse_string(input<Iter> &) {
932  return false;
933  }
935  return false;
936  }
937  template <typename Iter> bool parse_array_item(input<Iter> &, size_t) {
938  return false;
939  }
940  bool parse_array_stop(size_t) {
941  return false;
942  }
944  return false;
945  }
946  template <typename Iter> bool parse_object_item(input<Iter> &, const std::string &) {
947  return false;
948  }
949 };
950 
952 protected:
954 
955 public:
957  }
958  bool set_null() {
959  *out_ = value();
960  return true;
961  }
962  bool set_bool(bool b) {
963  *out_ = value(b);
964  return true;
965  }
966 #ifdef PICOJSON_USE_INT64
967  bool set_int64(int64_t i) {
968  *out_ = value(i);
969  return true;
970  }
971 #endif
972  bool set_number(double f) {
973  *out_ = value(f);
974  return true;
975  }
976  template <typename Iter> bool parse_string(input<Iter> &in) {
977  *out_ = value(string_type, false);
978  return _parse_string(out_->get<std::string>(), in);
979  }
981  *out_ = value(array_type, false);
982  return true;
983  }
984  template <typename Iter> bool parse_array_item(input<Iter> &in, size_t) {
985  array &a = out_->get<array>();
986  a.push_back(value());
987  default_parse_context ctx(&a.back());
988  return _parse(ctx, in);
989  }
990  bool parse_array_stop(size_t) {
991  return true;
992  }
994  *out_ = value(object_type, false);
995  return true;
996  }
997  template <typename Iter> bool parse_object_item(input<Iter> &in, const std::string &key) {
998  object &o = out_->get<object>();
999  default_parse_context ctx(&o[key]);
1000  return _parse(ctx, in);
1001  }
1002 
1003 private:
1006 };
1007 
1009 public:
1010  struct dummy_str {
1011  void push_back(int) {
1012  }
1013  };
1014 
1015 public:
1017  }
1018  bool set_null() {
1019  return true;
1020  }
1021  bool set_bool(bool) {
1022  return true;
1023  }
1024 #ifdef PICOJSON_USE_INT64
1025  bool set_int64(int64_t) {
1026  return true;
1027  }
1028 #endif
1029  bool set_number(double) {
1030  return true;
1031  }
1032  template <typename Iter> bool parse_string(input<Iter> &in) {
1033  dummy_str s;
1034  return _parse_string(s, in);
1035  }
1037  return true;
1038  }
1039  template <typename Iter> bool parse_array_item(input<Iter> &in, size_t) {
1040  return _parse(*this, in);
1041  }
1042  bool parse_array_stop(size_t) {
1043  return true;
1044  }
1046  return true;
1047  }
1048  template <typename Iter> bool parse_object_item(input<Iter> &in, const std::string &) {
1049  return _parse(*this, in);
1050  }
1051 
1052 private:
1055 };
1056 
1057 // obsolete, use the version below
1058 template <typename Iter> inline std::string parse(value &out, Iter &pos, const Iter &last) {
1059  std::string err;
1060  pos = parse(out, pos, last, &err);
1061  return err;
1062 }
1063 
1064 template <typename Context, typename Iter> inline Iter _parse(Context &ctx, const Iter &first, const Iter &last, std::string *err) {
1065  input<Iter> in(first, last);
1066  if (!_parse(ctx, in) && err != nullptr) {
1067  char buf[64];
1068  SNPRINTF(buf, sizeof(buf), "syntax error at line %d near: ", in.line());
1069  *err = buf;
1070  while (1) {
1071  int ch = in.getc();
1072  if (ch == -1 || ch == '\n') {
1073  break;
1074  } else if (ch >= ' ') {
1075  err->push_back(static_cast<char>(ch));
1076  }
1077  }
1078  }
1079  return in.cur();
1080 }
1081 
1082 template <typename Iter> inline Iter parse(value &out, const Iter &first, const Iter &last, std::string *err) {
1083  default_parse_context ctx(&out);
1084  return _parse(ctx, first, last, err);
1085 }
1086 
1087 inline std::string parse(value &out, const std::string &s) {
1088  std::string err;
1089  parse(out, s.begin(), s.end(), &err);
1090  return err;
1091 }
1092 
1093 inline std::string parse(value &out, std::istream &is) {
1094  std::string err;
1095  parse(out, std::istreambuf_iterator<char>(is.rdbuf()), std::istreambuf_iterator<char>(), &err);
1096  return err;
1097 }
1098 
1099 template <typename T> struct last_error_t { static std::string s; };
1100 template <typename T> std::string last_error_t<T>::s;
1101 
1102 inline void set_last_error(const std::string &s) {
1104 }
1105 
1106 inline const std::string &get_last_error() {
1107  return last_error_t<bool>::s;
1108 }
1109 
1110 inline bool operator==(const value &x, const value &y) {
1111  if (x.is<null>())
1112  return y.is<null>();
1113 #define PICOJSON_CMP(type) \
1114  if (x.is<type>()) \
1115  return y.is<type>() && x.get<type>() == y.get<type>()
1116  PICOJSON_CMP(bool);
1117  PICOJSON_CMP(double);
1118  PICOJSON_CMP(std::string);
1120  PICOJSON_CMP(object);
1121 #undef PICOJSON_CMP
1122  PICOJSON_ASSERT(0);
1123 #ifdef _MSC_VER
1124  __assume(0);
1125 #endif
1126  return false;
1127 }
1128 
1129 inline bool operator!=(const value &x, const value &y) {
1130  return !(x == y);
1131 }
1132 }
1133 
1134 #if !PICOJSON_USE_RVALUE_REFERENCE
1135 namespace std {
1136 template <> inline void swap(picojson::value &x, picojson::value &y) {
1137  x.swap(y);
1138 }
1139 }
1140 #endif
1141 
1142 inline std::istream &operator>>(std::istream &is, picojson::value &x) {
1143  picojson::set_last_error(std::string());
1144  const std::string err(picojson::parse(x, is));
1145  if (!err.empty()) {
1147  is.setstate(std::ios::failbit);
1148  }
1149  return is;
1150 }
1151 
1152 inline std::ostream &operator<<(std::ostream &os, const picojson::value &x) {
1153  x.serialize(std::ostream_iterator<char>(os));
1154  return os;
1155 }
1156 #ifdef _MSC_VER
1157 #pragma warning(pop)
1158 #endif
1159 
1160 #endif
picojson::value::get
T & get()
picojson::null_parse_context::set_null
bool set_null()
Definition: picojson.h:1018
picojson::default_parse_context
Definition: picojson.h:951
picojson::default_parse_context::set_number
bool set_number(double f)
Definition: picojson.h:972
SNPRINTF
#define SNPRINTF
Definition: picojson.h:100
IS
#define IS(ctype, jtype)
Definition: picojson.h:336
picojson::value
Definition: picojson.h:122
picojson::deny_parse_context::parse_object_item
bool parse_object_item(input< Iter > &, const std::string &)
Definition: picojson.h:946
picojson::default_parse_context::out_
value * out_
Definition: picojson.h:953
picojson::default_parse_context::parse_array_item
bool parse_array_item(input< Iter > &in, size_t)
Definition: picojson.h:984
picojson::value::array
std::vector< value > array
Definition: picojson.h:124
std::swap
void swap(picojson::value &x, picojson::value &y)
Definition: picojson.h:1136
picojson::string_type
@ string_type
Definition: picojson.h:109
picojson::serialize_str
void serialize_str(const std::string &s, Iter oi)
Definition: picojson.h:544
picojson::deny_parse_context::parse_array_item
bool parse_array_item(input< Iter > &, size_t)
Definition: picojson.h:937
picojson::input::ungetc
void ungetc()
Definition: picojson.h:660
picojson::serialize_str_char::oi
Iter oi
Definition: picojson.h:515
picojson::value::_storage::object_
object * object_
Definition: picojson.h:134
c
static double c(int i, int j, fullMatrix< double > &CA, const std::vector< SPoint3 > &P, const std::vector< SPoint3 > &Q)
Definition: discreteFrechetDistance.cpp:15
picojson::value::set
void set(const T &)
picojson::default_parse_context::parse_object_item
bool parse_object_item(input< Iter > &in, const std::string &key)
Definition: picojson.h:997
picojson::deny_parse_context::set_null
bool set_null()
Definition: picojson.h:917
picojson::null_parse_context::null_parse_context
null_parse_context()
Definition: picojson.h:1016
picojson::input::skip_ws
void skip_ws()
Definition: picojson.h:674
picojson::null_parse_context::set_number
bool set_number(double)
Definition: picojson.h:1029
LegendrePolynomials::f
void f(int n, double u, double *val)
Definition: orthogonalBasis.cpp:77
picojson::null_parse_context::dummy_str::push_back
void push_back(int)
Definition: picojson.h:1011
picojson::deny_parse_context::parse_array_start
bool parse_array_start()
Definition: picojson.h:934
picojson::value::clear
void clear()
Definition: picojson.h:279
GET
#define GET(ctype, var)
Definition: picojson.h:357
picojson::_parse_string
bool _parse_string(String &out, input< Iter > &in)
Definition: picojson.h:764
picojson::value::serialize
void serialize(Iter os, bool prettify=false) const
Definition: picojson.h:551
picojson::value::swap
void swap(value &x)
Definition: picojson.h:331
picojson::last_error_t
Definition: picojson.h:1099
SET
#define SET(ctype, jtype, setter)
Definition: picojson.h:380
INIT
#define INIT(p, v)
picojson::value::_storage::number_
double number_
Definition: picojson.h:128
picojson::_parse
bool _parse(Context &ctx, input< Iter > &in)
Definition: picojson.h:861
picojson::deny_parse_context::parse_array_stop
bool parse_array_stop(size_t)
Definition: picojson.h:940
picojson::deny_parse_context::parse_string
bool parse_string(input< Iter > &)
Definition: picojson.h:931
picojson::null_parse_context::dummy_str
Definition: picojson.h:1010
picojson::_parse_codepoint
bool _parse_codepoint(String &out, input< Iter > &in)
Definition: picojson.h:723
picojson::null_parse_context::set_bool
bool set_bool(bool)
Definition: picojson.h:1021
operator<<
std::ostream & operator<<(std::ostream &os, const picojson::value &x)
Definition: picojson.h:1152
picojson::value::u_
_storage u_
Definition: picojson.h:139
picojson::value::operator=
value & operator=(const value &x)
Definition: picojson.h:314
picojson::null_parse_context::parse_array_item
bool parse_array_item(input< Iter > &in, size_t)
Definition: picojson.h:1039
picojson::input::end_
Iter end_
Definition: picojson.h:639
picojson::deny_parse_context
Definition: picojson.h:915
picojson::value::_storage::boolean_
bool boolean_
Definition: picojson.h:127
picojson::input::expect
bool expect(const int expected)
Definition: picojson.h:683
picojson::last_error_t::s
static std::string s
Definition: picojson.h:1099
picojson::value::get
const T & get() const
picojson::default_parse_context::operator=
default_parse_context & operator=(const default_parse_context &)
picojson::value::_storage::array_
array * array_
Definition: picojson.h:133
picojson::default_parse_context::parse_array_stop
bool parse_array_stop(size_t)
Definition: picojson.h:990
picojson::set_last_error
void set_last_error(const std::string &s)
Definition: picojson.h:1102
swap
void swap(double &a, double &b)
Definition: meshTriangulation.cpp:27
PICOJSON_ASSERT
#define PICOJSON_ASSERT(e)
Definition: picojson.h:86
picojson
Definition: picojson.h:103
picojson::value::to_str
std::string to_str() const
Definition: picojson.h:465
picojson::default_parse_context::default_parse_context
default_parse_context(value *out)
Definition: picojson.h:956
picojson::_parse_quadhex
int _parse_quadhex(input< Iter > &in)
Definition: picojson.h:702
picojson::_parse_number
std::string _parse_number(input< Iter > &in)
Definition: picojson.h:841
picojson::value::type_
int type_
Definition: picojson.h:138
picojson::value::is
bool is() const
picojson::object
value::object object
Definition: picojson.h:195
picojson::value::_storage::string_
std::string * string_
Definition: picojson.h:132
picojson::get_last_error
const std::string & get_last_error()
Definition: picojson.h:1106
picojson::value::contains
bool contains(const size_t idx) const
Definition: picojson.h:454
picojson::parse
std::string parse(value &out, Iter &pos, const Iter &last)
Definition: picojson.h:1058
picojson::null_parse_context::parse_array_stop
bool parse_array_stop(size_t)
Definition: picojson.h:1042
picojson::null_type
@ null_type
Definition: picojson.h:106
picojson::null_parse_context::parse_object_start
bool parse_object_start()
Definition: picojson.h:1045
picojson::value::object
std::map< std::string, value > object
Definition: picojson.h:125
picojson::input::getc
int getc()
Definition: picojson.h:646
picojson::input::line_
int line_
Definition: picojson.h:641
picojson::input
Definition: picojson.h:637
picojson::boolean_type
@ boolean_type
Definition: picojson.h:107
picojson::null_parse_context
Definition: picojson.h:1008
picojson::default_parse_context::parse_string
bool parse_string(input< Iter > &in)
Definition: picojson.h:976
picojson::default_parse_context::default_parse_context
default_parse_context(const default_parse_context &)
picojson::serialize_str_char::operator()
void operator()(char c)
Definition: picojson.h:516
picojson::serialize_str_char
Definition: picojson.h:514
picojson::null_parse_context::operator=
null_parse_context & operator=(const null_parse_context &)
operator>>
std::istream & operator>>(std::istream &is, picojson::value &x)
Definition: picojson.h:1142
picojson::_parse_object
bool _parse_object(Context &ctx, input< Iter > &in)
Definition: picojson.h:822
picojson::_parse_array
bool _parse_array(Context &ctx, input< Iter > &in)
Definition: picojson.h:805
picojson::value::value
value()
Definition: picojson.h:197
PICOJSON_CMP
#define PICOJSON_CMP(type)
picojson::input::line
int line() const
Definition: picojson.h:671
std
Definition: picojson.h:1135
picojson::input::cur_
Iter cur_
Definition: picojson.h:639
picojson::operator!=
bool operator!=(const value &x, const value &y)
Definition: picojson.h:1129
picojson::copy
void copy(const std::string &s, Iter oi)
Definition: picojson.h:510
picojson::null_parse_context::parse_string
bool parse_string(input< Iter > &in)
Definition: picojson.h:1032
picojson::input::match
bool match(const std::string &pattern)
Definition: picojson.h:691
picojson::array
value::array array
Definition: picojson.h:194
picojson::value::evaluate_as_boolean
bool evaluate_as_boolean() const
Definition: picojson.h:409
picojson::operator==
bool operator==(const value &x, const value &y)
Definition: picojson.h:1110
picojson::input::cur
Iter cur() const
Definition: picojson.h:663
picojson::value::value
value(const T *)
picojson::value::serialize_
void serialize_(Iter os, int indent) const
Definition: picojson.h:566
picojson::deny_parse_context::set_bool
bool set_bool(bool)
Definition: picojson.h:920
picojson::array_type
@ array_type
Definition: picojson.h:110
picojson::input::consumed_
bool consumed_
Definition: picojson.h:640
DEINIT
#define DEINIT(p)
picojson::default_parse_context::set_bool
bool set_bool(bool b)
Definition: picojson.h:962
picojson::null_parse_context::parse_object_item
bool parse_object_item(input< Iter > &in, const std::string &)
Definition: picojson.h:1048
picojson::default_parse_context::parse_array_start
bool parse_array_start()
Definition: picojson.h:980
picojson::object_type
@ object_type
Definition: picojson.h:111
picojson::value::_indent
static void _indent(Iter os, int indent)
Definition: picojson.h:559
picojson::default_parse_context::parse_object_start
bool parse_object_start()
Definition: picojson.h:993
picojson::input::input
input(const Iter &first, const Iter &last)
Definition: picojson.h:644
picojson::INDENT_WIDTH
@ INDENT_WIDTH
Definition: picojson.h:118
picojson::value::~value
~value()
Definition: picojson.h:294
picojson::deny_parse_context::parse_object_start
bool parse_object_start()
Definition: picojson.h:943
MAP
#define MAP(val, sym)
picojson::default_parse_context::set_null
bool set_null()
Definition: picojson.h:958
picojson::null_parse_context::parse_array_start
bool parse_array_start()
Definition: picojson.h:1036
picojson::value::_storage
Definition: picojson.h:126
picojson::null
Definition: picojson.h:120
picojson::null_parse_context::null_parse_context
null_parse_context(const null_parse_context &)
picojson::deny_parse_context::set_number
bool set_number(double)
Definition: picojson.h:928
picojson::number_type
@ number_type
Definition: picojson.h:108