Compare commits
2 Commits
55363fc265
...
mutable-v4
Author | SHA1 | Date | |
---|---|---|---|
2273bdd966 | |||
52a3af664f |
64
json11.cpp
64
json11.cpp
@@ -41,10 +41,6 @@ using std::move;
|
|||||||
* Serialization
|
* Serialization
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void dump(std::nullptr_t, string &out) {
|
|
||||||
out += "null";
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dump(double value, string &out) {
|
static void dump(double value, string &out) {
|
||||||
if (std::isfinite(value)) {
|
if (std::isfinite(value)) {
|
||||||
char buf[32];
|
char buf[32];
|
||||||
@@ -55,10 +51,6 @@ static void dump(double value, string &out) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dump(int value, string &out) {
|
|
||||||
out += std::to_string(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dump(int64_ value, string &out) {
|
static void dump(int64_ value, string &out) {
|
||||||
out += std::to_string(value);
|
out += std::to_string(value);
|
||||||
}
|
}
|
||||||
@@ -146,6 +138,7 @@ void Json::dump(string &out) const {
|
|||||||
template <Json::Type tag, typename T>
|
template <Json::Type tag, typename T>
|
||||||
class Value : public JsonValue {
|
class Value : public JsonValue {
|
||||||
protected:
|
protected:
|
||||||
|
friend class JsonIndex;
|
||||||
|
|
||||||
// Constructors
|
// Constructors
|
||||||
explicit Value(const T &value) : m_value(value) {}
|
explicit Value(const T &value) : m_value(value) {}
|
||||||
@@ -164,12 +157,12 @@ protected:
|
|||||||
return m_value < static_cast<const Value<tag, T> *>(other)->m_value;
|
return m_value < static_cast<const Value<tag, T> *>(other)->m_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
const T m_value;
|
T m_value;
|
||||||
void dump(string &out) const override { json11::dump(m_value, out); }
|
void dump(string &out) const override { json11::dump(m_value, out); }
|
||||||
};
|
};
|
||||||
|
|
||||||
class JsonDouble final : public Value<Json::NUMBER, double> {
|
class JsonDouble final : public Value<Json::NUMBER, double> {
|
||||||
string as_string() const { return std::to_string(m_value); }
|
string as_string() const override { return std::to_string(m_value); }
|
||||||
bool bool_value() const override { return m_value != 0; }
|
bool bool_value() const override { return m_value != 0; }
|
||||||
double number_value() const override { return static_cast<double>(m_value); }
|
double number_value() const override { return static_cast<double>(m_value); }
|
||||||
int64_ int64_value() const override { return static_cast<int64_>(m_value); }
|
int64_ int64_value() const override { return static_cast<int64_>(m_value); }
|
||||||
@@ -181,7 +174,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
class JsonInt64 final : public Value<Json::NUMBER, int64_> {
|
class JsonInt64 final : public Value<Json::NUMBER, int64_> {
|
||||||
string as_string() const { return std::to_string(m_value); }
|
string as_string() const override { return std::to_string(m_value); }
|
||||||
bool bool_value() const override { return m_value != 0; }
|
bool bool_value() const override { return m_value != 0; }
|
||||||
double number_value() const override { return static_cast<double>(m_value); }
|
double number_value() const override { return static_cast<double>(m_value); }
|
||||||
int64_ int64_value() const override { return static_cast<int64_>(m_value); }
|
int64_ int64_value() const override { return static_cast<int64_>(m_value); }
|
||||||
@@ -193,7 +186,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
class JsonUInt64 final : public Value<Json::NUMBER, uint64_> {
|
class JsonUInt64 final : public Value<Json::NUMBER, uint64_> {
|
||||||
string as_string() const { return std::to_string(m_value); }
|
string as_string() const override { return std::to_string(m_value); }
|
||||||
bool bool_value() const override { return m_value != 0; }
|
bool bool_value() const override { return m_value != 0; }
|
||||||
double number_value() const override { return static_cast<double>(m_value); }
|
double number_value() const override { return static_cast<double>(m_value); }
|
||||||
int64_ int64_value() const override { return static_cast<int64_>(m_value); }
|
int64_ int64_value() const override { return static_cast<int64_>(m_value); }
|
||||||
@@ -211,7 +204,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
class JsonString final : public Value<Json::STRING, string> {
|
class JsonString final : public Value<Json::STRING, string> {
|
||||||
string as_string() const { return m_value; }
|
string as_string() const override { return m_value; }
|
||||||
const string &string_value() const override { return m_value; }
|
const string &string_value() const override { return m_value; }
|
||||||
bool bool_value() const override { return m_value != "" && m_value != "0"; }
|
bool bool_value() const override { return m_value != "" && m_value != "0"; }
|
||||||
double number_value() const override
|
double number_value() const override
|
||||||
@@ -259,9 +252,23 @@ public:
|
|||||||
explicit JsonObject(Json::object &&value) : Value(move(value)) {}
|
explicit JsonObject(Json::object &&value) : Value(move(value)) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class JsonNull final : public Value<Json::NUL, std::nullptr_t> {
|
class JsonNull final : public JsonValue {
|
||||||
public:
|
public:
|
||||||
JsonNull() : Value(nullptr) {}
|
JsonNull() {}
|
||||||
|
// Get type tag
|
||||||
|
Json::Type type() const override {
|
||||||
|
return Json::NUL;
|
||||||
|
}
|
||||||
|
// Comparisons - only within type
|
||||||
|
bool equals(const JsonValue * other) const override {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool less(const JsonValue * other) const override {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
void dump(string &out) const override {
|
||||||
|
out += "null";
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* * * * * * * * * * * * * * * * * * * *
|
/* * * * * * * * * * * * * * * * * * * *
|
||||||
@@ -321,7 +328,7 @@ const string & Json::string_value() const { return m_ptr->string_v
|
|||||||
const vector<Json> & Json::array_items() const { return m_ptr->array_items(); }
|
const vector<Json> & Json::array_items() const { return m_ptr->array_items(); }
|
||||||
const map<string, Json> & Json::object_items() const { return m_ptr->object_items(); }
|
const map<string, Json> & Json::object_items() const { return m_ptr->object_items(); }
|
||||||
const Json & Json::operator[] (size_t i) const { return (*m_ptr)[i]; }
|
const Json & Json::operator[] (size_t i) const { return (*m_ptr)[i]; }
|
||||||
const Json & Json::operator[] (const string &key) const { return (*m_ptr)[key]; }
|
JsonIndex Json::operator[] (const string &key) { return (JsonIndex){ .m_object = *this, .m_key = key }; }
|
||||||
|
|
||||||
double JsonValue::number_value() const { return 0; }
|
double JsonValue::number_value() const { return 0; }
|
||||||
int64_ JsonValue::int64_value() const { return 0; }
|
int64_ JsonValue::int64_value() const { return 0; }
|
||||||
@@ -836,8 +843,13 @@ bool Json::has_shape(const shape & types, string & err) const {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto & obj = object_items();
|
||||||
for (auto & item : types) {
|
for (auto & item : types) {
|
||||||
if ((*this)[item.first].type() != item.second) {
|
auto it = obj.find(item.first);
|
||||||
|
if (it == obj.end()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (it->second.type() != item.second) {
|
||||||
err = "bad type for " + item.first + " in " + dump();
|
err = "bad type for " + item.first + " in " + dump();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -846,4 +858,22 @@ bool Json::has_shape(const shape & types, string & err) const {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* * * * * * * * * * * * * * * * * * * *
|
||||||
|
* Indexed wrapper to prevent autovivification
|
||||||
|
*/
|
||||||
|
|
||||||
|
const Json & JsonIndex::self() const {
|
||||||
|
if (m_object.is_object()) {
|
||||||
|
return ((JsonObject*)m_object.m_ptr.get())->m_value[m_key];
|
||||||
|
}
|
||||||
|
return static_null();
|
||||||
|
}
|
||||||
|
|
||||||
|
Json JsonIndex::operator =(Json value) {
|
||||||
|
if (m_object.is_object()) {
|
||||||
|
return ((JsonObject*)m_object.m_ptr.get())->m_value[m_key] = value;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace json11
|
} // namespace json11
|
||||||
|
33
json11.hpp
33
json11.hpp
@@ -77,6 +77,8 @@ enum JsonParse {
|
|||||||
|
|
||||||
class JsonValue;
|
class JsonValue;
|
||||||
|
|
||||||
|
class JsonIndex;
|
||||||
|
|
||||||
#if __cplusplus < 201103L
|
#if __cplusplus < 201103L
|
||||||
#error This project can only be compiled with a compiler that supports C++11
|
#error This project can only be compiled with a compiler that supports C++11
|
||||||
#else
|
#else
|
||||||
@@ -165,7 +167,7 @@ public:
|
|||||||
// Return a reference to arr[i] if this is an array, Json() otherwise.
|
// Return a reference to arr[i] if this is an array, Json() otherwise.
|
||||||
const Json & operator[](size_t i) const;
|
const Json & operator[](size_t i) const;
|
||||||
// Return a reference to obj[key] if this is an object, Json() otherwise.
|
// Return a reference to obj[key] if this is an object, Json() otherwise.
|
||||||
const Json & operator[](const std::string &key) const;
|
JsonIndex operator[](const std::string &key);
|
||||||
|
|
||||||
// Serialize.
|
// Serialize.
|
||||||
void dump(std::string &out) const;
|
void dump(std::string &out) const;
|
||||||
@@ -220,9 +222,38 @@ public:
|
|||||||
bool has_shape(const shape & types, std::string & err) const;
|
bool has_shape(const shape & types, std::string & err) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
friend class JsonIndex;
|
||||||
std::shared_ptr<JsonValue> m_ptr;
|
std::shared_ptr<JsonValue> m_ptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class JsonIndex {
|
||||||
|
public:
|
||||||
|
Json m_object;
|
||||||
|
const std::string & m_key;
|
||||||
|
|
||||||
|
Json operator =(Json value);
|
||||||
|
operator const Json &() { return m_object[m_key]; }
|
||||||
|
const Json & self() const;
|
||||||
|
|
||||||
|
bool is_null() const { return self().is_null(); }
|
||||||
|
bool is_number() const { return self().is_number(); }
|
||||||
|
bool is_bool() const { return self().is_bool(); }
|
||||||
|
bool is_string() const { return self().is_string(); }
|
||||||
|
bool is_array() const { return self().is_array(); }
|
||||||
|
bool is_object() const { return self().is_object(); }
|
||||||
|
|
||||||
|
double number_value() const { return self().number_value(); }
|
||||||
|
int64_ int64_value() const { return self().int64_value(); }
|
||||||
|
uint64_ uint64_value() const { return self().uint64_value(); }
|
||||||
|
std::string as_string() const { return self().as_string(); }
|
||||||
|
bool bool_value() const { return self().bool_value(); }
|
||||||
|
const std::string &string_value() const { return self().string_value(); }
|
||||||
|
const Json::array &array_items() const { return self().array_items(); }
|
||||||
|
const Json::object &object_items() const { return self().object_items(); }
|
||||||
|
|
||||||
|
std::string dump() const { return self().dump(); }
|
||||||
|
};
|
||||||
|
|
||||||
// Internal class hierarchy - JsonValue objects are not exposed to users of this API.
|
// Internal class hierarchy - JsonValue objects are not exposed to users of this API.
|
||||||
class JsonValue {
|
class JsonValue {
|
||||||
protected:
|
protected:
|
||||||
|
Reference in New Issue
Block a user