blob: 8fdd6d8d4b0c34017bcee664cb7a9a05980da5b7 [file] [log] [blame]
/////////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