nlohmann/json Modern C++ 用の JSON
#include <iostream>
#include <fstream>
#include <vector>
#include <optional>
#include "json.hpp"
namespace nl = nlohmann;
enum class TestEnum : int {
Left = 0,
Right
};
struct SubTestStruct {
int test = 0;
};
struct TestStruct {
int test = 0;
bool testBool = false;
TestEnum testEnum = TestEnum::Left;
std::optional<bool> testOpt;
std::vector<int> testVec;
SubTestStruct subTestStruct;
};
// nl does not directly support optional, using adl_serializer can support serialization of any type
// https://github.com/nlohmann/json/pull/2117
// https://github.com/nlohmann/json#how-do-i-convert-third-party-types
namespace nlohmann {
template <typename T>
struct adl_serializer<std::optional<T>> {
static void to_json(json& j, const std::optional<T>& opt) {
if (opt == std::nullopt) {
j = nullptr;
} else {
j = *opt; // this will call adl_serializer<T>::to_json which will
// find the free function to_json in T's namespace!
}
}
static void from_json(const json& j, std::optional<T>& opt) {
if (j.is_null()) {
opt = std::nullopt;
} else {
opt = j.get<T>(); // same as above, but with
// adl_serializer<T>::from_json
}
}
};
}
// Serialize struct, class
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(SubTestStruct, test)
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(TestStruct, test, testBool, testEnum, testOpt, testVec, subTestStruct)
// Serialize enum
NLOHMANN_JSON_SERIALIZE_ENUM(TestEnum, {
{TestEnum::Left, "Left"},
{TestEnum::Right, "Right"},
})
void printTest(const TestStruct& s) {
nl::json jsonValue;
nl::to_json(jsonValue, s);
std::cout << "TestStruct test: " << s.test
<< ", testBool: " << s.testBool
<< ", testEnum: " << (int) s.testEnum
<< ", testOpt: " << (s.testOpt.has_value() && s.testOpt.value())
<< ", testVec: { ";
for(auto val : s.testVec) {
std::cout << val << ",";
}
std::cout << "\b" << " }";
std::cout << ", subTestStruct.test: " << s.subTestStruct.test;
std::cout << std::endl;
}
int main() {
// Write
std::ofstream sf("config.json");
nl::json j;
TestStruct s;
s.test = 100;
s.testOpt = true;
for(int i = 0; i < 5; ++i) {
s.testVec.push_back(i);
}
s.subTestStruct.test = 99;
printTest(s);
nl::to_json(j, s);
// Get a single value separately
std::cout << "Json value: " << j["test"] << std::endl;
// Write to file
sf << j;
sf.close();
// Read
std::ifstream is("config.json");
nl::json readJson;
is >> readJson;
TestStruct newS = readJson.get<TestStruct>();
// nl::from_json(readJson, newS);
printTest(newS);
is.close();
return 0;
}
Note: nl_json is a utf-8 only library, please be aware of encoding when using it in Chinese.