/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // extended_type_info_typeid.cpp: specific implementation of type info // that is based on typeid // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. #include #include #include #include #include // NULL #include #include #define BOOST_SERIALIZATION_SOURCE #include namespace boost { namespace serialization { namespace typeid_system { #define EXTENDED_TYPE_INFO_TYPE_KEY 1 struct type_compare { bool operator()( const extended_type_info_typeid_0 * lhs, const extended_type_info_typeid_0 * rhs ) const { return lhs->is_less_than(*rhs); } }; typedef std::multiset< const extended_type_info_typeid_0 *, type_compare > tkmap; 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 0 != m_ti->before( *(static_cast(rhs).m_ti) ); } BOOST_SERIALIZATION_DECL(bool) extended_type_info_typeid_0::is_equal( const boost::serialization::extended_type_info & rhs ) const { return // note: std::type_info == operator returns an int !!! // the following permits conversion to bool without a warning. ! ( * m_ti != *(static_cast(rhs).m_ti) ) ; } BOOST_SERIALIZATION_DECL(BOOST_PP_EMPTY()) extended_type_info_typeid_0::extended_type_info_typeid_0( const char * key ) : extended_type_info(EXTENDED_TYPE_INFO_TYPE_KEY, key), m_ti(NULL) {} BOOST_SERIALIZATION_DECL(BOOST_PP_EMPTY()) extended_type_info_typeid_0::~extended_type_info_typeid_0() {} BOOST_SERIALIZATION_DECL(void) extended_type_info_typeid_0::type_register(const std::type_info & ti){ m_ti = & ti; singleton::get_mutable_instance().insert(this); } BOOST_SERIALIZATION_DECL(void) extended_type_info_typeid_0::type_unregister() { if(NULL != m_ti){ if(! singleton::is_destroyed()){ tkmap & x = singleton::get_mutable_instance(); tkmap::iterator start = x.lower_bound(this); tkmap::iterator end = x.upper_bound(this); BOOST_ASSERT(start != end); // remove entry in map which corresponds to this type do{ if(this == *start) x.erase(start++); else ++start; }while(start != end); } } m_ti = NULL; } #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable : 4511 4512) #endif // this derivation is used for creating search arguments class extended_type_info_typeid_arg : public extended_type_info_typeid_0 { virtual void * construct(unsigned int /*count*/, ...) const{ BOOST_ASSERT(false); return NULL; } virtual void destroy(void const * const /*p*/) const { BOOST_ASSERT(false); } public: extended_type_info_typeid_arg(const std::type_info & ti) : extended_type_info_typeid_0(NULL) { // note absense of self register and key as this is used only as // search argument given a type_info reference and is not to // be added to the map. m_ti = & ti; } ~extended_type_info_typeid_arg(){ m_ti = NULL; } }; #ifdef BOOST_MSVC # pragma warning(pop) #endif BOOST_SERIALIZATION_DECL(const extended_type_info *) extended_type_info_typeid_0::get_extended_type_info( const std::type_info & ti ) const { typeid_system::extended_type_info_typeid_arg etia(ti); const tkmap & t = singleton::get_const_instance(); const tkmap::const_iterator it = t.find(& etia); if(t.end() == it) return NULL; return *(it); } } // namespace detail } // namespace serialization } // namespace boost