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 + -
显示快捷键?