From 582fc91adb10fa4c6ea124d36b34cbfdfc760a45 Mon Sep 17 00:00:00 2001 From: Boris Rasin Date: Sun, 9 Nov 2014 15:37:56 +0200 Subject: [PATCH] add more tests and documentation example for polymorphic_pointer_downcast --- cast.htm | 24 +++++++ test/polymorphic_cast_test.cpp | 112 +++++++++++++++++++++++++++++++-- 2 files changed, 131 insertions(+), 5 deletions(-) diff --git a/cast.htm b/cast.htm index 860ac17..d913d72 100644 --- a/cast.htm +++ b/cast.htm @@ -134,6 +134,30 @@ void f( Fruit * fruit ) { +

polymorphic_pointer_downcast example

+ +
+
#include <boost/polymorphic_cast.hpp>
+
+class Fruit { public: virtual ~Fruit(){} };
+class Banana : public Fruit {};
+
+// use one of these:
+
+typedef Fruit* FruitPtr;
+typedef std::shared_ptr<Fruit> FruitPtr;
+typedef boost::shared_ptr<Fruit> FruitPtr;
+typedef boost::intrusive_ptr<Fruit> FruitPtr;
+
+void f(FruitPtr fruit)
+{
+  // ... logic which leads us to believe it is a banana
+  auto banana = boost::polymorphic_pointer_downcast<Banana>(fruit);
+  ...
+}
+
+
+

History

polymorphic_cast was suggested by Bjarne Stroustrup in "The C++ diff --git a/test/polymorphic_cast_test.cpp b/test/polymorphic_cast_test.cpp index b8a500c..9c79152 100644 --- a/test/polymorphic_cast_test.cpp +++ b/test/polymorphic_cast_test.cpp @@ -13,8 +13,12 @@ #define BOOST_ENABLE_ASSERT_HANDLER #include +#include +#include +#include #include #include +#include static bool expect_assertion = false; static int assertion_failed_count = 0; @@ -38,7 +42,7 @@ void boost::assertion_failed( char const * expr, char const * function, char con // -struct Base +struct Base : boost::intrusive_ref_counter { virtual ~Base() {} virtual std::string kind() { return "Base"; } @@ -116,7 +120,7 @@ static void test_polymorphic_downcast() delete base; } -static void test_polymorphic_pointer_downcast() +static void test_polymorphic_pointer_downcast_builtin() { Base * base = new Derived; @@ -134,6 +138,52 @@ static void test_polymorphic_pointer_downcast() delete base; } +static void test_polymorphic_pointer_downcast_boost_shared() +{ + boost::shared_ptr base (new Derived); + + boost::shared_ptr derived = boost::polymorphic_pointer_downcast( 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 (new Derived); + + boost::intrusive_ptr derived = boost::polymorphic_pointer_downcast( 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 (new Derived); + + std::shared_ptr derived = boost::polymorphic_pointer_downcast( 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; @@ -158,7 +208,7 @@ static void test_polymorphic_downcast_fail() delete base; } -static void test_polymorphic_pointer_downcast_fail() +static void test_polymorphic_pointer_downcast_builtin_fail() { Base * base = new Base; @@ -173,14 +223,66 @@ static void test_polymorphic_pointer_downcast_fail() delete base; } +static void test_polymorphic_pointer_downcast_boost_shared_fail() +{ + boost::shared_ptr base (new Base); + + int old_count = assertion_failed_count; + expect_assertion = true; + + boost::polymorphic_pointer_downcast( 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 (new Base); + + int old_count = assertion_failed_count; + expect_assertion = true; + + boost::polymorphic_pointer_downcast( 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 (new Base); + + int old_count = assertion_failed_count; + expect_assertion = true; + + boost::polymorphic_pointer_downcast( base ); // should assert + + BOOST_TEST_EQ( assertion_failed_count, old_count + 1 ); + expect_assertion = false; +} + int main() { test_polymorphic_cast(); test_polymorphic_downcast(); - test_polymorphic_pointer_downcast(); + test_polymorphic_pointer_downcast_builtin(); + test_polymorphic_pointer_downcast_boost_shared(); + test_polymorphic_pointer_downcast_intrusive(); test_polymorphic_cast_fail(); test_polymorphic_downcast_fail(); - test_polymorphic_pointer_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(); }