Compare commits

..

15 Commits

Author SHA1 Message Date
Antony Polukhin 58e8e78899 Run TravisCI tests using valgrind 2015-10-17 17:05:23 +03:00
Antony Polukhin 8f4b6ec985 Fixed issue from track Ticket #11209: conversion - cast_test leaks memory 2015-09-25 19:58:48 +03:00
Antony Polukhin a6100358f4 Add missing include 2015-03-24 22:24:08 +03:00
Antony Polukhin 8f1126f6b2 Merge branch 'alexhenrie-master' into develop 2015-02-03 20:11:03 +03:00
Antony Polukhin b2019fa2df Added a README.md and improved some docs. Added TravicCI integration 2015-02-03 13:28:04 +03:00
Antony Polukhin dc25edb4dd Fixed type deduction on old compilers 2015-02-03 13:00:37 +03:00
Alex Henrie 43ee183296 Correct spelling of "suppress" 2015-01-30 15:22:27 -07:00
Antony Polukhin 84ab59227d Merge pull request #7 from Boris-Rasin/synopsis
fix synopsis for polymorphic_pointer_cast
2014-11-18 19:58:36 +03:00
Boris Rasin 0dc31621c8 fix synopsis for polymorphic_pointer_cast 2014-11-18 14:31:22 +02:00
Antony Polukhin 00b6a53f7e Add polymorphic_pointer_cast 2014-11-10 15:02:20 +04:00
Antony Polukhin 6199649ae2 Move polymorphic_pointer_downcast to a separate header, use pragma once and boost::throw_exception 2014-11-10 14:24:39 +04:00
Antony Polukhin a8253878c8 Merge pull request #6 from Boris-Rasin/polymorphic_pointer_downcast
Add polymorphic_pointer_downcast function template (pull request #2)

Looks really good.
I'll move your implementation into a separate polymorphic_pointer_cast.hpp header to avoid Typeof dependencies for users that do not use `polymorphic_pointer_downcast`
2014-11-10 12:15:34 +03:00
Boris Rasin 582fc91adb add more tests and documentation example for polymorphic_pointer_downcast 2014-11-09 15:37:56 +02:00
Boris Rasin 6a224fa5e9 =add polymorphic_pointer_downcast function template 2014-11-09 00:02:44 +02:00
Antony Polukhin 5d66fea7d5 Merge branch 'master' into develop 2014-08-11 13:19:35 +04:00
9 changed files with 481 additions and 16 deletions
+88
View File
@@ -0,0 +1,88 @@
# Use, modification, and distribution are
# 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)
#
# Copyright Antony Polukhin 2014-2015.
#
# See https://svn.boost.org/trac/boost/wiki/TravisCoverals for description of this file
# and how it can be used with Boost libraries.
#
language: cpp
os:
- linux
env:
- CXX_STANDARD=c++98
- CXX_STANDARD=c++0x
before_install:
# Set this to the name of your Boost library
# Autodetect library name by using the following code: - PROJECT_TO_TEST=$(basename $(pwd))
- PROJECT_TO_TEST=$(basename $(pwd))
# Autodetect Boost branch by using the following code: - BRANCH_TO_TEST=`git rev-parse --abbrev-ref HEAD`
# or by - BRANCH_TO_TEST=$TRAVIS_BRANCH or just directly specify it
- BRANCH_TO_TEST=$TRAVIS_BRANCH
# Files, which coverage results must be ignored (files from other projects). Example: - IGNORE_COVERAGE=
- IGNORE_COVERAGE=
# From this point and below code is same for all the Boost libs
# Cloning Boost libraries (fast nondeep cloning)
- PROJECT_DIR=`pwd`
- BOOST=$HOME/boost-local
- git init $BOOST
- cd $BOOST
- git remote add --no-tags -t $BRANCH_TO_TEST origin https://github.com/boostorg/boost.git
- git fetch --depth=1
- git checkout $BRANCH_TO_TEST
- git submodule update --init --merge
- git remote set-branches --add origin $BRANCH_TO_TEST
- git pull --recurse-submodules
- git submodule update --init
- git checkout $BRANCH_TO_TEST
- git submodule foreach "git reset --quiet --hard; git clean -fxd"
- git reset --hard; git clean -fxd
- git status
- rm -rf $BOOST/libs/$PROJECT_TO_TEST
- mv $PROJECT_DIR/../$PROJECT_TO_TEST/ $BOOST/libs/$PROJECT_TO_TEST
- PROJECT_DIR=$BOOST/libs/$PROJECT_TO_TEST
- ./bootstrap.sh
- ./b2 headers
- sudo apt-get update -qq
- sudo apt-get install -qq valgrind
script:
- if [ "$CCFLAGS" != "" ]; then FLAGS="cxxflags=\"$CCFLAGS\" linkflags=\"$LINKFLAGS\""; else FLAGS=""; fi
- cd $BOOST/libs/$PROJECT_TO_TEST/test/
# `--coverage` flags required to generate coverage info for Coveralls
- ../../../b2 testing.launcher=valgrind cxxflags="--coverage -std=$CXX_STANDARD" linkflags="--coverage"
after_success:
# Copying Coveralls data to a separate folder
- mkdir -p $PROJECT_DIR/coverals
- find ../../../bin.v2/ -name "*.gcda" -exec cp "{}" $PROJECT_DIR/coverals/ \;
- find ../../../bin.v2/ -name "*.gcno" -exec cp "{}" $PROJECT_DIR/coverals/ \;
# Preparing Coveralls data by
# ... installing the tools
- sudo apt-get install -qq python-yaml lcov
# ... changind data format to a readable one
- lcov --directory $PROJECT_DIR/coverals --base-directory ./ --capture --output-file $PROJECT_DIR/coverals/coverage.info
# ... erasing /test/ /example/ folder data
- cd $BOOST
- lcov --remove $PROJECT_DIR/coverals/coverage.info "/usr*" "*/$PROJECT_TO_TEST/test/*" $IGNORE_COVERAGE "*/$PROJECT_TO_TEST/tests/*" "*/$PROJECT_TO_TEST/examples/*" "*/$PROJECT_TO_TEST/example/*" -o $PROJECT_DIR/coverals/coverage.info
# ... erasing data that is not related to this project directly
- OTHER_LIBS=`grep "submodule .*" .gitmodules | sed 's/\[submodule\ "\(.*\)"\]/"\*\/boost\/\1\.hpp" "\*\/boost\/\1\/\*"/g'| sed "/\"\*\/boost\/$PROJECT_TO_TEST\/\*\"/d" | sed ':a;N;$!ba;s/\n/ /g'`
- echo $OTHER_LIBS
- eval "lcov --remove $PROJECT_DIR/coverals/coverage.info $OTHER_LIBS -o $PROJECT_DIR/coverals/coverage.info"
# Sending data to Coveralls
- cd $PROJECT_DIR
- gem install coveralls-lcov
- coveralls-lcov coverals/coverage.info
+16
View File
@@ -0,0 +1,16 @@
#[Boost.Conversion](http://boost.org/libs/conversion)
Boost.Conversion is one of the [Boost C++ Libraries](http://github.com/boostorg). This library improves program safety and clarity by performing otherwise messy conversions.
### Test results
@ | Build | Tests coverage | More info
----------------|-------------- | -------------- |-----------
Develop branch: | [![Build Status](https://travis-ci.org/apolukhin/conversion.svg?branch=develop)](https://travis-ci.org/apolukhin/conversion) | [![Coverage Status](https://coveralls.io/repos/apolukhin/conversion/badge.png?branch=develop)](https://coveralls.io/r/apolukhin/conversion?branch=develop) | [details...](http://www.boost.org/development/tests/develop/developer/conversion.html)
Master branch: | [![Build Status](https://travis-ci.org/apolukhin/conversion.svg?branch=master)](https://travis-ci.org/apolukhin/conversion) | [![Coverage Status](https://coveralls.io/repos/apolukhin/conversion/badge.png?branch=master)](https://coveralls.io/r/apolukhin/conversion?branch=master) | [details...](http://www.boost.org/development/tests/master/developer/conversion.html)
[Open Issues](https://svn.boost.org/trac/boost/query?status=!closed&component=conversion&or&status=!closed&component=lexical_cast)
### License
Distributed under the [Boost Software License, Version 1.0](http://boost.org/LICENSE_1_0.txt).
+58 -8
View File
@@ -26,10 +26,12 @@
<h2><a name="Cast Functions">Cast Functions</a></h2>
<p>The header <a href="../../boost/polymorphic_cast.hpp">boost/polymorphic_cast.hpp</a> provides <code>
<a href="#Polymorphic_cast">polymorphic_cast</a> and</code> <a href=
"#Polymorphic_cast"><code>polymorphic_downcast</code></a> function templates designed to
complement the C++ built-in casts.</p>
<p>The header <a href="../../boost/polymorphic_cast.hpp">boost/polymorphic_cast.hpp</a> provides
<code><a href="#Polymorphic_cast">polymorphic_cast</a></code> and
<code><a href="#Polymorphic_cast">polymorphic_downcast</a></code>
function templates designed to complement the C++ built-in casts.</p> <p>The header <a href="../../boost/polymorphic_pointer_cast.hpp">boost/polymorphic_pointer_cast.hpp</a> provides
<code><a href="#Polymorphic_cast">polymorphic_pointer_cast</a></code> and
<code><a href="#Polymorphic_cast">polymorphic_pointer_downcast</a></code> function templates.
<p>The program <a href="test/cast_test.cpp">cast_test.cpp</a> can be used to
verify these function templates work as expected.</p>
@@ -78,7 +80,7 @@
<b>Warning:</b> Because <code>polymorphic_downcast</code> uses assert(), it
violates the One Definition Rule (ODR) if NDEBUG is inconsistently
defined across translation units. [See ISO Std 3.2]
</p><p>
<p>
For crosscasts, or when the success of a cast can only be known at
runtime, or when efficiency is not important,
<code>polymorphic_cast</code> is preferred. </p>
@@ -88,7 +90,18 @@
whether a given interface is supported; in that case a return of 0 isn't
an error condition.</p>
<h3>polymorphic_cast and polymorphic_downcast synopsis</h3>
<p>While <code>polymorphic_downcast</code> and <code>polymorphic_cast</code> work with built-in pointer types only,
<code>polymorphic_pointer_downcast</code> and <code>polymorphic_pointer_cast</code> are more generic versions
with support for any pointer type for which the following expressions would be valid:<br><br>
<p> For <code>polymorphic_pointer_downcast</code>:</p>
<code>&nbsp;&nbsp;static_pointer_cast&lt;Derived&gt;(p);<br>&nbsp;&nbsp;dynamic_pointer_cast&lt;Derived&gt;(p);</code><br><br>
<p> For <code>polymorphic_pointer_cast</code>:</p>
<code>&nbsp;&nbsp;dynamic_pointer_cast&lt;Derived&gt;(p);<br>&nbsp;&nbsp;!p; // conversion to bool with negation</code><br><br>
<p>This includes C++ built-in pointers, <code>std::shared_ptr, boost::shared_ptr, boost::intrusive_ptr</code>, etc.</p>
<h3>polymorphic_cast, polymorphic_downcast, polymorphic_pointer_cast and polymorphic_pointer_downcast synopsis</h3>
<blockquote>
<pre>namespace boost {
@@ -103,6 +116,16 @@ inline Derived polymorphic_downcast(Base* x);
// Effects: assert( dynamic_cast&lt;Derived&gt;(x) == x );
// Returns: static_cast&lt;Derived&gt;(x)
template &lt;class Derived, class Base&gt;
inline auto polymorphic_pointer_cast(Base x);
// Throws: std::bad_cast if ( dynamic_pointer_cast&lt;Derived&gt;(x) == 0 )
// Returns: dynamic_pointer_cast&lt;Derived&gt;(x)
template &lt;class Derived, class Base&gt;
inline auto polymorphic_pointer_downcast(Base x);
// Effects: assert( dynamic_pointer_cast&lt;Derived&gt;(x) == x );
// Returns: static_pointer_cast&lt;Derived&gt;(x)
}
</pre>
</blockquote>
@@ -122,14 +145,41 @@ void f( Fruit * fruit ) {
</pre>
</blockquote>
<h3>polymorphic_pointer_downcast example</h3>
<blockquote>
<pre>#include &lt;boost/polymorphic_pointer_cast.hpp&gt;
class Fruit { public: virtual ~Fruit(){} };
class Banana : public Fruit {};
// use one of these:
typedef Fruit* FruitPtr;
typedef std::shared_ptr&lt;Fruit&gt; FruitPtr;
typedef boost::shared_ptr&lt;Fruit&gt; FruitPtr;
typedef boost::intrusive_ptr&lt;Fruit&gt; FruitPtr;
void f(FruitPtr fruit)
{
// ... logic which leads us to believe it is a banana
auto banana = boost::polymorphic_pointer_downcast&lt;Banana&gt;(fruit);
...
}
</pre>
</blockquote>
<h3>History</h3>
<p><code>polymorphic_cast</code> was suggested by Bjarne Stroustrup in "The C++
Programming Language".<br>
<code>polymorphic_downcast</code> was contributed by <a href=
"http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a>.<code><br>
"http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a>.<br>
<code>polymorphic_pointer_downcast</code> was contributed by <a href=
"http://www.boost.org/people/boris_rasin.htm">Boris Rasin</a> and
<code>polymorphic_pointer_cast</code> by Antony Polukhin.<br>
An old
numeric_cast</code> that was contributed by <a href=
<code>numeric_cast</code> that was contributed by <a href=
"http://www.boost.org/people/kevlin_henney.htm">Kevlin Henney</a> is now superseeded by the <a href="../numeric/conversion/doc/html/index.html">Boost Numeric Conversion Library</a></p>
<hr>
+10 -1
View File
@@ -1,6 +1,7 @@
// boost polymorphic_cast.hpp header file ----------------------------------------------//
// (C) Copyright Kevlin Henney and Dave Abrahams 1999.
// (C) Copyright Boris Rasin 2014.
// 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)
@@ -8,6 +9,9 @@
// See http://www.boost.org/libs/conversion for Documentation.
// Revision History
// 10 Nov 14 polymorphic_pointer_downcast moved to a separate header,
// minor improvements to stisfy latest Boost coding style
// 08 Nov 14 Add polymorphic_pointer_downcast (Boris Rasin)
// 09 Jun 14 "cast.hpp" was renamed to "polymorphic_cast.hpp" and
// inclusion of numeric_cast was removed (Antony Polukhin)
// 23 Jun 05 numeric_cast removed and redirected to the new verion (Fernando Cacciola)
@@ -47,8 +51,13 @@
# include <boost/config.hpp>
# include <boost/assert.hpp>
# include <boost/throw_exception.hpp>
# include <typeinfo>
#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif
namespace boost
{
// See the documentation for descriptions of how to choose between
@@ -64,7 +73,7 @@ namespace boost
inline Target polymorphic_cast(Source* x)
{
Target tmp = dynamic_cast<Target>(x);
if ( tmp == 0 ) throw std::bad_cast();
if ( tmp == 0 ) boost::throw_exception( std::bad_cast() );
return tmp;
}
@@ -0,0 +1,78 @@
// boost polymorphic_pointer_cast.hpp header file ----------------------------------------------//
// (C) Copyright Boris Rasin and Antony Polukhin 2014-2015.
// 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)
// See http://www.boost.org/libs/conversion for Documentation.
#ifndef BOOST_CONVERSION_POLYMORPHIC_POINTER_CAST_HPP
#define BOOST_CONVERSION_POLYMORPHIC_POINTER_CAST_HPP
# include <boost/config.hpp>
# include <boost/assert.hpp>
# include <boost/pointer_cast.hpp>
# include <boost/throw_exception.hpp>
# include <boost/utility/declval.hpp>
# ifdef BOOST_NO_CXX11_DECLTYPE
# include <boost/typeof/typeof.hpp>
# endif
#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif
namespace boost
{
// See the documentation for descriptions of how to choose between
// static_pointer_cast<>, dynamic_pointer_cast<>, polymorphic_pointer_cast<> and polymorphic_pointer_downcast<>
// polymorphic_pointer_downcast --------------------------------------------//
// BOOST_ASSERT() checked polymorphic downcast. Crosscasts prohibited.
// Supports any type with static_pointer_cast/dynamic_pointer_cast functions:
// built-in pointers, std::shared_ptr, boost::shared_ptr, boost::intrusive_ptr, etc.
// WARNING: Because this cast uses BOOST_ASSERT(), it violates
// the One Definition Rule if used in multiple translation units
// where BOOST_DISABLE_ASSERTS, BOOST_ENABLE_ASSERT_HANDLER
// NDEBUG are defined inconsistently.
// Contributed by Boris Rasin
namespace detail
{
template <typename Target, typename Source>
struct dynamic_pointer_cast_result
{
#ifdef BOOST_NO_CXX11_DECLTYPE
BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, dynamic_pointer_cast<Target>(boost::declval<Source>()))
typedef typename nested::type type;
#else
typedef decltype(dynamic_pointer_cast<Target>(boost::declval<Source>())) type;
#endif
};
}
template <typename Target, typename Source>
inline typename detail::dynamic_pointer_cast_result<Target, Source>::type
polymorphic_pointer_downcast (const Source& x)
{
BOOST_ASSERT(dynamic_pointer_cast<Target> (x) == x);
return static_pointer_cast<Target> (x);
}
template <typename Target, typename Source>
inline typename detail::dynamic_pointer_cast_result<Target, Source>::type
polymorphic_pointer_cast (const Source& x)
{
typename detail::dynamic_pointer_cast_result<Target, Source>::type tmp
= dynamic_pointer_cast<Target> (x);
if ( !tmp ) boost::throw_exception( std::bad_cast() );
return tmp;
}
} // namespace boost
#endif // BOOST_CONVERSION_POLYMORPHIC_POINTER_CAST_HPP
+6 -2
View File
@@ -27,10 +27,14 @@ Standard's built-in casts.</p>
Conversion Library is
supplied by several headers:</p>
<ul>
<li>The <a href="cast.htm">boost/cast</a> header provides <b>polymorphic_cast&lt;&gt;</b>
and <b>polymorphic_downcast&lt;&gt;</b> to perform safe casting between
<li>The <a href="cast.htm">boost/polymorphic_cast.hpp and boost/polymorphic_pointer_cast.hpp</a>
headers provide <b>polymorphic_cast&lt;&gt;</b>,
<b>polymorphic_downcast&lt;&gt;</b> and <b>polymorphic_pointer_downcast&lt;&gt;</b> to perform safe casting between
polymorphic types.<br>
</li>
<li>The boost/implicit_cast.hpp header provides <b>implicit_cast&lt;&gt;</b>
to perform implicit casts only (no down-cast, no void*->T*, no U->T if T has only explicit constructors for U).<br>
</li>
<li>The <a href="../../doc/html/boost_lexical_cast.html">boost/lexical_cast</a> header provides <b>lexical_cast&lt;&gt;</b>
general literal text conversions, such as an <code>int</code> represented as
a <code>string</code>, or vice-versa.</li>
+4 -2
View File
@@ -51,7 +51,8 @@ int main( int argc, char * argv[] )
// test polymorphic_cast ---------------------------------------------------//
// tests which should succeed
Base * base = new Derived;
Derived derived_instance;
Base * base = &derived_instance;
Base2 * base2 = 0;
Derived * derived = 0;
derived = polymorphic_downcast<Derived*>( base ); // downcast
@@ -66,7 +67,8 @@ int main( int argc, char * argv[] )
// tests which should result in errors being detected
int err_count = 0;
base = new Base;
Base base_instance;
base = &base_instance;
if ( argc > 1 && *argv[1] == '1' )
{ derived = polymorphic_downcast<Derived*>( base ); } // #1 assert failure
+1 -1
View File
@@ -29,7 +29,7 @@ int main()
type<foo> f = check_return(boost::implicit_cast<foo>("hello"));
type<long> z = check_return(boost::implicit_cast<long>(foo("hello")));
// warning supression:
// warning suppression:
(void)x;
(void)f;
(void)z;
+220 -2
View File
@@ -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();
}