Util: Add more ways of accessing and creating Json::Value objects
This commit is contained in:
+18
-1
@@ -7,6 +7,7 @@
|
|||||||
#ifndef JSON_ARRAY_H
|
#ifndef JSON_ARRAY_H
|
||||||
#define JSON_ARRAY_H
|
#define JSON_ARRAY_H
|
||||||
|
|
||||||
|
#include <initializer_list>
|
||||||
#include <utility> // move
|
#include <utility> // move
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -19,6 +20,10 @@ public:
|
|||||||
Array() {}
|
Array() {}
|
||||||
virtual ~Array() {}
|
virtual ~Array() {}
|
||||||
|
|
||||||
|
Array(const std::initializer_list<Value>& values)
|
||||||
|
: m_values(values)
|
||||||
|
{}
|
||||||
|
|
||||||
Array(const Array& other)
|
Array(const Array& other)
|
||||||
: m_values(other.m_values)
|
: m_values(other.m_values)
|
||||||
{
|
{
|
||||||
@@ -29,6 +34,19 @@ public:
|
|||||||
m_values.emplace_back(std::move(value));
|
m_values.emplace_back(std::move(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Value& at(size_t index)
|
||||||
|
{
|
||||||
|
if (index + 1 > m_values.size()) {
|
||||||
|
m_values.resize(index + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_values.at(index);
|
||||||
|
}
|
||||||
|
Value& operator[](size_t index) { return at(index); }
|
||||||
|
const Value& at(size_t index) const { return m_values.at(index); }
|
||||||
|
const Value& operator[](size_t index) const { return m_values.at(index); }
|
||||||
|
|
||||||
|
size_t size() const { return m_values.size(); }
|
||||||
const std::vector<Value>& values() const { return m_values; }
|
const std::vector<Value>& values() const { return m_values; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -37,5 +55,4 @@ private:
|
|||||||
|
|
||||||
} // namespace Json
|
} // namespace Json
|
||||||
|
|
||||||
|
|
||||||
#endif // JSON_ARRAY_H
|
#endif // JSON_ARRAY_H
|
||||||
|
|||||||
@@ -30,6 +30,18 @@ public:
|
|||||||
m_members.emplace(key, std::move(value));
|
m_members.emplace(key, std::move(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Value& at(const std::string& key)
|
||||||
|
{
|
||||||
|
if (m_members.find(key) == m_members.end()) {
|
||||||
|
emplace(key, {});
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_members.at(key);
|
||||||
|
}
|
||||||
|
Value& operator[](const std::string& key) { return at(key); }
|
||||||
|
const Value& at(const std::string& key) const { return m_members.at(key); }
|
||||||
|
const Value& operator[](const std::string& key) const { return m_members.at(key); }
|
||||||
|
|
||||||
const std::map<std::string, Value>& members() const { return m_members; }
|
const std::map<std::string, Value>& members() const { return m_members; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
+54
-4
@@ -4,6 +4,7 @@
|
|||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <algorithm> // all_of
|
||||||
#include <cassert> // assert
|
#include <cassert> // assert
|
||||||
#include <cstdint> // uint32_t
|
#include <cstdint> // uint32_t
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@@ -38,6 +39,12 @@ Value::Value(bool value)
|
|||||||
m_value.asBool = value;
|
m_value.asBool = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Value::Value(int value)
|
||||||
|
: m_type(Type::Number)
|
||||||
|
{
|
||||||
|
m_value.asDouble = value;
|
||||||
|
}
|
||||||
|
|
||||||
Value::Value(double value)
|
Value::Value(double value)
|
||||||
: m_type(Type::Number)
|
: m_type(Type::Number)
|
||||||
{
|
{
|
||||||
@@ -68,7 +75,29 @@ Value::Value(const Object& value)
|
|||||||
m_value.asObject = new Object(value);
|
m_value.asObject = new Object(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
Value Value::operator[](size_t index)
|
Value::Value(const std::initializer_list<Value>& values)
|
||||||
|
{
|
||||||
|
bool isObject = std::all_of(values.begin(), values.end(), [](const Value& value) {
|
||||||
|
return value.type() == Type::Array
|
||||||
|
&& value.m_value.asArray->size() == 2
|
||||||
|
&& value[0].m_type == Type::String;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!isObject) {
|
||||||
|
m_type = Type::Array;
|
||||||
|
m_value.asArray = new Array(values);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_type = Type::Object;
|
||||||
|
m_value.asObject = new Object;
|
||||||
|
|
||||||
|
for (auto& value : values) {
|
||||||
|
m_value.asObject->emplace(std::move(*value[0].m_value.asString),
|
||||||
|
std::move(value[1]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------
|
// ------------------------------------------
|
||||||
|
|
||||||
Value Value::parse(const std::string& input)
|
Value Value::parse(const std::string& input)
|
||||||
@@ -87,15 +116,36 @@ std::string Value::dump(const uint32_t indent, const char indentCharacter) const
|
|||||||
return stringify.dump();
|
return stringify.dump();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
|
||||||
|
Value& Value::operator[](size_t index)
|
||||||
{
|
{
|
||||||
assert(m_type == Type::Array);
|
assert(m_type == Type::Array);
|
||||||
return m_value.asArray->values().at(index);
|
return m_value.asArray->at(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
Value Value::operator[](const std::string& key)
|
Value& Value::operator[](const std::string& key)
|
||||||
|
{
|
||||||
|
// Implicit conversion to an object
|
||||||
|
if (m_type == Type::Null) {
|
||||||
|
m_type = Type::Object;
|
||||||
|
m_value.asObject = new Object;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(m_type == Type::Object);
|
||||||
|
return m_value.asObject->at(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
const Value& Value::operator[](size_t index) const
|
||||||
|
{
|
||||||
|
assert(m_type == Type::Array);
|
||||||
|
return m_value.asArray->at(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
const Value& Value::operator[](const std::string& key) const
|
||||||
{
|
{
|
||||||
assert(m_type == Type::Object);
|
assert(m_type == Type::Object);
|
||||||
return m_value.asObject->members().at(key);
|
return m_value.asObject->at(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------
|
// ------------------------------------------
|
||||||
|
|||||||
+12
-2
@@ -7,7 +7,9 @@
|
|||||||
#ifndef JSON_VALUE_H
|
#ifndef JSON_VALUE_H
|
||||||
#define JSON_VALUE_H
|
#define JSON_VALUE_H
|
||||||
|
|
||||||
|
#include <cstddef> // nullptr_t
|
||||||
#include <cstdint> // uint32_t
|
#include <cstdint> // uint32_t
|
||||||
|
#include <initializer_list>
|
||||||
#include <iostream> // istream, ostream
|
#include <iostream> // istream, ostream
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
@@ -36,20 +38,28 @@ public:
|
|||||||
Value& operator=(const Value& other);
|
Value& operator=(const Value& other);
|
||||||
|
|
||||||
Value(bool value);
|
Value(bool value);
|
||||||
|
Value(int value);
|
||||||
Value(double value);
|
Value(double value);
|
||||||
Value(const char* value);
|
Value(const char* value);
|
||||||
Value(const std::string& value);
|
Value(const std::string& value);
|
||||||
Value(const Array& value);
|
Value(const Array& value);
|
||||||
Value(const Object& value);
|
Value(const Object& value);
|
||||||
|
Value(const std::initializer_list<Value>& values);
|
||||||
|
|
||||||
// ------------------------------------------
|
// ------------------------------------------
|
||||||
|
|
||||||
static Value parse(const std::string& input);
|
static Value parse(const std::string& input);
|
||||||
std::string dump(const uint32_t indent = 0, const char indentCharacter = ' ') const;
|
std::string dump(const uint32_t indent = 0, const char indentCharacter = ' ') const;
|
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
|
||||||
// Array index operator
|
// Array index operator
|
||||||
Value operator[](size_t index);
|
Value& operator[](size_t index);
|
||||||
Value operator[](const std::string& key);
|
Value& operator[](const std::string& key);
|
||||||
|
const Value& operator[](size_t index) const;
|
||||||
|
const Value& operator[](const std::string& key) const;
|
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
|
||||||
Type type() const { return m_type; }
|
Type type() const { return m_type; }
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user