添加int64类型,但是还是会溢出

pull/5/head
Zhijiang TAO 2016-08-16 00:14:02 +08:00
parent 787809178d
commit f6b4188933
3 changed files with 61 additions and 8 deletions

View File

@ -61,6 +61,12 @@ static void dump(int value, string &out) {
out += buf;
}
static void dump(int64_ value, string &out) {
char buf[64];
snprintf(buf, sizeof buf, "%ld", value);
out += buf;
}
static void dump(bool value, string &out) {
out += value ? "true" : "false";
}
@ -164,6 +170,7 @@ 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); }
int64_ int64_value() const override { return static_cast<int64_>(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:
@ -173,12 +180,23 @@ public:
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; }
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 JsonBoolean final : public Value<Json::BOOL, bool> {
bool bool_value() const override { return m_value; }
public:
@ -244,7 +262,8 @@ 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<JsonInt>(value)) {}
Json::Json(int64_ value) : m_ptr(make_shared<JsonInt64>(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))) {}
@ -260,7 +279,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(); }
int Json::int_value() const { return m_ptr->int_value(); }
int64_ Json::int64_value() const { return m_ptr->int64_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(); }
@ -269,7 +289,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; }
int JsonValue::int_value() const { return 0; }
int64_ JsonValue::int64_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; }
@ -581,9 +602,12 @@ struct JsonParser final {
return fail("invalid " + esc(str[i]) + " in number");
}
if (str[i] != '.' && str[i] != 'e' && str[i] != 'E'
&& (i - start_pos) <= static_cast<size_t>(std::numeric_limits<int>::digits10)) {
return std::atoi(str.c_str() + start_pos);
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));
}
// Decimal part

View File

@ -55,6 +55,7 @@
#include <map>
#include <memory>
#include <initializer_list>
#include <cstdint>
#ifdef _MSC_VER
#if _MSC_VER <= 1800 // VS 2013
@ -76,6 +77,8 @@ enum JsonParse {
class JsonValue;
using int64_ = int64_t;
class Json final {
public:
// Types
@ -91,7 +94,8 @@ 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(bool value); // BOOL
Json(const std::string &value); // STRING
Json(std::string &&value); // STRING
@ -133,10 +137,11 @@ public:
bool is_object() const { return type() == OBJECT; }
// Return the enclosed value if this is a number, 0 otherwise. Note that json11 does not
// distinguish between integer and non-integer numbers - number_value() and int_value()
// 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;
// Return the enclosed value if this is a boolean, false otherwise.
bool bool_value() const;
@ -213,6 +218,7 @@ class JsonValue {
protected:
friend class Json;
friend class JsonInt;
friend class JsonInt64;
friend class JsonDouble;
virtual Json::Type type() const = 0;
virtual bool equals(const JsonValue * other) const = 0;
@ -220,6 +226,7 @@ protected:
virtual void dump(std::string &out) const = 0;
virtual double number_value() const;
virtual int int_value() const;
virtual int64_ int64_value() const;
virtual bool bool_value() const;
virtual const std::string &string_value() const;
virtual const Json::array &array_items() const;

View File

@ -59,6 +59,28 @@ CHECK_TRAIT(is_nothrow_move_assignable<Json>);
CHECK_TRAIT(is_nothrow_destructible<Json>);
JSON11_TEST_CASE(json11_test) {
std::cout << "int int64 test" << std::endl;
const string str_it = R"({"message_id":105308320612483198,"msg_type":3,"order":0,
"ques_id":0,"session_id":105308187502051928,"site_id":122062,
"timestamp":1471140271,
"visitor_id":9941658010949867158,"worker_id":133746})";
string err_it;
auto json_it = Json::parse(str_it, err_it);
assert(json_it["message_id"].int64_value() == 105308320612483198);
assert(json_it["message_id"].int_value() != 105308320612483198);
assert(json_it["msg_type"].int64_value() == 3);
assert(json_it["msg_type"].int_value() == 3);
assert(json_it["order"].int64_value() == 0);
assert(json_it["session_id"].int64_value() == 105308187502051928);
assert(json_it["site_id"].int_value() == 122062);
assert(json_it["site_id"].int64_value() == 122062);
std::cout << (unsigned long long)json_it["visitor_id"].int64_value() << std::endl;
assert((unsigned long long)(json_it["visitor_id"].int64_value()) == 9941658010949867158);
std::cout << "int int64 test passed!" << std::endl;
const string simple_test =
R"({"k1":"v1", "k2":42, "k3":["a",123,true,false,null]})";