Move polymorphic_pointer_downcast to a separate header, use pragma once and boost::throw_exception

This commit is contained in:
Antony Polukhin
2014-11-10 14:24:39 +04:00
parent a8253878c8
commit 6199649ae2
4 changed files with 80 additions and 44 deletions

View File

@@ -27,10 +27,10 @@
<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></code>,
<code><a href="#Polymorphic_cast">polymorphic_downcast</a></code> and
<code><a href="#Polymorphic_cast">polymorphic_pointer_downcast</a></code>
function templates designed to complement the C++ built-in casts.</p>
<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_downcast</a></code> function template.
<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>
@@ -137,7 +137,7 @@ void f( Fruit * fruit ) {
<h3>polymorphic_pointer_downcast example</h3>
<blockquote>
<pre>#include &lt;boost/polymorphic_cast.hpp&gt;
<pre>#include &lt;boost/polymorphic_pointer_cast.hpp&gt;
class Fruit { public: virtual ~Fruit(){} };
class Banana : public Fruit {};

View File

@@ -9,6 +9,8 @@
// 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)
@@ -49,11 +51,13 @@
# include <boost/config.hpp>
# include <boost/assert.hpp>
# include <boost/pointer_cast.hpp>
# include <boost/utility/declval.hpp>
# include <boost/typeof/typeof.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
@@ -69,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;
}
@@ -91,41 +95,6 @@ namespace boost
return static_cast<Target>(x);
}
// 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 static_pointer_cast_result
{
#ifdef BOOST_NO_CXX11_DECLTYPE
BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, static_pointer_cast<Target>(boost::declval<Source>()))
typedef typename nested::type type;
#else
typedef decltype(static_pointer_cast<Target>(boost::declval<Source>())) type;
#endif
};
}
template <typename Target, typename Source>
inline typename detail::static_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);
}
} // namespace boost
#endif // BOOST_POLYMORPHIC_CAST_HPP

View File

@@ -0,0 +1,66 @@
// boost polymorphic_pointer_cast.hpp header file ----------------------------------------------//
// (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)
// 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/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 static_pointer_cast_result
{
#ifdef BOOST_NO_CXX11_DECLTYPE
BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, static_pointer_cast<Target>(boost::declval<Source>()))
typedef typename nested::type type;
#else
typedef decltype(static_pointer_cast<Target>(boost::declval<Source>())) type;
#endif
};
}
template <typename Target, typename Source>
inline typename detail::static_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);
}
} // namespace boost
#endif // BOOST_CONVERSION_POLYMORPHIC_POINTER_CAST_HPP

View File

@@ -13,6 +13,7 @@
#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>