Chris@102: // boost polymorphic_pointer_cast.hpp header file ----------------------------------------------// Chris@102: // (C) Copyright Boris Rasin and Antony Polukhin 2014-2015. Chris@102: // Distributed under the Boost Chris@102: // Software License, Version 1.0. (See accompanying file Chris@102: // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@102: Chris@102: // See http://www.boost.org/libs/conversion for Documentation. Chris@102: Chris@102: #ifndef BOOST_CONVERSION_POLYMORPHIC_POINTER_CAST_HPP Chris@102: #define BOOST_CONVERSION_POLYMORPHIC_POINTER_CAST_HPP Chris@102: Chris@102: # include Chris@102: # include Chris@102: # include Chris@102: # include Chris@102: # include Chris@102: # ifdef BOOST_NO_CXX11_DECLTYPE Chris@102: # include Chris@102: # endif Chris@102: Chris@102: #ifdef BOOST_HAS_PRAGMA_ONCE Chris@102: # pragma once Chris@102: #endif Chris@102: Chris@102: namespace boost Chris@102: { Chris@102: // See the documentation for descriptions of how to choose between Chris@102: // static_pointer_cast<>, dynamic_pointer_cast<>, polymorphic_pointer_cast<> and polymorphic_pointer_downcast<> Chris@102: Chris@102: // polymorphic_pointer_downcast --------------------------------------------// Chris@102: Chris@102: // BOOST_ASSERT() checked polymorphic downcast. Crosscasts prohibited. Chris@102: // Supports any type with static_pointer_cast/dynamic_pointer_cast functions: Chris@102: // built-in pointers, std::shared_ptr, boost::shared_ptr, boost::intrusive_ptr, etc. Chris@102: Chris@102: // WARNING: Because this cast uses BOOST_ASSERT(), it violates Chris@102: // the One Definition Rule if used in multiple translation units Chris@102: // where BOOST_DISABLE_ASSERTS, BOOST_ENABLE_ASSERT_HANDLER Chris@102: // NDEBUG are defined inconsistently. Chris@102: Chris@102: // Contributed by Boris Rasin Chris@102: Chris@102: namespace detail Chris@102: { Chris@102: template Chris@102: struct dynamic_pointer_cast_result Chris@102: { Chris@102: #ifdef BOOST_NO_CXX11_DECLTYPE Chris@102: BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, dynamic_pointer_cast(boost::declval())) Chris@102: typedef typename nested::type type; Chris@102: #else Chris@102: typedef decltype(dynamic_pointer_cast(boost::declval())) type; Chris@102: #endif Chris@102: }; Chris@102: } Chris@102: Chris@102: template Chris@102: inline typename detail::dynamic_pointer_cast_result::type Chris@102: polymorphic_pointer_downcast (const Source& x) Chris@102: { Chris@102: BOOST_ASSERT(dynamic_pointer_cast (x) == x); Chris@102: return static_pointer_cast (x); Chris@102: } Chris@102: Chris@102: template Chris@102: inline typename detail::dynamic_pointer_cast_result::type Chris@102: polymorphic_pointer_cast (const Source& x) Chris@102: { Chris@102: typename detail::dynamic_pointer_cast_result::type tmp Chris@102: = dynamic_pointer_cast (x); Chris@102: if ( !tmp ) boost::throw_exception( std::bad_cast() ); Chris@102: Chris@102: return tmp; Chris@102: } Chris@102: Chris@102: } // namespace boost Chris@102: Chris@102: #endif // BOOST_CONVERSION_POLYMORPHIC_POINTER_CAST_HPP