void_cast.cpp

来自「Boost provides free peer-reviewed portab」· C++ 代码 · 共 260 行

CPP
260
字号
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8// void_cast.cpp: implementation of run-time casting of void pointers// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at// http://www.boost.org/LICENSE_1_0.txt)// <gennadiy.rozental@tfn.com>//  See http://www.boost.org for updates, documentation, and revision history.#if (defined _MSC_VER) && (_MSC_VER == 1200)# pragma warning (disable : 4786) // too long name, harmless warning#endif#include <cassert>#include <cstddef> // NULL// STL#include <vector>#include <functional>#include <algorithm>#include <cassert>// BOOST#define BOOST_SERIALIZATION_SOURCE#include <boost/serialization/singleton.hpp>#define BOOST_SERIALIZATION_SOURCE#include <boost/serialization/extended_type_info.hpp>#include <boost/serialization/void_cast.hpp>namespace boost { namespace serialization {namespace void_cast_detail {typedef std::vector<const void_caster *> set_type;typedef boost::serialization::singleton<set_type> void_caster_registry;inline boolvoid_caster::operator==(void_caster const & rhs) const{    if(m_derived != rhs.m_derived)        return false;    if(m_base != rhs.m_base)        return false;    return true;}// implementation of void caster base classBOOST_SERIALIZATION_DECL(BOOST_PP_EMPTY())void_caster::void_caster(    extended_type_info const & derived,    extended_type_info const & base ) :    m_derived(derived),    m_base(base){}BOOST_SERIALIZATION_DECL(void)void_caster::static_register() const {    void_caster_registry::get_mutable_instance().push_back(this);    // to do - add new void_caster_derived entries    // which can be generated by adding this new primitive    /*    while(){        if(!extend_down(this)        && !extend_up(this))            break;    }    */}BOOST_SERIALIZATION_DECL(void)void_caster::static_unregister() const {    if(! void_caster_registry::is_destroyed()){        void_cast_detail::set_type & st             = void_caster_registry::get_mutable_instance();        void_cast_detail::set_type::iterator it;        it = std::find(st.begin(), st.end(), this);        assert(st.end() != it);        st.erase(it);        // to do - remove all void_caster_derived entries        // which depend upon this primitive        /*        while(){            if(!truncate_down(this)            && !truncate_up(this))                break;        }        */    }}#if 0// implementation of shortcut void casterclass void_caster_derived : public void_caster{    std::ptrdiff_t difference;    virtual void const *    upcast(void const * const t) const{        return static_cast<const char *> ( t ) + difference;    }    virtual void const *    downcast(void const * const t) const{        return static_cast<const char *> ( t ) - difference;    }public:    void_caster_derived(        extended_type_info const & derived,        extended_type_info const & base,        std::ptrdiff_t difference    ) :        void_caster(derived, base),        difference( difference )    {        this->static_register();    }    ~void_caster_derived(){        this->static_unregister();    }};#endif// just used as a search keyclass void_caster_argument : public void_caster{    virtual void const *    upcast(void const * const t) const {        assert(false);        return NULL;    }    virtual void const *    downcast( void const * const t) const {        assert(false);        return NULL;    }public:    void_caster_argument(        extended_type_info const & derived,        extended_type_info const & base    ) :        void_caster(derived, base)    {}    ~void_caster_argument(){};};struct match {    void_cast_detail::void_caster_argument const * const m_ca;    match(void_cast_detail::void_caster_argument const * const ca) :        m_ca(ca)    {}    bool operator()(const void_cast_detail::void_caster * vc){        return * vc == * m_ca;    };};} // namespace void_cast_detail// Given a void *, assume that it really points to an instance of one type// and alter it so that it would point to an instance of a related type.// Return the altered pointer. If there exists no sequence of casts that// can transform from_type to to_type, return a NULL.  BOOST_SERIALIZATION_DECL(void const *)  void_upcast(    extended_type_info const & derived,    extended_type_info const & base,    void const * const t){    // same types - trivial case    if (derived == base)        return t;    // check to see if base/derived pair is found in the registry    const void_cast_detail::set_type & s        = void_cast_detail::void_caster_registry::get_const_instance();    void_cast_detail::set_type::const_iterator it;    void_cast_detail::void_caster_argument ca(derived, base);    it = std::find_if(        s.begin(),         s.end(),        void_cast_detail::match(& ca)    );        // if so    if (s.end() != it)        // we're done        return (*it)->upcast(t);    // try to find a chain that gives us what we want    for(it = s.begin(); it != s.end(); ++it){        // if the current candidate doesn't cast to the desired target type        if((*it)->m_base == base){            // if the current candidate casts from the desired source type            if ((*it)->m_derived == derived){                // we have a base/derived match - we're done                // cast to the intermediate type                return (*it)->upcast(t);            }            const void * t_new;            t_new = void_upcast(derived, (*it)->m_derived, t);            if(NULL != t_new)                return (*it)->upcast(t_new);        }    }    return NULL;}BOOST_SERIALIZATION_DECL(void const *)  void_downcast(    extended_type_info const & derived,    extended_type_info const & base,    void const * const t){    // same types - trivial case    if (derived == base)        return t;    // check to see if base/derived pair is found in the registry    const void_cast_detail::set_type & s        = void_cast_detail::void_caster_registry::get_const_instance();    void_cast_detail::set_type::const_iterator it;    void_cast_detail::void_caster_argument ca(derived, base);    it = std::find_if(        s.begin(),         s.end(),        void_cast_detail::match(& ca)    );            // if so    if (s.end() != it)        // we're done        return(*it)->downcast(t);    // try to find a chain that gives us what we want    for(it = s.begin(); it != s.end(); ++it){        // if the current candidate doesn't cast to the desired target type        if ((*it)->m_derived == derived){            // if the current candidate casts from the desired source type            if ((*it)->m_base == base){                // we have a base/derived match - we're done                // cast to the intermediate type                return (*it)->downcast(t);            }            const void * t_new;            t_new = void_downcast((*it)->m_base, base, t);            if(NULL != t_new)                return (*it)->downcast(t_new);        }    }    return NULL;}} // namespace serialization} // namespace boost// EOF

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?