using longlong for internel storage

mutable-v2
Zhijiang TAO 2016-08-16 11:00:25 +08:00
parent f6b4188933
commit eb4d67a68e
2 changed files with 56 additions and 33 deletions

View File

@ -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<Json::NUMBER, double> {
double number_value() const override { return m_value; }
int int_value() const override { return static_cast<int>(m_value); }
double number_value() const override { return static_cast<double>(m_value); }
int64_ int64_value() const override { return static_cast<int64_>(m_value); }
uint64_ uint64_value() const override { return static_cast<uint64_>(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<Json::NUMBER, int> {
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<Json::NUMBER, int64_> {
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<double>(m_value); }
int64_ int64_value() const override { return static_cast<int64_>(m_value); }
uint64_ uint64_value() const override { return static_cast<uint64_>(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<Json::NUMBER, uint64_> {
double number_value() const override { return static_cast<double>(m_value); }
int64_ int64_value() const override { return static_cast<int64_>(m_value); }
uint64_ uint64_value() const override { return static_cast<uint64_>(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<Json::BOOL, bool> {
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<JsonDouble>(value)) {}
Json::Json(int value) : m_ptr(make_shared<JsonInt>(value)) {}
Json::Json(int value) : m_ptr(make_shared<JsonInt64>(value)) {}
Json::Json(int64_ value) : m_ptr(make_shared<JsonInt64>(value)) {}
Json::Json(uint64_ value) : m_ptr(make_shared<JsonUInt64>(value)) {}
Json::Json(bool value) : m_ptr(value ? statics().t : statics().f) {}
Json::Json(const string &value) : m_ptr(make_shared<JsonString>(value)) {}
Json::Json(string &&value) : m_ptr(make_shared<JsonString>(move(value))) {}
@ -279,8 +281,8 @@ Json::Json(Json::object &&values) : m_ptr(make_shared<JsonObject>(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> & 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<Json> & 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<size_t>(std::numeric_limits<int>::digits10))
return (int)(std::atoll(str.c_str() + start_pos));
if ((i - start_pos) <= static_cast<size_t>(std::numeric_limits<int64_>::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<int64_>::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<uint64_>::digits * std::log10(2) ))
{
uint64_ conv_val = std::strtoull(str.c_str() + start_pos, 0, 10);
if (errno != ERANGE)
return conv_val;
}
}
}
// Decimal part

View File

@ -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;