From db0f1cf47fabcebf46a3823c086d08a1b67a5abc Mon Sep 17 00:00:00 2001 From: Shane Grant Date: Fri, 6 Sep 2013 16:33:23 -0700 Subject: [PATCH] Changed the way vector works to avoid issues with XML. XML out of order seems to be working fine but the unit tests are running into a crash on the out of order test, which doesn't show up in the sandbox version of the same thing. Need to debug this and out of order should be good to go for XML. --- include/cereal/archives/xml.hpp | 17 +++++++++-------- include/cereal/types/vector.hpp | 32 ++++++++++++++++++++++---------- sandbox.cpp | 5 ++--- unittests.cpp | 8 ++++---- 4 files changed, 37 insertions(+), 25 deletions(-) diff --git a/include/cereal/archives/xml.hpp b/include/cereal/archives/xml.hpp index cc7b586d..32b11c04 100644 --- a/include/cereal/archives/xml.hpp +++ b/include/cereal/archives/xml.hpp @@ -318,8 +318,10 @@ namespace cereal named after the NVP that is being loaded. If that NVP does not exist, we throw an exception. */ void startNode() { + //std::cerr << "..Starting node from parent " << itsNodes.top().node->name() << std::endl; auto next = itsNodes.top().child; // By default we would move to the next child node auto const expectedName = itsNodes.top().name; // this is the expected name from the NVP, if provided + //std::cerr << "...Default child would be " << (next ? next->name() : "null") << std::endl; //std::cerr << "End of nodes? " << (next == nullptr) << std::endl; //std::cerr << "Expected name: " << (expectedName ? expectedName : "null") << std::endl; @@ -343,12 +345,11 @@ namespace cereal //! Finishes reading the current node void finishNode() { - //std::cerr << "FINISH NODE: " << itsNodes.top().node->name() << std::endl; // remove current itsNodes.pop(); // advance parent - std::cerr << "Advancing node whose parent is " << itsNodes.top().node->name() << std::endl; + //std::cerr << "Advancing node whose parent is " << itsNodes.top().node->name() << std::endl; itsNodes.top().advance(); // Reset name @@ -492,21 +493,21 @@ namespace cereal size( XMLInputArchive::getNumChildren( n ) ), name( nullptr ) { - std::cerr << "Parent " << node->name() << " first child is " << (child ? child->name() : "null") << std::endl; + //std::cerr << "Parent " << node->name() << " first child is " << (child ? child->name() : "null") << std::endl; } //! Advances to the next sibling node of the child /*! If this is the last sibling child will be null after calling */ void advance() { - std::cerr << " node " << node->name() << " size " << size << std::endl; + //std::cerr << " node " << node->name() << " size " << size << std::endl; if( size > 0 ) { --size; - std::cerr << "Advancing node, new size is " << size << " child was previously: " << (child ? child->name() : "null") << std::endl; + //std::cerr << "Advancing node, new size is " << size << " child was previously: " << (child ? child->name() : "null") << std::endl; child = child->next_sibling(); - std::cerr << "New child is " << (child ? child->name() : "null") << std::endl; + //std::cerr << "New child is " << (child ? child->name() : "null") << std::endl; } } @@ -520,7 +521,7 @@ namespace cereal size_t new_size = XMLInputArchive::getNumChildren( node ); size_t name_size = rapidxml::internal::measure( name ); - std::cerr << "Searching for " << name << " with length " << name_size << std::endl; + //std::cerr << "Searching for " << name << " with length " << name_size << std::endl; //std::cerr << "Resetting to base height of " << new_size << std::endl; for( auto new_child = node->first_node(); new_child != nullptr; new_child = new_child->next_sibling() ) @@ -529,7 +530,7 @@ namespace cereal if( rapidxml::internal::compare( new_child->name(), new_child->name_size(), name, name_size, true ) ) { - std::cerr << "Found a match at size " << new_size << std::endl; + //std::cerr << "Found a match at size " << new_size << std::endl; size = new_size; child = new_child; diff --git a/include/cereal/types/vector.hpp b/include/cereal/types/vector.hpp index a3f82cbf..9962cd21 100644 --- a/include/cereal/types/vector.hpp +++ b/include/cereal/types/vector.hpp @@ -58,11 +58,10 @@ namespace cereal ar( binary_data( vector.data(), static_cast( vectorSize ) * sizeof(T) ) ); } - //! Serialization for non-arithmetic (and bool) vector types + //! Serialization for non-arithmetic vector types template inline typename std::enable_if, Archive>::value - || !std::is_arithmetic::value - || std::is_same::value, void>::type + || !std::is_arithmetic::value, void>::type save( Archive & ar, std::vector const & vector ) { ar( make_size_tag( static_cast(vector.size()) ) ); // number of elements @@ -70,11 +69,10 @@ namespace cereal ar( *it ); } - //! Serialization for non-arithmetic (not bool) vector types + //! Serialization for non-arithmetic vector types template inline typename std::enable_if, Archive>::value - || !std::is_arithmetic::value - || std::is_same::value, void>::type + || !std::is_arithmetic::value, void>::type load( Archive & ar, std::vector & vector ) { size_type size; @@ -85,11 +83,25 @@ namespace cereal ar( *it ); } - //! Specialization for serializing vector of bool references - template inline - void serialize( Archive & ar, std::vector::reference & r ) + //! Serialization for bool vector types + template inline + void save( Archive & ar, std::vector const & vector ) { - ar( static_cast( r ) ); + ar( make_size_tag( static_cast(vector.size()) ) ); // number of elements + for( auto it = vector.begin(), end = vector.end(); it != end; ++it ) + ar( static_cast( *it ) ); + } + + //! Serialization for non-arithmetic (not bool) vector types + template inline + void load( Archive & ar, std::vector & vector ) + { + size_type size; + ar( make_size_tag( size ) ); + + vector.resize( static_cast( size ) ); + for( auto it = vector.begin(), end = vector.end(); it != end; ++it ) + ar( static_cast( *it ) ); } } // namespace cereal diff --git a/sandbox.cpp b/sandbox.cpp index 452da0ad..8ef20e05 100644 --- a/sandbox.cpp +++ b/sandbox.cpp @@ -318,12 +318,11 @@ void test_unordered_loads() std::random_device rd; std::mt19937 gen(rd()); - auto rngB = [](){ return true; }; auto rngI = [](){ return 1; }; auto rngF = [](){ return 2.0f; }; auto rngD = [](){ return 3.2; }; - for(int i=0; i<1; ++i) + for(int i=0; i<100; ++i) { auto const name1 = "1"; auto const name2 = "2"; @@ -335,7 +334,7 @@ void test_unordered_loads() int o_int1 = rngI(); double o_double2 = rngD(); - std::vector o_vecbool3 = { rngB(), rngB(), rngB(), rngB(), rngB() }; + std::vector o_vecbool3 = { true, false, true, false, true }; int o_int4 = rngI(); int o_int5 = rngI(); int o_int6 = rngI(); diff --git a/unittests.cpp b/unittests.cpp index d601c83e..cea29ffd 100644 --- a/unittests.cpp +++ b/unittests.cpp @@ -3061,7 +3061,7 @@ BOOST_AUTO_TEST_CASE( xml_unordered_loads ) test_unordered_loads(); } -BOOST_AUTO_TEST_CASE( json_unordered_loads ) -{ - test_unordered_loads(); -} +//BOOST_AUTO_TEST_CASE( json_unordered_loads ) +//{ +// test_unordered_loads(); +//}