Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r55271 - in sandbox/fmhess: boost/generic_ptr boost/generic_ptr/detail libs/generic_ptr/test
From: fmhess_at_[hidden]
Date: 2009-07-30 14:45:00


Author: fmhess
Date: 2009-07-29 15:40:47 EDT (Wed, 29 Jul 2009)
New Revision: 55271
URL: http://svn.boost.org/trac/boost/changeset/55271

Log:
Fixed slicing which could occur on casting of generic_ptr::cloning.

Text files modified:
   sandbox/fmhess/boost/generic_ptr/cloning.hpp | 84 +++++++++++++++++++++++++++++++--------
   sandbox/fmhess/boost/generic_ptr/detail/util.hpp | 4 +
   sandbox/fmhess/boost/generic_ptr/shared.hpp | 4 -
   sandbox/fmhess/libs/generic_ptr/test/cloning_test.cpp | 5 -
   4 files changed, 73 insertions(+), 24 deletions(-)

Modified: sandbox/fmhess/boost/generic_ptr/cloning.hpp
==============================================================================
--- sandbox/fmhess/boost/generic_ptr/cloning.hpp (original)
+++ sandbox/fmhess/boost/generic_ptr/cloning.hpp 2009-07-29 15:40:47 EDT (Wed, 29 Jul 2009)
@@ -16,6 +16,7 @@
 
 #include <boost/assert.hpp>
 #include <boost/config.hpp>
+#include <boost/generic_ptr/detail/util.hpp>
 #include <boost/generic_ptr/pointer_traits.hpp>
 #include <boost/generic_ptr/shared.hpp>
 #include <boost/mpl/identity.hpp>
@@ -84,7 +85,7 @@
           boost::swap(_impl, other._impl);
         }
       private:
- clone_factory& operator=(const clone_factory &); // could be implemented if we need it
+ clone_factory& operator=(const clone_factory &); // could be implemented and made public if we needed it
 
         scoped_ptr<clone_factory_impl_base> _impl;
       };
@@ -134,6 +135,65 @@
>(_cloner.get_pointer())
         )
       {}
+
+ // casts
+ template<typename U>
+ cloning(const cloning<U> & other, detail::static_cast_tag):
+ _cloner(other._cloner),
+ px
+ (
+ static_cast
+ <
+ value_type *
+ >
+ (
+ static_cast
+ <
+ typename pointer_traits<U>::value_type *
+ >(_cloner.get_pointer())
+ )
+ )
+ {}
+ template<typename U>
+ cloning(const cloning<U> & other, detail::const_cast_tag):
+ _cloner(other._cloner),
+ px
+ (
+ const_cast
+ <
+ value_type *
+ >
+ (
+ static_cast
+ <
+ typename pointer_traits<U>::value_type *
+ >(_cloner.get_pointer())
+ )
+ )
+ {}
+ template<typename U>
+ cloning(const cloning<U> & other, detail::dynamic_cast_tag):
+ _cloner(other._cloner),
+ px
+ (
+ dynamic_cast
+ <
+ value_type *
+ >
+ (
+ static_cast
+ <
+ typename pointer_traits<U>::value_type *
+ >(_cloner.get_pointer())
+ )
+ )
+ {
+ if(get_plain_pointer(px) == 0)
+ {
+ detail::clone_factory().swap(_cloner);
+ }
+ }
+
 #ifndef BOOST_NO_RVALUE_REFERENCES
       cloning(cloning && other): _cloner(std::move(other._cloner)), px(std::move(other.px))
       {}
@@ -214,42 +274,32 @@
     template<typename ToValueType, typename U>
     typename rebind<cloning<U>, ToValueType>::other static_pointer_cast
     (
- cloning<U> const & p,
+ cloning<U> const & cp,
       mpl::identity<ToValueType> to_type_iden = mpl::identity<ToValueType>()
     )
     {
       typedef typename rebind<cloning<U>, ToValueType>::other result_type;
- typename result_type::pointer wrapped_p(static_pointer_cast(p.get(), to_type_iden));
- typename result_type::value_type *plain_p = get_plain_old_pointer(wrapped_p);
- if(plain_p == 0) return result_type(plain_p);
- return result_type(new_clone(*plain_p));
+ return result_type(cp, detail::static_cast_tag());
     }
     template<typename ToValueType, typename U>
     typename rebind<cloning<U>, ToValueType>::other const_pointer_cast
     (
- cloning<U> const & p,
+ cloning<U> const & cp,
       mpl::identity<ToValueType> to_type_iden = mpl::identity<ToValueType>()
     )
     {
       typedef typename rebind<cloning<U>, ToValueType>::other result_type;
- typename result_type::pointer wrapped_p(const_pointer_cast(p.get(), to_type_iden));
- typename result_type::value_type *plain_p = get_plain_old_pointer(wrapped_p);
- if(plain_p == 0) return result_type(plain_p);
- return result_type(new_clone(*plain_p));
+ return result_type(cp, detail::const_cast_tag());
     }
     template<typename ToValueType, typename U>
     typename rebind<cloning<U>, ToValueType>::other dynamic_pointer_cast
     (
- cloning<U> const & p,
+ cloning<U> const & cp,
       mpl::identity<ToValueType> to_type_iden = mpl::identity<ToValueType>()
     )
     {
       typedef typename rebind<cloning<U>, ToValueType>::other result_type;
- return result_type(dynamic_pointer_cast(p.get(), to_type_iden));
- typename result_type::pointer wrapped_p(static_pointer_cast(p.get(), to_type_iden));
- typename result_type::value_type *plain_p = get_plain_old_pointer(wrapped_p);
- if(plain_p == 0) return result_type(plain_p);
- return result_type(new_clone(*plain_p));
+ return result_type(cp, detail::dynamic_cast_tag());
     }
 
     // comparisons

Modified: sandbox/fmhess/boost/generic_ptr/detail/util.hpp
==============================================================================
--- sandbox/fmhess/boost/generic_ptr/detail/util.hpp (original)
+++ sandbox/fmhess/boost/generic_ptr/detail/util.hpp 2009-07-29 15:40:47 EDT (Wed, 29 Jul 2009)
@@ -16,6 +16,10 @@
   {
     namespace detail
     {
+ struct static_cast_tag {};
+ struct const_cast_tag {};
+ struct dynamic_cast_tag {};
+
       template<typename T>
       void set_plain_old_pointer_to_null(T * &p)
       {

Modified: sandbox/fmhess/boost/generic_ptr/shared.hpp
==============================================================================
--- sandbox/fmhess/boost/generic_ptr/shared.hpp (original)
+++ sandbox/fmhess/boost/generic_ptr/shared.hpp 2009-07-29 15:40:47 EDT (Wed, 29 Jul 2009)
@@ -83,10 +83,6 @@
 namespace detail
 {
 
-struct static_cast_tag {};
-struct const_cast_tag {};
-struct dynamic_cast_tag {};
-
 // enable_shared_from_this support
 
 template< class X, class Y, class T > inline void sp_enable_shared_from_this( shared<X> const * ppx, Y const * py,

Modified: sandbox/fmhess/libs/generic_ptr/test/cloning_test.cpp
==============================================================================
--- sandbox/fmhess/libs/generic_ptr/test/cloning_test.cpp (original)
+++ sandbox/fmhess/libs/generic_ptr/test/cloning_test.cpp 2009-07-29 15:40:47 EDT (Wed, 29 Jul 2009)
@@ -98,10 +98,9 @@
   boost::generic_ptr::cloning<X*> cp2 = boost::generic_ptr::static_pointer_cast<X>(cp);
   BOOST_TEST(X::instances == 2);
   BOOST_TEST(cp != cp2);
-/* boost::generic_ptr::cloning<X*> cp3(boost::generic_ptr::dynamic_pointer_cast<X>(cp));
+ boost::generic_ptr::cloning<X_base*> cp3(boost::generic_ptr::static_pointer_cast<X_base>(cp2));
   BOOST_TEST(X::instances == 3);
- BOOST_TEST(get_plain_old_pointer(cp3) != 0);
- BOOST_TEST(cp != cp3);*/
+ BOOST_TEST(cp2 != cp3);
 }
 
 int main()


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk