diff options
Diffstat (limited to 'libs/conversion/test/polymorphic_cast_test.cpp')
-rw-r--r-- | libs/conversion/test/polymorphic_cast_test.cpp | 222 |
1 files changed, 220 insertions, 2 deletions
diff --git a/libs/conversion/test/polymorphic_cast_test.cpp b/libs/conversion/test/polymorphic_cast_test.cpp index b3f139768..db448503f 100644 --- a/libs/conversion/test/polymorphic_cast_test.cpp +++ b/libs/conversion/test/polymorphic_cast_test.cpp @@ -1,9 +1,11 @@ // -// Test boost::polymorphic_cast, boost::polymorphic_downcast +// Test boost::polymorphic_cast, boost::polymorphic_downcast and +// boost::polymorphic_pointer_cast, boost::polymorphic_pointer_downcast // // Copyright 1999 Beman Dawes // Copyright 1999 Dave Abrahams // Copyright 2014 Peter Dimov +// Copyright 2014 Boris Rasin, Antony Polukhin // // Distributed under the Boost Software License, Version 1.0. // @@ -12,8 +14,13 @@ #define BOOST_ENABLE_ASSERT_HANDLER #include <boost/polymorphic_cast.hpp> +#include <boost/polymorphic_pointer_cast.hpp> +#include <boost/smart_ptr/shared_ptr.hpp> +#include <boost/smart_ptr/intrusive_ptr.hpp> +#include <boost/smart_ptr/intrusive_ref_counter.hpp> #include <boost/core/lightweight_test.hpp> #include <string> +#include <memory> static bool expect_assertion = false; static int assertion_failed_count = 0; @@ -37,7 +44,7 @@ void boost::assertion_failed( char const * expr, char const * function, char con // -struct Base +struct Base : boost::intrusive_ref_counter<Base> { virtual ~Base() {} virtual std::string kind() { return "Base"; } @@ -97,6 +104,67 @@ static void test_polymorphic_cast() delete base; } +static void test_polymorphic_pointer_cast() +{ + Base * base = new Derived; + + Derived * derived; + + try + { + derived = boost::polymorphic_pointer_cast<Derived>( base ); + + BOOST_TEST( derived != 0 ); + + if( derived != 0 ) + { + BOOST_TEST_EQ( derived->kind(), "Derived" ); + } + } + catch( std::bad_cast const& ) + { + BOOST_ERROR( "boost::polymorphic_pointer_cast<Derived>( base ) threw std::bad_cast" ); + } + + Base2 * base2; + + try + { + base2 = boost::polymorphic_pointer_cast<Base2>( base ); // crosscast + + BOOST_TEST( base2 != 0 ); + + if( base2 != 0 ) + { + BOOST_TEST_EQ( base2->kind2(), "Base2" ); + } + } + catch( std::bad_cast const& ) + { + BOOST_ERROR( "boost::polymorphic_pointer_cast<Base2>( base ) threw std::bad_cast" ); + } + + boost::shared_ptr<Base> sp_base( base ); + boost::shared_ptr<Base2> sp_base2; + try + { + sp_base2 = boost::polymorphic_pointer_cast<Base2>( sp_base ); // crosscast + + BOOST_TEST( sp_base2 != 0 ); + + if( sp_base2 != 0 ) + { + BOOST_TEST_EQ( base2->kind2(), "Base2" ); + } + } + catch( std::bad_cast const& ) + { + BOOST_ERROR( "boost::polymorphic_pointer_cast<Base2>( sp_base ) threw std::bad_cast" ); + } + + // we do not `delete base;` because sahred_ptr is holding base +} + static void test_polymorphic_downcast() { Base * base = new Derived; @@ -115,6 +183,70 @@ static void test_polymorphic_downcast() delete base; } +static void test_polymorphic_pointer_downcast_builtin() +{ + Base * base = new Derived; + + Derived * derived = boost::polymorphic_pointer_downcast<Derived>( base ); + + BOOST_TEST( derived != 0 ); + + if( derived != 0 ) + { + BOOST_TEST_EQ( derived->kind(), "Derived" ); + } + + // polymorphic_pointer_downcast can't do crosscasts + + delete base; +} + +static void test_polymorphic_pointer_downcast_boost_shared() +{ + boost::shared_ptr<Base> base (new Derived); + + boost::shared_ptr<Derived> derived = boost::polymorphic_pointer_downcast<Derived>( base ); + + BOOST_TEST( derived != 0 ); + + if( derived != 0 ) + { + BOOST_TEST_EQ( derived->kind(), "Derived" ); + } +} + +static void test_polymorphic_pointer_downcast_intrusive() +{ + boost::intrusive_ptr<Base> base (new Derived); + + boost::intrusive_ptr<Derived> derived = boost::polymorphic_pointer_downcast<Derived>( base ); + + BOOST_TEST( derived != 0 ); + + if( derived != 0 ) + { + BOOST_TEST_EQ( derived->kind(), "Derived" ); + } +} + +#ifndef BOOST_NO_CXX11_SMART_PTR + +static void test_polymorphic_pointer_downcast_std_shared() +{ + std::shared_ptr<Base> base (new Derived); + + std::shared_ptr<Derived> derived = boost::polymorphic_pointer_downcast<Derived>( base ); + + BOOST_TEST( derived != 0 ); + + if( derived != 0 ) + { + BOOST_TEST_EQ( derived->kind(), "Derived" ); + } +} + +#endif + static void test_polymorphic_cast_fail() { Base * base = new Base; @@ -124,6 +256,21 @@ static void test_polymorphic_cast_fail() delete base; } +static void test_polymorphic_pointer_cast_fail() +{ + Base * base = new Base; + BOOST_TEST_THROWS( boost::polymorphic_pointer_cast<Derived>( base ), std::bad_cast ); + delete base; + + BOOST_TEST_THROWS( boost::polymorphic_pointer_cast<Derived>( boost::shared_ptr<Base>(new Base) ), std::bad_cast ); + +#ifndef BOOST_NO_CXX11_SMART_PTR + BOOST_TEST_THROWS( boost::polymorphic_pointer_cast<Derived>( std::shared_ptr<Base>(new Base) ), std::bad_cast ); +#endif + + BOOST_TEST_THROWS( boost::polymorphic_pointer_cast<Derived>( boost::intrusive_ptr<Base>(new Base) ), std::bad_cast ); +} + static void test_polymorphic_downcast_fail() { Base * base = new Base; @@ -139,12 +286,83 @@ static void test_polymorphic_downcast_fail() delete base; } +static void test_polymorphic_pointer_downcast_builtin_fail() +{ + Base * base = new Base; + + int old_count = assertion_failed_count; + expect_assertion = true; + + boost::polymorphic_pointer_downcast<Derived>( base ); // should assert + + BOOST_TEST_EQ( assertion_failed_count, old_count + 1 ); + expect_assertion = false; + + delete base; +} + +static void test_polymorphic_pointer_downcast_boost_shared_fail() +{ + boost::shared_ptr<Base> base (new Base); + + int old_count = assertion_failed_count; + expect_assertion = true; + + boost::polymorphic_pointer_downcast<Derived>( base ); // should assert + + BOOST_TEST_EQ( assertion_failed_count, old_count + 1 ); + expect_assertion = false; +} + +#ifndef BOOST_NO_CXX11_SMART_PTR + +static void test_polymorphic_pointer_downcast_std_shared_fail() +{ + std::shared_ptr<Base> base (new Base); + + int old_count = assertion_failed_count; + expect_assertion = true; + + boost::polymorphic_pointer_downcast<Derived>( base ); // should assert + + BOOST_TEST_EQ( assertion_failed_count, old_count + 1 ); + expect_assertion = false; +} + +#endif + +static void test_polymorphic_pointer_downcast_intrusive_fail() +{ + boost::intrusive_ptr<Base> base (new Base); + + int old_count = assertion_failed_count; + expect_assertion = true; + + boost::polymorphic_pointer_downcast<Derived>( base ); // should assert + + BOOST_TEST_EQ( assertion_failed_count, old_count + 1 ); + expect_assertion = false; +} + int main() { test_polymorphic_cast(); + test_polymorphic_pointer_cast(); test_polymorphic_downcast(); + test_polymorphic_pointer_downcast_builtin(); + test_polymorphic_pointer_downcast_boost_shared(); + test_polymorphic_pointer_downcast_intrusive(); test_polymorphic_cast_fail(); + test_polymorphic_pointer_cast_fail(); test_polymorphic_downcast_fail(); + test_polymorphic_pointer_downcast_builtin_fail(); + test_polymorphic_pointer_downcast_boost_shared_fail(); + test_polymorphic_pointer_downcast_intrusive_fail(); + +#ifndef BOOST_NO_CXX11_SMART_PTR + test_polymorphic_pointer_downcast_std_shared(); + test_polymorphic_pointer_downcast_std_shared_fail(); +#endif return boost::report_errors(); } |