#include "JsonValue.h" #include #include #include #include #include #include class JsonValue; //重载visited template struct overloaded : Ts... {using Ts::operator()...; }; template overloaded(Ts...) -> overloaded; JsonValue::JsonValue(): v(nullptr) {} JsonValue::JsonValue(const char* s): v(std::string(s)) {} JsonValue::JsonValue(const int& n): v(static_cast(n)) {} JsonValue::JsonValue(const std::nullptr_t& p): v(p) {} JsonValue::JsonValue(const bool& p): v(p) {} JsonValue::JsonValue(const std::vector& p): v(p) {} JsonValue::JsonValue(const std::map& p): v(p) {} JsonValue::JsonValue(const std::string& p): v(p) {} JsonValue::JsonValue(const double& p): v(p) {} JsonValue::JsonValue(Type type){ switch(type){ case Type::Null: v = nullptr; break; case Type::Bool: v = false; break; case Type::Double: v = 0.0; break; case Type::String: v = std::string(); break; case Type::List: v = std::vector(); break; case Type::Map: v = std::map(); break; } } bool JsonValue::is_nullptr() const{ if(std::holds_alternative(v)){ return true; } else { return false; } } bool JsonValue::is_bool() const{ if(std::holds_alternative(v)) return true; else return false; } bool JsonValue::is_double() const{ if(std::holds_alternative(v)) return true; else return false; } bool JsonValue::is_string() const{ if(std::holds_alternative(v)) return true; else return false; } bool JsonValue::is_list() const{ if(std::holds_alternative>(v)) return true; else return false; } bool JsonValue::is_map() const{ if(std::holds_alternative>(v)) return true; else return false; } const std::string& JsonValue::asString() const { if(auto* p = std::get_if(&(this->v))) return *p; throw std::runtime_error("JsonValue is not a string"); } bool JsonValue::asBool() const { if(auto* p = std::get_if(&(this->v))) return *p; throw std::runtime_error("JsonValue is not a bool type"); } double JsonValue::asDouble() const { if(auto* p = std::get_if(&(this->v))) return *p; throw std::runtime_error("JsonValue is not a double"); } std::vector JsonValue::asList() const { if(auto* p = std::get_if>(&v)) return *p; throw std::runtime_error("JsonValue is not a List"); } std::map JsonValue::asMap() const{ if(auto* p = std::get_if>(&v)) return *p; throw std::runtime_error("JsonValue is not a Map"); } JsonValue& JsonValue::operator[] (int idx) { if(!is_list()) v = std::vector(); return std::get>(v).at(idx); } const JsonValue& JsonValue::operator[] (int idx) const { if(!is_list()) throw std::runtime_error("JsonValue is not a list(vector)"); return std::get>(v).at(idx); } void JsonValue::push_back(const JsonValue& val){ if(!std::holds_alternative>(v)){ throw std::runtime_error("Not a list"); } std::get>(v).push_back(val); } JsonValue& JsonValue::operator[] (const std::string& key){ if(is_nullptr()) v = std::map(); if(!is_map()) throw std::runtime_error("JsonValue is not a map"); return std::get>(v)[key]; } const JsonValue& JsonValue::operator[] (const std::string& key) const{ if (auto p = std::get_if>(&v)){ auto it = p->find(key); if (it != p->end()){ return it->second; } throw std::runtime_error("Key is not found" + key); } throw std::runtime_error("JsonValue is not a object(map)"); } void JsonValue::print() const{ //递归打印 vector, map /* static auto recursive_print = [](auto& self, const JsonValue& jval, int indent) -> void { std::string space(indent, ' '); // 缩进几个 }; */ std::visit(overloaded { [&](std::nullptr_t) {std::cout << "null"; }, [&](bool val) {std::cout << (val ? "true" : "false"); }, [&](double val) {std::cout << val; }, [&](const std::string& val) {std::cout << "\"" << val << "\"";}, [&](const std::vector& vec) { std::cout << "["; for(size_t i = 0; i < vec.size(); ++i){ vec[i].print(); if (i < vec.size() - 1) std::cout << ","; //std::cout << "\n"; } std::cout << "]"; }, [&](const std::map& mp) { std::cout << "{" ; for(auto it = mp.begin(); it != mp.end(); ++it){ std::cout << "\"" << it->first << "\":"; it->second.print(); if(std::next(it) != mp.end()) std::cout << ","; } std::cout << "}" ; } }, v); }