1/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
2// extended_type_info_typeid.cpp: specific implementation of type info
3// that is based on typeid
4
5// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
6// Use, modification and distribution is subject to the Boost Software
7// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
8// http://www.boost.org/LICENSE_1_0.txt)
9
10// See http://www.boost.org for updates, documentation, and revision history.
11
12#include <algorithm>
13#include <cstddef> // NULL
14#include <set>
15#include <typeinfo>
16
17#include <boost/assert.hpp>
18#include <boost/core/no_exceptions_support.hpp>
19
20// it marks our code with proper attributes as being exported when
21// we're compiling it while marking it import when just the headers
22// is being included.
23#define BOOST_SERIALIZATION_SOURCE
24#include <boost/serialization/config.hpp>
25#include <boost/serialization/singleton.hpp>
26#include <boost/serialization/extended_type_info_typeid.hpp>
27
28namespace boost {
29namespace serialization {
30namespace typeid_system {
31
32#define EXTENDED_TYPE_INFO_TYPE_KEY 1
33
34struct type_compare
35{
36 bool
37 operator()(
38 const extended_type_info_typeid_0 * lhs,
39 const extended_type_info_typeid_0 * rhs
40 ) const {
41 return lhs->is_less_than(rhs: *rhs);
42 }
43};
44
45typedef std::multiset<
46 const extended_type_info_typeid_0 *,
47 type_compare
48> tkmap;
49
50BOOST_SERIALIZATION_DECL bool
51extended_type_info_typeid_0::is_less_than(
52 const boost::serialization::extended_type_info & rhs
53) const {
54 // shortcut for common case
55 if(this == & rhs)
56 return false;
57 return 0 != m_ti->before(
58 arg: *(static_cast<const extended_type_info_typeid_0 &>(rhs).m_ti)
59 );
60}
61
62BOOST_SERIALIZATION_DECL bool
63extended_type_info_typeid_0::is_equal(
64 const boost::serialization::extended_type_info & rhs
65) const {
66 return
67 // note: std::type_info == operator returns an int !!!
68 // the following permits conversion to bool without a warning.
69 ! (
70 * m_ti
71 != *(static_cast<const extended_type_info_typeid_0 &>(rhs).m_ti)
72 )
73 ;
74}
75
76BOOST_SERIALIZATION_DECL
77extended_type_info_typeid_0::extended_type_info_typeid_0(
78 const char * key
79) :
80 extended_type_info(EXTENDED_TYPE_INFO_TYPE_KEY, key),
81 m_ti(NULL)
82{}
83
84BOOST_SERIALIZATION_DECL
85extended_type_info_typeid_0::~extended_type_info_typeid_0()
86{}
87
88BOOST_SERIALIZATION_DECL void
89extended_type_info_typeid_0::type_register(const std::type_info & ti){
90 m_ti = & ti;
91 singleton<tkmap>::get_mutable_instance().insert(x: this);
92}
93
94BOOST_SERIALIZATION_DECL void
95extended_type_info_typeid_0::type_unregister()
96{
97 if(NULL != m_ti){
98 // note: previously this conditional was a runtime assertion with
99 // BOOST_ASSERT. We've changed it because we've discovered that at
100 // least one platform is not guaranteed to destroy singletons in
101 // reverse order of destruction.
102 // BOOST_ASSERT(! singleton<tkmap>::is_destroyed());
103 if(! singleton<tkmap>::is_destroyed()){
104 tkmap & x = singleton<tkmap>::get_mutable_instance();
105
106 // remove all entries in map which corresponds to this type
107 // make sure that we don't use any invalidated iterators
108 while(true){
109 const tkmap::iterator & it = x.find(x: this);
110 if(it == x.end())
111 break;
112 x.erase(position: it);
113 }
114 }
115 }
116 m_ti = NULL;
117}
118
119#ifdef BOOST_MSVC
120# pragma warning(push)
121# pragma warning(disable : 4511 4512)
122#endif
123
124// this derivation is used for creating search arguments
125class extended_type_info_typeid_arg :
126 public extended_type_info_typeid_0
127{
128 void * construct(unsigned int /*count*/, ...) const BOOST_OVERRIDE {
129 BOOST_ASSERT(false);
130 return NULL;
131 }
132 void destroy(void const * const /*p*/) const BOOST_OVERRIDE {
133 BOOST_ASSERT(false);
134 }
135public:
136 extended_type_info_typeid_arg(const std::type_info & ti) :
137 extended_type_info_typeid_0(NULL)
138 {
139 // note absence of self register and key as this is used only as
140 // search argument given a type_info reference and is not to
141 // be added to the map.
142 m_ti = & ti;
143 }
144 ~extended_type_info_typeid_arg() BOOST_OVERRIDE {
145 m_ti = NULL;
146 }
147};
148
149#ifdef BOOST_MSVC
150# pragma warning(pop)
151#endif
152
153BOOST_SERIALIZATION_DECL const extended_type_info *
154extended_type_info_typeid_0::get_extended_type_info(
155 const std::type_info & ti
156) const {
157 typeid_system::extended_type_info_typeid_arg etia(ti);
158 const tkmap & t = singleton<tkmap>::get_const_instance();
159 const tkmap::const_iterator it = t.find(x: & etia);
160 if(t.end() == it)
161 return NULL;
162 return *(it);
163}
164
165} // namespace detail
166} // namespace serialization
167} // namespace boost
168

source code of boost/libs/serialization/src/extended_type_info_typeid.cpp