Changed the way vector<bool> 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.
This commit is contained in:
Shane Grant
2013-09-06 16:33:23 -07:00
parent 7137314e58
commit db0f1cf47f
4 changed files with 37 additions and 25 deletions

View File

@@ -318,8 +318,10 @@ namespace cereal
named after the NVP that is being loaded. If that NVP does not exist, we throw an exception. */ named after the NVP that is being loaded. If that NVP does not exist, we throw an exception. */
void startNode() 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 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 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 << "End of nodes? " << (next == nullptr) << std::endl;
//std::cerr << "Expected name: " << (expectedName ? expectedName : "null") << std::endl; //std::cerr << "Expected name: " << (expectedName ? expectedName : "null") << std::endl;
@@ -343,12 +345,11 @@ namespace cereal
//! Finishes reading the current node //! Finishes reading the current node
void finishNode() void finishNode()
{ {
//std::cerr << "FINISH NODE: " << itsNodes.top().node->name() << std::endl;
// remove current // remove current
itsNodes.pop(); itsNodes.pop();
// advance parent // 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(); itsNodes.top().advance();
// Reset name // Reset name
@@ -492,21 +493,21 @@ namespace cereal
size( XMLInputArchive::getNumChildren( n ) ), size( XMLInputArchive::getNumChildren( n ) ),
name( nullptr ) 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 //! Advances to the next sibling node of the child
/*! If this is the last sibling child will be null after calling */ /*! If this is the last sibling child will be null after calling */
void advance() void advance()
{ {
std::cerr << " node " << node->name() << " size " << size << std::endl; //std::cerr << " node " << node->name() << " size " << size << std::endl;
if( size > 0 ) if( size > 0 )
{ {
--size; --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(); 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 new_size = XMLInputArchive::getNumChildren( node );
size_t name_size = rapidxml::internal::measure( name ); 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; //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() ) 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 ) ) 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; size = new_size;
child = new_child; child = new_child;

View File

@@ -58,11 +58,10 @@ namespace cereal
ar( binary_data( vector.data(), static_cast<std::size_t>( vectorSize ) * sizeof(T) ) ); ar( binary_data( vector.data(), static_cast<std::size_t>( vectorSize ) * sizeof(T) ) );
} }
//! Serialization for non-arithmetic (and bool) vector types //! Serialization for non-arithmetic vector types
template <class Archive, class T, class A> inline template <class Archive, class T, class A> inline
typename std::enable_if<!traits::is_output_serializable<BinaryData<T>, Archive>::value typename std::enable_if<!traits::is_output_serializable<BinaryData<T>, Archive>::value
|| !std::is_arithmetic<T>::value || !std::is_arithmetic<T>::value, void>::type
|| std::is_same<T, bool>::value, void>::type
save( Archive & ar, std::vector<T, A> const & vector ) save( Archive & ar, std::vector<T, A> const & vector )
{ {
ar( make_size_tag( static_cast<size_type>(vector.size()) ) ); // number of elements ar( make_size_tag( static_cast<size_type>(vector.size()) ) ); // number of elements
@@ -70,11 +69,10 @@ namespace cereal
ar( *it ); ar( *it );
} }
//! Serialization for non-arithmetic (not bool) vector types //! Serialization for non-arithmetic vector types
template <class Archive, class T, class A> inline template <class Archive, class T, class A> inline
typename std::enable_if<!traits::is_input_serializable<BinaryData<T>, Archive>::value typename std::enable_if<!traits::is_input_serializable<BinaryData<T>, Archive>::value
|| !std::is_arithmetic<T>::value || !std::is_arithmetic<T>::value, void>::type
|| std::is_same<T, bool>::value, void>::type
load( Archive & ar, std::vector<T, A> & vector ) load( Archive & ar, std::vector<T, A> & vector )
{ {
size_type size; size_type size;
@@ -85,11 +83,25 @@ namespace cereal
ar( *it ); ar( *it );
} }
//! Specialization for serializing vector of bool references //! Serialization for bool vector types
template <class Archive> inline template <class Archive, class A> inline
void serialize( Archive & ar, std::vector<bool>::reference & r ) void save( Archive & ar, std::vector<bool, A> const & vector )
{ {
ar( static_cast<bool>( r ) ); ar( make_size_tag( static_cast<size_type>(vector.size()) ) ); // number of elements
for( auto it = vector.begin(), end = vector.end(); it != end; ++it )
ar( static_cast<bool>( *it ) );
}
//! Serialization for non-arithmetic (not bool) vector types
template <class Archive, class A> inline
void load( Archive & ar, std::vector<bool, A> & vector )
{
size_type size;
ar( make_size_tag( size ) );
vector.resize( static_cast<std::size_t>( size ) );
for( auto it = vector.begin(), end = vector.end(); it != end; ++it )
ar( static_cast<bool>( *it ) );
} }
} // namespace cereal } // namespace cereal

View File

@@ -318,12 +318,11 @@ void test_unordered_loads()
std::random_device rd; std::random_device rd;
std::mt19937 gen(rd()); std::mt19937 gen(rd());
auto rngB = [](){ return true; };
auto rngI = [](){ return 1; }; auto rngI = [](){ return 1; };
auto rngF = [](){ return 2.0f; }; auto rngF = [](){ return 2.0f; };
auto rngD = [](){ return 3.2; }; 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 name1 = "1";
auto const name2 = "2"; auto const name2 = "2";
@@ -335,7 +334,7 @@ void test_unordered_loads()
int o_int1 = rngI(); int o_int1 = rngI();
double o_double2 = rngD(); double o_double2 = rngD();
std::vector<bool> o_vecbool3 = { rngB(), rngB(), rngB(), rngB(), rngB() }; std::vector<bool> o_vecbool3 = { true, false, true, false, true };
int o_int4 = rngI(); int o_int4 = rngI();
int o_int5 = rngI(); int o_int5 = rngI();
int o_int6 = rngI(); int o_int6 = rngI();

View File

@@ -3061,7 +3061,7 @@ BOOST_AUTO_TEST_CASE( xml_unordered_loads )
test_unordered_loads<cereal::XMLInputArchive, cereal::XMLOutputArchive>(); test_unordered_loads<cereal::XMLInputArchive, cereal::XMLOutputArchive>();
} }
BOOST_AUTO_TEST_CASE( json_unordered_loads ) //BOOST_AUTO_TEST_CASE( json_unordered_loads )
{ //{
test_unordered_loads<cereal::JSONInputArchive, cereal::JSONOutputArchive>(); // test_unordered_loads<cereal::JSONInputArchive, cereal::JSONOutputArchive>();
} //}