mirror of
https://github.com/boostorg/conversion.git
synced 2026-08-06 05:24:08 +02:00
Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 58e8e78899 | |||
| 8f4b6ec985 | |||
| a6100358f4 | |||
| 8f1126f6b2 | |||
| b2019fa2df | |||
| dc25edb4dd | |||
| 43ee183296 | |||
| 84ab59227d | |||
| 0dc31621c8 | |||
| 00b6a53f7e | |||
| 6199649ae2 | |||
| a8253878c8 | |||
| 582fc91adb | |||
| 6a224fa5e9 | |||
| 5d66fea7d5 |
+88
@@ -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
|
||||
@@ -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: | [](https://travis-ci.org/apolukhin/conversion) | [](https://coveralls.io/r/apolukhin/conversion?branch=develop) | [details...](http://www.boost.org/development/tests/develop/developer/conversion.html)
|
||||
Master branch: | [](https://travis-ci.org/apolukhin/conversion) | [](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).
|
||||
@@ -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> static_pointer_cast<Derived>(p);<br> dynamic_pointer_cast<Derived>(p);</code><br><br>
|
||||
|
||||
<p> For <code>polymorphic_pointer_cast</code>:</p>
|
||||
<code> dynamic_pointer_cast<Derived>(p);<br> !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<Derived>(x) == x );
|
||||
// Returns: static_cast<Derived>(x)
|
||||
|
||||
template <class Derived, class Base>
|
||||
inline auto polymorphic_pointer_cast(Base x);
|
||||
// Throws: std::bad_cast if ( dynamic_pointer_cast<Derived>(x) == 0 )
|
||||
// Returns: dynamic_pointer_cast<Derived>(x)
|
||||
|
||||
template <class Derived, class Base>
|
||||
inline auto polymorphic_pointer_downcast(Base x);
|
||||
// Effects: assert( dynamic_pointer_cast<Derived>(x) == x );
|
||||
// Returns: static_pointer_cast<Derived>(x)
|
||||
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
@@ -122,14 +145,41 @@ void f( Fruit * fruit ) {
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<h3>polymorphic_pointer_downcast example</h3>
|
||||
|
||||
<blockquote>
|
||||
<pre>#include <boost/polymorphic_pointer_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);
|
||||
...
|
||||
}
|
||||
</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>
|
||||
|
||||
|
||||
@@ -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
@@ -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<></b>
|
||||
and <b>polymorphic_downcast<></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<></b>,
|
||||
<b>polymorphic_downcast<></b> and <b>polymorphic_pointer_downcast<></b> to perform safe casting between
|
||||
polymorphic types.<br>
|
||||
</li>
|
||||
<li>The boost/implicit_cast.hpp header provides <b>implicit_cast<></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<></b>
|
||||
general literal text conversions, such as an <code>int</code> represented as
|
||||
a <code>string</code>, or vice-versa.</li>
|
||||
|
||||
+4
-2
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user