#ifndef TDGAME_CJ_HPP #define TDGAME_CJ_HPP #include #include #include #include #include struct customJson { struct Node { std::variant, std::map> value; Node() : value(nullptr) {} Node(bool b) : value(b) {} Node(double d) : value(d) {} Node(const std::string& s) : value(s) {} Node(const char* s) : value(std::string(s)) {} Node(std::vector a) : value(a) {} Node(std::map o) : value(o) {} // Accessors with type checking const std::map& as_object() const { return std::get>(value); } const std::vector& as_array() const { return std::get>(value); } const std::string& as_string() const { return std::get(value); } double as_double() const { return std::get(value); } bool as_bool() const { return std::get(value); } bool is_null() const { return std::holds_alternative(value); } // Convenience accessor const Node& at(const std::string& key) const { return as_object().at(key); } bool contains(const std::string& key) const { return as_object().count(key); } }; static void skip_whitespace(std::string::const_iterator& it, const std::string::const_iterator& end) { while (it != end && isspace(*it)) ++it; } static std::string parse_string(std::string::const_iterator& it, const std::string::const_iterator& end) { std::string result; if (*it == '"') ++it; while (it != end && *it != '"') { if (*it == '\\') { // Handle basic escapes ++it; if (it != end) result += *it; } else { result += *it; } ++it; } if (it != end && *it == '"') ++it; return result; } static Node parse_number_or_literal(std::string::const_iterator& it, const std::string::const_iterator& end) { std::string literal; while (it != end && (isalnum(*it) || *it == '.' || *it == '-')) { literal += *it; ++it; } if (literal == "true") return Node(true); if (literal == "false") return Node(false); if (literal == "null") return Node(nullptr); try { return Node(std::stod(literal)); } catch (...) { throw std::runtime_error("Invalid number or literal: " + literal); } } static std::vector parse_array(std::string::const_iterator& it, const std::string::const_iterator& end) { std::vector arr; if (*it == '[') ++it; skip_whitespace(it, end); while (it != end && *it != ']') { arr.push_back(parse_node(it, end)); skip_whitespace(it, end); if (it != end && *it == ',') { ++it; skip_whitespace(it, end); } } if (it != end && *it == ']') ++it; return arr; } static std::map parse_object(std::string::const_iterator& it, const std::string::const_iterator& end) { std::map obj; if (*it == '{') ++it; skip_whitespace(it, end); while (it != end && *it != '}') { std::string key = parse_string(it, end); skip_whitespace(it, end); if (it != end && *it == ':') ++it; skip_whitespace(it, end); obj[key] = parse_node(it, end); skip_whitespace(it, end); if (it != end && *it == ',') { ++it; skip_whitespace(it, end); } } if (it != end && *it == '}') ++it; return obj; } static Node parse_node(std::string::const_iterator& it, const std::string::const_iterator& end) { skip_whitespace(it, end); if (it == end) throw std::runtime_error("Unexpected end of input"); switch (*it) { case '{': return Node(parse_object(it, end)); case '[': return Node(parse_array(it, end)); case '"': return Node(parse_string(it, end)); default: return parse_number_or_literal(it, end); } } static Node parse(const std::string& json_str) { auto it = json_str.cbegin(); return parse_node(it, json_str.cend()); } }; #endif