diff --git a/include/cereal/details/polymorphic_impl.hpp b/include/cereal/details/polymorphic_impl.hpp index fc669b69e..ab3b4e2bd 100644 --- a/include/cereal/details/polymorphic_impl.hpp +++ b/include/cereal/details/polymorphic_impl.hpp @@ -118,7 +118,7 @@ namespace cereal //! Maps from base type index to a map from derived type index to caster std::unordered_map>> map; - std::unordered_multimap reverseMap; + std::multimap reverseMap; //! Error message used for unregistered polymorphic casts #define UNREGISTERED_POLYMORPHIC_CAST_EXCEPTION(LoadSave) \ @@ -267,12 +267,23 @@ namespace cereal }; std::stack parentStack; // Holds the parent nodes to be processed - std::unordered_set dirtySet; // Marks child nodes that have been changed + std::vector dirtySet; // Marks child nodes that have been changed std::unordered_set processedParents; // Marks parent nodes that have been processed + // Checks if a child has been marked dirty + auto isDirty = [&](std::type_index const & c) + { + auto const dirtySetSize = dirtySet.size(); + for( size_t i = 0; i < dirtySetSize; ++i ) + if( dirtySet[i] == c ) + return true; + + return false; + }; + // Begin processing the base key and mark derived as dirty parentStack.push( baseKey ); - dirtySet.emplace( derivedKey ); + dirtySet.emplace_back( derivedKey ); while( !parentStack.empty() ) { @@ -286,7 +297,7 @@ namespace cereal for( auto const & childPair : baseMap[parent] ) { const auto child = childPair.first; - if( dirtySet.count( child ) && baseMap.count( child ) ) + if( isDirty( child ) && baseMap.count( child ) ) { auto parentChildPath = checkRelation( parent, child ); @@ -345,7 +356,7 @@ namespace cereal } // Mark current parent as modified - dirtySet.insert( parent ); + dirtySet.emplace_back( parent ); // Insert all parents of the current parent node that haven't yet been processed auto parentRange = reverseMap.equal_range( parent );