os/ossrv/ossrv_pub/boost_apis/boost/serialization/void_cast.hpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
#ifndef  BOOST_SERIALIZATION_VOID_CAST_HPP
sl@0
     2
#define BOOST_SERIALIZATION_VOID_CAST_HPP
sl@0
     3
sl@0
     4
// MS compatible compilers support #pragma once
sl@0
     5
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
sl@0
     6
# pragma once
sl@0
     7
#endif
sl@0
     8
sl@0
     9
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
sl@0
    10
// void_cast.hpp:   interface for run-time casting of void pointers.
sl@0
    11
sl@0
    12
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . 
sl@0
    13
// Use, modification and distribution is subject to the Boost Software
sl@0
    14
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
sl@0
    15
// http://www.boost.org/LICENSE_1_0.txt)
sl@0
    16
// gennadiy.rozental@tfn.com
sl@0
    17
sl@0
    18
//  See http://www.boost.org for updates, documentation, and revision history.
sl@0
    19
sl@0
    20
#include <boost/smart_cast.hpp>
sl@0
    21
#include <boost/mpl/eval_if.hpp>
sl@0
    22
#include <boost/mpl/identity.hpp>
sl@0
    23
sl@0
    24
#include <boost/serialization/config.hpp>
sl@0
    25
#include <boost/serialization/force_include.hpp>
sl@0
    26
#include <boost/serialization/type_info_implementation.hpp>
sl@0
    27
sl@0
    28
#include <boost/config/abi_prefix.hpp> // must be the last header
sl@0
    29
sl@0
    30
#ifdef BOOST_MSVC
sl@0
    31
#  pragma warning(push)
sl@0
    32
#  pragma warning(disable : 4251 4231 4660 4275)
sl@0
    33
#endif
sl@0
    34
sl@0
    35
namespace boost { 
sl@0
    36
namespace serialization { 
sl@0
    37
sl@0
    38
class BOOST_SERIALIZATION_DECL(BOOST_PP_EMPTY()) extended_type_info;
sl@0
    39
sl@0
    40
// Given a void *, assume that it really points to an instance of one type
sl@0
    41
// and alter it so that it would point to an instance of a related type.
sl@0
    42
// Return the altered pointer. If there exists no sequence of casts that
sl@0
    43
// can transform from_type to to_type, return a NULL.  
sl@0
    44
sl@0
    45
BOOST_SERIALIZATION_DECL(void const *)
sl@0
    46
void_upcast(
sl@0
    47
    extended_type_info const & derived_type,  
sl@0
    48
    extended_type_info const & base_type, 
sl@0
    49
    void const * const t,
sl@0
    50
    bool top = true
sl@0
    51
);
sl@0
    52
sl@0
    53
inline void *
sl@0
    54
void_upcast(
sl@0
    55
    extended_type_info const & derived_type_,
sl@0
    56
    extended_type_info const & base_type_,
sl@0
    57
    void * const t 
sl@0
    58
){
sl@0
    59
    return const_cast<void*>(void_upcast(
sl@0
    60
        derived_type_, 
sl@0
    61
        base_type_, 
sl@0
    62
        const_cast<void const *>(t)
sl@0
    63
    ));
sl@0
    64
}
sl@0
    65
sl@0
    66
BOOST_SERIALIZATION_DECL(void const *)
sl@0
    67
void_downcast(
sl@0
    68
    extended_type_info const & derived_type,  
sl@0
    69
    extended_type_info const & base_type, 
sl@0
    70
    void const * const t,
sl@0
    71
    bool top = true
sl@0
    72
);
sl@0
    73
sl@0
    74
inline void *
sl@0
    75
void_downcast(
sl@0
    76
    extended_type_info const & derived_type_,
sl@0
    77
    extended_type_info const & base_type_,
sl@0
    78
    void * const t 
sl@0
    79
){
sl@0
    80
    return const_cast<void*>(void_downcast(
sl@0
    81
        derived_type_, 
sl@0
    82
        base_type_, 
sl@0
    83
        const_cast<void const *>(t)
sl@0
    84
    ));
sl@0
    85
}
sl@0
    86
sl@0
    87
namespace void_cast_detail {
sl@0
    88
sl@0
    89
// note: can't be abstract because an instance is used as a search argument
sl@0
    90
class BOOST_SERIALIZATION_DECL(BOOST_PP_EMPTY()) void_caster
sl@0
    91
{
sl@0
    92
    friend struct void_caster_compare ;
sl@0
    93
    friend 
sl@0
    94
    BOOST_SERIALIZATION_DECL(void const *)  
sl@0
    95
    boost::serialization::void_upcast(
sl@0
    96
        const extended_type_info & derived_type,
sl@0
    97
        const extended_type_info & base_type,
sl@0
    98
        const void * t,
sl@0
    99
        bool top
sl@0
   100
    );
sl@0
   101
    friend 
sl@0
   102
    BOOST_SERIALIZATION_DECL(void const *)  
sl@0
   103
    boost::serialization::void_downcast(
sl@0
   104
        const extended_type_info & derived_type,
sl@0
   105
        const extended_type_info & base_type,
sl@0
   106
        const void * t,
sl@0
   107
        bool top
sl@0
   108
    );
sl@0
   109
    // each derived class must re-implement these;
sl@0
   110
    virtual void const * upcast(void const * t) const = 0;
sl@0
   111
    virtual void const * downcast(void const * t) const = 0;
sl@0
   112
    // Data members
sl@0
   113
    extended_type_info const & m_derived_type;
sl@0
   114
    extended_type_info const & m_base_type;
sl@0
   115
protected:
sl@0
   116
    static void static_register(const void_caster *);
sl@0
   117
public:
sl@0
   118
    // Constructor
sl@0
   119
    void_caster(
sl@0
   120
        extended_type_info const & derived_type_,
sl@0
   121
        extended_type_info const & base_type_ 
sl@0
   122
    );
sl@0
   123
    // predicate used to determine if this void caster includes
sl@0
   124
    // a particular eti *
sl@0
   125
    bool includes(const extended_type_info * eti) const;
sl@0
   126
    virtual ~void_caster();
sl@0
   127
private:
sl@0
   128
    // cw 8.3 requires this!!
sl@0
   129
    void_caster& operator=(void_caster const&);
sl@0
   130
};
sl@0
   131
sl@0
   132
template <class Derived, class Base>
sl@0
   133
class void_caster_primitive : 
sl@0
   134
    public void_caster
sl@0
   135
{
sl@0
   136
    virtual void const* downcast( void const * t ) const {
sl@0
   137
        Derived * d = boost::smart_cast<const Derived *, const Base *>(
sl@0
   138
            static_cast<const Base *>(t)
sl@0
   139
        );
sl@0
   140
        return d;
sl@0
   141
    }
sl@0
   142
    virtual void const* upcast(void const * t) const {
sl@0
   143
        Base * b = boost::smart_cast<const Base *, const Derived *>(
sl@0
   144
            static_cast<const Derived *>(t)
sl@0
   145
        );
sl@0
   146
        return b;
sl@0
   147
    }
sl@0
   148
sl@0
   149
public:
sl@0
   150
    static const void_caster_primitive instance;
sl@0
   151
    void_caster_primitive() BOOST_USED;
sl@0
   152
};
sl@0
   153
sl@0
   154
template <class Derived, class Base>
sl@0
   155
void_caster_primitive<Derived, Base>::void_caster_primitive() :
sl@0
   156
    void_caster( 
sl@0
   157
        * type_info_implementation<Derived>::type::get_instance(), 
sl@0
   158
        * type_info_implementation<Base>::type::get_instance() 
sl@0
   159
    )
sl@0
   160
{
sl@0
   161
    this->static_register(& instance);
sl@0
   162
}
sl@0
   163
sl@0
   164
// the purpose of this class is to create to->from and from->to instances
sl@0
   165
// of void_caster_primitive for each related pair of types.  This has to be
sl@0
   166
// done a pre-execution time - hence the usage of static variable.
sl@0
   167
template<class Derived, class Base>
sl@0
   168
const void_caster_primitive<Derived, Base>
sl@0
   169
    void_caster_primitive<Derived, Base>::instance;
sl@0
   170
sl@0
   171
} // void_cast_detail 
sl@0
   172
sl@0
   173
// Register a base/derived pair.  This indicates that it is possible
sl@0
   174
// to upcast a void pointer from Derived to Base and downcast a
sl@0
   175
// void pointer from Base to Derived.  Note bogus arguments to workaround
sl@0
   176
// bug in msvc 6.0
sl@0
   177
template<class Derived, class Base>
sl@0
   178
BOOST_DLLEXPORT 
sl@0
   179
inline const void_cast_detail::void_caster & void_cast_register(
sl@0
   180
    const Derived * dnull, 
sl@0
   181
    const Base * bnull
sl@0
   182
) BOOST_USED;
sl@0
   183
template<class Derived, class Base>
sl@0
   184
BOOST_DLLEXPORT 
sl@0
   185
inline const void_cast_detail::void_caster & void_cast_register(
sl@0
   186
    const Derived * /* dnull = NULL */, 
sl@0
   187
    const Base * /* bnull = NULL */
sl@0
   188
){
sl@0
   189
    return void_cast_detail::void_caster_primitive<
sl@0
   190
        const Derived, 
sl@0
   191
        const Base
sl@0
   192
    >::instance;
sl@0
   193
}
sl@0
   194
sl@0
   195
} // namespace serialization
sl@0
   196
} // namespace boost
sl@0
   197
sl@0
   198
#include <boost/config/abi_suffix.hpp> // pops abi_suffix.hpp pragmas
sl@0
   199
sl@0
   200
#endif // BOOST_SERIALIZATION_VOID_CAST_HPP