#include #include "value.h" namespace json { Value::Value() { _type = NullType; _data = "null"; } Value::Value(bool_type const &value) { _type = BoolType; _data = value; } Value::Value(int const &value) { _type = IntType; _data = (int_type)value; } Value::Value(int_type const &value) { _type = IntType; _data = value; } Value::Value(decimal_type const &value) { _type = DecimalType; _data = value; } Value::Value(string_type const &value) { _type = StringType; _data = value; } Value::Value(const char *value) { _type = StringType; _data = std::string(value); } Value::Value(list_type const &value) { _type = ListType; _data = value; } Value::Value(dict_type const &value) { _type = DictType; _data = value; } void *Value::_value() { switch (_type) { case NullType: // null: value, type_id, variant has no in it. return std::get_if(&_data); case BoolType: return std::get_if(&_data); case IntType: return std::get_if(&_data); case DecimalType: return std::get_if(&_data); case StringType: return std::get_if(&_data); case ListType: return std::get_if(&_data); case DictType: return std::get_if(&_data); default: // will not be here throw std::logic_error("Got an unrecognized type_id"); } } constexpr TYPE Value::type_id() const { return _type; } std::string Value::type_name() const { return _typeIdToName[_type]; } constexpr bool Value::is_basic() const { return _type == NullType || _type == BoolType || _type == IntType || _type == DecimalType || _type == StringType; } std::string Value::str(bool const &format_need, int const &indent, int layer) { void *v = _value(); std::ostringstream buff; switch (_type) { case NullType: buff << "null"; break; case BoolType: if (GET_VALUE(bool_type, v)) buff << "true"; else buff << "false"; break; case IntType: buff << GET_VALUE(int_type, v); break; case DecimalType: buff << GET_VALUE(decimal_type, v); break; case StringType: buff << '"' << GET_VALUE(string_type, v) << '"'; break; case ListType: { list_type &list = GET_VALUE(list_type, v); buff << '['; bool first = true; for (Value &item: list) { if (first) { first = false; if (format_need) buff << item.str(format_need, indent, layer + 1); else buff << item.str(); } else { if (format_need) buff << ", " << item.str(format_need, indent, layer + 1); else buff << ',' << item.str(); } } buff << ']'; break; } case DictType: { dict_type &dict = GET_VALUE(dict_type, v); if (format_need) { buff << "{\n"; for (auto it = dict.begin(); it != dict.end(); ++it) { if (it != dict.begin()) buff << ",\n"; for (int i = 0; i < layer * indent; ++i) buff << ' '; buff << '"' << it->first << "\": " << it->second.str(format_need, indent, layer + 1); } buff << '\n'; for (int i = 0; i < (layer - 1) * indent; ++i) buff << ' '; buff << '}'; } else { buff << '{'; for (auto it = dict.begin(); it != dict.end(); it++) { if (it != dict.begin()) buff << ','; buff << '"' << it->first << "\":" << it->second.str(); } buff << '}'; } break; } default: // will not be here throw std::logic_error("Got an unrecognized type_id"); } return buff.str(); } void Value::push_back(Value const &val) { auto &list = value(); list.push_back(val); } void Value::pop_back() { auto &list = value(); list.pop_back(); } void Value::erase(int const &index) { auto &list = value(); list.erase(list.begin() + index); } void Value::erase(std::string const &key) { auto &dict = value(); if (dict.find(key) != dict.end()) dict.erase(key); } Value &Value::operator[](int const &index) { auto &list = value(); return list.at(index); } Value &Value::operator[](std::string const &key) { auto &dict = value(); return dict[key]; } }