From 45e40375b60c8c59cb6f13405d0fdc40c1d8ecf8 Mon Sep 17 00:00:00 2001 From: CHP Date: Mon, 14 Mar 2022 21:29:42 +0100 Subject: [PATCH] Fix long long json serialization (#728) * Fix long long json serialization * Update pod.hpp --- include/cereal/archives/json.hpp | 17 ++++++++ unittests/pod.cpp | 10 +++++ unittests/pod.hpp | 68 ++++++++++++++++++++++++++++++++ 3 files changed, 95 insertions(+) diff --git a/include/cereal/archives/json.hpp b/include/cereal/archives/json.hpp index 199efc94..ff8c2ef9 100644 --- a/include/cereal/archives/json.hpp +++ b/include/cereal/archives/json.hpp @@ -261,6 +261,13 @@ namespace cereal //! Saves a nullptr to the current node void saveValue(std::nullptr_t) { itsWriter.Null(); } + template inline + typename std::enable_if::value && std::is_same::value, void>::type + saveValue(T val) { itsWriter.Int64(val); } + template inline + typename std::enable_if::value && std::is_same::value, void>::type + saveValue(T val) { itsWriter.Uint64(val); } + private: // Some compilers/OS have difficulty disambiguating the above for various flavors of longs, so we provide // special overloads to handle these cases. @@ -310,6 +317,8 @@ namespace cereal !std::is_same::value, !std::is_same::value, !std::is_same::value, + !std::is_same::value, + !std::is_same::value, (sizeof(T) >= sizeof(long double) || sizeof(T) >= sizeof(long long))> = traits::sfinae> inline void saveValue(T const & t) { @@ -659,6 +668,12 @@ namespace cereal //! Loads a nullptr from the current node void loadValue(std::nullptr_t&) { search(); CEREAL_RAPIDJSON_ASSERT(itsIteratorStack.back().value().IsNull()); ++itsIteratorStack.back(); } + template inline + typename std::enable_if::value && std::is_same::value, void>::type + loadValue(T & val) { search(); val = itsIteratorStack.back().value().GetInt64(); ++itsIteratorStack.back(); } + template inline + typename std::enable_if::value && std::is_same::value, void>::type + loadValue(T & val) { search(); val = itsIteratorStack.back().value().GetUint64(); ++itsIteratorStack.back(); } // Special cases to handle various flavors of long, which tend to conflict with // the int32_t or int64_t on various compiler/OS combinations. MSVC doesn't need any of this. #ifndef _MSC_VER @@ -714,6 +729,8 @@ namespace cereal !std::is_same::value, !std::is_same::value, !std::is_same::value, + !std::is_same::value, + !std::is_same::value, (sizeof(T) >= sizeof(long double) || sizeof(T) >= sizeof(long long))> = traits::sfinae> inline void loadValue(T & val) { diff --git a/unittests/pod.cpp b/unittests/pod.cpp index e4048dbd..0c8d377f 100644 --- a/unittests/pod.cpp +++ b/unittests/pod.cpp @@ -49,4 +49,14 @@ TEST_CASE("json_pod") test_pod(); } +TEST_CASE("xml_pod_serialization") +{ + test_pod_serialization(); +} + +TEST_CASE("json_pod_serialization") +{ + test_pod_serialization(); +} + TEST_SUITE_END(); diff --git a/unittests/pod.hpp b/unittests/pod.hpp index ad6894b5..a4ad8361 100644 --- a/unittests/pod.hpp +++ b/unittests/pod.hpp @@ -144,4 +144,72 @@ void test_pod() } } +template +void test_pod_serialization(std::mt19937& gen) +{ + T1 const o_t1 = random_value(gen); + T2 const o_t2 = o_t1; + + std::ostringstream os1; + { + OArchive oar(os1); + oar(o_t1); + } + + std::ostringstream os2; + { + OArchive oar(os2); + oar(o_t2); + } + + CHECK_EQ(os1.str(), os2.str()); + + T1 i_t1 = T1(); + T2 i_t2 = T2(); + CHECK_EQ(os1.str(), os2.str()); + std::istringstream is1(os1.str()); + { + IArchive iar(is1); + iar(i_t1); + } + CHECK_EQ(o_t1, i_t1); + + std::istringstream is2(os2.str()); + { + IArchive iar(is2); + iar(i_t2); + } + CHECK_EQ(o_t2, i_t2); +} + +template +void test_pod_serialization() +{ + std::random_device rd; + std::mt19937 gen(rd()); + for (size_t i = 0; i < 100; ++i) { + test_pod_serialization(gen); + test_pod_serialization(gen); + + test_pod_serialization(gen); + test_pod_serialization(gen); + + test_pod_serialization(gen); + test_pod_serialization(gen); + + test_pod_serialization(gen); + test_pod_serialization(gen); + + test_pod_serialization(gen); + test_pod_serialization( + gen); + + test_pod_serialization(gen); + test_pod_serialization(gen); + + test_pod_serialization(gen); + test_pod_serialization(gen); + } +} + #endif // CEREAL_TEST_POD_H_