]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/serialization/src/void_cast.cpp
9009993326eb508ea873ebaea95f61713a76f01e
1 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
2 // void_cast.cpp: implementation of run-time casting of void pointers
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 // <gennadiy.rozental@tfn.com>
10 // See http://www.boost.org for updates, documentation, and revision history.
12 #if (defined _MSC_VER) && (_MSC_VER == 1200)
13 # pragma warning (disable : 4786) // too long name, harmless warning
20 #include <cstddef> // NULL
21 #ifdef BOOST_SERIALIZATION_LOG
26 #include <boost/config.hpp>
27 #include <boost/assert.hpp>
29 #define BOOST_SERIALIZATION_SOURCE
30 #include <boost/serialization/config.hpp>
31 // it marks our code with proper attributes as being exported when
32 // we're compiling it while marking it import when just the headers
34 #include <boost/serialization/singleton.hpp>
35 #include <boost/serialization/extended_type_info.hpp>
36 #include <boost/serialization/void_cast.hpp>
39 namespace serialization
{
40 namespace void_cast_detail
{
42 // note that void_casters are keyed on value of
43 // member extended type info records - NOT their
44 // addresses. This is necessary in order for the
45 // void cast operations to work across dll and exe
47 bool void_caster::operator<(const void_caster
& rhs
) const {
48 // include short cut to save time and eliminate
49 // problems when when base class aren't virtual
50 if(m_derived
!= rhs
.m_derived
){
51 if(*m_derived
< *rhs
.m_derived
)
53 if(*rhs
.m_derived
< *m_derived
)
56 // m_derived == rhs.m_derived
57 if(m_base
!= rhs
.m_base
)
58 return *m_base
< *rhs
.m_base
;
63 struct void_caster_compare
{
64 bool operator()(const void_caster
* lhs
, const void_caster
* rhs
) const {
69 typedef std::set
<const void_caster
*, void_caster_compare
> set_type
;
70 typedef boost::serialization::singleton
<set_type
> void_caster_registry
;
73 # pragma warning(push)
74 # pragma warning(disable : 4511 4512)
77 // implementation of shortcut void caster
78 class void_caster_shortcut
: public void_caster
80 bool m_includes_virtual_base
;
91 upcast(void const * const t
) const{
92 if(m_includes_virtual_base
)
94 return static_cast<const char *> ( t
) - m_difference
;
97 downcast(void const * const t
) const{
98 if(m_includes_virtual_base
)
99 return vbc_downcast(t
);
100 return static_cast<const char *> ( t
) + m_difference
;
102 virtual bool is_shortcut() const {
105 virtual bool has_virtual_base() const {
106 return m_includes_virtual_base
;
109 void_caster_shortcut(
110 extended_type_info
const * derived
,
111 extended_type_info
const * base
,
112 std::ptrdiff_t difference
,
113 bool includes_virtual_base
,
114 void_caster
const * const parent
116 void_caster(derived
, base
, difference
, parent
),
117 m_includes_virtual_base(includes_virtual_base
)
119 recursive_register(includes_virtual_base
);
121 virtual ~void_caster_shortcut(){
122 recursive_unregister();
127 # pragma warning(pop)
131 void_caster_shortcut::vbc_downcast(
134 // try to find a chain that gives us what we want
135 const void_cast_detail::set_type
& s
136 = void_cast_detail::void_caster_registry::get_const_instance();
137 void_cast_detail::set_type::const_iterator it
;
138 for(it
= s
.begin(); it
!= s
.end(); ++it
){
139 // if the current candidate casts to the desired target type
140 if ((*it
)->m_derived
== m_derived
){
141 // and if it's not us
142 if ((*it
)->m_base
!= m_base
){
143 // try to cast from the candidate base to our base
145 t_new
= void_downcast(*(*it
)->m_base
, *m_base
, t
);
146 // if we were successful
148 // recast to our derived
149 const void_caster
* vc
= *it
;
150 return vc
->downcast(t_new
);
159 void_caster_shortcut::vbc_upcast(
162 // try to find a chain that gives us what we want
163 const void_cast_detail::set_type
& s
164 = void_cast_detail::void_caster_registry::get_const_instance();
165 void_cast_detail::set_type::const_iterator it
;
166 for(it
= s
.begin(); it
!= s
.end(); ++it
){
167 // if the current candidate casts from the desired base type
168 if((*it
)->m_base
== m_base
){
169 // and if it's not us
170 if ((*it
)->m_derived
!= m_derived
){
171 // try to cast from the candidate derived to our our derived
173 t_new
= void_upcast(*m_derived
, *(*it
)->m_derived
, t
);
175 return (*it
)->upcast(t_new
);
183 # pragma warning(push)
184 # pragma warning(disable : 4511 4512)
187 // just used as a search key
188 class void_caster_argument
: public void_caster
191 upcast(void const * const /*t*/) const {
196 downcast( void const * const /*t*/) const {
200 virtual bool has_virtual_base() const {
205 void_caster_argument(
206 extended_type_info
const * derived
,
207 extended_type_info
const * base
209 void_caster(derived
, base
)
211 virtual ~void_caster_argument(){};
215 # pragma warning(pop)
218 // implementation of void caster base class
219 BOOST_SERIALIZATION_DECL
void
220 void_caster::recursive_register(bool includes_virtual_base
) const {
221 void_cast_detail::set_type
& s
222 = void_cast_detail::void_caster_registry::get_mutable_instance();
224 #ifdef BOOST_SERIALIZATION_LOG
225 std::clog
<< "recursive_register\n";
226 std::clog
<< m_derived
->get_debug_info();
228 std::clog
<< m_base
->get_debug_info();
232 std::pair
<void_cast_detail::set_type::const_iterator
, bool> result
;
233 // comment this out for now.
234 result
= s
.insert(this);
235 //assert(result.second);
237 // generate all implied void_casts.
238 void_cast_detail::set_type::const_iterator it
;
239 for(it
= s
.begin(); it
!= s
.end(); ++it
){
240 if(* m_derived
== * (*it
)->m_base
){
241 const void_caster_argument
vca(
245 void_cast_detail::set_type::const_iterator i
;
248 new void_caster_shortcut(
251 m_difference
+ (*it
)->m_difference
,
252 (*it
)->has_virtual_base() || includes_virtual_base
,
257 if(* (*it
)->m_derived
== * m_base
){
258 const void_caster_argument
vca(
262 void_cast_detail::set_type::const_iterator i
;
265 new void_caster_shortcut(
268 m_difference
+ (*it
)->m_difference
,
269 (*it
)->has_virtual_base() || includes_virtual_base
,
277 BOOST_SERIALIZATION_DECL
void
278 void_caster::recursive_unregister() const {
279 if(void_caster_registry::is_destroyed())
282 #ifdef BOOST_SERIALIZATION_LOG
283 std::clog
<< "recursive_unregister\n";
284 std::clog
<< m_derived
->get_debug_info();
286 std::clog
<< m_base
->get_debug_info();
290 void_cast_detail::set_type
& s
291 = void_caster_registry::get_mutable_instance();
293 // delete all shortcuts which use this primitive
294 void_cast_detail::set_type::iterator it
;
295 for(it
= s
.begin(); it
!= s
.end();){
296 const void_caster
* vc
= *it
;
301 if(vc
->m_parent
== this){
311 } // namespace void_cast_detail
313 BOOST_SYMBOL_VISIBLE
void const *
315 extended_type_info
const & derived
,
316 extended_type_info
const & base
,
320 // Given a void *, assume that it really points to an instance of one type
321 // and alter it so that it would point to an instance of a related type.
322 // Return the altered pointer. If there exists no sequence of casts that
323 // can transform from_type to to_type, return a NULL.
324 BOOST_SERIALIZATION_DECL
void const *
326 extended_type_info
const & derived
,
327 extended_type_info
const & base
,
330 // same types - trivial case
334 // check to see if base/derived pair is found in the registry
335 const void_cast_detail::set_type
& s
336 = void_cast_detail::void_caster_registry::get_const_instance();
337 const void_cast_detail::void_caster_argument
ca(& derived
, & base
);
339 void_cast_detail::set_type::const_iterator it
;
342 return (*it
)->upcast(t
);
347 BOOST_SYMBOL_VISIBLE
void const *
349 extended_type_info
const & derived
,
350 extended_type_info
const & base
,
354 BOOST_SERIALIZATION_DECL
void const *
356 extended_type_info
const & derived
,
357 extended_type_info
const & base
,
360 // same types - trivial case
364 // check to see if base/derived pair is found in the registry
365 const void_cast_detail::set_type
& s
366 = void_cast_detail::void_caster_registry::get_const_instance();
367 const void_cast_detail::void_caster_argument
ca(& derived
, & base
);
369 void_cast_detail::set_type::const_iterator it
;
372 return(*it
)->downcast(t
);
377 } // namespace serialization