|
|
|
@ -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,33 +169,33 @@ 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; } |
|
|
|
|
class JsonInt64 final : public Value<Json::NUMBER, int64_> { |
|
|
|
|
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 JsonInt(int value) : Value(value) {} |
|
|
|
|
explicit JsonInt64(int64_ 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; } |
|
|
|
|
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 JsonInt64(int64_ value) : Value(value) {} |
|
|
|
|
explicit JsonUInt64(uint64_ value) : Value(value) {} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
class JsonBoolean final : public Value<Json::BOOL, bool> { |
|
|
|
@ -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
|
|
|
|
|