Compare commits

..

1 Commits

Author SHA1 Message Date
Vitaliy Filippov fd37016cf8 Allow trailing comma 2023-02-23 01:15:28 +03:00
2 changed files with 29 additions and 57 deletions

View File

@ -131,27 +131,6 @@ void Json::dump(string &out) const {
m_ptr->dump(out); m_ptr->dump(out);
} }
/* * * * * * * * * * * * * * * * * * * *
* Indexed wrapper to prevent autovivification
*/
JsonIndex::JsonIndex(Json obj, const std::string & key)
{
m_object = obj;
m_key = key;
}
Json & JsonIndex::operator =(const Json & value)
{
auto & obj = m_object.object_items();
return obj[m_key] = value;
}
JsonIndex::operator Json()
{
return m_object[m_key];
}
/* * * * * * * * * * * * * * * * * * * * /* * * * * * * * * * * * * * * * * * * *
* Value wrappers * Value wrappers
*/ */
@ -177,7 +156,7 @@ 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;
} }
T m_value; const 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); }
}; };
@ -257,16 +236,16 @@ public:
}; };
class JsonArray final : public Value<Json::ARRAY, Json::array> { class JsonArray final : public Value<Json::ARRAY, Json::array> {
Json::array &array_items() override { return m_value; } const Json::array &array_items() const override { return m_value; }
Json & operator[](size_t i) override; const Json & operator[](size_t i) const override;
public: public:
explicit JsonArray(const Json::array &value) : Value(value) {} explicit JsonArray(const Json::array &value) : Value(value) {}
explicit JsonArray(Json::array &&value) : Value(move(value)) {} explicit JsonArray(Json::array &&value) : Value(move(value)) {}
}; };
class JsonObject final : public Value<Json::OBJECT, Json::object> { class JsonObject final : public Value<Json::OBJECT, Json::object> {
Json::object &object_items() override { return m_value; } const Json::object &object_items() const override { return m_value; }
Json & operator[](const string &key) override; const Json & operator[](const string &key) const override;
public: public:
explicit JsonObject(const Json::object &value) : Value(value) {} explicit JsonObject(const Json::object &value) : Value(value) {}
explicit JsonObject(Json::object &&value) : Value(move(value)) {} explicit JsonObject(Json::object &&value) : Value(move(value)) {}
@ -341,14 +320,14 @@ Json::Json(Json::object &&values) : m_ptr(make_shared<JsonObject>(move(valu
Json::Type Json::type() const { return m_ptr->type(); } Json::Type Json::type() const { return m_ptr->type(); }
double Json::number_value() const { return m_ptr->number_value(); } double Json::number_value() const { return m_ptr->number_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(); } uint64_ Json::uint64_value() const { return m_ptr->uint64_value(); }
bool Json::bool_value() const { return m_ptr->bool_value(); } bool Json::bool_value() const { return m_ptr->bool_value(); }
string Json::as_string() const { return m_ptr->as_string(); } string Json::as_string() const { return m_ptr->as_string(); }
const string & Json::string_value() const { return m_ptr->string_value(); } const string & Json::string_value() const { return m_ptr->string_value(); }
vector<Json> & Json::array_items() { return m_ptr->array_items(); } const vector<Json> & Json::array_items() const { return m_ptr->array_items(); }
map<string, Json> & Json::object_items() { return m_ptr->object_items(); } const map<string, Json> & Json::object_items() const { return m_ptr->object_items(); }
Json & Json::operator[] (size_t i) { return (*m_ptr)[i]; } const Json & Json::operator[] (size_t i) const { return (*m_ptr)[i]; }
Json & Json::operator[] (const string &key) { return (*m_ptr)[key]; } const Json & Json::operator[] (const string &key) const { return (*m_ptr)[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; }
@ -356,16 +335,16 @@ uint64_ JsonValue::uint64_value() const { return
bool JsonValue::bool_value() const { return false; } bool JsonValue::bool_value() const { return false; }
string JsonValue::as_string() const { return statics().empty_string; } string JsonValue::as_string() const { return statics().empty_string; }
const string & JsonValue::string_value() const { return statics().empty_string; } const string & JsonValue::string_value() const { return statics().empty_string; }
vector<Json> & JsonValue::array_items() { return statics().empty_vector; } const vector<Json> & JsonValue::array_items() const { return statics().empty_vector; }
map<string, Json> & JsonValue::object_items() { return statics().empty_map; } const map<string, Json> & JsonValue::object_items() const { return statics().empty_map; }
Json & JsonValue::operator[] (size_t) { return static_null(); } const Json & JsonValue::operator[] (size_t) const { return static_null(); }
Json & JsonValue::operator[] (const string &) { return static_null(); } const Json & JsonValue::operator[] (const string &) const { return static_null(); }
Json & JsonObject::operator[] (const string &key) { const Json & JsonObject::operator[] (const string &key) const {
auto iter = m_value.find(key); auto iter = m_value.find(key);
return (iter == m_value.end()) ? static_null() : iter->second; return (iter == m_value.end()) ? static_null() : iter->second;
} }
Json & JsonArray::operator[] (size_t i) { const Json & JsonArray::operator[] (size_t i) const {
if (i >= m_value.size()) return static_null(); if (i >= m_value.size()) return static_null();
else return m_value[i]; else return m_value[i];
} }
@ -790,6 +769,8 @@ struct JsonParser final {
return fail("expected ',' in object, got " + esc(ch)); return fail("expected ',' in object, got " + esc(ch));
ch = get_next_token(); ch = get_next_token();
if (ch == '}')
break;
} }
return data; return data;
} }
@ -813,6 +794,8 @@ struct JsonParser final {
return fail("expected ',' in list, got " + esc(ch)); return fail("expected ',' in list, got " + esc(ch));
ch = get_next_token(); ch = get_next_token();
if (ch == ']')
break;
(void)ch; (void)ch;
} }
return data; return data;

View File

@ -150,7 +150,7 @@ public:
int64_ int64_value() const; int64_ int64_value() const;
uint64_ uint64_value() const; uint64_ uint64_value() const;
// Return the enclosed value as string. // Return the enclosed string if this is a string, "" otherwise.
std::string as_string() const; std::string as_string() const;
// Return the enclosed value if this is a boolean, false otherwise. // Return the enclosed value if this is a boolean, false otherwise.
@ -158,14 +158,14 @@ public:
// Return the enclosed string if this is a string, "" otherwise. // Return the enclosed string if this is a string, "" otherwise.
const std::string &string_value() const; const std::string &string_value() const;
// Return the enclosed std::vector if this is an array, or an empty vector otherwise. // Return the enclosed std::vector if this is an array, or an empty vector otherwise.
array &array_items(); const array &array_items() const;
// Return the enclosed std::map if this is an object, or an empty map otherwise. // Return the enclosed std::map if this is an object, or an empty map otherwise.
object &object_items(); const object &object_items() const;
// 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.
Json & operator[](size_t i); 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.
Json & operator[](const std::string &key); const Json & operator[](const std::string &key) const;
// Serialize. // Serialize.
void dump(std::string &out) const; void dump(std::string &out) const;
@ -220,20 +220,9 @@ 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 {
protected:
Json m_object;
std::string m_key;
public:
JsonIndex(Json obj, const std::string & key);
Json &operator = (const Json & value);
operator Json ();
};
// 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:
@ -251,10 +240,10 @@ protected:
virtual bool bool_value() const; virtual bool bool_value() const;
virtual const std::string &string_value() const; virtual const std::string &string_value() const;
virtual std::string as_string() const; virtual std::string as_string() const;
virtual Json::array &array_items(); virtual const Json::array &array_items() const;
virtual Json &operator[](size_t i); virtual const Json &operator[](size_t i) const;
virtual Json::object &object_items(); virtual const Json::object &object_items() const;
virtual Json &operator[](const std::string &key); virtual const Json &operator[](const std::string &key) const;
virtual ~JsonValue() {} virtual ~JsonValue() {}
}; };