diff --git a/binary_archive/tuple.hpp b/binary_archive/tuple.hpp index 24f22275..39c0b3b6 100644 --- a/binary_archive/tuple.hpp +++ b/binary_archive/tuple.hpp @@ -10,17 +10,25 @@ namespace cereal namespace tuple_detail { // unwinds a tuple to save it - template inline - void serialize( Archive & ar, std::tuple & tuple ) + template + struct serialize { - ar & std::get( tuple ); - serialize( ar, tuple ); - } + template inline + static void apply( Archive & ar, std::tuple & tuple ) + { + ar & std::get( tuple ); + serialize::template apply( ar, tuple ); + } + }; // Zero height specialization - nothing to do here - template inline - void serialize<0, Types...>( Archive & ar, std::tuple & tuple ) - { } + template <> + struct serialize<0> + { + template inline + static void apply( Archive & ar, std::tuple & tuple ) + { } + }; } //! Serializing for std::tuple to binary @@ -28,7 +36,7 @@ namespace cereal CEREAL_ARCHIVE_RESTRICT_SERIALIZE(BinaryInputArchive, BinaryOutputArchive) serialize( Archive & ar, std::tuple & tuple ) { - tuple_size::serialize>>( ar, tuple ); + tuple_detail::serialize>::value>::template apply( ar, tuple ); } } // namespace cereal diff --git a/unittests.cpp b/unittests.cpp index f586c579..a9246009 100644 --- a/unittests.cpp +++ b/unittests.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -1607,3 +1608,62 @@ BOOST_AUTO_TEST_CASE( binary_pair ) } } +// ###################################################################### +BOOST_AUTO_TEST_CASE( binary_tuple ) +{ + std::random_device rd; + std::mt19937 gen(rd()); + + auto rng = [&](){ return random_value(gen); }; + + for(int i=0; i<100; ++i) + { + std::ostringstream os; + cereal::BinaryOutputArchive oar(os); + + auto o_podtuple = std::make_tuple( rng(), rng(), rng(), rng() ); + auto o_isertuple = std::make_tuple( StructInternalSerialize( rng(), rng() ), + StructInternalSerialize( rng(), rng() ), + StructInternalSerialize( rng(), rng() ), + StructInternalSerialize( rng(), rng() ) ); + auto o_ispltuple = std::make_tuple( StructInternalSplit( rng(), rng() ), + StructInternalSplit( rng(), rng() ), + StructInternalSplit( rng(), rng() ), + StructInternalSplit( rng(), rng() ) ); + auto o_esertuple = std::make_tuple( StructExternalSerialize( rng(), rng() ), + StructExternalSerialize( rng(), rng() ), + StructExternalSerialize( rng(), rng() ), + StructExternalSerialize( rng(), rng() ) ); + auto o_espltuple = std::make_tuple( StructExternalSerialize( rng(), rng() ), + StructExternalSerialize( rng(), rng() ), + StructExternalSerialize( rng(), rng() ), + StructExternalSerialize( rng(), rng() ) ); + + oar & o_podtuple; + oar & o_isertuple; + oar & o_ispltuple; + oar & o_esertuple; + oar & o_espltuple; + + std::istringstream is(os.str()); + cereal::BinaryInputArchive iar(is); + + decltype( o_podtuple ) i_podtuple; + decltype( o_isertuple ) i_isertuple; + decltype( o_ispltuple ) i_ispltuple; + decltype( o_esertuple ) i_esertuple; + decltype( o_espltuple ) i_espltuple; + + iar & i_podtuple; + iar & i_isertuple; + iar & i_ispltuple; + iar & i_esertuple; + iar & i_espltuple; + + BOOST_CHECK_EQUAL( i_podtuple == o_podtuple, true ); + BOOST_CHECK_EQUAL( i_isertuple == o_isertuple, true ); + BOOST_CHECK_EQUAL( i_ispltuple == o_ispltuple, true ); + BOOST_CHECK_EQUAL( i_esertuple == o_esertuple, true ); + BOOST_CHECK_EQUAL( i_espltuple == o_espltuple, true ); + } +}