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

Revision 857, 6.1 KB checked in by igarcia, 18 years ago (diff)
Line 
1#ifndef BOOST_SERIALIZATION_BASE_OBJECT_HPP
2#define BOOST_SERIALIZATION_BASE_OBJECT_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// base_object.hpp:
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
17//  See http://www.boost.org for updates, documentation, and revision history.
18
19// if no archive headers have been included this is a no op
20// this is to permit BOOST_EXPORT etc to be included in a
21// file declaration header
22
23#include <boost/config.hpp>
24#include <boost/detail/workaround.hpp>
25
26#include <boost/mpl/eval_if.hpp>
27#include <boost/mpl/int.hpp>
28#include <boost/type_traits/is_base_and_derived.hpp>
29#include <boost/type_traits/is_pointer.hpp>
30#include <boost/type_traits/is_const.hpp>
31
32#include <boost/static_assert.hpp>
33#include <boost/serialization/type_info_implementation.hpp>
34#include <boost/serialization/force_include.hpp>
35#include <boost/serialization/void_cast_fwd.hpp>
36
37namespace boost {
38namespace serialization {
39
40namespace detail {
41    // metrowerks CodeWarrior
42    #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3206))
43        // only register void casts if the types are polymorphic
44        template<class Base, class Derived>
45        struct base_register{
46            struct nothing {
47                static const void_cast_detail::void_caster & invoke(){
48                    return static_cast<const void_cast_detail::void_caster &>(
49                        * static_cast<const void_cast_detail::void_caster *>(NULL)
50                    );
51                }
52            };
53
54            // hold a reference to the void_cast_register and void_caster in the hope of
55            // ensuring code instantiation for some compilers with over-zealous link time
56            // optimiser. The compiler that demanded this was CW
57            struct reg{
58                typedef const void_cast_detail::void_caster & (* t_vcr)(
59                    const Derived *,
60                    const Base *
61                );
62                t_vcr m_vcr;
63                static const void_cast_detail::void_caster & invoke(){
64                    return  void_cast_register<const Derived, const Base>(
65                        static_cast<const Derived *>(NULL),
66                        static_cast<const Base *>(NULL)
67                    );
68                }
69                reg() :
70                    m_vcr(static_cast<t_vcr>(void_cast_register))
71                {
72                }
73            } m_reg;
74
75            static const void_cast_detail::void_caster & invoke(){
76                typedef BOOST_DEDUCED_TYPENAME mpl::eval_if<
77                    BOOST_DEDUCED_TYPENAME type_info_implementation<Base>::type::is_polymorphic,
78                    mpl::identity<reg>,
79                    mpl::identity<nothing>
80                >::type typex;
81                return typex::invoke();
82            }
83
84            const void_cast_detail::void_caster & m_vc;
85            Derived & m_d;
86
87            base_register(Derived & d) :
88                m_vc(invoke()),
89                m_d(d)
90            {}
91            Base & get_base() const {
92                return m_d;
93            }
94        };
95    #else
96        // only register void casts if the types are polymorphic
97        template<class Base, class Derived>
98        struct base_register{
99            struct nothing {
100                static void invoke(){}
101            };
102            struct reg{
103                static void invoke(){
104                    void_cast_register<const Derived, const Base>(
105                        static_cast<const Derived *>(NULL),
106                        static_cast<const Base *>(NULL)
107                    );
108                }
109            };
110            static void invoke(){
111                typedef BOOST_DEDUCED_TYPENAME mpl::eval_if<
112                    BOOST_DEDUCED_TYPENAME type_info_implementation<Base>::type::is_polymorphic,
113                    mpl::identity<reg>,
114                    mpl::identity<nothing>
115                >::type typex;
116                typex::invoke();
117            }
118        };
119    #endif
120    // get the base type for a given derived type
121    // preserving the const-ness
122    template<class B, class D>
123    struct base_cast
124    {
125        typedef BOOST_DEDUCED_TYPENAME
126            mpl::if_<
127                is_const<D>,
128                const B,
129                B
130        >::type type;
131        BOOST_STATIC_ASSERT(is_const<type>::value == is_const<D>::value);
132    };
133} // namespace detail
134
135// metrowerks CodeWarrior
136#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3206))
137template<class Base, class Derived>
138BOOST_DEDUCED_TYPENAME detail::base_cast<Base, Derived>::type &
139base_object(Derived &d)
140{
141    BOOST_STATIC_ASSERT(( is_base_and_derived<Base,Derived>::value));
142    BOOST_STATIC_ASSERT(! is_pointer<Derived>::value);
143    typedef BOOST_DEDUCED_TYPENAME detail::base_cast<Base, Derived>::type type;
144    return detail::base_register<type, Derived>(d).get_base();
145}
146// BORLAND
147#elif BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x560))
148template<class Base, class Derived>
149const Base &
150base_object(const Derived & d)
151{
152    BOOST_STATIC_ASSERT(! is_pointer<Derived>::value);
153    detail::base_register<Base, Derived>::invoke();
154    return static_cast<const Base &>(d);
155}
156#else
157template<class Base, class Derived>
158BOOST_DEDUCED_TYPENAME detail::base_cast<Base, Derived>::type &
159base_object(Derived &d)
160{
161    BOOST_STATIC_ASSERT(( is_base_and_derived<Base,Derived>::value));
162    BOOST_STATIC_ASSERT(! is_pointer<Derived>::value);
163    typedef BOOST_DEDUCED_TYPENAME detail::base_cast<Base, Derived>::type type;
164    detail::base_register<type, Derived>::invoke();
165    return static_cast<type &>(d);
166}
167#endif
168
169} // namespace serialization
170} // namespace boost
171
172#endif // BOOST_SERIALIZATION_BASE_OBJECT_HPP
Note: See TracBrowser for help on using the repository browser.