|
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