/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // test_smart_cast.cpp: // (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) // #include #include #include "test_tools.hpp" #include using namespace boost::serialization; class Base1 : public boost::noncopyable { char a; }; class Base2 { int b; }; #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable : 4511 4512) #endif class Derived : public Base1, public Base2 { long c; }; #ifdef BOOST_MSVC #pragma warning(pop) #endif // if compiler doesn't support TPS, the smart_cast syntax doesn't // work for references. One has to use the smart_cast_reference // syntax (tested below ) instead. void test_static_reference_cast_2(){ Derived d; Base1 & b1 = static_cast(d); Base2 & b2 = static_cast(d); Base1 & scb1 = smart_cast(d); Base2 & scb2 = smart_cast(d); BOOST_CHECK_EQUAL(& b1, & scb1); BOOST_CHECK_EQUAL(& b2, & scb2); // downcast // BOOST_CHECK_EQUAL(& d, & (smart_cast(b1))); // BOOST_CHECK_EQUAL(& d, & (smart_cast(b2))); // crosscast pointers fails at compiler time // BOOST_CHECK_EQUAL(pB2,smart_cast(pB1)); // though explicit cross cast will always work BOOST_CHECK_EQUAL(& b2,( & smart_cast( smart_cast(b1) )) ); } void test_static_reference_cast_1(){ Derived d; Base1 & b1 = static_cast(d); Base2 & b2 = static_cast(d); Base1 & scb1 = smart_cast_reference(d); Base2 & scb2 = smart_cast_reference(d); BOOST_CHECK_EQUAL(& b1, & scb1); BOOST_CHECK_EQUAL(& b2, & scb2); // downcast BOOST_CHECK_EQUAL(& d, & (smart_cast_reference(b1))); BOOST_CHECK_EQUAL(& d, & (smart_cast_reference(b2))); // crosscast pointers fails at compiler time // BOOST_CHECK_EQUAL(pB2,smart_cast(pB1)); // though explicit cross cast will always work BOOST_CHECK_EQUAL(& b2,( & smart_cast_reference( smart_cast_reference(b1) )) ); } void test_static_pointer_cast(){ // pointers Derived d; Derived *pD = & d; Base1 *pB1 = pD; Base2 *pB2 = pD; // upcast BOOST_CHECK_EQUAL(pB1, smart_cast(pD)); BOOST_CHECK_EQUAL(pB2, smart_cast(pD)); // downcast BOOST_CHECK_EQUAL(pD, smart_cast(pB1)); BOOST_CHECK_EQUAL(pD, smart_cast(pB2)); // crosscast pointers fails at compiler time // BOOST_CHECK_EQUAL(pB2, smart_cast(pB1)); // though explicit cross cast will always work BOOST_CHECK_EQUAL(pB2, smart_cast( smart_cast(pB1) ) ); } class VBase1 : public boost::noncopyable { char a; public: virtual ~VBase1(){}; }; class VBase2 { int b; public: virtual ~VBase2(){}; }; #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable : 4511 4512) #endif class VDerived : public VBase1, public VBase2 { long c; public: virtual ~VDerived(){}; }; #ifdef BOOST_MSVC #pragma warning(pop) #endif // see above void test_dynamic_reference_cast_2(){ VDerived d; VBase1 &b1 = dynamic_cast(d); VBase2 &b2 = static_cast(d); VBase1 & vb1 = smart_cast(d); BOOST_CHECK_EQUAL(& b1, & vb1); BOOST_CHECK_EQUAL(& b2, (& smart_cast(d))); // downcast BOOST_CHECK_EQUAL(& d, (& smart_cast(b1))); BOOST_CHECK_EQUAL(& d, (& smart_cast(b2))); // crosscast BOOST_CHECK_EQUAL(& b2, (& smart_cast(b1))); // explicit cross cast should always work BOOST_CHECK_EQUAL(& b2, ( & smart_cast( smart_cast(b1) )) ); } void test_dynamic_reference_cast_1(){ VDerived d; VBase1 &b1 = dynamic_cast(d); VBase2 &b2 = static_cast(d); VBase1 & vb1 = smart_cast_reference(d); BOOST_CHECK_EQUAL(& b1, & vb1); BOOST_CHECK_EQUAL(& b2, (& smart_cast_reference(d))); // downcast BOOST_CHECK_EQUAL(& d, (& smart_cast_reference(b1))); BOOST_CHECK_EQUAL(& d, (& smart_cast_reference(b2))); // crosscast BOOST_CHECK_EQUAL(& b2, (& smart_cast_reference(b1))); // explicit cross cast should always work BOOST_CHECK_EQUAL(& b2, ( & smart_cast_reference( smart_cast_reference(b1) )) ); } void test_dynamic_pointer_cast(){ // pointers VDerived d; VDerived *pD = & d; VBase1 *pB1 = pD; VBase2 *pB2 = pD; // upcast BOOST_CHECK_EQUAL(pB1, smart_cast(pD)); BOOST_CHECK_EQUAL(pB2, smart_cast(pD)); // downcast BOOST_CHECK_EQUAL(pD, smart_cast(pB1)); BOOST_CHECK_EQUAL(pD, smart_cast(pB2)); // crosscast pointers fails at compiler time BOOST_CHECK_EQUAL(pB2, smart_cast(pB1)); // though explicit cross cast will always work BOOST_CHECK_EQUAL(pB2, smart_cast( smart_cast(pB1) ) ); } int test_main(int /* argc */, char * /* argv */[]) { test_static_reference_cast_2(); test_static_reference_cast_1(); test_static_pointer_cast(); test_dynamic_reference_cast_2(); test_dynamic_reference_cast_1(); test_dynamic_pointer_cast(); return EXIT_SUCCESS; }