json.h
#ifndef JSON_H
#define JSON_H
#include <any>
#include <map>
#include <string>
#include <sstream>
#include <vector>
#include <iomanip>
namespace std
{
template<class T>
static bool any_same(const any &val) {
if (typeid(T) == val.type())
return true;
return false;
}
std::string to_string_kpw(float val)
{
std::stringstream ss;
ss.flags(ios::left|ios::fixed);
ss.precision(7);
ss.fill('0');
ss.width(7);
ss << val;
return ss.str();
};
std::string to_string_kpw(double val)
{
std::stringstream ss;
ss.flags(ios::left|ios::fixed);
ss.precision(16);
ss.fill('0');
ss.precision(16);
ss << val;
return ss.str();
};
std::string to_string_kpw(long double val)
{
std::stringstream ss;
ss.flags(ios::left|ios::fixed);
ss.precision(19);
ss.fill('0');
ss.width(19);
ss << val;
return ss.str();
};
}
namespace Json {
struct Value;
struct Array : std::vector<Value>
{
Array() = default;
Array(const std::initializer_list<value_type> &list) : std::vector<Value>(list) {}
std::string toJsonStr() const;
};
struct Object : std::map<std::string, Value>
{
Object() = default;
Object(const std::initializer_list<value_type> &list)
: std::map<std::string, Value>(list) {}
std::string toJsonStr() const;
};
struct Value : std::any
{
Value() = default;
Value(char val) : std::any(val){}
Value(short val) : std::any(val){}
Value(int val) : std::any(val){}
Value(long val) : std::any(val){}
Value(float val) : std::any(val){}
Value(double val) : std::any(val){}
Value(long double val) :std::any(val){}
Value(const std::string &val) : std::any(val){}
Value(const char *val) : std::any(std::string(val)){}
Value(const Array &val) : std::any(val){}
Value(const Object &val) : std::any(val){}
bool isChar() const { return std::any_same<char>(*this); }
bool isShort() const { return std::any_same<short>(*this); }
bool isInt() const { return std::any_same<int>(*this); }
bool isLong() const { return std::any_same<long>(*this); }
bool isFloat() const { return std::any_same<float>(*this); }
bool isDouble() const { return std::any_same<double>(*this); }
bool isLDouble() const {return std::any_same<long double>(*this); }
bool isStdString() const { return std::any_same<std::string>(*this); }
bool isArray() const { return std::any_same<Array>(*this); }
bool isObject() const { return std::any_same<Object>(*this);}
char toChar() const { return std::any_cast<char>(*this); }
short toShort() const { return std::any_cast<short>(*this); }
int toInt() const { return std::any_cast<int>(*this); }
long toLong() const { return std::any_cast<long>(*this); }
float toFloat() const { return std::any_cast<float>(*this); }
double toDouble() const { return std::any_cast<double>(*this); }
long double toLDouble() const { return std::any_cast<long double>(*this); }
std::string toStdString() const { return std::any_cast<std::string>(*this); }
Array toArray() const { return std::any_cast<Array>(*this); }
Object toObject() const {return std::any_cast<Object>(*this); }
unsigned char toUChar() const { return std::any_cast<char>(*this); }
unsigned short toUShort() const { return std::any_cast<short>(*this); }
unsigned int toUInt() const { return std::any_cast<int>(*this); }
unsigned long toULong() const { return std::any_cast<long>(*this); }
signed char toSChar() const { return std::any_cast<char>(*this); }
signed short toSShort() const { return std::any_cast<short>(*this); }
signed int toSInt() const { return std::any_cast<int>(*this); }
signed long toSLong() const { return std::any_cast<long>(*this); }
std::string toJsonStr() const {
if (isChar()) return std::to_string(toChar());
if (isShort()) return std::to_string(toShort());
if (isInt()) return std::to_string(toInt());
if (isLong()) return std::to_string(toLong());
if (isFloat()) return std::to_string_kpw(toFloat());
if (isDouble()) return std::to_string_kpw(toDouble());
if (isLDouble()) return std::to_string_kpw(toLDouble());
if (isStdString()) return "\"" + toStdString() + "\"";
if (isArray()) return toArray().toJsonStr();
if (isObject()) return toObject().toJsonStr();
return "null";
}
};
std::string Array::toJsonStr() const
{
auto itera = begin();
std::string ret = "[" + itera->toJsonStr();
itera ++;
while (itera != end())
{
ret += ",";
ret += itera->toJsonStr();
itera ++;
}
ret += "]";
return ret;
}
inline std::string Object::toJsonStr() const
{
std::string ret;
auto formatKey = [=](const std::string &key) -> std::string
{ return "\"" + key + "\""; };
auto itera = begin();
ret += "{";
ret += formatKey(itera->first) + ":" + itera->second.toJsonStr();
itera ++;
while (itera != end())
{
ret += ",";
ret += formatKey(itera->first) + ":" + itera->second.toJsonStr();
itera ++;
}
ret += "}";
return ret;
}
}
#endif // JSON_H
main.cpp 使用方法
#include "json.h"
#include <iostream>
int main(int argc, char *argv[])
{
Json::Object obj;
obj.insert({"hello", ""});
Json::Array array{1,2,3,4,5,6};
std::cout << array.toJsonStr() << std::endl;
obj.insert({"array", array});
obj["array2"] = array;
Json::Object obj2
{
{"array", Json::Array{5,6,7}},
{"null", {}},
{"string", "this test"},
{"float", float(0.0000001)},
{"double", double(0.0000000000000001)},
{"long double", (long double)(0.0000000000000000001)},
{"int", 10},
{"sint", -10},
{"char", 'a'},
};
std::cout << obj.toJsonStr() << std::endl;
std::cout << obj2.toJsonStr() << std::endl;
return 0;
}
输出如下:
[1,2,3,4,5,6]
{"array":[1,2,3,4,5,6],"array2":[1,2,3,4,5,6],"hello":""}
{"array":[5,6,7],"char":97,"double":0.0000000000000001,"float":0.0000001,"int":10,"long double":0.0000000000000000001,"null":null,"sint":-10,"string":"this test"}
注:隐式构造会优先 std::any 规则,与默认语法一致,使用时最好使用强类型
,如:
{"float", float(0.0000001)},
{"double", double(0.0000000000000001)},
{"long double", (long double)(0.0000000000000000001)},