[Common] Updating picojson library 72/188872/1
authorSzymon Jastrzebski <s.jastrzebsk@partner.samsung.com>
Fri, 31 Aug 2018 11:16:25 +0000 (13:16 +0200)
committerSzymon Jastrzebski <s.jastrzebsk@partner.samsung.com>
Tue, 11 Sep 2018 06:31:24 +0000 (08:31 +0200)
+ All the changes made to previous version of picojson were applied to
  the latest version.
+ Removed the PICOJSON_USE_LOCALE macro, because the localization is
  already handled and the solution was verified.

Change-Id: Icd4b6c29e8309d5573943f7ed7d174fe3f5a70dc
Signed-off-by: Szymon Jastrzebski <s.jastrzebsk@partner.samsung.com>
src/common/common.gyp
src/common/picojson.h

index ff428eed8a8e7a7bf58f4efe04eaeefbc0336fee..f65dd109c8dae390b00cf51b85ee8db650f79231 100644 (file)
       },
     },
   ],
+  'defines': ['PICOJSON_USE_RVALUE_REFERENCE'],
 }
index 44ae54313dfcfa99ff2161f5b3a2729fbc6b1aa1..c6b9aded56842dc2f067ba8f7531a174f44e2d68 100644 (file)
 /*
  * Copyright 2009-2010 Cybozu Labs, Inc.
- * Copyright 2011 Kazuho Oku
+ * Copyright 2011-2014 Kazuho Oku
+ * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
  *
  * 1. Redistributions of source code must retain the above copyright notice,
  *    this list of conditions and the following disclaimer.
+ *
  * 2. Redistributions in binary form must reproduce the above copyright notice,
  *    this list of conditions and the following disclaimer in the documentation
  *    and/or other materials provided with the distribution.
  *
- * THIS SOFTWARE IS PROVIDED BY CYBOZU LABS, INC. ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL CYBOZU LABS, INC. OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * The views and conclusions contained in the software and documentation are
- * those of the authors and should not be interpreted as representing official
- * policies, either expressed or implied, of Cybozu Labs, Inc.
- *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  */
 #ifndef picojson_h
 #define picojson_h
 
 #include <algorithm>
-#include <cmath>
+#include <cstddef>
 #include <cstdio>
 #include <cstdlib>
 #include <cstring>
 #include <iomanip>
 #include <iostream>
 #include <iterator>
+#include <limits>
 #include <map>
+#include <memory>
 #include <sstream>
+#include <stdexcept>
 #include <string>
+#include <utility>
 #include <vector>
 #include "common/assert.h"
 
+// for isnan/isinf
+#if __cplusplus >= 201103L
+#include <cmath>
+#else
+extern "C" {
+#ifdef _MSC_VER
+#include <float.h>
+#elif defined(__INTEL_COMPILER)
+#include <mathimf.h>
+#else
+#include <math.h>
+#endif
+}
+#endif
+
+#ifndef PICOJSON_USE_RVALUE_REFERENCE
+#if (defined(__cpp_rvalue_references) && __cpp_rvalue_references >= 200610) || \
+    (defined(_MSC_VER) && _MSC_VER >= 1600)
+#define PICOJSON_USE_RVALUE_REFERENCE 1
+#else
+#define PICOJSON_USE_RVALUE_REFERENCE 0
+#endif
+#endif  // PICOJSON_USE_RVALUE_REFERENCE
+
+#ifndef PICOJSON_NOEXCEPT
+#if PICOJSON_USE_RVALUE_REFERENCE
+#define PICOJSON_NOEXCEPT noexcept
+#else
+#define PICOJSON_NOEXCEPT throw()
+#endif
+#endif
+
+// experimental support for int64_t (see README.mkdn for detail)
+#ifdef PICOJSON_USE_INT64
+#define __STDC_FORMAT_MACROS
+#include <errno.h>
+#include <inttypes.h>
+#endif
+
 #ifdef _MSC_VER
 #define SNPRINTF _snprintf_s
 #pragma warning(push)
 #pragma warning(disable : 4244)  // conversion from int to char
+#pragma warning(disable : 4127)  // conditional expression is constant
+#pragma warning(disable : 4702)  // unreachable code
 #else
 #define SNPRINTF snprintf
 #endif
 
 namespace picojson {
 
-enum { null_type, boolean_type, number_type, string_type, array_type, object_type };
+enum {
+  null_type,
+  boolean_type,
+  number_type,
+  string_type,
+  array_type,
+  object_type
+#ifdef PICOJSON_USE_INT64
+  ,
+  int64_type
+#endif
+};
+
+enum { INDENT_WIDTH = 2 };
 
 struct null {};
 
@@ -65,9 +121,12 @@ class value {
   union _storage {
     bool boolean_;
     double number_;
-    std::string* string_;
-    array* array_;
-    object* object_;
+#ifdef PICOJSON_USE_INT64
+    int64_t int64_;
+#endif
+    std::string *string_;
+    array *array_;
+    object *object_;
   };
 
  protected:
@@ -78,44 +137,71 @@ class value {
   value();
   value(int type, bool);
   explicit value(bool b);
+#ifdef PICOJSON_USE_INT64
+  explicit value(int64_t i);
+#endif
   explicit value(double n);
-  explicit value(const std::string& s);
-  explicit value(const array& a);
-  explicit value(const object& o);
-  explicit value(const char* s);
-  value(const char* s, size_t len);
+  explicit value(const std::string &s);
+  explicit value(const array &a);
+  explicit value(const object &o);
+#if PICOJSON_USE_RVALUE_REFERENCE
+  explicit value(std::string &&s);
+  explicit value(array &&a);
+  explicit value(object &&o);
+#endif
+  explicit value(const char *s);
+  value(const char *s, size_t len);
   ~value();
-  value(const value& x);
-  value& operator=(const value& x);
-  void swap(value& x);
+  value(const value &x);
+  value &operator=(const value &x);
+#if PICOJSON_USE_RVALUE_REFERENCE
+  value(value &&x) PICOJSON_NOEXCEPT;
+  value &operator=(value &&x) PICOJSON_NOEXCEPT;
+#endif
+  void swap(value &x) PICOJSON_NOEXCEPT;
   template <typename T>
   bool is() const;
   template <typename T>
-  const T& get() const;
+  const T &get() const;
+  template <typename T>
+  T &get();
   template <typename T>
-  T& get();
+  void set(const T &);
+#if PICOJSON_USE_RVALUE_REFERENCE
+  template <typename T>
+  void set(T &&);
+#endif
   bool evaluate_as_boolean() const;
-  const value& get(size_t idx) const;
-  const value& get(const std::string& key) const;
-  bool contains(size_t idx) const;
-  bool contains(const std::string& key) const;
+  const value &get(const size_t idx) const;
+  const value &get(const std::string &key) const;
+  value &get(const size_t idx);
+  value &get(const std::string &key);
+
+  bool contains(const size_t idx) const;
+  bool contains(const std::string &key) const;
   std::string to_str() const;
   template <typename Iter>
-  void serialize(Iter os) const;
-  std::string serialize() const;
+  void serialize(Iter os, bool prettify = false) const;
+  std::string serialize(bool prettify = false) const;
 
  private:
   template <typename T>
-  value(const T*);  // intentionally defined to block implicit conversion of pointer to bool
+  value(const T *);  // intentionally defined to block implicit conversion of pointer to bool
+  template <typename Iter>
+  static void _indent(Iter os, int indent);
+  template <typename Iter>
+  void _serialize(Iter os, int indent) const;
+  std::string _serialize(int indent) const;
+  void clear();
 };
 
 typedef value::array array;
 typedef value::object object;
 
-inline value::value() : type_(null_type) {
+inline value::value() : type_(null_type), u_() {
 }
 
-inline value::value(int type, bool) : type_(type) {
+inline value::value(int type, bool) : type_(type), u_() {
   switch (type) {
 #define INIT(p, v) \
   case p##type:    \
@@ -123,6 +209,9 @@ inline value::value(int type, bool) : type_(type) {
     break
     INIT(boolean_, false);
     INIT(number_, 0.0);
+#ifdef PICOJSON_USE_INT64
+    INIT(int64_, 0);
+#endif
     INIT(string_, new std::string());
     INIT(array_, new array());
     INIT(object_, new object());
@@ -132,35 +221,66 @@ inline value::value(int type, bool) : type_(type) {
   }
 }
 
-inline value::value(bool b) : type_(boolean_type) {
+inline value::value(bool b) : type_(boolean_type), u_() {
   u_.boolean_ = b;
 }
 
-inline value::value(double n) : type_(number_type) {
+#ifdef PICOJSON_USE_INT64
+inline value::value(int64_t i) : type_(int64_type), u_() {
+  u_.int64_ = i;
+}
+#endif
+
+inline value::value(double n) : type_(number_type), u_() {
+  if (
+#ifdef _MSC_VER
+      !_finite(n)
+#elif __cplusplus >= 201103L
+      std::isnan(n) || std::isinf(n)
+#else
+      isnan(n) || isinf(n)
+#endif
+          ) {
+    throw std::overflow_error("");
+  }
   u_.number_ = n;
 }
 
-inline value::value(const std::string& s) : type_(string_type) {
+inline value::value(const std::string &s) : type_(string_type), u_() {
   u_.string_ = new std::string(s);
 }
 
-inline value::value(const array& a) : type_(array_type) {
+inline value::value(const array &a) : type_(array_type), u_() {
   u_.array_ = new array(a);
 }
 
-inline value::value(const object& o) : type_(object_type) {
+inline value::value(const object &o) : type_(object_type), u_() {
   u_.object_ = new object(o);
 }
 
-inline value::value(const char* s) : type_(string_type) {
+#if PICOJSON_USE_RVALUE_REFERENCE
+inline value::value(std::string &&s) : type_(string_type), u_() {
+  u_.string_ = new std::string(std::move(s));
+}
+
+inline value::value(array &&a) : type_(array_type), u_() {
+  u_.array_ = new array(std::move(a));
+}
+
+inline value::value(object &&o) : type_(object_type), u_() {
+  u_.object_ = new object(std::move(o));
+}
+#endif
+
+inline value::value(const char *s) : type_(string_type), u_() {
   u_.string_ = new std::string(s);
 }
 
-inline value::value(const char* s, size_t len) : type_(string_type) {
+inline value::value(const char *s, size_t len) : type_(string_type), u_() {
   u_.string_ = new std::string(s, len);
 }
 
-inline value::~value() {
+inline void value::clear() {
   switch (type_) {
 #define DEINIT(p) \
   case p##type:   \
@@ -175,7 +295,11 @@ inline value::~value() {
   }
 }
 
-inline value::value(const value& x) : type_(x.type_) {
+inline value::~value() {
+  clear();
+}
+
+inline value::value(const value &x) : type_(x.type_), u_() {
   switch (type_) {
 #define INIT(p, v) \
   case p##type:    \
@@ -191,15 +315,24 @@ inline value::value(const value& x) : type_(x.type_) {
   }
 }
 
-inline value& value::operator=(const value& x) {
+inline value &value::operator=(const value &x) {
   if (this != &x) {
-    this->~value();
-    new (this) value(x);
+    value t(x);
+    swap(t);
   }
   return *this;
 }
 
-inline void value::swap(value& x) {
+#if PICOJSON_USE_RVALUE_REFERENCE
+inline value::value(value &&x) PICOJSON_NOEXCEPT : type_(null_type), u_() {
+  swap(x);
+}
+inline value &value::operator=(value &&x) PICOJSON_NOEXCEPT {
+  swap(x);
+  return *this;
+}
+#endif
+inline void value::swap(value &x) PICOJSON_NOEXCEPT {
   std::swap(type_, x.type_);
   std::swap(u_, x.u_);
 }
@@ -211,31 +344,78 @@ inline void value::swap(value& x) {
   }
 IS(null, null)
 IS(bool, boolean)
-IS(int, number)
-IS(double, number)
+#ifdef PICOJSON_USE_INT64
+IS(int64_t, int64)
+#endif
 IS(std::string, string)
 IS(array, array)
 IS(object, object)
 #undef IS
+template <>
+inline bool value::is<double>() const {
+  return type_ == number_type
+#ifdef PICOJSON_USE_INT64
+         || type_ == int64_type
+#endif
+      ;
+}
 
-#define GET(ctype, var)                                                          \
-  template <>                                                                    \
-  inline const ctype& value::get<ctype>() const {                                \
-    Assert("type mismatch! call vis<type>() before get<type>()" && is<ctype>()); \
-    return var;                                                                  \
-  }                                                                              \
-  template <>                                                                    \
-  inline ctype& value::get<ctype>() {                                            \
-    Assert("type mismatch! call is<type>() before get<type>()" && is<ctype>());  \
-    return var;                                                                  \
+#define GET(ctype, var)                                                         \
+  template <>                                                                   \
+  inline const ctype &value::get<ctype>() const {                               \
+    Assert("type mismatch! call is<type>() before get<type>()" && is<ctype>()); \
+    return var;                                                                 \
+  }                                                                             \
+  template <>                                                                   \
+  inline ctype &value::get<ctype>() {                                           \
+    Assert("type mismatch! call is<type>() before get<type>()" && is<ctype>()); \
+    return var;                                                                 \
   }
 GET(bool, u_.boolean_)
-GET(double, u_.number_)
 GET(std::string, *u_.string_)
 GET(array, *u_.array_)
 GET(object, *u_.object_)
+#ifdef PICOJSON_USE_INT64
+GET(double, (type_ == int64_type && (const_cast<value *>(this)->type_ = number_type,
+                                     const_cast<value *>(this)->u_.number_ = u_.int64_),
+             u_.number_))
+GET(int64_t, u_.int64_)
+#else
+GET(double, u_.number_)
+#endif
 #undef GET
 
+#define SET(ctype, jtype, setter)                    \
+  template <>                                        \
+  inline void value::set<ctype>(const ctype &_val) { \
+    clear();                                         \
+    type_ = jtype##_type;                            \
+    setter                                           \
+  }
+SET(bool, boolean, u_.boolean_ = _val;)
+SET(std::string, string, u_.string_ = new std::string(_val);)
+SET(array, array, u_.array_ = new array(_val);)
+SET(object, object, u_.object_ = new object(_val);)
+SET(double, number, u_.number_ = _val;)
+#ifdef PICOJSON_USE_INT64
+SET(int64_t, int64, u_.int64_ = _val;)
+#endif
+#undef SET
+
+#if PICOJSON_USE_RVALUE_REFERENCE
+#define MOVESET(ctype, jtype, setter)            \
+  template <>                                    \
+  inline void value::set<ctype>(ctype && _val) { \
+    clear();                                     \
+    type_ = jtype##_type;                        \
+    setter                                       \
+  }
+MOVESET(std::string, string, u_.string_ = new std::string(std::move(_val));)
+MOVESET(array, array, u_.array_ = new array(std::move(_val));)
+MOVESET(object, object, u_.object_ = new object(std::move(_val));)
+#undef MOVESET
+#endif
+
 inline bool value::evaluate_as_boolean() const {
   switch (type_) {
     case null_type:
@@ -244,6 +424,10 @@ inline bool value::evaluate_as_boolean() const {
       return u_.boolean_;
     case number_type:
       return u_.number_ != 0;
+#ifdef PICOJSON_USE_INT64
+    case int64_type:
+      return u_.int64_ != 0;
+#endif
     case string_type:
       return !u_.string_->empty();
     default:
@@ -251,25 +435,38 @@ inline bool value::evaluate_as_boolean() const {
   }
 }
 
-inline const value& value::get(size_t idx) const {
+inline const value &value::get(const size_t idx) const {
+  static value s_null;
+  Assert(is<array>());
+  return idx < u_.array_->size() ? (*u_.array_)[idx] : s_null;
+}
+
+inline value &value::get(const size_t idx) {
   static value s_null;
   Assert(is<array>());
   return idx < u_.array_->size() ? (*u_.array_)[idx] : s_null;
 }
 
-inline const value& value::get(const std::string& key) const {
+inline const value &value::get(const std::string &key) const {
   static value s_null;
   Assert(is<object>());
   object::const_iterator i = u_.object_->find(key);
   return i != u_.object_->end() ? i->second : s_null;
 }
 
-inline bool value::contains(size_t idx) const {
+inline value &value::get(const std::string &key) {
+  static value s_null;
+  Assert(is<object>());
+  object::iterator i = u_.object_->find(key);
+  return i != u_.object_->end() ? i->second : s_null;
+}
+
+inline bool value::contains(const size_t idx) const {
   Assert(is<array>());
   return idx < u_.array_->size();
 }
 
-inline bool value::contains(const std::stringkey) const {
+inline bool value::contains(const std::string &key) const {
   Assert(is<object>());
   object::const_iterator i = u_.object_->find(key);
   return i != u_.object_->end();
@@ -281,6 +478,13 @@ inline std::string value::to_str() const {
       return "null";
     case boolean_type:
       return u_.boolean_ ? "true" : "false";
+#ifdef PICOJSON_USE_INT64
+    case int64_type: {
+      char buf[sizeof("-9223372036854775808")];
+      SNPRINTF(buf, sizeof(buf), "%" PRId64, u_.int64_);
+      return buf;
+    }
+#endif
     case number_type: {
       std::stringstream num_str;
       num_str.imbue(std::locale::classic());
@@ -303,24 +507,24 @@ inline std::string value::to_str() const {
 }
 
 template <typename Iter>
-void copy(const std::strings, Iter oi) {
+void copy(const std::string &s, Iter oi) {
   std::copy(s.begin(), s.end(), oi);
 }
 
 template <typename Iter>
-void serialize_str(const std::string& s, Iter oi) {
-  // C0 control characters, 00-1F
-  static const char* u_map[] = {
-      "\\u0000", "\\u0001", "\\u0002", "\\u0003", "\\u0004", "\\u0005", "\\u0006", "\\u0007",
-      "\\b",     "\\t",     "\\n",     "\\u000b", "\\f",     "\\r",     "\\u000e", "\\u000f",
-      "\\u0010", "\\u0011", "\\u0012", "\\u0013", "\\u0014", "\\u0015", "\\u0016", "\\u0017",
-      "\\u0018", "\\u0019", "\\u001a", "\\u001b", "\\u001c", "\\u001d", "\\u001e", "\\u001f"};
-  // To be sure we could rewrite C1 control characters also (first decode UTF-8, check, then map to
-  // \u sequence), but for now chromium allows C1 in JSON.parse
-
-  *oi++ = '"';
-  for (std::string::const_iterator i = s.begin(); i != s.end(); ++i) {
-    switch (*i) {
+struct serialize_str_char {
+  Iter oi;
+  void operator()(char c) {
+    // C0 control characters, 00-1F
+    static const char *u_map[] = {
+        "\\u0000", "\\u0001", "\\u0002", "\\u0003", "\\u0004", "\\u0005", "\\u0006", "\\u0007",
+        "\\b",     "\\t",     "\\n",     "\\u000b", "\\f",     "\\r",     "\\u000e", "\\u000f",
+        "\\u0010", "\\u0011", "\\u0012", "\\u0013", "\\u0014", "\\u0015", "\\u0016", "\\u0017",
+        "\\u0018", "\\u0019", "\\u001a", "\\u001b", "\\u001c", "\\u001d", "\\u001e", "\\u001f"};
+    // To be sure we could rewrite C1 control characters also (first decode UTF-8, check, then map
+    // to
+    // \u sequence), but for now chromium allows C1 in JSON.parse
+    switch (c) {
       case '"':
         copy("\\\"", oi);
         break;
@@ -331,46 +535,97 @@ void serialize_str(const std::string& s, Iter oi) {
         copy("\\u007f", oi);
         break;
       default:
-        if ((unsigned char)*i < 0x20) {
-          const char* u = u_map[(unsigned char)*i];
+        if ((unsigned char)c < 0x20) {
+          const char *u = u_map[(unsigned char)c];
           while (*u) {
             *oi++ = *u++;
           }
         } else {
-          *oi++ = *i;
+          *oi++ = c;
         }
         break;
     }
   }
+};
+
+template <typename Iter>
+void serialize_str(const std::string &s, Iter oi) {
+  *oi++ = '"';
+  serialize_str_char<Iter> process_char = {oi};
+  std::for_each(s.begin(), s.end(), process_char);
   *oi++ = '"';
 }
 
 template <typename Iter>
-void value::serialize(Iter oi) const {
+void value::serialize(Iter oi, bool prettify) const {
+  return _serialize(oi, prettify ? 0 : -1);
+}
+
+inline std::string value::serialize(bool prettify) const {
+  return _serialize(prettify ? 0 : -1);
+}
+
+template <typename Iter>
+void value::_indent(Iter oi, int indent) {
+  *oi++ = '\n';
+  for (int i = 0; i < indent * INDENT_WIDTH; ++i) {
+    *oi++ = ' ';
+  }
+}
+
+template <typename Iter>
+void value::_serialize(Iter oi, int indent) const {
   switch (type_) {
     case string_type:
       serialize_str(*u_.string_, oi);
       break;
     case array_type: {
       *oi++ = '[';
+      if (indent != -1) {
+        ++indent;
+      }
       for (array::const_iterator i = u_.array_->begin(); i != u_.array_->end(); ++i) {
         if (i != u_.array_->begin()) {
           *oi++ = ',';
         }
-        i->serialize(oi);
+        if (indent != -1) {
+          _indent(oi, indent);
+        }
+        i->_serialize(oi, indent);
+      }
+      if (indent != -1) {
+        --indent;
+        if (!u_.array_->empty()) {
+          _indent(oi, indent);
+        }
       }
       *oi++ = ']';
       break;
     }
     case object_type: {
       *oi++ = '{';
+      if (indent != -1) {
+        ++indent;
+      }
       for (object::const_iterator i = u_.object_->begin(); i != u_.object_->end(); ++i) {
         if (i != u_.object_->begin()) {
           *oi++ = ',';
         }
+        if (indent != -1) {
+          _indent(oi, indent);
+        }
         serialize_str(i->first, oi);
         *oi++ = ':';
-        i->second.serialize(oi);
+        if (indent != -1) {
+          *oi++ = ' ';
+        }
+        i->second._serialize(oi, indent);
+      }
+      if (indent != -1) {
+        --indent;
+        if (!u_.object_->empty()) {
+          _indent(oi, indent);
+        }
       }
       *oi++ = '}';
       break;
@@ -379,11 +634,14 @@ void value::serialize(Iter oi) const {
       copy(to_str(), oi);
       break;
   }
+  if (indent == 0) {
+    *oi++ = '\n';
+  }
 }
 
-inline std::string value::serialize() const {
+inline std::string value::_serialize(int indent) const {
   std::string s;
-  serialize(std::back_inserter(s));
+  _serialize(std::back_inserter(s), indent);
   return s;
 }
 
@@ -391,36 +649,35 @@ template <typename Iter>
 class input {
  protected:
   Iter cur_, end_;
-  int last_ch_;
-  bool ungot_;
+  bool consumed_;
   int line_;
 
  public:
-  input(const Iter& first, const Iter& last)
-      : cur_(first), end_(last), last_ch_(-1), ungot_(false), line_(1) {
+  input(const Iter &first, const Iter &last) : cur_(first), end_(last), consumed_(false), line_(1) {
   }
   int getc() {
-    if (ungot_) {
-      ungot_ = false;
-      return last_ch_;
+    if (consumed_) {
+      if (*cur_ == '\n') {
+        ++line_;
+      }
+      ++cur_;
     }
     if (cur_ == end_) {
-      last_ch_ = -1;
+      consumed_ = false;
       return -1;
     }
-    if (last_ch_ == '\n') {
-      line_++;
-    }
-    last_ch_ = *cur_++ & 0xff;
-    return last_ch_;
+    consumed_ = true;
+    return *cur_ & 0xff;
   }
   void ungetc() {
-    if (last_ch_ != -1) {
-      Assert(!ungot_);
-      ungot_ = true;
-    }
+    consumed_ = false;
   }
   Iter cur() const {
+    if (consumed_) {
+      input<Iter> *self = const_cast<input<Iter> *>(this);
+      self->consumed_ = false;
+      ++self->cur_;
+    }
     return cur_;
   }
   int line() const {
@@ -435,15 +692,15 @@ class input {
       }
     }
   }
-  bool expect(int expect) {
+  bool expect(const int expected) {
     skip_ws();
-    if (getc() != expect) {
+    if (getc() != expected) {
       ungetc();
       return false;
     }
     return true;
   }
-  bool match(const std::stringpattern) {
+  bool match(const std::string &pattern) {
     for (std::string::const_iterator pi(pattern.begin()); pi != pattern.end(); ++pi) {
       if (getc() != *pi) {
         ungetc();
@@ -455,7 +712,7 @@ class input {
 };
 
 template <typename Iter>
-inline int _parse_quadhex(input<Iter>in) {
+inline int _parse_quadhex(input<Iter> &in) {
   int uni_ch = 0, hex;
   for (int i = 0; i < 4; i++) {
     if ((hex = in.getc()) == -1) {
@@ -477,7 +734,7 @@ inline int _parse_quadhex(input<Iter>& in) {
 }
 
 template <typename String, typename Iter>
-inline bool _parse_codepoint(String& out, input<Iter>& in) {
+inline bool _parse_codepoint(String &out, input<Iter> &in) {
   int uni_ch;
   if ((uni_ch = _parse_quadhex(in)) == -1) {
     return false;
@@ -500,26 +757,26 @@ inline bool _parse_codepoint(String& out, input<Iter>& in) {
     uni_ch += 0x10000;
   }
   if (uni_ch < 0x80) {
-    out.push_back(uni_ch);
+    out.push_back(static_cast<char>(uni_ch));
   } else {
     if (uni_ch < 0x800) {
-      out.push_back(0xc0 | (uni_ch >> 6));
+      out.push_back(static_cast<char>(0xc0 | (uni_ch >> 6)));
     } else {
       if (uni_ch < 0x10000) {
-        out.push_back(0xe0 | (uni_ch >> 12));
+        out.push_back(static_cast<char>(0xe0 | (uni_ch >> 12)));
       } else {
-        out.push_back(0xf0 | (uni_ch >> 18));
-        out.push_back(0x80 | ((uni_ch >> 12) & 0x3f));
+        out.push_back(static_cast<char>(0xf0 | (uni_ch >> 18)));
+        out.push_back(static_cast<char>(0x80 | ((uni_ch >> 12) & 0x3f)));
       }
-      out.push_back(0x80 | ((uni_ch >> 6) & 0x3f));
+      out.push_back(static_cast<char>(0x80 | ((uni_ch >> 6) & 0x3f)));
     }
-    out.push_back(0x80 | (uni_ch & 0x3f));
+    out.push_back(static_cast<char>(0x80 | (uni_ch & 0x3f)));
   }
   return true;
 }
 
 template <typename String, typename Iter>
-inline bool _parse_string(String& out, input<Iter>& in) {
+inline bool _parse_string(String &out, input<Iter> &in) {
   while (1) {
     int ch = in.getc();
     if (ch < ' ') {
@@ -554,32 +811,32 @@ inline bool _parse_string(String& out, input<Iter>& in) {
           return false;
       }
     } else {
-      out.push_back(ch);
+      out.push_back(static_cast<char>(ch));
     }
   }
   return false;
 }
 
 template <typename Context, typename Iter>
-inline bool _parse_array(Context& ctx, input<Iter>& in) {
+inline bool _parse_array(Context &ctx, input<Iter> &in) {
   if (!ctx.parse_array_start()) {
     return false;
   }
+  size_t idx = 0;
   if (in.expect(']')) {
-    return true;
+    return ctx.parse_array_stop(idx);
   }
-  size_t idx = 0;
   do {
     if (!ctx.parse_array_item(in, idx)) {
       return false;
     }
     idx++;
   } while (in.expect(','));
-  return in.expect(']');
+  return in.expect(']') && ctx.parse_array_stop(idx);
 }
 
 template <typename Context, typename Iter>
-inline bool _parse_object(Context& ctx, input<Iter>& in) {
+inline bool _parse_object(Context &ctx, input<Iter> &in) {
   if (!ctx.parse_object_start()) {
     return false;
   }
@@ -599,13 +856,13 @@ inline bool _parse_object(Context& ctx, input<Iter>& in) {
 }
 
 template <typename Iter>
-inline bool _parse_number(double& out, input<Iter>& in) {
+inline std::string _parse_number(input<Iter> &in) {
   std::stringstream num_str;
   num_str.imbue(std::locale::classic());
 
   while (true) {
     int ch = in.getc();
-    if (('0' <= ch && ch <= '9') || ch == '+' || ch == '-' || ch == '.' || ch == 'e' || ch == 'E') {
+    if (('0' <= ch && ch <= '9') || ch == '+' || ch == '-' || ch == 'e' || ch == 'E' || ch == '.') {
       num_str.put(ch);
     } else {
       in.ungetc();
@@ -613,13 +870,11 @@ inline bool _parse_number(double& out, input<Iter>& in) {
     }
   }
 
-  num_str >> out;
-
-  return num_str && num_str.eof();
+  return num_str.str();
 }
 
 template <typename Context, typename Iter>
-inline bool _parse(Context& ctx, input<Iter>& in) {
+inline bool _parse(Context &ctx, input<Iter> &in) {
   in.skip_ws();
   int ch = in.getc();
   switch (ch) {
@@ -642,14 +897,31 @@ inline bool _parse(Context& ctx, input<Iter>& in) {
       return _parse_object(ctx, in);
     default:
       if (('0' <= ch && ch <= '9') || ch == '-') {
-        in.ungetc();
         double f;
-        if (_parse_number(f, in)) {
+        char *endp;
+        in.ungetc();
+        std::string num_str(_parse_number(in));
+        if (num_str.empty()) {
+          return false;
+        }
+#ifdef PICOJSON_USE_INT64
+        {
+          errno = 0;
+          intmax_t ival = strtoimax(num_str.c_str(), &endp, 10);
+          if (errno == 0 && std::numeric_limits<int64_t>::min() <= ival &&
+              ival <= std::numeric_limits<int64_t>::max() &&
+              endp == num_str.c_str() + num_str.size()) {
+            ctx.set_int64(ival);
+            return true;
+          }
+        }
+#endif
+        f = strtod(num_str.c_str(), &endp);
+        if (endp == num_str.c_str() + num_str.size()) {
           ctx.set_number(f);
           return true;
-        } else {
-          return false;
         }
+        return false;
       }
       break;
   }
@@ -665,35 +937,43 @@ class deny_parse_context {
   bool set_bool(bool) {
     return false;
   }
+#ifdef PICOJSON_USE_INT64
+  bool set_int64(int64_t) {
+    return false;
+  }
+#endif
   bool set_number(double) {
     return false;
   }
   template <typename Iter>
-  bool parse_string(input<Iter>&) {
+  bool parse_string(input<Iter> &) {
     return false;
   }
   bool parse_array_start() {
     return false;
   }
   template <typename Iter>
-  bool parse_array_item(input<Iter>&, size_t) {
+  bool parse_array_item(input<Iter> &, size_t) {
+    return false;
+  }
+  bool parse_array_stop(size_t) {
     return false;
   }
   bool parse_object_start() {
     return false;
   }
   template <typename Iter>
-  bool parse_object_item(input<Iter>&, const std::string&) {
+  bool parse_object_item(input<Iter> &, const std::string &) {
     return false;
   }
 };
 
 class default_parse_context {
  protected:
-  valueout_;
+  value *out_;
 
  public:
-  default_parse_context(valueout) : out_(out) {
+  default_parse_context(value *out) : out_(out) {
   }
   bool set_null() {
     *out_ = value();
@@ -703,12 +983,18 @@ class default_parse_context {
     *out_ = value(b);
     return true;
   }
+#ifdef PICOJSON_USE_INT64
+  bool set_int64(int64_t i) {
+    *out_ = value(i);
+    return true;
+  }
+#endif
   bool set_number(double f) {
     *out_ = value(f);
     return true;
   }
   template <typename Iter>
-  bool parse_string(input<Iter>in) {
+  bool parse_string(input<Iter> &in) {
     *out_ = value(string_type, false);
     return _parse_string(out_->get<std::string>(), in);
   }
@@ -717,26 +1003,29 @@ class default_parse_context {
     return true;
   }
   template <typename Iter>
-  bool parse_array_item(input<Iter>in, size_t) {
-    arraya = out_->get<array>();
+  bool parse_array_item(input<Iter> &in, size_t) {
+    array &a = out_->get<array>();
     a.push_back(value());
     default_parse_context ctx(&a.back());
     return _parse(ctx, in);
   }
+  bool parse_array_stop(size_t) {
+    return true;
+  }
   bool parse_object_start() {
     *out_ = value(object_type, false);
     return true;
   }
   template <typename Iter>
-  bool parse_object_item(input<Iter>& in, const std::string& key) {
-    objecto = out_->get<object>();
+  bool parse_object_item(input<Iter> &in, const std::string &key) {
+    object &o = out_->get<object>();
     default_parse_context ctx(&o[key]);
     return _parse(ctx, in);
   }
 
  private:
-  default_parse_context(const default_parse_context&);
-  default_parse_context& operator=(const default_parse_context&);
+  default_parse_context(const default_parse_context &);
+  default_parse_context &operator=(const default_parse_context &);
 };
 
 class null_parse_context {
@@ -755,11 +1044,16 @@ class null_parse_context {
   bool set_bool(bool) {
     return true;
   }
+#ifdef PICOJSON_USE_INT64
+  bool set_int64(int64_t) {
+    return true;
+  }
+#endif
   bool set_number(double) {
     return true;
   }
   template <typename Iter>
-  bool parse_string(input<Iter>in) {
+  bool parse_string(input<Iter> &in) {
     dummy_str s;
     return _parse_string(s, in);
   }
@@ -767,32 +1061,35 @@ class null_parse_context {
     return true;
   }
   template <typename Iter>
-  bool parse_array_item(input<Iter>in, size_t) {
+  bool parse_array_item(input<Iter> &in, size_t) {
     return _parse(*this, in);
   }
+  bool parse_array_stop(size_t) {
+    return true;
+  }
   bool parse_object_start() {
     return true;
   }
   template <typename Iter>
-  bool parse_object_item(input<Iter>& in, const std::string&) {
+  bool parse_object_item(input<Iter> &in, const std::string &) {
     return _parse(*this, in);
   }
 
  private:
-  null_parse_context(const null_parse_context&);
-  null_parse_context& operator=(const null_parse_context&);
+  null_parse_context(const null_parse_context &);
+  null_parse_context &operator=(const null_parse_context &);
 };
 
 // obsolete, use the version below
 template <typename Iter>
-inline std::string parse(value& out, Iter& pos, const Iter& last) {
+inline std::string parse(value &out, Iter &pos, const Iter &last) {
   std::string err;
   pos = parse(out, pos, last, &err);
   return err;
 }
 
 template <typename Context, typename Iter>
-inline Iter _parse(Context& ctx, const Iter& first, const Iter& last, std::string* err) {
+inline Iter _parse(Context &ctx, const Iter &first, const Iter &last, std::string *err) {
   input<Iter> in(first, last);
   if (!_parse(ctx, in) && err != NULL) {
     char buf[64];
@@ -803,7 +1100,7 @@ inline Iter _parse(Context& ctx, const Iter& first, const Iter& last, std::strin
       if (ch == -1 || ch == '\n') {
         break;
       } else if (ch >= ' ') {
-        err->push_back(ch);
+        err->push_back(static_cast<char>(ch));
       }
     }
   }
@@ -811,12 +1108,18 @@ inline Iter _parse(Context& ctx, const Iter& first, const Iter& last, std::strin
 }
 
 template <typename Iter>
-inline Iter parse(value& out, const Iter& first, const Iter& last, std::string* err) {
+inline Iter parse(value &out, const Iter &first, const Iter &last, std::string *err) {
   default_parse_context ctx(&out);
   return _parse(ctx, first, last, err);
 }
 
-inline std::string parse(value& out, std::istream& is) {
+inline std::string parse(value &out, const std::string &s) {
+  std::string err;
+  parse(out, s.begin(), s.end(), &err);
+  return err;
+}
+
+inline std::string parse(value &out, std::istream &is) {
   std::string err;
   parse(out, std::istreambuf_iterator<char>(is.rdbuf()), std::istreambuf_iterator<char>(), &err);
   return err;
@@ -829,15 +1132,15 @@ struct last_error_t {
 template <typename T>
 std::string last_error_t<T>::s;
 
-inline void set_last_error(const std::strings) {
+inline void set_last_error(const std::string &s) {
   last_error_t<bool>::s = s;
 }
 
-inline const std::stringget_last_error() {
+inline const std::string &get_last_error() {
   return last_error_t<bool>::s;
 }
 
-inline bool operator==(const value& x, const value& y) {
+inline bool operator==(const value &x, const value &y) {
   if (x.is<null>()) return y.is<null>();
 #define PICOJSON_CMP(type) \
   if (x.is<type>()) return y.is<type>() && x.get<type>() == y.get<type>()
@@ -854,21 +1157,23 @@ inline bool operator==(const value& x, const value& y) {
   return false;
 }
 
-inline bool operator!=(const value& x, const value& y) {
+inline bool operator!=(const value &x, const value &y) {
   return !(x == y);
 }
 }
 
+#if !PICOJSON_USE_RVALUE_REFERENCE
 namespace std {
 template <>
-inline void swap(picojson::value& x, picojson::value& y) {
+inline void swap(picojson::value &x, picojson::value &y) {
   x.swap(y);
 }
 }
+#endif
 
-inline std::istream& operator>>(std::istream& is, picojson::value& x) {
+inline std::istream &operator>>(std::istream &is, picojson::value &x) {
   picojson::set_last_error(std::string());
-  std::string err = picojson::parse(x, is);
+  const std::string err(picojson::parse(x, is));
   if (!err.empty()) {
     picojson::set_last_error(err);
     is.setstate(std::ios::failbit);
@@ -876,7 +1181,7 @@ inline std::istream& operator>>(std::istream& is, picojson::value& x) {
   return is;
 }
 
-inline std::ostream& operator<<(std::ostream& os, const picojson::value& x) {
+inline std::ostream &operator<<(std::ostream &os, const picojson::value &x) {
   x.serialize(std::ostream_iterator<char>(os));
   return os;
 }
@@ -885,235 +1190,3 @@ inline std::ostream& operator<<(std::ostream& os, const picojson::value& x) {
 #endif
 
 #endif
-#ifdef TEST_PICOJSON
-#ifdef _MSC_VER
-#pragma warning(disable : 4127)  // conditional expression is constant
-#endif
-
-using namespace std;
-
-static void plan(int num) {
-  printf("1..%d\n", num);
-}
-
-static bool success = true;
-
-static void ok(bool b, const char* name = "") {
-  static int n = 1;
-  if (!b) success = false;
-  printf("%s %d - %s\n", b ? "ok" : "ng", n++, name);
-}
-
-template <typename T>
-void is(const T& x, const T& y, const char* name = "") {
-  if (x == y) {
-    ok(true, name);
-  } else {
-    ok(false, name);
-  }
-}
-
-#include <float.h>
-#include <limits.h>
-#include <algorithm>
-#include <sstream>
-
-int main(void) {
-  plan(85);
-
-// constructors
-#define TEST(expr, expected) \
-  is(picojson::value expr.serialize(), string(expected), "picojson::value" #expr)
-
-  TEST((true), "true");
-  TEST((false), "false");
-  TEST((42.0), "42");
-  TEST((string("hello")), "\"hello\"");
-  TEST(("hello"), "\"hello\"");
-  TEST(("hello", 4), "\"hell\"");
-
-  {
-    double a = 1;
-    for (int i = 0; i < 1024; i++) {
-      picojson::value vi(a);
-      std::stringstream ss;
-      ss << vi;
-      picojson::value vo;
-      ss >> vo;
-      double b = vo.get<double>();
-      if ((i < 53 && a != b) || fabs(a - b) / b > 1e-8) {
-        printf("ng i=%d a=%.18e b=%.18e\n", i, a, b);
-      }
-      a *= 2;
-    }
-  }
-
-#undef TEST
-
-#define TEST(in, type, cmp, serialize_test)             \
-  {                                                     \
-    picojson::value v;                                  \
-    const char* s = in;                                 \
-    string err = picojson::parse(v, s, s + strlen(s));  \
-    ok(err.empty(), in " no error");                    \
-    ok(v.is<type>(), in " check type");                 \
-    is<type>(v.get<type>(), cmp, in " correct output"); \
-    is(*s, '\0', in " read to eof");                    \
-    if (serialize_test) {                               \
-      is(v.serialize(), string(in), in " serialize");   \
-    }                                                   \
-  }
-  TEST("false", bool, false, true);
-  TEST("true", bool, true, true);
-  TEST("90.5", double, 90.5, false);
-  TEST("1.7976931348623157e+308", double, DBL_MAX, false);
-  TEST("\"hello\"", string, string("hello"), true);
-  TEST("\"\\\"\\\\\\/\\b\\f\\n\\r\\t\"", string, string("\"\\/\b\f\n\r\t"), true);
-  TEST("\"\\u0061\\u30af\\u30ea\\u30b9\"", string, string("a\xe3\x82\xaf\xe3\x83\xaa\xe3\x82\xb9"),
-       false);
-  TEST("\"\\ud840\\udc0b\"", string, string("\xf0\xa0\x80\x8b"), false);
-#undef TEST
-
-#define TEST(type, expr)                                               \
-  {                                                                    \
-    picojson::value v;                                                 \
-    const char* s = expr;                                              \
-    string err = picojson::parse(v, s, s + strlen(s));                 \
-    ok(err.empty(), "empty " #type " no error");                       \
-    ok(v.is<picojson::type>(), "empty " #type " check type");          \
-    ok(v.get<picojson::type>().empty(), "check " #type " array size"); \
-  }
-  TEST(array, "[]");
-  TEST(object, "{}");
-#undef TEST
-
-  {
-    picojson::value v;
-    const char* s = "[1,true,\"hello\"]";
-    string err = picojson::parse(v, s, s + strlen(s));
-    ok(err.empty(), "array no error");
-    ok(v.is<picojson::array>(), "array check type");
-    is(v.get<picojson::array>().size(), size_t(3), "check array size");
-    ok(v.contains(0), "check contains array[0]");
-    ok(v.get(0).is<double>(), "check array[0] type");
-    is(v.get(0).get<double>(), 1.0, "check array[0] value");
-    ok(v.contains(1), "check contains array[1]");
-    ok(v.get(1).is<bool>(), "check array[1] type");
-    ok(v.get(1).get<bool>(), "check array[1] value");
-    ok(v.contains(2), "check contains array[2]");
-    ok(v.get(2).is<string>(), "check array[2] type");
-    is(v.get(2).get<string>(), string("hello"), "check array[2] value");
-    ok(!v.contains(3), "check not contains array[3]");
-  }
-
-  {
-    picojson::value v;
-    const char* s = "{ \"a\": true }";
-    string err = picojson::parse(v, s, s + strlen(s));
-    ok(err.empty(), "object no error");
-    ok(v.is<picojson::object>(), "object check type");
-    is(v.get<picojson::object>().size(), size_t(1), "check object size");
-    ok(v.contains("a"), "check contains property");
-    ok(v.get("a").is<bool>(), "check bool property exists");
-    is(v.get("a").get<bool>(), true, "check bool property value");
-    is(v.serialize(), string("{\"a\":true}"), "serialize object");
-    ok(!v.contains("z"), "check not contains property");
-  }
-
-#define TEST(json, msg)                                \
-  do {                                                 \
-    picojson::value v;                                 \
-    const char* s = json;                              \
-    string err = picojson::parse(v, s, s + strlen(s)); \
-    is(err, string("syntax error at line " msg), msg); \
-  } while (0)
-  TEST("falsoa", "1 near: oa");
-  TEST("{]", "1 near: ]");
-  TEST("\n\bbell", "2 near: bell");
-  TEST("\"abc\nd\"", "1 near: ");
-#undef TEST
-
-  {
-    picojson::value v1, v2;
-    const char* s;
-    string err;
-    s = "{ \"b\": true, \"a\": [1,2,\"three\"], \"d\": 2 }";
-    err = picojson::parse(v1, s, s + strlen(s));
-    s = "{ \"d\": 2.0, \"b\": true, \"a\": [1,2,\"three\"] }";
-    err = picojson::parse(v2, s, s + strlen(s));
-    ok((v1 == v2), "check == operator in deep comparison");
-  }
-
-  {
-    picojson::value v1, v2;
-    const char* s;
-    string err;
-    s = "{ \"b\": true, \"a\": [1,2,\"three\"], \"d\": 2 }";
-    err = picojson::parse(v1, s, s + strlen(s));
-    s = "{ \"d\": 2.0, \"a\": [1,\"three\"], \"b\": true }";
-    err = picojson::parse(v2, s, s + strlen(s));
-    ok((v1 != v2), "check != operator for array in deep comparison");
-  }
-
-  {
-    picojson::value v1, v2;
-    const char* s;
-    string err;
-    s = "{ \"b\": true, \"a\": [1,2,\"three\"], \"d\": 2 }";
-    err = picojson::parse(v1, s, s + strlen(s));
-    s = "{ \"d\": 2.0, \"a\": [1,2,\"three\"], \"b\": false }";
-    err = picojson::parse(v2, s, s + strlen(s));
-    ok((v1 != v2), "check != operator for object in deep comparison");
-  }
-
-  {
-    picojson::value v1, v2;
-    const char* s;
-    string err;
-    s = "{ \"b\": true, \"a\": [1,2,\"three\"], \"d\": 2 }";
-    err = picojson::parse(v1, s, s + strlen(s));
-    picojson::object& o = v1.get<picojson::object>();
-    o.erase("b");
-    picojson::array& a = o["a"].get<picojson::array>();
-    picojson::array::iterator i;
-    i = std::remove(a.begin(), a.end(), picojson::value(std::string("three")));
-    a.erase(i, a.end());
-    s = "{ \"a\": [1,2], \"d\": 2 }";
-    err = picojson::parse(v2, s, s + strlen(s));
-    ok((v1 == v2), "check erase()");
-  }
-
-  ok(picojson::value(3.0).serialize() == "3", "integral number should be serialized as a integer");
-
-  {
-    const char* s = "{ \"a\": [1,2], \"d\": 2 }";
-    picojson::null_parse_context ctx;
-    string err;
-    picojson::_parse(ctx, s, s + strlen(s), &err);
-    ok(err.empty(), "null_parse_context");
-  }
-
-  {
-    picojson::value v1, v2;
-    v1 = picojson::value(true);
-    swap(v1, v2);
-    ok(v1.is<picojson::null>(), "swap (null)");
-    ok(v2.get<bool>() == true, "swap (bool)");
-
-    v1 = picojson::value("a");
-    v2 = picojson::value(1.0);
-    swap(v1, v2);
-    ok(v1.get<double>() == 1.0, "swap (dobule)");
-    ok(v2.get<string>() == "a", "swap (string)");
-
-    v1 = picojson::value(picojson::object());
-    v2 = picojson::value(picojson::array());
-    swap(v1, v2);
-    ok(v1.is<picojson::array>(), "swap (array)");
-    ok(v2.is<picojson::object>(), "swap (object)");
-  }
-
-  return success ? 0 : 1;
-}
-
-#endif