Working out STL-like support for json arrays and objects.
This commit is contained in:
@@ -11,18 +11,11 @@ A bare-minimal, yet industrial-strength C++ 20 library for reading, writing, and
|
||||
## Features
|
||||
|
||||
* Modern C++ (20)
|
||||
* Simple, well-documented API.
|
||||
* Static Library
|
||||
* GCC and MSVC support
|
||||
* Tested on Fedora Linux and Windows 10.
|
||||
|
||||
## Benchmarks
|
||||
|
||||
## Using JJX
|
||||
|
||||
### Installing via CPM
|
||||
|
||||
### Usage Sample
|
||||
|
||||
|
||||
## Contributing
|
||||
|
||||
|
@@ -62,41 +62,58 @@ namespace JJX::json {
|
||||
std::tuple<json::value, std::string> parse(std::string);
|
||||
std::string deparse(json::value, std::string whitespace = "");
|
||||
|
||||
|
||||
/// This object holds JSON constructs, known as 'values', and associates them to a type.
|
||||
/// A value represents a single piece of JSON information.
|
||||
struct value
|
||||
{
|
||||
/// This member denotes what type of JSON value this object represents.
|
||||
value_type type;
|
||||
|
||||
/// The following member variables store the actual data this object represents.
|
||||
/// Only one member at a time should contain any data, depending on the value_type.
|
||||
|
||||
std::optional<std::string> string;
|
||||
std::optional<double> number;
|
||||
std::optional<bool> boolean;
|
||||
std::optional<std::vector<value>> array;
|
||||
std::optional<std::map<std::string, value>> object;
|
||||
|
||||
value_type type;
|
||||
|
||||
/// The default constructor initializes to a JSON null.
|
||||
/// The default constructor initializes to a JSON null value.
|
||||
explicit value();
|
||||
/// Constructs a json value that represents the corresponding number.
|
||||
explicit value(double v);
|
||||
/// Constructs a json value that represents a string.
|
||||
explicit value(const std::string& v);
|
||||
/// Constructs a json value that represents an array.
|
||||
explicit value(const std::vector<value>& v);
|
||||
/// Constructs a json value that represents an object.
|
||||
explicit value(const std::map<std::string, value>& v);
|
||||
/// Constructs a json value that represents an object, from a key-value pair.
|
||||
explicit value(const std::pair<std::string, value>& kvp) : object({kvp}), type(value_type::object) {}
|
||||
/// Constructs a json value that represents an object, from a list of key-value pairs.
|
||||
explicit value(const std::vector<std::pair<std::string, value>>& kvp_list);
|
||||
|
||||
|
||||
/// Assigns this value to a number, and sets the value_type::number.
|
||||
value& operator=(double in);
|
||||
/// Assigns this value to a string, and sets the value_type::string.
|
||||
value& operator=(const std::string& in);
|
||||
/// Assigns this value to a boolean, and sets the value_type::boolean.
|
||||
value& operator=(bool in);
|
||||
/// Assigns this value to an array, and sets the value_type::array.
|
||||
value& operator=(const std::vector<value>& in);
|
||||
/// Assigns this value to a map, and sets the value_type::map.
|
||||
value& operator=(const std::map<std::string, value>& in);
|
||||
|
||||
explicit operator double() const { return number.value(); }
|
||||
explicit operator std::string() const { return string.value(); }
|
||||
explicit operator bool() const { return boolean.value(); }
|
||||
explicit operator std::vector<value>() const { return this->value::array.value(); }
|
||||
explicit operator std::map<std::string, value>() const { return object.value(); }
|
||||
explicit operator double() const;
|
||||
explicit operator std::string() const;
|
||||
explicit operator bool() const;
|
||||
explicit operator std::vector<value>() const;
|
||||
explicit operator std::map<std::string, value>() const;
|
||||
|
||||
/// Returns this value's data, converted to a json::object, which is a specialization of this type.
|
||||
/// @see struct object
|
||||
[[nodiscard]] struct object as_object() const;
|
||||
/// Returns this value's data, converted to a json::array, which is a specialization of this type.
|
||||
[[nodiscard]] struct array as_array() const;
|
||||
[[nodiscard]] struct string as_string() const;
|
||||
[[nodiscard]] struct number as_number() const;
|
||||
@@ -107,7 +124,9 @@ namespace JJX::json {
|
||||
|
||||
};
|
||||
|
||||
/// A specialized json::value which provides STL-compatibility with std::string, and other functions for convenience.
|
||||
struct string : value {
|
||||
/// The default constructor initializes to an empty string literal.
|
||||
explicit string() : value("") {}
|
||||
explicit string(const std::string& v) : value(v) {}
|
||||
|
||||
@@ -115,53 +134,80 @@ namespace JJX::json {
|
||||
operator std::string();
|
||||
};
|
||||
struct number : value {
|
||||
/// The default constructor initializes to floating-point literal zero.
|
||||
explicit number() : value(0.0) {}
|
||||
explicit number(double v) : value(v) {}
|
||||
};
|
||||
struct boolean : value {
|
||||
/// The default constructor initializes to false.
|
||||
explicit boolean() : value(false) {}
|
||||
explicit boolean(bool v) : value(v) {}
|
||||
};
|
||||
|
||||
/// A specialized json::value which provides STL compatibility with std::map, and other functions for convenience.
|
||||
/// As per JSON specification, only std::strings are allowed to be used as keys in this data type.
|
||||
struct object : value
|
||||
{
|
||||
/// The default constructor initializes to an empty map.
|
||||
explicit object() : value(std::map<std::string, value>{}) {}
|
||||
/// Constructs this object from a list of key-value pairs, in the form of std::map.
|
||||
explicit object(const std::map<std::string, value>& v) : value(v) {}
|
||||
|
||||
/// Adds a key-value pair to this object.
|
||||
void insert(const std::pair<std::string, value>& kvp);
|
||||
|
||||
/// Adds a key-value pair to this object.
|
||||
/// @param key The key to associate with the value.
|
||||
void insert(const std::string& key, const value& val);
|
||||
|
||||
|
||||
/// Shorthand operator for adding a key-value pair to this object,
|
||||
json::object& operator+=(const std::pair<std::string, value>& kvp);
|
||||
|
||||
/// Shorthand operator for adding a boolean-value to this object, with a string key.
|
||||
json::object& operator+=(const std::pair<std::string, bool>& kvp);
|
||||
|
||||
json::object& operator+=(const std::pair<std::string, double>& kvp);
|
||||
|
||||
json::object& operator+=(const std::pair<std::string, std::string>& kvp);
|
||||
|
||||
/// @return The json value associated with the given key.
|
||||
value& at(const std::string& key);
|
||||
value& operator[] (const std::string& key);
|
||||
|
||||
/// @see object::at()
|
||||
value& operator[] (const std::string& key);
|
||||
const value& operator[] (const std::string& key) const;
|
||||
|
||||
/// @return True if a key-value pair in this object has a key that matches the given value.
|
||||
bool contains(const std::string& key);
|
||||
|
||||
/// @return The json-type of the value of the first key-value pair where the key matches the given string.
|
||||
json::value_type type_of(const std::string& key);
|
||||
|
||||
using map_spec = std::map<std::string, value>;
|
||||
using iterator = map_spec::iterator;
|
||||
using const_iterator = map_spec::const_iterator;
|
||||
|
||||
iterator begin() { return value::object->begin();}
|
||||
iterator end() { return value::object->end();}
|
||||
|
||||
const_iterator begin() const { return value::object->cbegin(); }
|
||||
const_iterator end() const { return value::object->cend(); }
|
||||
|
||||
size_t size() const { return value::object->size();}
|
||||
bool empty() const { return value::object->empty(); }
|
||||
|
||||
};
|
||||
|
||||
struct array : value {
|
||||
explicit array() : value(std::vector<value>{}) {}
|
||||
explicit array(const std::vector<value>& v) : value(v) {}
|
||||
explicit array(const value& v) {
|
||||
if (v.type == value_type::array) {
|
||||
this->value::array = v.value::array;
|
||||
}
|
||||
}
|
||||
/// The default constructor
|
||||
explicit array();
|
||||
|
||||
explicit array(const std::vector<value>& v);
|
||||
|
||||
/// Default Copy Constructor
|
||||
explicit array(const array& v) = default;
|
||||
|
||||
void push_back(const value& element);
|
||||
|
||||
|
||||
value& operator+= (const value& v);
|
||||
|
||||
value& operator+= (bool v) { push_back(json::boolean(v)); return *this; }
|
||||
|
30
src/JSON.cpp
30
src/JSON.cpp
@@ -213,6 +213,16 @@ namespace JJX::json {
|
||||
return *this;
|
||||
}
|
||||
|
||||
value::operator double() const { return number.value(); }
|
||||
|
||||
value::operator std::string() const { return string.value(); }
|
||||
|
||||
value::operator bool() const { return boolean.value(); }
|
||||
|
||||
value::operator std::vector<value>() const { return this->value::array.value(); }
|
||||
|
||||
value::operator std::map<std::string, value>() const { return object.value(); }
|
||||
|
||||
struct json::object json::value::as_object() const {
|
||||
return json::object(object.value());
|
||||
}
|
||||
@@ -298,6 +308,8 @@ namespace JJX::json {
|
||||
return this->value::object.value()[key];
|
||||
}
|
||||
|
||||
const value & object::operator[](const std::string &key) const { return value::object->at(key);}
|
||||
|
||||
|
||||
value& array::operator[](int key)
|
||||
{
|
||||
@@ -580,18 +592,15 @@ namespace JJX::json {
|
||||
return out;
|
||||
}
|
||||
|
||||
struct array array(std::vector<value> input)
|
||||
array::array(const std::vector<value>& v)
|
||||
{
|
||||
struct array arr;
|
||||
arr.type = value_type::array;
|
||||
arr.value::array = std::vector<value>();
|
||||
|
||||
for (auto& elem: input)
|
||||
{
|
||||
arr.value::array->push_back(elem);
|
||||
}
|
||||
this->type = value_type::array;
|
||||
this->value::array = std::vector<value>();
|
||||
|
||||
for (auto& elem: v)
|
||||
this->value::array->push_back(elem);
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
/*struct array array()
|
||||
@@ -657,4 +666,7 @@ namespace JJX::json {
|
||||
json::value_type object::type_of(const std::string &key) {
|
||||
return this->value::object->at(key).type;
|
||||
}
|
||||
|
||||
array::array(): value(std::vector<value>{}) {}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user