github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/mattn/go-sqlite3/_example/mod_vtable/picojson.h (about)

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