From eb4d67a68ee4d4f1ca3fe874602cb4aaa2724d5e Mon Sep 17 00:00:00 2001 From: Zhijiang TAO Date: Tue, 16 Aug 2016 11:00:25 +0800 Subject: [PATCH] using longlong for internel storage --- json11.cpp | 75 +++++++++++++++++++++++++++++++++--------------------- json11.hpp | 14 +++++++--- 2 files changed, 56 insertions(+), 33 deletions(-) diff --git a/json11.cpp b/json11.cpp index ac9d727..9f593a0 100644 --- a/json11.cpp +++ b/json11.cpp @@ -56,17 +56,18 @@ static void dump(double value, string &out) { } static void dump(int value, string &out) { - char buf[32]; - snprintf(buf, sizeof buf, "%d", value); - out += buf; + out += std::to_string(value); } static void dump(int64_ value, string &out) { - char buf[64]; - snprintf(buf, sizeof buf, "%ld", value); - out += buf; + out += std::to_string(value); } +static void dump(uint64_ value, string &out) { + out += std::to_string(value); +} + + static void dump(bool value, string &out) { out += value ? "true" : "false"; } @@ -168,35 +169,35 @@ protected: }; class JsonDouble final : public Value { - double number_value() const override { return m_value; } - int int_value() const override { return static_cast(m_value); } + double number_value() const override { return static_cast(m_value); } int64_ int64_value() const override { return static_cast(m_value); } + uint64_ uint64_value() const override { return static_cast(m_value); } bool equals(const JsonValue * other) const override { return m_value == other->number_value(); } bool less(const JsonValue * other) const override { return m_value < other->number_value(); } public: explicit JsonDouble(double value) : Value(value) {} }; -class JsonInt final : public Value { - double number_value() const override { return m_value; } - int int_value() const override { return m_value; } - int64_ int64_value() const override { return m_value; } - bool equals(const JsonValue * other) const override { return m_value == other->number_value(); } - bool less(const JsonValue * other) const override { return m_value < other->number_value(); } -public: - explicit JsonInt(int value) : Value(value) {} -}; - class JsonInt64 final : public Value { - double number_value() const override { return m_value; } - int int_value() const override { return m_value; } - int64_ int64_value() const override { return m_value; } + double number_value() const override { return static_cast(m_value); } + int64_ int64_value() const override { return static_cast(m_value); } + uint64_ uint64_value() const override { return static_cast(m_value); } bool equals(const JsonValue * other) const override { return m_value == other->number_value(); } bool less(const JsonValue * other) const override { return m_value < other->number_value(); } public: explicit JsonInt64(int64_ value) : Value(value) {} }; +class JsonUInt64 final : public Value { + double number_value() const override { return static_cast(m_value); } + int64_ int64_value() const override { return static_cast(m_value); } + uint64_ uint64_value() const override { return static_cast(m_value); } + bool equals(const JsonValue * other) const override { return m_value == other->number_value(); } + bool less(const JsonValue * other) const override { return m_value < other->number_value(); } +public: + explicit JsonUInt64(uint64_ value) : Value(value) {} +}; + class JsonBoolean final : public Value { bool bool_value() const override { return m_value; } public: @@ -262,8 +263,9 @@ static const Json & static_null() { Json::Json() noexcept : m_ptr(statics().null) {} Json::Json(std::nullptr_t) noexcept : m_ptr(statics().null) {} Json::Json(double value) : m_ptr(make_shared(value)) {} -Json::Json(int value) : m_ptr(make_shared(value)) {} +Json::Json(int value) : m_ptr(make_shared(value)) {} Json::Json(int64_ value) : m_ptr(make_shared(value)) {} +Json::Json(uint64_ value) : m_ptr(make_shared(value)) {} Json::Json(bool value) : m_ptr(value ? statics().t : statics().f) {} Json::Json(const string &value) : m_ptr(make_shared(value)) {} Json::Json(string &&value) : m_ptr(make_shared(move(value))) {} @@ -279,8 +281,8 @@ Json::Json(Json::object &&values) : m_ptr(make_shared(move(valu Json::Type Json::type() const { return m_ptr->type(); } double Json::number_value() const { return m_ptr->number_value(); } -int Json::int_value() const { return m_ptr->int_value(); } -int64_ Json::int64_value() const { return m_ptr->int64_value(); } +int64_ Json::int64_value() const { return m_ptr->int64_value(); } +uint64_ Json::uint64_value() const { return m_ptr->uint64_value(); } bool Json::bool_value() const { return m_ptr->bool_value(); } const string & Json::string_value() const { return m_ptr->string_value(); } const vector & Json::array_items() const { return m_ptr->array_items(); } @@ -289,8 +291,8 @@ const Json & Json::operator[] (size_t i) const { return (*m_ptr)[i]; const Json & Json::operator[] (const string &key) const { return (*m_ptr)[key]; } double JsonValue::number_value() const { return 0; } -int JsonValue::int_value() const { return 0; } int64_ JsonValue::int64_value() const { return 0; } +uint64_ JsonValue::uint64_value() const { return 0; } bool JsonValue::bool_value() const { return false; } const string & JsonValue::string_value() const { return statics().empty_string; } const vector & JsonValue::array_items() const { return statics().empty_vector; } @@ -604,10 +606,25 @@ struct JsonParser final { if (str[i] != '.' && str[i] != 'e' && str[i] != 'E') { - if ((i - start_pos) <= static_cast(std::numeric_limits::digits10)) - return (int)(std::atoll(str.c_str() + start_pos)); - if ((i - start_pos) <= static_cast(std::numeric_limits::digits10)) - return (int64_)(std::atoll(str.c_str() + start_pos)); + if (*(str.c_str() + start_pos) == '-') // signed value + { + if ((i - start_pos) <= (ceil(std::numeric_limits::digits * std::log10(2) + 1/*sign*/) )) + { + // On Linux, the global errno variable is thread-specific + int64_t conv_val = std::atoll(str.c_str() + start_pos); + if (errno != ERANGE) + return conv_val; + } + } + else + { + if ((i - start_pos) <= ceil(std::numeric_limits::digits * std::log10(2) )) + { + uint64_ conv_val = std::strtoull(str.c_str() + start_pos, 0, 10); + if (errno != ERANGE) + return conv_val; + } + } } // Decimal part diff --git a/json11.hpp b/json11.hpp index f26d4f2..37d75e4 100644 --- a/json11.hpp +++ b/json11.hpp @@ -77,7 +77,12 @@ enum JsonParse { class JsonValue; +#if __cplusplus < 201103L + #error This project can only be compiled with a compiler that supports C++11 +#else using int64_ = int64_t; +using uint64_ = uint64_t; +#endif class Json final { public: @@ -94,8 +99,9 @@ public: Json() noexcept; // NUL Json(std::nullptr_t) noexcept; // NUL Json(double value); // NUMBER - Json(int value); // NUMBER + Json(int value); // NUMBER Json(int64_ value); // NUMBER + Json(uint64_ value); // NUMBER Json(bool value); // BOOL Json(const std::string &value); // STRING Json(std::string &&value); // STRING @@ -140,8 +146,8 @@ public: // distinguish between integer and non-integer numbers - number_value() and int64_value() // can both be applied to a NUMBER-typed object. double number_value() const; - int int_value() const; int64_ int64_value() const; + uint64_ uint64_value() const; // Return the enclosed value if this is a boolean, false otherwise. bool bool_value() const; @@ -217,16 +223,16 @@ private: class JsonValue { protected: friend class Json; - friend class JsonInt; friend class JsonInt64; + friend class JsonUInt64; friend class JsonDouble; virtual Json::Type type() const = 0; virtual bool equals(const JsonValue * other) const = 0; virtual bool less(const JsonValue * other) const = 0; virtual void dump(std::string &out) const = 0; virtual double number_value() const; - virtual int int_value() const; virtual int64_ int64_value() const; + virtual uint64_ uint64_value() const; virtual bool bool_value() const; virtual const std::string &string_value() const; virtual const Json::array &array_items() const;