Skip to content

Instantly share code, notes, and snippets.

@Enhex
Created June 5, 2016 17:15
Show Gist options
  • Save Enhex/293382d1504b6a1febcdb45569aa7a15 to your computer and use it in GitHub Desktop.
Save Enhex/293382d1504b6a1febcdb45569aa7a15 to your computer and use it in GitHub Desktop.
#include <unordered_map>
#include <cereal\types\unordered_map.hpp>
#include <cereal\archives\json.hpp>
#include <cereal\details\traits.hpp>
#include <fstream>
class Test
{
public:
std::unordered_map<std::string, int> map_int;
std::unordered_map<std::string, float> map_float;
std::unordered_map<std::string, std::string> map_string;
// serialize
template<class Archive,
cereal::traits::EnableIf<cereal::traits::is_text_archive<Archive>::value>
= cereal::traits::sfinae>
void save(Archive & archive) const
{
// Only serialize non-empty members
if (!map_int.empty())
archive(CEREAL_NVP(map_int));
if (!map_float.empty())
archive(CEREAL_NVP(map_float));
if (!map_string.empty())
archive(CEREAL_NVP(map_string));
}
template<class Archive,
cereal::traits::EnableIf<cereal::traits::is_text_archive<Archive>::value>
= cereal::traits::sfinae>
void load(Archive & archive)
{
// Ignore missing members
try { archive(CEREAL_NVP(map_int)); } catch (cereal::Exception) {}
try { archive(CEREAL_NVP(map_float)); } catch (cereal::Exception) {}
try { archive(CEREAL_NVP(map_string)); } catch (cereal::Exception) {}
}
// Handle binary normally since it can't load out of order
template<class Archive,
cereal::traits::DisableIf<cereal::traits::is_text_archive<Archive>::value>
= cereal::traits::sfinae>
void serialize(Archive & archive)
{
archive(CEREAL_NVP(map_int),
CEREAL_NVP(map_float),
CEREAL_NVP(map_string));
}
};
class TestClass
{
public:
int x;
Test test;
template <class Archive>
void serialize(Archive & archive)
{
archive(CEREAL_NVP(x),
CEREAL_NVP(test)); // Last value has optional last element. If it wasn't last there would be no exception
}
};
int main()
{
{
Test test;
test.map_int["one"] = 1;
test.map_float["one"] = 1;
//test.map_string["asdf"] = "fdsa"; // last element is missing. If it wasn't last there would be no exception
TestClass testClass;
testClass.x = 10;
testClass.test = test;
/* Would throw too
std::unordered_map<std::string, TestClass> m;
m["a"] = testClass; // last element is missing, and there are more elements afterwards. If it was the last element there would be no exception
m["b"] = testClass;
*/
std::unordered_map<std::string, Test> m;
m["a"] = test; // last element is missing, and there are more elements afterwards. If it was the last element there would be no exception
m["b"] = test;
std::ofstream os("test.json");
cereal::JSONOutputArchive outArchive(os);
outArchive(CEREAL_NVP(m));
}
/*
If the JSON contains a non-last node of a class that its last value is optional and missing, cereal would throw exception
*/
//Test test;
//std::unordered_map<std::string, TestClass> m;
std::unordered_map<std::string, Test> m;
std::ifstream is("test.json");
cereal::JSONInputArchive inArchive(is);
inArchive(CEREAL_NVP(m));
//std::cout << testClass.test.map_string["asdf"] << std::endl;
//std::cout << testClass.test.map_int["one"] << std::endl;
// pause
int p; std::cin >> p;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment