Fixed everything
This commit is contained in:
parent
fadf87c0d2
commit
0d2fefbfb0
@ -49,7 +49,6 @@ struct TestWebsiteBuildScript {
|
||||
"utf8.cpp",
|
||||
"jsonobj.cpp",
|
||||
"quality_of_life.cpp",
|
||||
"quality_of_life_2.cpp",
|
||||
"integer.cpp",
|
||||
"inner_storage.cpp",
|
||||
"generator.cpp",
|
||||
|
@ -24,6 +24,8 @@ namespace json {
|
||||
}
|
||||
|
||||
Integer & Integer::operator=(const Integer &other) {
|
||||
if (this == &other)
|
||||
return *this;
|
||||
value = other.value;
|
||||
free(uncomprehendable_horror); uncomprehendable_horror = NULL;
|
||||
copy_horror(*this, other.uncomprehendable_horror);
|
||||
|
@ -83,12 +83,4 @@ namespace json {
|
||||
/* This is by far the most serious function I have ever written */
|
||||
nullify(*this);
|
||||
}
|
||||
|
||||
JSON_reference JSON::r() noexcept {
|
||||
return {*this, {}};
|
||||
}
|
||||
|
||||
JSON_reference_const JSON::r() const noexcept {
|
||||
return {*this, false};
|
||||
}
|
||||
}
|
||||
|
@ -21,14 +21,6 @@ namespace json {
|
||||
dictionary,
|
||||
};
|
||||
|
||||
enum imaginary_key_t {
|
||||
undefined_array_element,
|
||||
undefined_dictionary_element,
|
||||
};
|
||||
|
||||
struct JSON_reference;
|
||||
struct JSON_reference_const;
|
||||
|
||||
struct JSON;
|
||||
|
||||
typedef std::vector<JSON> jarr;
|
||||
@ -52,10 +44,6 @@ namespace json {
|
||||
JSON& operator=(const JSON& other);
|
||||
~JSON();
|
||||
|
||||
JSON_reference r() noexcept;
|
||||
|
||||
JSON_reference_const r() const noexcept;
|
||||
|
||||
json_t getType() const;
|
||||
|
||||
bool isNull() const;
|
||||
@ -96,58 +84,15 @@ namespace json {
|
||||
|
||||
std::map<std::string, JSON>& asDictionary();
|
||||
|
||||
JSON_reference operator[](size_t index);
|
||||
JSON_reference operator[](const std::string& key);
|
||||
JSON& operator[](size_t index);
|
||||
JSON& operator[](const std::string& key);
|
||||
|
||||
JSON_reference_const operator[](size_t index) const;
|
||||
JSON_reference_const operator[](const std::string& key) const;
|
||||
|
||||
JSON& operator=(int64_t V);
|
||||
JSON& operator=(const Integer& V);
|
||||
JSON& operator=(const char* V);
|
||||
JSON& operator=(const std::string& V);
|
||||
const JSON& operator[](size_t index) const;
|
||||
const JSON& operator[](const std::string& key) const;
|
||||
|
||||
bool operator==(const JSON& B) const;
|
||||
bool operator!=(const JSON& B) const;
|
||||
};
|
||||
|
||||
struct ImaginaryKeyChainEValue {
|
||||
imaginary_key_t type;
|
||||
/* Why messing with RAII-ing (int|string) value behind some void pointer when I can just include both.
|
||||
* C'mon, bros, memory consumption issue does not exist */
|
||||
size_t when_array_index;
|
||||
std::string when_dictionary_key;
|
||||
};
|
||||
|
||||
/* These references get invalidated as soon as referenced object or any of its parents get changed */
|
||||
struct JSON_reference {
|
||||
JSON& last_real;
|
||||
std::vector<ImaginaryKeyChainEValue> imaginary_chain;
|
||||
|
||||
bool isDefined();
|
||||
|
||||
JSON& operator*();
|
||||
JSON& g();
|
||||
|
||||
void operator=(const JSON& obj);
|
||||
|
||||
JSON_reference operator[](size_t index);
|
||||
JSON_reference operator[](const std::string& key);
|
||||
};
|
||||
|
||||
/* text */
|
||||
struct JSON_reference_const {
|
||||
const JSON& last_real;
|
||||
bool bad = false;
|
||||
|
||||
bool isDefined();
|
||||
|
||||
const JSON& operator*();
|
||||
const JSON& g();
|
||||
|
||||
JSON_reference_const operator[](size_t index);
|
||||
JSON_reference_const operator[](const std::string& key);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -165,7 +165,7 @@ namespace json {
|
||||
skipWhitespaces(pctx);
|
||||
int herald = peep(pctx);
|
||||
if (herald == '"') {
|
||||
result = demandStringJson(pctx);
|
||||
result.asString() = demandStringJson(pctx);
|
||||
} else if (isIntegerStart(herald)) {
|
||||
size_t pos_beg = pctx.pos;
|
||||
bool terrifying = false;
|
||||
@ -175,16 +175,16 @@ namespace json {
|
||||
read_int_int_part(pctx, mantis_abs_max18, terrifying);
|
||||
read_int_frac_exp_part(pctx, terrifying);
|
||||
if (terrifying) {
|
||||
result = Integer(pctx.text.substr(pos_beg, pctx.pos).c_str());
|
||||
result.asInteger() = Integer(pctx.text.substr(pos_beg, pctx.pos).c_str());
|
||||
} else if (mantis_minus) {
|
||||
result = -mantis_abs_max18;
|
||||
result.asInteger() = Integer(-mantis_abs_max18);
|
||||
} else {
|
||||
result = mantis_abs_max18;
|
||||
result.asInteger() = Integer(mantis_abs_max18);
|
||||
}
|
||||
} else if (isSymbolConstituent(herald)) {
|
||||
std::string sym;
|
||||
while (isSymbolConstituent(peep(pctx))) {
|
||||
sym += peep(pctx);
|
||||
sym += (char)(uint8_t)peep(pctx);
|
||||
skip(pctx);
|
||||
}
|
||||
if (sym == "null") {
|
||||
|
@ -87,7 +87,9 @@ namespace json {
|
||||
value = new Integer();
|
||||
type = integer;
|
||||
}
|
||||
if (isInteger())
|
||||
return const_cast<Integer&>(const_cast<const JSON*>(this)->asInteger());
|
||||
throw misuse("JSON::asInteger() can't convert non-null to integer");
|
||||
}
|
||||
|
||||
std::string &JSON::asString() {
|
||||
@ -95,7 +97,9 @@ namespace json {
|
||||
value = new std::string();
|
||||
type = string;
|
||||
}
|
||||
if (isString())
|
||||
return const_cast<std::string&>(const_cast<const JSON*>(this)->asString());
|
||||
throw misuse("JSON::asString() can't convert non-null to string");
|
||||
}
|
||||
|
||||
std::vector<JSON> &JSON::asArray() {
|
||||
@ -103,7 +107,9 @@ namespace json {
|
||||
value = new ArrayData();
|
||||
type = array;
|
||||
}
|
||||
if (isArray())
|
||||
return const_cast<std::vector<JSON>&>(const_cast<const JSON*>(this)->asArray());
|
||||
throw misuse("JSON::asArray() can't convert non-null to array");
|
||||
}
|
||||
|
||||
std::map<std::string, JSON> &JSON::asDictionary() {
|
||||
@ -111,54 +117,36 @@ namespace json {
|
||||
value = new DictionaryData();
|
||||
type = dictionary;
|
||||
}
|
||||
if (isDictionary())
|
||||
return const_cast<std::map<std::string, JSON>&>(const_cast<const JSON*>(this)->asDictionary());
|
||||
throw misuse("JSON::asDictionary() can't convert non-null to dictionary");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
JSON_reference JSON::operator[](size_t index) {
|
||||
return r()[index];
|
||||
JSON& JSON::operator[](size_t index) {
|
||||
std::vector<JSON>& arr = asArray();
|
||||
if (arr.size() <= index)
|
||||
arr.resize(index + 1);
|
||||
return arr[index];
|
||||
}
|
||||
|
||||
JSON_reference JSON::operator[](const std::string &key) {
|
||||
return r()[key];
|
||||
JSON& JSON::operator[](const std::string &key) {
|
||||
std::map<std::string, JSON>& dict = asDictionary();
|
||||
return dict[key];
|
||||
}
|
||||
|
||||
JSON_reference_const JSON::operator[](size_t index) const {
|
||||
return r()[index];
|
||||
const JSON& JSON::operator[](size_t index) const {
|
||||
if (!isArray() || asArray().size() <= index)
|
||||
throw misuse("Index out of range");
|
||||
return static_cast<ArrayData*>(value)->data[index];
|
||||
}
|
||||
|
||||
JSON_reference_const JSON::operator[](const std::string &key) const {
|
||||
return r()[key];
|
||||
}
|
||||
|
||||
JSON& JSON::operator=(int64_t V) {
|
||||
nullify(*this);
|
||||
value = new Integer(V);
|
||||
type = integer;
|
||||
return *this;
|
||||
}
|
||||
|
||||
JSON & JSON::operator=(const Integer &V) {
|
||||
nullify(*this);
|
||||
value = new Integer(V);
|
||||
type = integer;
|
||||
return *this;
|
||||
}
|
||||
|
||||
JSON & JSON::operator=(const char *V) {
|
||||
nullify(*this);
|
||||
value = new std::string(V);
|
||||
type = string;
|
||||
return *this;
|
||||
}
|
||||
|
||||
JSON & JSON::operator=(const std::string &V) {
|
||||
nullify(*this);
|
||||
value = new std::string(V);
|
||||
type = string;
|
||||
return *this;
|
||||
const JSON& JSON::operator[](const std::string &key) const {
|
||||
if (!isDictionary() || asDictionary().count(key) != 1)
|
||||
throw misuse("No such key");
|
||||
return asDictionary().at(key);
|
||||
}
|
||||
|
||||
bool JSON::operator==(const JSON &B) const {
|
||||
|
@ -1,94 +0,0 @@
|
||||
#include "jsonobj.h"
|
||||
|
||||
namespace json {
|
||||
bool JSON_reference::isDefined(){
|
||||
return imaginary_chain.empty();
|
||||
}
|
||||
|
||||
JSON& JSON_reference::operator*(){
|
||||
return g();
|
||||
}
|
||||
|
||||
JSON& patch_up(JSON_reference& ref) {
|
||||
JSON* cur_last_real = &ref.last_real;
|
||||
for (const auto& ck: ref.imaginary_chain) {
|
||||
if (ck.type == undefined_array_element) {
|
||||
if (cur_last_real->type == null_symbol)
|
||||
*cur_last_real = JSON(array);
|
||||
if (cur_last_real->type != array)
|
||||
throw misuse("Implicit array creation on top of neither non-null nor short-array json obj is not allowed");
|
||||
cur_last_real->asArray().resize(ck.when_array_index + 1);
|
||||
cur_last_real = &cur_last_real->asArray()[ck.when_array_index];
|
||||
} else {
|
||||
if (cur_last_real->type == null_symbol)
|
||||
*cur_last_real = JSON(dictionary);
|
||||
if (cur_last_real->type != dictionary)
|
||||
throw misuse("Implicit dictionary creation on top of neither non-null nor illiterate-dict json obj is not allowed");
|
||||
cur_last_real = &(cur_last_real->asDictionary()[ck.when_dictionary_key]);
|
||||
}
|
||||
}
|
||||
return *cur_last_real;
|
||||
}
|
||||
|
||||
JSON & JSON_reference::g() {
|
||||
return patch_up(*this);
|
||||
}
|
||||
|
||||
void JSON_reference::operator=(const JSON &obj) {
|
||||
patch_up(*this) = obj;
|
||||
}
|
||||
|
||||
JSON_reference JSON_reference::operator[](size_t index) {
|
||||
if (!imaginary_chain.empty()) {
|
||||
std::vector<ImaginaryKeyChainEValue> elongated = imaginary_chain;
|
||||
elongated.push_back({undefined_array_element, index, ""});
|
||||
return {last_real, elongated};
|
||||
}
|
||||
if (last_real.isArray() && last_real.asArray().size() > index) {
|
||||
return {last_real.asArray()[index], {}};
|
||||
}
|
||||
return {last_real, {ImaginaryKeyChainEValue{undefined_array_element, index, ""}}};
|
||||
}
|
||||
|
||||
JSON_reference JSON_reference::operator[](const std::string &key) {
|
||||
if (!imaginary_chain.empty()) {
|
||||
std::vector<ImaginaryKeyChainEValue> elongated = imaginary_chain;
|
||||
elongated.push_back({undefined_dictionary_element, 0, key});
|
||||
return {last_real, elongated};
|
||||
}
|
||||
if (last_real.isDictionary() && last_real.asDictionary().count(key) > 0) {
|
||||
return {last_real.asDictionary()[key], {}};
|
||||
}
|
||||
return {last_real, {ImaginaryKeyChainEValue{undefined_dictionary_element, 0, key}}};
|
||||
}
|
||||
|
||||
bool JSON_reference_const::isDefined() {
|
||||
return !bad;
|
||||
}
|
||||
|
||||
const JSON & JSON_reference_const::operator*() {
|
||||
return g();
|
||||
}
|
||||
|
||||
const JSON & JSON_reference_const::g() {
|
||||
if (bad)
|
||||
throw misuse("dereferencing const json reference with non-empty imaginary part");
|
||||
return last_real;
|
||||
}
|
||||
|
||||
JSON_reference_const JSON_reference_const::operator[](size_t index) {
|
||||
if (bad)
|
||||
return {last_real, true};
|
||||
if (last_real.isArray() && last_real.asArray().size() > index)
|
||||
return {last_real.asArray()[index], false};
|
||||
return {last_real, true};
|
||||
}
|
||||
|
||||
JSON_reference_const JSON_reference_const::operator[](const std::string &key) {
|
||||
if (bad)
|
||||
return {last_real, true};
|
||||
if (last_real.isDictionary() && last_real.asDictionary().count(key) > 0)
|
||||
return {last_real.asDictionary().at(key), false};
|
||||
return {last_real, true};
|
||||
}
|
||||
}
|
@ -31,20 +31,31 @@ void test_obvious(const JSON& A) {
|
||||
big[1] = A;
|
||||
test(big, A, false);
|
||||
big[0] = A;
|
||||
test(*big[0], *big[1], true);
|
||||
test(big[0], big[1], true);
|
||||
}
|
||||
|
||||
void ftest(int i) {
|
||||
JSON A;
|
||||
JSON B;
|
||||
A["aaa"][(size_t)i]["bbb"].g().asArray().push_back(JSON(jarr{JSON(""), JSON("")}));
|
||||
// B.asDictionary().
|
||||
A["aaa"][(size_t)i]["bbb"].asArray().push_back(JSON(jarr{JSON("Hihi"), JSON("Haha")}));
|
||||
A["aaa"][i]["bbb"][4]["hihi"].asInteger() = Integer(4123);
|
||||
B.asDictionary()["aaa"][(size_t)i].asDictionary()["bbb"][0][0].asString() = "Hihi";
|
||||
B.asDictionary()["aaa"][(size_t)i].asDictionary()["bbb"][0][1].asString() = "Haha";
|
||||
B["aaa"].asArray()[i]["bbb"][4].asDictionary()["hihi"] = JSON(4123l);
|
||||
prettyprint_json(A);
|
||||
prettyprint_json(B);
|
||||
test(A, B, true);
|
||||
}
|
||||
|
||||
int main() {
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
ftest(i);
|
||||
}
|
||||
int main(){
|
||||
json::JSON A;
|
||||
A[1].asString();
|
||||
A[0].asInteger();
|
||||
json::JSON B;
|
||||
B[0].asInteger();
|
||||
B[1].asString();
|
||||
test(A, B, true);
|
||||
return 0;
|
||||
test_obvious(parse_str_flawless("{ \"aaa\": true, \"2\":[true]}"));
|
||||
test_obvious(parse_str_flawless("{ \"aa\": true, \"tttt\": [true, false]}"));
|
||||
test_obvious(parse_str_flawless("[[[]]]"));
|
||||
@ -56,5 +67,8 @@ int main() {
|
||||
test(parse_str_flawless("132123123123123123123123123123123123"), parse_str_flawless("132123123123123123123123123123123123"), true);
|
||||
test(parse_str_flawless("{}"), parse_str_flawless("{}"), true);
|
||||
test(parse_str_flawless("{}"), parse_str_flawless("true"), false);
|
||||
for (int i = 0; i < 100; i += 10) {
|
||||
ftest(i);
|
||||
}
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user