Ticket #9799: cast.diff

File cast.diff, 1.8 KB (added by Camille Gillot <k1000.jlo@…>, 9 years ago)
  • cast.hpp

    old new  
    4949# include <boost/type.hpp>
    5050# include <boost/limits.hpp>
    5151# include <boost/detail/select_type.hpp>
     52# include <boost/mpl/if.hpp>
     53# include <boost/type_traits/remove_pointer.hpp>
     54# include <boost/type_traits/is_virtual_base_of.hpp>
    5255
    5356//  It has been demonstrated numerous times that MSVC 6.0 fails silently at link
    5457//  time if you use a template function which has template parameters that don't
     
    8285
    8386//  polymorphic_downcast  ----------------------------------------------------//
    8487
     88    namespace detail
     89    {
     90
     91        template<typename Out, typename In>
     92        struct polymorphic_static_downcast
     93        {
     94            static Out eval(In* in)
     95            { return static_cast<Out>( in ); }
     96        };
     97
     98        template<typename Out, typename In>
     99        struct polymorphic_dynamic_downcast
     100        {
     101            static Out eval(In* in)
     102            { return dynamic_cast<Out>( in ); }
     103        };
     104
     105    }
     106
    85107    //  BOOST_ASSERT() checked polymorphic downcast.  Crosscasts prohibited.
    86108
    87109    //  WARNING: Because this cast uses BOOST_ASSERT(), it violates
     
    95117    inline Target polymorphic_downcast(Source* x BOOST_EXPLICIT_DEFAULT_TARGET)
    96118    {
    97119        BOOST_ASSERT( dynamic_cast<Target>(x) == x );  // detect logic error
    98         return static_cast<Target>(x);
     120
     121        typedef typename boost::remove_pointer<Out>::type out_class;
     122        typedef boost::is_virtual_base_of<in_class, out_class> dyn;
     123        typedef typename boost::mpl::if_<dyn
     124        , polymorphic_dynamic_downcast<Out, In>
     125        , polymorphic_static_downcast<Out, In>
     126        >::type impl;
     127
     128        return impl::eval(x);
    99129    }
    100130
    101131#  undef BOOST_EXPLICIT_DEFAULT_TARGET