1/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
2// extended_type_info.cpp: implementation for portable version of type_info
3
4// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
5// Use, modification and distribution is subject to the Boost Software
6// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7// http://www.boost.org/LICENSE_1_0.txt)
8
9// See http://www.boost.org for updates, documentation, and revision history.
10
11#if (defined _MSC_VER) && (_MSC_VER == 1200)
12# pragma warning (disable : 4786) // too long name, harmless warning
13#endif
14
15#include <algorithm>
16#include <set>
17#include <utility>
18#include <boost/assert.hpp>
19#include <cstddef> // NULL
20
21#include <cstring>
22#if defined(BOOST_NO_STDC_NAMESPACE)
23namespace std{ using ::strcmp; }
24#endif
25
26#include <boost/config.hpp> // msvc needs this to suppress warning
27
28#include <boost/core/no_exceptions_support.hpp>
29
30// it marks our code with proper attributes as being exported when
31// we're compiling it while marking it import when just the headers
32// is being included.
33#define BOOST_SERIALIZATION_SOURCE
34#include <boost/serialization/config.hpp>
35#include <boost/serialization/singleton.hpp>
36#include <boost/serialization/force_include.hpp>
37#include <boost/serialization/extended_type_info.hpp>
38
39#ifdef BOOST_MSVC
40# pragma warning(push)
41# pragma warning(disable : 4511 4512)
42#endif
43
44namespace boost {
45namespace serialization {
46namespace detail {
47
48struct key_compare
49{
50 bool
51 operator()(
52 const extended_type_info * lhs,
53 const extended_type_info * rhs
54 ) const {
55 // performance shortcut
56 if(lhs == rhs)
57 return false;
58 const char * l = lhs->get_key();
59 BOOST_ASSERT(NULL != l);
60 const char * r = rhs->get_key();
61 BOOST_ASSERT(NULL != r);
62 // performance shortcut
63 // shortcut to exploit string pooling
64 if(l == r)
65 return false;
66 // for exported types, use the string key so that
67 // multiple instances in different translation units
68 // can be matched up
69 return std::strcmp(s1: l, s2: r) < 0;
70 }
71};
72
73typedef std::multiset<const extended_type_info *, key_compare> ktmap;
74
75#ifdef BOOST_MSVC
76# pragma warning(push)
77# pragma warning(disable : 4511 4512)
78#endif
79
80class extended_type_info_arg : public extended_type_info
81{
82 bool
83 is_less_than(const extended_type_info & /*rhs*/) const BOOST_OVERRIDE {
84 BOOST_ASSERT(false);
85 return false;
86 }
87 bool
88 is_equal(const extended_type_info & /*rhs*/) const BOOST_OVERRIDE {
89 BOOST_ASSERT(false);
90 return false;
91 }
92 const char * get_debug_info() const BOOST_OVERRIDE {
93 return get_key();
94 }
95 void * construct(unsigned int /*count*/, ...) const BOOST_OVERRIDE {
96 BOOST_ASSERT(false);
97 return NULL;
98 }
99 void destroy(void const * const /*p*/) const BOOST_OVERRIDE {
100 BOOST_ASSERT(false);
101 }
102public:
103 extended_type_info_arg(const char * key) :
104 extended_type_info(0, key)
105 {}
106
107 ~extended_type_info_arg() BOOST_OVERRIDE {}
108};
109
110#ifdef BOOST_MSVC
111# pragma warning(pop)
112#endif
113
114} // namespace detail
115
116BOOST_SERIALIZATION_DECL void
117extended_type_info::key_register() const{
118 if(NULL == get_key())
119 return;
120 singleton<detail::ktmap>::get_mutable_instance().insert(x: this);
121}
122
123BOOST_SERIALIZATION_DECL void
124extended_type_info::key_unregister() const{
125 if(NULL == get_key())
126 return;
127 // note: it's been discovered that at least one platform is not guaranteed
128 // to destroy singletons reverse order of construction. So we can't
129 // use a runtime assert here. Leave this in a reminder not to do this!
130 // BOOST_ASSERT(! singleton<detail::ktmap>::is_destroyed());
131 if(! singleton<detail::ktmap>::is_destroyed()){
132 detail::ktmap & x = singleton<detail::ktmap>::get_mutable_instance();
133 detail::ktmap::iterator start = x.lower_bound(x: this);
134 detail::ktmap::iterator end = x.upper_bound(x: this);
135 // remove entry in map which corresponds to this type
136 for(;start != end; ++start){
137 if(this == *start){
138 x.erase(position: start);
139 break;
140 }
141 }
142 }
143}
144
145BOOST_SERIALIZATION_DECL const extended_type_info *
146extended_type_info::find(const char *key) {
147 BOOST_ASSERT(NULL != key);
148 const detail::ktmap & k = singleton<detail::ktmap>::get_const_instance();
149 const detail::extended_type_info_arg eti_key(key);
150 const detail::ktmap::const_iterator it = k.find(x: & eti_key);
151 if(k.end() == it)
152 return NULL;
153 return *(it);
154}
155
156BOOST_SERIALIZATION_DECL
157extended_type_info::extended_type_info(
158 const unsigned int type_info_key,
159 const char * key
160) :
161 m_type_info_key(type_info_key),
162 m_key(key)
163{
164}
165
166BOOST_SERIALIZATION_DECL
167extended_type_info::~extended_type_info(){
168}
169
170BOOST_SERIALIZATION_DECL bool
171extended_type_info::operator<(const extended_type_info &rhs) const {
172 // short cut for a common cases
173 if(this == & rhs)
174 return false;
175 if(m_type_info_key == rhs.m_type_info_key){
176 return is_less_than(rhs);
177 }
178 if(m_type_info_key < rhs.m_type_info_key)
179 return true;
180 return false;
181}
182
183BOOST_SERIALIZATION_DECL bool
184extended_type_info::operator==(const extended_type_info &rhs) const {
185 // short cut for a common cases
186 if(this == & rhs)
187 return true;
188 if(m_type_info_key != rhs.m_type_info_key){
189 return false;
190 }
191 return is_equal(rhs);
192}
193
194} // namespace serialization
195} // namespace boost
196

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