| /////////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 <algorithm> |
| #include <set> |
| #include <cassert> |
| #include <typeinfo> |
| #include <cstddef> // NULL |
| |
| #include <boost/detail/no_exceptions_support.hpp> |
| |
| #include <boost/serialization/singleton.hpp> |
| |
| #define BOOST_SERIALIZATION_SOURCE |
| #include <boost/serialization/extended_type_info_typeid.hpp> |
| |
| 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<const extended_type_info_typeid_0 &>(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<const extended_type_info_typeid_0 &>(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<tkmap>::get_mutable_instance().insert(this); |
| } |
| |
| BOOST_SERIALIZATION_DECL(void) |
| extended_type_info_typeid_0::type_unregister() |
| { |
| if(NULL != m_ti){ |
| if(! singleton<tkmap>::is_destroyed()){ |
| tkmap & x = singleton<tkmap>::get_mutable_instance(); |
| tkmap::iterator start = x.lower_bound(this); |
| tkmap::iterator end = x.upper_bound(this); |
| 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{ |
| assert(false); |
| return NULL; |
| } |
| virtual void destroy(void const * const /*p*/) const { |
| 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<tkmap>::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 |