forked from boostorg/conversion
Move polymorphic_pointer_downcast to a separate header, use pragma once and boost::throw_exception
This commit is contained in:
10
cast.htm
10
cast.htm
@@ -27,10 +27,10 @@
|
|||||||
<h2><a name="Cast Functions">Cast Functions</a></h2>
|
<h2><a name="Cast Functions">Cast Functions</a></h2>
|
||||||
|
|
||||||
<p>The header <a href="../../boost/polymorphic_cast.hpp">boost/polymorphic_cast.hpp</a> provides
|
<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_cast</a></code> and
|
||||||
<code><a href="#Polymorphic_cast">polymorphic_downcast</a></code> and
|
<code><a href="#Polymorphic_cast">polymorphic_downcast</a></code>
|
||||||
<code><a href="#Polymorphic_cast">polymorphic_pointer_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
|
||||||
function templates designed to complement the C++ built-in casts.</p>
|
<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
|
<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>
|
verify these function templates work as expected.</p>
|
||||||
@@ -137,7 +137,7 @@ void f( Fruit * fruit ) {
|
|||||||
<h3>polymorphic_pointer_downcast example</h3>
|
<h3>polymorphic_pointer_downcast example</h3>
|
||||||
|
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<pre>#include <boost/polymorphic_cast.hpp>
|
<pre>#include <boost/polymorphic_pointer_cast.hpp>
|
||||||
|
|
||||||
class Fruit { public: virtual ~Fruit(){} };
|
class Fruit { public: virtual ~Fruit(){} };
|
||||||
class Banana : public Fruit {};
|
class Banana : public Fruit {};
|
||||||
|
@@ -9,6 +9,8 @@
|
|||||||
// See http://www.boost.org/libs/conversion for Documentation.
|
// See http://www.boost.org/libs/conversion for Documentation.
|
||||||
|
|
||||||
// Revision History
|
// 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)
|
// 08 Nov 14 Add polymorphic_pointer_downcast (Boris Rasin)
|
||||||
// 09 Jun 14 "cast.hpp" was renamed to "polymorphic_cast.hpp" and
|
// 09 Jun 14 "cast.hpp" was renamed to "polymorphic_cast.hpp" and
|
||||||
// inclusion of numeric_cast was removed (Antony Polukhin)
|
// inclusion of numeric_cast was removed (Antony Polukhin)
|
||||||
@@ -49,11 +51,13 @@
|
|||||||
|
|
||||||
# include <boost/config.hpp>
|
# include <boost/config.hpp>
|
||||||
# include <boost/assert.hpp>
|
# include <boost/assert.hpp>
|
||||||
# include <boost/pointer_cast.hpp>
|
# include <boost/throw_exception.hpp>
|
||||||
# include <boost/utility/declval.hpp>
|
|
||||||
# include <boost/typeof/typeof.hpp>
|
|
||||||
# include <typeinfo>
|
# include <typeinfo>
|
||||||
|
|
||||||
|
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||||
|
# pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
// See the documentation for descriptions of how to choose between
|
// See the documentation for descriptions of how to choose between
|
||||||
@@ -69,7 +73,7 @@ namespace boost
|
|||||||
inline Target polymorphic_cast(Source* x)
|
inline Target polymorphic_cast(Source* x)
|
||||||
{
|
{
|
||||||
Target tmp = dynamic_cast<Target>(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;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,41 +95,6 @@ namespace boost
|
|||||||
return static_cast<Target>(x);
|
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
|
} // namespace boost
|
||||||
|
|
||||||
#endif // BOOST_POLYMORPHIC_CAST_HPP
|
#endif // BOOST_POLYMORPHIC_CAST_HPP
|
||||||
|
66
include/boost/polymorphic_pointer_cast.hpp
Normal file
66
include/boost/polymorphic_pointer_cast.hpp
Normal 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
|
@@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
#define BOOST_ENABLE_ASSERT_HANDLER
|
#define BOOST_ENABLE_ASSERT_HANDLER
|
||||||
#include <boost/polymorphic_cast.hpp>
|
#include <boost/polymorphic_cast.hpp>
|
||||||
|
#include <boost/polymorphic_pointer_cast.hpp>
|
||||||
#include <boost/smart_ptr/shared_ptr.hpp>
|
#include <boost/smart_ptr/shared_ptr.hpp>
|
||||||
#include <boost/smart_ptr/intrusive_ptr.hpp>
|
#include <boost/smart_ptr/intrusive_ptr.hpp>
|
||||||
#include <boost/smart_ptr/intrusive_ref_counter.hpp>
|
#include <boost/smart_ptr/intrusive_ref_counter.hpp>
|
||||||
|
Reference in New Issue
Block a user