From 0d2fefbfb00995e25dc44c87d12599c60e3da75a Mon Sep 17 00:00:00 2001 From: Andreev Gregory Date: Tue, 27 Aug 2024 15:30:23 +0300 Subject: [PATCH] Fixed everything --- building/main.cpp | 1 - src/library/jsonincpp/integer.cpp | 2 + src/library/jsonincpp/jsonobj.cpp | 8 -- src/library/jsonincpp/jsonobj.h | 63 +------------- src/library/jsonincpp/parser.cpp | 10 +-- src/library/jsonincpp/quality_of_life.cpp | 68 ++++++--------- src/library/jsonincpp/quality_of_life_2.cpp | 94 --------------------- src/tests/test0.cpp | 28 ++++-- 8 files changed, 60 insertions(+), 214 deletions(-) delete mode 100644 src/library/jsonincpp/quality_of_life_2.cpp diff --git a/building/main.cpp b/building/main.cpp index af9a7b3..50cbb2e 100644 --- a/building/main.cpp +++ b/building/main.cpp @@ -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", diff --git a/src/library/jsonincpp/integer.cpp b/src/library/jsonincpp/integer.cpp index 31512d3..f9de92e 100644 --- a/src/library/jsonincpp/integer.cpp +++ b/src/library/jsonincpp/integer.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); diff --git a/src/library/jsonincpp/jsonobj.cpp b/src/library/jsonincpp/jsonobj.cpp index ced9981..d14796b 100644 --- a/src/library/jsonincpp/jsonobj.cpp +++ b/src/library/jsonincpp/jsonobj.cpp @@ -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}; - } } diff --git a/src/library/jsonincpp/jsonobj.h b/src/library/jsonincpp/jsonobj.h index 0017b88..b33660d 100644 --- a/src/library/jsonincpp/jsonobj.h +++ b/src/library/jsonincpp/jsonobj.h @@ -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 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& 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 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 diff --git a/src/library/jsonincpp/parser.cpp b/src/library/jsonincpp/parser.cpp index 8af7f80..29613a7 100644 --- a/src/library/jsonincpp/parser.cpp +++ b/src/library/jsonincpp/parser.cpp @@ -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") { diff --git a/src/library/jsonincpp/quality_of_life.cpp b/src/library/jsonincpp/quality_of_life.cpp index 1c83000..2ce823d 100644 --- a/src/library/jsonincpp/quality_of_life.cpp +++ b/src/library/jsonincpp/quality_of_life.cpp @@ -87,7 +87,9 @@ namespace json { value = new Integer(); type = integer; } - return const_cast(const_cast(this)->asInteger()); + if (isInteger()) + return const_cast(const_cast(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; } - return const_cast(const_cast(this)->asString()); + if (isString()) + return const_cast(const_cast(this)->asString()); + throw misuse("JSON::asString() can't convert non-null to string"); } std::vector &JSON::asArray() { @@ -103,7 +107,9 @@ namespace json { value = new ArrayData(); type = array; } - return const_cast&>(const_cast(this)->asArray()); + if (isArray()) + return const_cast&>(const_cast(this)->asArray()); + throw misuse("JSON::asArray() can't convert non-null to array"); } std::map &JSON::asDictionary() { @@ -111,54 +117,36 @@ namespace json { value = new DictionaryData(); type = dictionary; } - return const_cast&>(const_cast(this)->asDictionary()); + if (isDictionary()) + return const_cast&>(const_cast(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& 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& 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(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 { diff --git a/src/library/jsonincpp/quality_of_life_2.cpp b/src/library/jsonincpp/quality_of_life_2.cpp deleted file mode 100644 index 7e4034d..0000000 --- a/src/library/jsonincpp/quality_of_life_2.cpp +++ /dev/null @@ -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 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 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}; - } -} diff --git a/src/tests/test0.cpp b/src/tests/test0.cpp index f635e73..122a45a 100644 --- a/src/tests/test0.cpp +++ b/src/tests/test0.cpp @@ -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; } \ No newline at end of file