diff --git a/src/basic_serializer_map.cpp b/src/basic_serializer_map.cpp index d166aa36..4bd56407 100644 --- a/src/basic_serializer_map.cpp +++ b/src/basic_serializer_map.cpp @@ -12,8 +12,6 @@ # pragma warning (disable : 4786) // too long name, harmless warning #endif -#include - #define BOOST_ARCHIVE_SOURCE #include #include @@ -25,45 +23,52 @@ namespace boost { namespace archive { namespace detail { -bool -basic_serializer_map::type_info_pointer_compare::operator()( - const basic_serializer * lhs, const basic_serializer * rhs -) const { - return *lhs < *rhs; -} +// note: We can't implement this as an associative +// container as such a container might be dependent +// upon the extended_type_info::m_key which might not +// be assigned until later. So we use a "slower" method. +// This not a big deal however as the slower "find" operations +// operations are only called occasionally: +// a) At module unloading +// b) Once per input archive - the value is cached in the archive +// implemenation. -BOOST_ARCHIVE_DECL(bool) +BOOST_ARCHIVE_DECL(void) basic_serializer_map::insert(const basic_serializer * bs){ - return m_map.insert(bs).second; + m_map.push_back(bs); } BOOST_ARCHIVE_DECL(void) basic_serializer_map::erase(const basic_serializer * bs){ map_type::iterator it = m_map.begin(); map_type::iterator it_end = m_map.end(); - - while(it != it_end){ - // note item 9 from Effective STL !!! it++ - if(*it == bs) - m_map.erase(it++); - else - it++; + it = std::find(it, it_end, bs); + if(it != it_end){ + m_map.erase(it); } - // note: we can't do this since some of the eti records - // we're pointing to might be expired and the comparison - // won't work. Leave this as a reminder not to "optimize" this. - //it = m_map.find(bs); - //assert(it != m_map.end()); - //if(*it == bs) - // m_map.erase(it); + else + assert(false); // this should never occur } + +class equals { + const boost::serialization::extended_type_info * m_eti; +public: + bool operator()(const basic_serializer * bs) const { + return *m_eti == bs->get_eti(); + } + equals(const boost::serialization::extended_type_info * eti) : + m_eti(eti) + {} +}; + +// find the "oldest" matching pointer serializer BOOST_ARCHIVE_DECL(const basic_serializer *) basic_serializer_map::find( const boost::serialization::extended_type_info & eti ) const { - const basic_serializer_arg bs(eti); - map_type::const_iterator it; - it = m_map.find(& bs); + map_type::const_iterator it = m_map.begin(); + map_type::const_iterator it_end = m_map.end(); + it = std::find_if(it, it_end, equals(& eti)); assert(it != m_map.end()); return *it; } diff --git a/src/extended_type_info.cpp b/src/extended_type_info.cpp index 8f8ebbd2..ca869600 100644 --- a/src/extended_type_info.cpp +++ b/src/extended_type_info.cpp @@ -43,6 +43,9 @@ struct key_compare const extended_type_info * lhs, const extended_type_info * rhs ) const { + // performance shortcut + if(lhs == rhs) + return false; const char * l = lhs->get_key(); assert(NULL != l); const char * r = rhs->get_key(); @@ -72,13 +75,6 @@ class extended_type_info_arg : public extended_type_info assert(false); return false; }; - virtual bool & - get_is_destroyed() const { - static bool dummy = true; - assert(false); - return dummy; - } - public: extended_type_info_arg(const char * key) : extended_type_info() @@ -156,6 +152,9 @@ extended_type_info::~extended_type_info(){ BOOST_SERIALIZATION_DECL(bool) extended_type_info::operator<(const extended_type_info &rhs) const { + // short cut for a common cases + if(this == & rhs) + return false; if(m_type_info_key == rhs.m_type_info_key){ return is_less_than(rhs); } diff --git a/src/extended_type_info_no_rtti.cpp b/src/extended_type_info_no_rtti.cpp index 78384d72..3b4a704d 100644 --- a/src/extended_type_info_no_rtti.cpp +++ b/src/extended_type_info_no_rtti.cpp @@ -11,6 +11,7 @@ #include #include // NULL +#include #include #if defined(BOOST_NO_STDC_NAMESPACE) @@ -35,8 +36,20 @@ BOOST_SERIALIZATION_DECL(bool) extended_type_info_no_rtti_0::is_less_than( const boost::serialization::extended_type_info &rhs) const { + // shortcut for common case + if(this == & rhs) + return false; const char * l = m_key; const char * r = rhs.get_key(); + // if this assertion is triggered, it could mean one of the following + // a) This class was never exported - make sure all calls which use + // this method of type id are in fact exported. + // b) This class was used (e.g. serialized through a pointer) before + // it was exported. Make sure that classes which use this method + // of type id are NOT "automatically" registered by serializating + // through a pointer to the to most derived class. OR make sure + // that the BOOST_CLASS_EXPORT is included in every file + // which does this. assert(NULL != l); assert(NULL != r); return std::strcmp(l, r) < 0; @@ -46,14 +59,18 @@ BOOST_SERIALIZATION_DECL(bool) extended_type_info_no_rtti_0::is_equal( const boost::serialization::extended_type_info &rhs) const { - const char * l = m_key; - const char * r = rhs.get_key(); - if(l == r) + // shortcut for common case + if(this == & rhs) return true; + // null keys don't match with anything + const char * l = m_key; + //assert(NULL != l); if(NULL == l) return false; + const char * r = rhs.get_key(); if(NULL == r) return false; + assert(NULL != r); return 0 == std::strcmp(l, r); } diff --git a/src/extended_type_info_typeid.cpp b/src/extended_type_info_typeid.cpp index 126364a7..65ba0dca 100644 --- a/src/extended_type_info_typeid.cpp +++ b/src/extended_type_info_typeid.cpp @@ -48,6 +48,9 @@ BOOST_SERIALIZATION_DECL(bool) extended_type_info_typeid_0::is_less_than( const boost::serialization::extended_type_info & rhs ) const { + // shortcut for common case + if(this == & rhs) + return false; return static_cast(m_ti->before( *(static_cast(rhs).m_ti) )); @@ -57,6 +60,9 @@ BOOST_SERIALIZATION_DECL(bool) extended_type_info_typeid_0::is_equal( const boost::serialization::extended_type_info & rhs ) const { + // shortcut for common case + if(this == & rhs) + return true; return static_cast( * m_ti == *(static_cast(rhs).m_ti) @@ -105,13 +111,6 @@ extended_type_info_typeid_0::type_unregister() class extended_type_info_typeid_arg : public extended_type_info_typeid_0 { -private: - virtual bool & - get_is_destroyed() const { - static bool dummy = false; - assert(false); - return dummy; - } public: extended_type_info_typeid_arg(const std::type_info & ti){ // note absense of self register and key as this is used only as