1 #ifndef BOOST_SERIALIZATION_VOID_CAST_HPP
2 #define BOOST_SERIALIZATION_VOID_CAST_HPP
4 // MS compatible compilers support #pragma once
5 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
9 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
10 // void_cast.hpp: interface for run-time casting of void pointers.
12 // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
13 // Use, modification and distribution is subject to the Boost Software
14 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
15 // http://www.boost.org/LICENSE_1_0.txt)
16 // gennadiy.rozental@tfn.com
18 // See http://www.boost.org for updates, documentation, and revision history.
20 #include <boost/smart_cast.hpp>
21 #include <boost/mpl/eval_if.hpp>
22 #include <boost/mpl/identity.hpp>
24 #include <boost/serialization/config.hpp>
25 #include <boost/serialization/force_include.hpp>
26 #include <boost/serialization/type_info_implementation.hpp>
28 #include <boost/config/abi_prefix.hpp> // must be the last header
31 # pragma warning(push)
32 # pragma warning(disable : 4251 4231 4660 4275)
36 namespace serialization {
38 class BOOST_SERIALIZATION_DECL(BOOST_PP_EMPTY()) extended_type_info;
40 // Given a void *, assume that it really points to an instance of one type
41 // and alter it so that it would point to an instance of a related type.
42 // Return the altered pointer. If there exists no sequence of casts that
43 // can transform from_type to to_type, return a NULL.
45 BOOST_SERIALIZATION_DECL(void const *)
47 extended_type_info const & derived_type,
48 extended_type_info const & base_type,
55 extended_type_info const & derived_type_,
56 extended_type_info const & base_type_,
59 return const_cast<void*>(void_upcast(
62 const_cast<void const *>(t)
66 BOOST_SERIALIZATION_DECL(void const *)
68 extended_type_info const & derived_type,
69 extended_type_info const & base_type,
76 extended_type_info const & derived_type_,
77 extended_type_info const & base_type_,
80 return const_cast<void*>(void_downcast(
83 const_cast<void const *>(t)
87 namespace void_cast_detail {
89 // note: can't be abstract because an instance is used as a search argument
90 class BOOST_SERIALIZATION_DECL(BOOST_PP_EMPTY()) void_caster
92 friend struct void_caster_compare ;
94 BOOST_SERIALIZATION_DECL(void const *)
95 boost::serialization::void_upcast(
96 const extended_type_info & derived_type,
97 const extended_type_info & base_type,
102 BOOST_SERIALIZATION_DECL(void const *)
103 boost::serialization::void_downcast(
104 const extended_type_info & derived_type,
105 const extended_type_info & base_type,
109 // each derived class must re-implement these;
110 virtual void const * upcast(void const * t) const = 0;
111 virtual void const * downcast(void const * t) const = 0;
113 extended_type_info const & m_derived_type;
114 extended_type_info const & m_base_type;
116 static void static_register(const void_caster *);
120 extended_type_info const & derived_type_,
121 extended_type_info const & base_type_
123 // predicate used to determine if this void caster includes
124 // a particular eti *
125 bool includes(const extended_type_info * eti) const;
126 virtual ~void_caster();
128 // cw 8.3 requires this!!
129 void_caster& operator=(void_caster const&);
132 template <class Derived, class Base>
133 class void_caster_primitive :
136 virtual void const* downcast( void const * t ) const {
137 Derived * d = boost::smart_cast<const Derived *, const Base *>(
138 static_cast<const Base *>(t)
142 virtual void const* upcast(void const * t) const {
143 Base * b = boost::smart_cast<const Base *, const Derived *>(
144 static_cast<const Derived *>(t)
150 static const void_caster_primitive instance;
151 void_caster_primitive() BOOST_USED;
154 template <class Derived, class Base>
155 void_caster_primitive<Derived, Base>::void_caster_primitive() :
157 * type_info_implementation<Derived>::type::get_instance(),
158 * type_info_implementation<Base>::type::get_instance()
161 this->static_register(& instance);
164 // the purpose of this class is to create to->from and from->to instances
165 // of void_caster_primitive for each related pair of types. This has to be
166 // done a pre-execution time - hence the usage of static variable.
167 template<class Derived, class Base>
168 const void_caster_primitive<Derived, Base>
169 void_caster_primitive<Derived, Base>::instance;
171 } // void_cast_detail
173 // Register a base/derived pair. This indicates that it is possible
174 // to upcast a void pointer from Derived to Base and downcast a
175 // void pointer from Base to Derived. Note bogus arguments to workaround
177 template<class Derived, class Base>
179 inline const void_cast_detail::void_caster & void_cast_register(
180 const Derived * dnull,
183 template<class Derived, class Base>
185 inline const void_cast_detail::void_caster & void_cast_register(
186 const Derived * /* dnull = NULL */,
187 const Base * /* bnull = NULL */
189 return void_cast_detail::void_caster_primitive<
195 } // namespace serialization
198 #include <boost/config/abi_suffix.hpp> // pops abi_suffix.hpp pragmas
200 #endif // BOOST_SERIALIZATION_VOID_CAST_HPP