| /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 |
| // test_void_cast.cpp: test 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> |
| |
| #include <cstddef> // NULL |
| #include "test_tools.hpp" |
| #include <boost/serialization/extended_type_info_typeid.hpp> |
| #include <boost/serialization/void_cast.hpp> |
| #include <boost/serialization/singleton.hpp> |
| |
| class Base1 |
| { |
| char a; |
| }; |
| |
| class Base2 |
| { |
| int b; |
| }; |
| |
| class Derived : public Base1, public Base2 |
| { |
| long c; |
| }; |
| |
| class MostDerived : public Derived |
| { |
| char d[32]; |
| }; |
| |
| template<class T> |
| const boost::serialization::extended_type_info & eti(){ |
| return boost::serialization::singleton< |
| boost::serialization::extended_type_info_typeid< T > |
| >::get_const_instance(); |
| } |
| |
| int |
| test_main( int /* argc */, char* /* argv */[] ) |
| { |
| MostDerived md; |
| MostDerived* pmd =& md; |
| Derived* pd = static_cast<Derived*>(pmd); |
| |
| Base2* pb2 = static_cast<Base2*>(pmd); |
| Base1* pb1 = static_cast<Base1*>(pd); |
| |
| void* vpmd = static_cast<void*>(pmd); |
| void* vpb1 = static_cast<void*>(pb1); |
| void* vpb2 = static_cast<void*>(pb2); |
| void* vpd = static_cast<void*>(pd); |
| |
| // simple casts only requiring table lookup |
| BOOST_CHECK(vpd == boost::serialization::void_downcast( |
| eti<Derived>(), |
| eti<Base1>(), |
| vpb1 |
| )); |
| BOOST_CHECK(vpb1 == boost::serialization::void_upcast( |
| eti<Derived>(), |
| eti<Base1>(), |
| vpd |
| )); |
| BOOST_CHECK(vpd == boost::serialization::void_downcast( |
| eti<Derived>(), |
| eti<Base2>(), |
| vpb2 |
| )); |
| BOOST_CHECK(vpb2 == boost::serialization::void_upcast( |
| eti<Derived>(), |
| eti<Base2>(), |
| vpd |
| )); |
| BOOST_CHECK(vpmd == boost::serialization::void_downcast( |
| eti<MostDerived>(), |
| eti<Derived>(), |
| vpd |
| )); |
| BOOST_CHECK(vpd == boost::serialization::void_upcast( |
| eti<MostDerived>(), |
| eti<Derived>(), |
| vpmd |
| )); |
| // note relationship between MostDerived and Base1 is automatically derived |
| BOOST_CHECK(vpmd == boost::serialization::void_downcast( |
| eti<MostDerived>(), |
| eti<Base1>(), |
| vpb1 |
| )); |
| BOOST_CHECK(vpb1 == boost::serialization::void_upcast( |
| eti<MostDerived>(), |
| eti<Base1>(), |
| vpmd |
| )); |
| |
| // note relationship between MostDerived and Base2 is automatically derived |
| BOOST_CHECK(vpmd == boost::serialization::void_downcast( |
| eti<MostDerived>(), |
| eti<Base2>(), |
| vpb2 |
| )); |
| BOOST_CHECK(vpb2 == boost::serialization::void_upcast( |
| eti<MostDerived>(), |
| eti<Base2>(), |
| vpmd |
| )); |
| |
| // note: currently derivations are not optimised. See void_cast.cpp |
| // for and explanation. These should still work though. |
| |
| // need to double check to validate speed up optimization of derivations |
| BOOST_CHECK(vpmd == boost::serialization::void_downcast( |
| eti<MostDerived>(), |
| eti<Base1>(), |
| vpb1 |
| )); |
| BOOST_CHECK(vpb1 == boost::serialization::void_upcast( |
| eti<MostDerived>(), |
| eti<Base1>(), |
| vpmd |
| )); |
| BOOST_CHECK(vpmd == boost::serialization::void_downcast( |
| eti<MostDerived>(), |
| eti<Base2>(), |
| vpb2 |
| )); |
| BOOST_CHECK(vpb2 == boost::serialization::void_upcast( |
| eti<MostDerived>(), |
| eti<Base2>(), |
| vpmd |
| )); |
| |
| // check things that should fail |
| BOOST_CHECK(NULL == boost::serialization::void_downcast( |
| eti<Base2>(), |
| eti<Base1>(), |
| vpb1 |
| )); |
| |
| // note that a fundamental feature is that derived/base pairs are created |
| // at compiler time so that all are registered before the main program starts |
| // so leave the registration here at the end to verify this. Note bogus arguments |
| // to workaround msvc 6 bug |
| boost::serialization::void_cast_register<Derived, Base1>( |
| static_cast<Derived *>(NULL), |
| static_cast<Base1 *>(NULL) |
| ); |
| boost::serialization::void_cast_register<Derived, Base2>( |
| static_cast<Derived *>(NULL), |
| static_cast<Base2 *>(NULL) |
| ); |
| boost::serialization::void_cast_register<MostDerived, Derived>( |
| static_cast<MostDerived *>(NULL), |
| static_cast<Derived *>(NULL) |
| ); |
| |
| return EXIT_SUCCESS; |
| } |
| |
| // EOF |