source: NonGTP/Boost/boost/serialization/void_cast.hpp @ 857

Revision 857, 6.1 KB checked in by igarcia, 19 years ago (diff)
Line 
1#ifndef  BOOST_SERIALIZATION_VOID_CAST_HPP
2#define BOOST_SERIALIZATION_VOID_CAST_HPP
3
4// MS compatible compilers support #pragma once
5#if defined(_MSC_VER) && (_MSC_VER >= 1020)
6# pragma once
7#endif
8
9/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
10// void_cast.hpp:   interface for run-time casting of void pointers.
11
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
17
18//  See http://www.boost.org for updates, documentation, and revision history.
19
20#include <boost/smart_cast.hpp>
21#include <boost/mpl/eval_if.hpp>
22#include <boost/mpl/identity.hpp>
23
24#include <boost/serialization/config.hpp>
25#include <boost/serialization/force_include.hpp>
26#include <boost/serialization/type_info_implementation.hpp>
27
28#include <boost/config/abi_prefix.hpp> // must be the last header
29
30#ifdef BOOST_MSVC
31#  pragma warning(push)
32#  pragma warning(disable : 4251 4231 4660 4275)
33#endif
34
35namespace boost {
36namespace serialization {
37
38class BOOST_SERIALIZATION_DECL(BOOST_PP_EMPTY()) extended_type_info;
39
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. 
44
45BOOST_SERIALIZATION_DECL(void const *)
46void_upcast(
47    extended_type_info const & derived_type, 
48    extended_type_info const & base_type,
49    void const * const t,
50    bool top = true
51);
52
53inline void *
54void_upcast(
55    extended_type_info const & derived_type_,
56    extended_type_info const & base_type_,
57    void * const t
58){
59    return const_cast<void*>(void_upcast(
60        derived_type_,
61        base_type_,
62        const_cast<void const *>(t)
63    ));
64}
65
66BOOST_SERIALIZATION_DECL(void const *)
67void_downcast(
68    extended_type_info const & derived_type, 
69    extended_type_info const & base_type,
70    void const * const t,
71    bool top = true
72);
73
74inline void *
75void_downcast(
76    extended_type_info const & derived_type_,
77    extended_type_info const & base_type_,
78    void * const t
79){
80    return const_cast<void*>(void_downcast(
81        derived_type_,
82        base_type_,
83        const_cast<void const *>(t)
84    ));
85}
86
87namespace void_cast_detail {
88
89// note: can't be abstract because an instance is used as a search argument
90class BOOST_SERIALIZATION_DECL(BOOST_PP_EMPTY()) void_caster
91{
92    friend struct void_caster_compare ;
93    friend
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,
98        const void * t,
99        bool top
100    );
101    friend
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,
106        const void * t,
107        bool top
108    );
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;
112    // Data members
113    extended_type_info const & m_derived_type;
114    extended_type_info const & m_base_type;
115protected:
116    static void static_register(const void_caster *);
117public:
118    // Constructor
119    void_caster(
120        extended_type_info const & derived_type_,
121        extended_type_info const & base_type_
122    );
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();
127};
128
129template <class Derived, class Base>
130class void_caster_primitive :
131    public void_caster
132{
133    virtual void const* downcast( void const * t ) const {
134        Derived * d = boost::smart_cast<const Derived *, const Base *>(
135            static_cast<const Base *>(t)
136        );
137        return d;
138    }
139    virtual void const* upcast(void const * t) const {
140        Base * b = boost::smart_cast<const Base *, const Derived *>(
141            static_cast<const Derived *>(t)
142        );
143        return b;
144    }
145
146public:
147    static const void_caster_primitive instance;
148    void_caster_primitive() BOOST_USED;
149};
150
151template <class Derived, class Base>
152void_caster_primitive<Derived, Base>::void_caster_primitive() :
153    void_caster(
154        * type_info_implementation<Derived>::type::get_instance(),
155        * type_info_implementation<Base>::type::get_instance()
156    )
157{
158    this->static_register(& instance);
159}
160
161// the purpose of this class is to create to->from and from->to instances
162// of void_caster_primitive for each related pair of types.  This has to be
163// done a pre-execution time - hence the usage of static variable.
164template<class Derived, class Base>
165const void_caster_primitive<Derived, Base>
166    void_caster_primitive<Derived, Base>::instance;
167
168} // void_cast_detail
169
170// Register a base/derived pair.  This indicates that it is possible
171// to upcast a void pointer from Derived to Base and downcast a
172// void pointer from Base to Derived.  Note bogus arguments to workaround
173// bug in msvc 6.0
174template<class Derived, class Base>
175BOOST_DLLEXPORT
176inline const void_cast_detail::void_caster &
177void_cast_register(
178    const Derived * /* dnull = NULL */,
179    const Base * /* bnull = NULL */
180) BOOST_USED;
181template<class Derived, class Base>
182BOOST_DLLEXPORT
183inline const void_cast_detail::void_caster &
184void_cast_register(
185    const Derived * /* dnull = NULL */,
186    const Base * /* bnull = NULL */
187){
188    return void_cast_detail::void_caster_primitive<
189        const Derived,
190        const Base
191    >::instance;
192}
193
194} // namespace serialization
195} // namespace boost
196
197#include <boost/config/abi_suffix.hpp> // pops abi_suffix.hpp pragmas
198
199#endif // BOOST_SERIALIZATION_VOID_CAST_HPP
Note: See TracBrowser for help on using the repository browser.