来自C++ 标准库封装 Json结构极易扩展

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)},
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值