AFLOW
 
Loading...
Searching...
No Matches
aurostd_xparser_json.h
Go to the documentation of this file.
1
2#ifndef AUROSTD_XPARSER_JSON_H
3#define AUROSTD_XPARSER_JSON_H
4
5#include <cmath>
6#include <cstddef>
7#include <deque>
8#include <iosfwd>
9#include <list>
10#include <map>
11#include <memory>
12#include <set>
13#include <string>
14#include <type_traits>
15#include <utility>
16#include <vector>
17
18#include "aurostd_type_traits.tpp"
19#include "aurostd_xcomplex.h"
20#include "aurostd_xfile.h"
21#include "aurostd_xmatrix.h"
22#include "aurostd_xvector.h"
23
24template <typename T> class JsonSerializable;
25
26namespace aurostd {
27 // JSON namespace for reading and writing //HE20221109
28 namespace JSON {
29
30 template <typename T> using is_string_like = std::is_same<std::decay_t<T>, std::string>;
31 template <typename T> using is_json_list_like = std::conjunction<aurostd::is_list_like<T>, std::negation<is_string_like<T>>>;
32 template <typename T> using enable_list_like = std::enable_if_t<is_json_list_like<T>::value, bool>;
33 template <typename T> using enable_dict_like = std::enable_if_t<aurostd::is_dict_like_v<T>, bool>;
34 template <typename T> using enable_serializable = std::enable_if_t<std::is_base_of_v<JsonSerializable<T>, T>, bool>;
35 template <typename T> using enable_arithmetic = std::enable_if_t<std::is_arithmetic_v<T>, bool>;
36
37 typedef std::vector<object> List;
38 typedef std::map<std::string, object> Dictionary;
39
40 enum class object_types { // order is important!
49 };
50
51 struct object {
53 std::shared_ptr<void> obj = nullptr;
54
55 // operators
56 JSON::object& operator[](size_t index) const;
57 JSON::object& operator[](const std::string& key) const;
58 JSON::object& operator[](const char* key) const;
59 JSON::object& operator=(const char* content); // for literal strings
60 JSON::object& operator=(const std::string& content);
61 JSON::object& operator=(bool content);
62 JSON::object& operator=(std::nullptr_t content);
63 JSON::object& operator=(const List& content);
64 JSON::object& operator=(const Dictionary& content);
65 template <class utype, enable_arithmetic<utype> = true> JSON::object& operator=(utype content);
66 template <class utype> JSON::object& operator=(const xcomplex<utype>& content);
67 template <class utype> JSON::object& operator=(const std::vector<utype>& content);
68 template <class utype> JSON::object& operator=(const std::deque<utype>& content);
69 template <class utype> JSON::object& operator=(const std::map<std::string, utype>& content);
70 template <class utype> JSON::object& operator=(const xvector<utype>& content);
71 template <class utype> JSON::object& operator=(const xmatrix<utype>& content);
72 template <class utype> JSON::object& operator=(const JsonSerializable<utype>& content);
73 template <class T, enable_list_like<T> = true> JSON::object& operator=(const T& content);
74 template <class T, enable_dict_like<T> = true> JSON::object& operator=(const T& content);
75
76 // converting constructors
77 object() = default;
78 object(const char* content);
79 object(const std::string& content);
80 object(bool content);
81 object(std::nullptr_t content);
82 object(object_types create_type);
83 object(const List& content);
84 object(const Dictionary& content);
85 template <typename utype, enable_arithmetic<utype> = true> object(utype content);
86 template <typename utype> object(const xcomplex<utype>& content);
87 template <typename utype> object(const std::vector<utype>& content);
88 template <typename utype> object(const std::deque<utype>& content);
89 template <typename utype> object(const std::map<std::string, utype>& content);
90 template <typename utype> object(const xvector<utype>& content);
91 template <typename utype> object(const xmatrix<utype>& content);
92 template <typename T> object(const JsonSerializable<T>& content) : JSON::object(std::move(content.serialize())) {}
93 template <typename T, enable_list_like<T> = true> object(const T& content);
94 template <typename T, enable_dict_like<T> = true> object(const T& content);
95
96 // conversion functions
97 explicit operator bool() const;
98 explicit operator std::string() const;
99 explicit operator double() const;
100 explicit operator long double() const;
101 explicit operator float() const;
102 explicit operator long long() const;
103 explicit operator long() const;
104 explicit operator int() const;
105 explicit operator char() const;
106 explicit operator unsigned long long() const;
107 explicit operator unsigned long() const;
108 explicit operator unsigned int() const;
109 operator List() const;
110 operator Dictionary() const;
111 template <class utype> operator xcomplex<utype>() const;
112 template <class utype> operator std::vector<utype>() const;
113 template <class utype> operator std::deque<utype>() const;
114 template <class utype> operator std::set<utype>() const;
115 template <class utype> operator std::map<std::string, utype>() const;
116 template <class utype> operator aurostd::xvector<utype>() const;
117 template <class utype> operator aurostd::xmatrix<utype>() const;
118 template <class T, enable_list_like<T> = true> explicit operator T() const;
119 template <class T, enable_dict_like<T> = true> explicit operator T() const;
120 template <class T, enable_serializable<T> = true> explicit operator T() const;
121
122 // type specific functions
123 void push_back(const JSON::object& content) const;
124 void join(const JSON::object& content) const;
125 [[nodiscard]] size_t size() const;
126 [[nodiscard]] bool empty() const;
127 [[nodiscard]] size_t count(const std::string&) const;
128 [[nodiscard]] std::map<std::string, JSON::object>::iterator find(const std::string& key) const;
129 template <class utype> typename std::list<utype>::iterator find_list(const utype& key) const;
130 [[nodiscard]] std::map<std::string, JSON::object>::iterator end() const;
131 [[nodiscard]] std::map<std::string, JSON::object>::iterator begin() const;
132 [[nodiscard]] std::vector<std::string> keys() const;
133
134 // conversion helper
135 void fromString(const std::string& content);
136 void fromList(const List& content);
137 void fromDictionary(const Dictionary& content);
138 template <class utype> void fromNumber(utype content);
139 template <class utype> void fromComplex(const xcomplex<utype>& content);
140 template <class utype> void fromVector(const std::vector<utype>& content);
141 template <class utype> void fromDeque(const std::deque<utype>& content);
142 template <class utype> void fromMap(const std::map<std::string, utype>& content);
143 template <class utype> void fromXvector(const xvector<utype>& content);
144 template <class utype> void fromXmatrix(const xmatrix<utype>& content);
145 template <class T, enable_list_like<T> = true> void fromListLike(const T& content);
146 template <class T, enable_dict_like<T> = true> void fromDictLike(const T& content);
147 template <class T, enable_list_like<T> = true> T toListLike() const;
148 template <class T, enable_dict_like<T> = true> T toDictLike() const;
149
150 [[nodiscard]] std::string toString(bool json_format = true, bool escape_unicode = true) const;
151 void saveFile(const std::string& file_path, compression_type ct = compression_type::None, bool escape_unicode = true) const;
152 };
153
154 // unicode helper function
155 std::string unescape_unicode(const std::string& raw, size_t& pos);
156 std::string escape(const std::string& raw, bool unicode = true);
157 std::string char32_to_string(char32_t cp);
158 std::string char_escape(char16_t c);
159
160 // basic functions
161 object loadFile(const std::string& file_path);
162 object loadString(const std::string& content);
163 void saveFile(const object& root, const std::string& file_path, compression_type ct = compression_type::None, bool escape_unicode = true);
164 std::string toString(const object& root, bool escape_unicode = false);
165
166 // navigation functions
167 std::pair<size_t, size_t> find_string(const std::string& raw_content, std::pair<size_t, size_t> border = {0, 0});
168 std::pair<size_t, size_t> find_bracket(const std::string& raw_content, char kind_open, std::pair<size_t, size_t> border = {0, 0});
169 std::pair<size_t, size_t> find_strip(const std::string& raw_content, std::pair<size_t, size_t> border = {0, 0});
170
171 // parser core
172 object parse(const std::string& raw_content, std::pair<size_t, size_t> border = {0, 0});
173 std::string parse_string(const std::string& raw_content, std::pair<size_t, size_t> border = {0, 0});
174
175 }; // namespace JSON
176
177 // insertion operator: enable easy interaction with cout
178 std::ostream& operator<<(std::ostream& os, const JSON::object& jo);
179} // namespace aurostd
180
181#include "aurostd_xparser_json.tpp" // NOLINT / template implementation
182
183#endif // AUROSTD_XPARSER_JSON_H
Interface for Json serialization functionality using CRTP.
unified namespace to read and write JSON
std::pair< size_t, size_t > find_bracket(const std::string &raw_content, char kind_open, std::pair< size_t, size_t > border={0, 0})
find the border of an encapsulated by brackets
std::enable_if_t< std::is_arithmetic_v< T >, bool > enable_arithmetic
std::pair< size_t, size_t > find_string(const std::string &raw_content, std::pair< size_t, size_t > border={0, 0})
find the border of a JSON string
std::string toString(const object &root, bool escape_unicode=false)
convert JSON::object to string
std::enable_if_t< aurostd::is_dict_like_v< T >, bool > enable_dict_like
void saveFile(const object &root, const std::string &file_path, compression_type ct=compression_type::None, bool escape_unicode=true)
save JSON::object to file
std::string parse_string(const std::string &raw_content, std::pair< size_t, size_t > border={0, 0})
parse JSON string
std::map< std::string, object > Dictionary
shortcut for JSON::object_types::DICTIONARY
std::enable_if_t< std::is_base_of_v< JsonSerializable< T >, T >, bool > enable_serializable
std::enable_if_t< is_json_list_like< T >::value, bool > enable_list_like
object parse(const std::string &raw_content, std::pair< size_t, size_t > border={0, 0})
parse a raw JSON string
std::string unescape_unicode(const std::string &raw, size_t &pos)
unescape JSON unicode instances
std::vector< object > List
shortcut for JSON::object_types::LIST
std::string char32_to_string(char32_t cp)
convert a unicode codepoint to a series of utf8 chars
object loadString(const std::string &content)
create a JSON::object from raw string
std::pair< size_t, size_t > find_strip(const std::string &raw_content, std::pair< size_t, size_t > border={0, 0})
strip whitespaces
object loadFile(const std::string &file_path)
create a JSON::object from file
std::is_same< std::decay_t< T >, std::string > is_string_like
std::string escape(const std::string &raw, bool unicode=true)
prepare string for JSON output with or without Unicode escapes
std::conjunction< aurostd::is_list_like< T >, std::negation< is_string_like< T > > > is_json_list_like
std::string char_escape(char16_t c)
escape characters to JSON
b64_encoder_proxy operator<<(std::ostream &os, b64_encoder_creator)
storge container for a JSON object
JSON::object & operator=(const xvector< utype > &content)
JSON::object & operator=(const xcomplex< utype > &content)
void fromListLike(const T &content)
size_t count(const std::string &) const
count the occurrence of key string in a JSON::object_type::DICTIONARY
JSON::object & operator[](size_t index) const
direct index access to JSON::object_types::LIST objects
void fromDictionary(const Dictionary &content)
change this JSON::object to a JSON::object_types::DICTIONARY
std::vector< std::string > keys() const
returns a vector of all keys in a JSON::object_type::DICTIONARY
JSON::object & operator=(utype content)
void fromDeque(const std::deque< utype > &content)
size_t size() const
gives the size of JSON::object_tpe::LIST, JSON::object_tpe::DICTIONARY or JSON::object_tpe::STRING
object(const JsonSerializable< T > &content)
JSON::object & operator=(const JsonSerializable< utype > &content)
void fromDictLike(const T &content)
void fromMap(const std::map< std::string, utype > &content)
JSON::object & operator=(const char *content)
assignment operator for char
void fromList(const List &content)
change this JSON::object to a JSON::object_types::LIST
std::map< std::string, JSON::object >::iterator begin() const
returns an iterator to the begin() of a JSON::object_type::DICTIONARY
object(const T &content)
std::map< std::string, JSON::object >::iterator find(const std::string &key) const
returns an iterator to the result of find in JSON::object_type::DICTIONARY
JSON::object & operator=(const std::deque< utype > &content)
object(const std::deque< utype > &content)
void fromNumber(utype content)
void fromXvector(const xvector< utype > &content)
void fromComplex(const xcomplex< utype > &content)
void push_back(const JSON::object &content) const
allow to append to JSON::object_type::LIST
void fromVector(const std::vector< utype > &content)
JSON::object & operator=(const T &content)
std::shared_ptr< void > obj
std::string toString(bool json_format=true, bool escape_unicode=true) const
converts a JSON::object into a string
object(const Dictionary &content)
object(utype content)
object(const xcomplex< utype > &content)
std::map< std::string, JSON::object >::iterator end() const
returns an iterator to the end() of a JSON::object_type::DICTIONARY
void fromString(const std::string &content)
change this JSON::object to a JSON::object_types::STRING
bool empty() const
checks if JSON::object_tpe::LIST, JSON::object_tpe::DICTIONARY or JSON::object_tpe::STRING is empty
object(const std::vector< utype > &content)
void join(const JSON::object &content) const
allow to merge two dictionaries or lists
object(const List &content)
std::list< utype >::iterator find_list(const utype &key) const
JSON::object & operator=(const std::vector< utype > &content)
void saveFile(const std::string &file_path, compression_type ct=compression_type::None, bool escape_unicode=true) const
save JSON::object to file
void fromXmatrix(const xmatrix< utype > &content)
JSON::object & operator=(const std::map< std::string, utype > &content)
object(const xmatrix< utype > &content)
JSON::object & operator=(const xmatrix< utype > &content)
object(const std::map< std::string, utype > &content)
object(const xvector< utype > &content)