diff --git a/include/boost/implicit_cast.hpp b/include/boost/implicit_cast.hpp index 5b1cd92..d82db76 100644 --- a/include/boost/implicit_cast.hpp +++ b/include/boost/implicit_cast.hpp @@ -5,17 +5,24 @@ #ifndef IMPLICIT_CAST_DWA200356_HPP # define IMPLICIT_CAST_DWA200356_HPP -# include - namespace boost { +namespace detail { + +template struct icast_identity +{ + typedef T type; +}; + +} // namespace detail + // implementation originally suggested by C. Green in // http://lists.boost.org/MailArchives/boost/msg00886.php // The use of identity creates a non-deduced form, so that the // explicit template argument must be supplied template -inline T implicit_cast (typename mpl::identity::type x) { +inline T implicit_cast (typename boost::detail::icast_identity::type x) { return x; } diff --git a/include/boost/polymorphic_cast.hpp b/include/boost/polymorphic_cast.hpp index f02d7ea..03013c7 100644 --- a/include/boost/polymorphic_cast.hpp +++ b/include/boost/polymorphic_cast.hpp @@ -48,9 +48,6 @@ # include # include # include -# include -# include -# include namespace boost { diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index f79e724..69f8b3c 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -27,5 +27,6 @@ test-suite conversion [ compile-fail implicit_cast_fail.cpp ] [ run cast_test.cpp ] [ run numeric_cast_test.cpp ] + [ run polymorphic_cast_test.cpp ] + [ compile-fail implicit_cast_fail2.cpp ] ; - diff --git a/test/cast_test.cpp b/test/cast_test.cpp index fa30df8..5295e32 100644 --- a/test/cast_test.cpp +++ b/test/cast_test.cpp @@ -14,14 +14,8 @@ // 3 Aug 99 Initial Version #include -#include -#include // for DBL_MAX (Peter Schmid) #include -# if SCHAR_MAX == LONG_MAX -# error "This test program doesn't work if SCHAR_MAX == LONG_MAX" -# endif - using namespace boost; using std::cout; diff --git a/test/implicit_cast_fail.cpp b/test/implicit_cast_fail.cpp index 442fa4c..86ccbb2 100644 --- a/test/implicit_cast_fail.cpp +++ b/test/implicit_cast_fail.cpp @@ -4,10 +4,6 @@ // http://www.boost.org/LICENSE_1_0.txt) #include -#include - -#define BOOST_INCLUDE_MAIN -#include using boost::implicit_cast; @@ -16,11 +12,9 @@ struct foo explicit foo(char const*) {} }; -int test_main(int, char*[]) +int main() { foo x = implicit_cast("foobar"); (void)x; // warning suppression. - BOOST_CHECK(false); // suppressing warning about 'boost::unit_test::{anonymous}::unit_test_log' defined but not used return 0; } - diff --git a/test/implicit_cast_fail2.cpp b/test/implicit_cast_fail2.cpp new file mode 100644 index 0000000..97cc2d8 --- /dev/null +++ b/test/implicit_cast_fail2.cpp @@ -0,0 +1,19 @@ +// +// Test that implicit_cast requires a template argument +// +// Copyright 2014 Peter Dimov +// +// Distributed under 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 + +int main() +{ + int x = boost::implicit_cast( 1 ); + (void)x; + + return 0; +} diff --git a/test/polymorphic_cast_test.cpp b/test/polymorphic_cast_test.cpp new file mode 100644 index 0000000..b3f1397 --- /dev/null +++ b/test/polymorphic_cast_test.cpp @@ -0,0 +1,150 @@ +// +// Test boost::polymorphic_cast, boost::polymorphic_downcast +// +// Copyright 1999 Beman Dawes +// Copyright 1999 Dave Abrahams +// Copyright 2014 Peter Dimov +// +// Distributed under 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 +// + +#define BOOST_ENABLE_ASSERT_HANDLER +#include +#include +#include + +static bool expect_assertion = false; +static int assertion_failed_count = 0; + +// BOOST_ASSERT custom handler +void boost::assertion_failed( char const * expr, char const * function, char const * file, long line ) +{ + if( expect_assertion ) + { + ++assertion_failed_count; + } + else + { + BOOST_ERROR( "unexpected assertion" ); + + BOOST_LIGHTWEIGHT_TEST_OSTREAM + << file << "(" << line << "): assertion '" << expr << "' failed in function '" + << function << "'" << std::endl; + } +} + +// + +struct Base +{ + virtual ~Base() {} + virtual std::string kind() { return "Base"; } +}; + +struct Base2 +{ + virtual ~Base2() {} + virtual std::string kind2() { return "Base2"; } +}; + +struct Derived : public Base, Base2 +{ + virtual std::string kind() { return "Derived"; } +}; + +static void test_polymorphic_cast() +{ + Base * base = new Derived; + + Derived * derived; + + try + { + derived = boost::polymorphic_cast( base ); + + BOOST_TEST( derived != 0 ); + + if( derived != 0 ) + { + BOOST_TEST_EQ( derived->kind(), "Derived" ); + } + } + catch( std::bad_cast const& ) + { + BOOST_ERROR( "boost::polymorphic_cast( base ) threw std::bad_cast" ); + } + + Base2 * base2; + + try + { + base2 = boost::polymorphic_cast( base ); // crosscast + + BOOST_TEST( base2 != 0 ); + + if( base2 != 0 ) + { + BOOST_TEST_EQ( base2->kind2(), "Base2" ); + } + } + catch( std::bad_cast const& ) + { + BOOST_ERROR( "boost::polymorphic_cast( base ) threw std::bad_cast" ); + } + + delete base; +} + +static void test_polymorphic_downcast() +{ + Base * base = new Derived; + + Derived * derived = boost::polymorphic_downcast( base ); + + BOOST_TEST( derived != 0 ); + + if( derived != 0 ) + { + BOOST_TEST_EQ( derived->kind(), "Derived" ); + } + + // polymorphic_downcast can't do crosscasts + + delete base; +} + +static void test_polymorphic_cast_fail() +{ + Base * base = new Base; + + BOOST_TEST_THROWS( boost::polymorphic_cast( base ), std::bad_cast ); + + delete base; +} + +static void test_polymorphic_downcast_fail() +{ + Base * base = new Base; + + int old_count = assertion_failed_count; + expect_assertion = true; + + boost::polymorphic_downcast( base ); // should assert + + BOOST_TEST_EQ( assertion_failed_count, old_count + 1 ); + expect_assertion = false; + + delete base; +} + +int main() +{ + test_polymorphic_cast(); + test_polymorphic_downcast(); + test_polymorphic_cast_fail(); + test_polymorphic_downcast_fail(); + + return boost::report_errors(); +}