Working out STL-like support for json arrays and objects.

This commit is contained in:
2025-03-26 00:19:19 -05:00
parent 7bbcb98914
commit 6d700fcf97
3 changed files with 89 additions and 38 deletions

View File

@@ -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

View File

@@ -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; }

View File

@@ -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>{}) {}
}