Skip to content

Commit 45e4037

Browse files
Fix long long json serialization (#728)
* Fix long long json serialization * Update pod.hpp
1 parent ebef1e9 commit 45e4037

3 files changed

Lines changed: 95 additions & 0 deletions

File tree

include/cereal/archives/json.hpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,13 @@ namespace cereal
261261
//! Saves a nullptr to the current node
262262
void saveValue(std::nullptr_t) { itsWriter.Null(); }
263263

264+
template <class T> inline
265+
typename std::enable_if<!std::is_same<T, int64_t>::value && std::is_same<T, long long>::value, void>::type
266+
saveValue(T val) { itsWriter.Int64(val); }
267+
template <class T> inline
268+
typename std::enable_if<!std::is_same<T, uint64_t>::value && std::is_same<T, unsigned long long>::value, void>::type
269+
saveValue(T val) { itsWriter.Uint64(val); }
270+
264271
private:
265272
// Some compilers/OS have difficulty disambiguating the above for various flavors of longs, so we provide
266273
// special overloads to handle these cases.
@@ -310,6 +317,8 @@ namespace cereal
310317
!std::is_same<T, unsigned long>::value,
311318
!std::is_same<T, std::int64_t>::value,
312319
!std::is_same<T, std::uint64_t>::value,
320+
!std::is_same<T, long long>::value,
321+
!std::is_same<T, unsigned long long>::value,
313322
(sizeof(T) >= sizeof(long double) || sizeof(T) >= sizeof(long long))> = traits::sfinae> inline
314323
void saveValue(T const & t)
315324
{
@@ -659,6 +668,12 @@ namespace cereal
659668
//! Loads a nullptr from the current node
660669
void loadValue(std::nullptr_t&) { search(); CEREAL_RAPIDJSON_ASSERT(itsIteratorStack.back().value().IsNull()); ++itsIteratorStack.back(); }
661670

671+
template <class T> inline
672+
typename std::enable_if<!std::is_same<T, int64_t>::value && std::is_same<T, long long>::value, void>::type
673+
loadValue(T & val) { search(); val = itsIteratorStack.back().value().GetInt64(); ++itsIteratorStack.back(); }
674+
template <class T> inline
675+
typename std::enable_if<!std::is_same<T, uint64_t>::value && std::is_same<T, unsigned long long>::value, void>::type
676+
loadValue(T & val) { search(); val = itsIteratorStack.back().value().GetUint64(); ++itsIteratorStack.back(); }
662677
// Special cases to handle various flavors of long, which tend to conflict with
663678
// the int32_t or int64_t on various compiler/OS combinations. MSVC doesn't need any of this.
664679
#ifndef _MSC_VER
@@ -714,6 +729,8 @@ namespace cereal
714729
!std::is_same<T, unsigned long>::value,
715730
!std::is_same<T, std::int64_t>::value,
716731
!std::is_same<T, std::uint64_t>::value,
732+
!std::is_same<T, long long>::value,
733+
!std::is_same<T, unsigned long long>::value,
717734
(sizeof(T) >= sizeof(long double) || sizeof(T) >= sizeof(long long))> = traits::sfinae>
718735
inline void loadValue(T & val)
719736
{

unittests/pod.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,14 @@ TEST_CASE("json_pod")
4949
test_pod<cereal::JSONInputArchive, cereal::JSONOutputArchive>();
5050
}
5151

52+
TEST_CASE("xml_pod_serialization")
53+
{
54+
test_pod_serialization<cereal::XMLInputArchive, cereal::XMLOutputArchive>();
55+
}
56+
57+
TEST_CASE("json_pod_serialization")
58+
{
59+
test_pod_serialization<cereal::JSONInputArchive, cereal::JSONOutputArchive>();
60+
}
61+
5262
TEST_SUITE_END();

unittests/pod.hpp

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,4 +144,72 @@ void test_pod()
144144
}
145145
}
146146

147+
template <class IArchive, class OArchive, class T1, class T2>
148+
void test_pod_serialization(std::mt19937& gen)
149+
{
150+
T1 const o_t1 = random_value<T1>(gen);
151+
T2 const o_t2 = o_t1;
152+
153+
std::ostringstream os1;
154+
{
155+
OArchive oar(os1);
156+
oar(o_t1);
157+
}
158+
159+
std::ostringstream os2;
160+
{
161+
OArchive oar(os2);
162+
oar(o_t2);
163+
}
164+
165+
CHECK_EQ(os1.str(), os2.str());
166+
167+
T1 i_t1 = T1();
168+
T2 i_t2 = T2();
169+
CHECK_EQ(os1.str(), os2.str());
170+
std::istringstream is1(os1.str());
171+
{
172+
IArchive iar(is1);
173+
iar(i_t1);
174+
}
175+
CHECK_EQ(o_t1, i_t1);
176+
177+
std::istringstream is2(os2.str());
178+
{
179+
IArchive iar(is2);
180+
iar(i_t2);
181+
}
182+
CHECK_EQ(o_t2, i_t2);
183+
}
184+
185+
template <class IArchive, class OArchive>
186+
void test_pod_serialization()
187+
{
188+
std::random_device rd;
189+
std::mt19937 gen(rd());
190+
for (size_t i = 0; i < 100; ++i) {
191+
test_pod_serialization<IArchive, OArchive, int8_t, int16_t>(gen);
192+
test_pod_serialization<IArchive, OArchive, uint8_t, uint16_t>(gen);
193+
194+
test_pod_serialization<IArchive, OArchive, int8_t, int32_t>(gen);
195+
test_pod_serialization<IArchive, OArchive, uint8_t, uint32_t>(gen);
196+
197+
test_pod_serialization<IArchive, OArchive, int8_t, int64_t>(gen);
198+
test_pod_serialization<IArchive, OArchive, uint8_t, uint64_t>(gen);
199+
200+
test_pod_serialization<IArchive, OArchive, int8_t, long>(gen);
201+
test_pod_serialization<IArchive, OArchive, uint8_t, unsigned long>(gen);
202+
203+
test_pod_serialization<IArchive, OArchive, int8_t, long long>(gen);
204+
test_pod_serialization<IArchive, OArchive, uint8_t, unsigned long long>(
205+
gen);
206+
207+
test_pod_serialization<IArchive, OArchive, int8_t, int>(gen);
208+
test_pod_serialization<IArchive, OArchive, uint8_t, unsigned int>(gen);
209+
210+
test_pod_serialization<IArchive, OArchive, int8_t, short>(gen);
211+
test_pod_serialization<IArchive, OArchive, uint8_t, unsigned short>(gen);
212+
}
213+
}
214+
147215
#endif // CEREAL_TEST_POD_H_

0 commit comments

Comments
 (0)