Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r55074 - sandbox/fmhess/boost/smart_ptr
From: fmhess_at_[hidden]
Date: 2009-07-21 14:29:02


Author: fmhess
Date: 2009-07-21 14:29:01 EDT (Tue, 21 Jul 2009)
New Revision: 55074
URL: http://svn.boost.org/trac/boost/changeset/55074

Log:
Added enable_generic_shared_from_this.hpp. All smart_ptr tests pass now
using shared_ptr/weak_ptr/enabled_shared_from_this implementations built
on top of generic_shared/generic_weak/enable_generic_shared_from_this,
except for the one test that uses enable_shared_from_this2.

Added:
   sandbox/fmhess/boost/smart_ptr/enable_generic_shared_from_this.hpp
      - copied, changed from r55073, /trunk/boost/smart_ptr/enable_shared_from_this.hpp
   sandbox/fmhess/boost/smart_ptr/enable_shared_from_this.hpp (contents, props changed)
Text files modified:
   sandbox/fmhess/boost/smart_ptr/enable_generic_shared_from_this.hpp | 41 +++++++++--------
   sandbox/fmhess/boost/smart_ptr/generic_shared.hpp | 90 ++++++++++++++++++++++++++++++++++-----
   sandbox/fmhess/boost/smart_ptr/shared_ptr.hpp | 33 ++++++++++++-
   3 files changed, 127 insertions(+), 37 deletions(-)

Copied: sandbox/fmhess/boost/smart_ptr/enable_generic_shared_from_this.hpp (from r55073, /trunk/boost/smart_ptr/enable_shared_from_this.hpp)
==============================================================================
--- /trunk/boost/smart_ptr/enable_shared_from_this.hpp (original)
+++ sandbox/fmhess/boost/smart_ptr/enable_generic_shared_from_this.hpp 2009-07-21 14:29:01 EDT (Tue, 21 Jul 2009)
@@ -1,10 +1,11 @@
-#ifndef BOOST_SMART_PTR_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED
-#define BOOST_SMART_PTR_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED
+#ifndef BOOST_SMART_PTR_ENABLE_GENERIC_SHARED_FROM_THIS_HPP_INCLUDED
+#define BOOST_SMART_PTR_ENABLE_GENERIC_SHARED_FROM_THIS_HPP_INCLUDED
 
 //
-// enable_shared_from_this.hpp
+// enable_generic_shared_from_this.hpp
 //
 // Copyright 2002, 2009 Peter Dimov
+// Copyright 2009 Frank Mori Hess
 //
 // Distributed under the Boost Software License, Version 1.0.
 // See accompanying file LICENSE_1_0.txt or copy at
@@ -13,67 +14,67 @@
 // http://www.boost.org/libs/smart_ptr/enable_shared_from_this.html
 //
 
-#include <boost/smart_ptr/weak_ptr.hpp>
-#include <boost/smart_ptr/shared_ptr.hpp>
+#include <boost/smart_ptr/generic_weak.hpp>
+#include <boost/smart_ptr/generic_shared.hpp>
 #include <boost/assert.hpp>
 #include <boost/config.hpp>
 
 namespace boost
 {
 
-template<class T> class enable_shared_from_this
+template<class T> class enable_generic_shared_from_this
 {
 protected:
 
- enable_shared_from_this()
+ enable_generic_shared_from_this()
     {
     }
 
- enable_shared_from_this(enable_shared_from_this const &)
+ enable_generic_shared_from_this(enable_generic_shared_from_this const &)
     {
     }
 
- enable_shared_from_this & operator=(enable_shared_from_this const &)
+ enable_generic_shared_from_this & operator=(enable_generic_shared_from_this const &)
     {
         return *this;
     }
 
- ~enable_shared_from_this()
+ ~enable_generic_shared_from_this()
     {
     }
 
 public:
 
- shared_ptr<T> shared_from_this()
+ generic_shared<T> shared_from_this()
     {
- shared_ptr<T> p( weak_this_ );
+ generic_shared<T> p( weak_this_ );
         BOOST_ASSERT( p.get() == this );
         return p;
     }
-
- shared_ptr<T const> shared_from_this() const
+//FIXME: yikes! we need to make it easier to add/remove const from a generic pointer's value_type
+ typename generic_shared<T>::template rebind<typename generic_shared<T>::value_type const>::other shared_from_this() const
     {
- shared_ptr<T const> p( weak_this_ );
+ typename generic_shared<T>::template rebind<typename generic_shared<T>::value_type const>::other p( weak_this_ );
         BOOST_ASSERT( p.get() == this );
         return p;
     }
 
 public: // actually private, but avoids compiler template friendship issues
 
- // Note: invoked automatically by shared_ptr; do not call
- template<class X, class Y> void _internal_accept_owner( shared_ptr<X> const * ppx, Y * py ) const
+ // Note: invoked automatically by generic_shared; do not call
+ template<class X, class Y> void _internal_accept_owner( generic_shared<X> const * ppx, Y py ) const
     {
         if( weak_this_.expired() )
         {
- weak_this_ = shared_ptr<T>( *ppx, py );
+ weak_this_ = generic_shared<T>( *ppx, py );
         }
     }
 
 private:
 
- mutable weak_ptr<T> weak_this_;
+ mutable generic_weak<T> weak_this_;
 };
 
 } // namespace boost
 
-#endif // #ifndef BOOST_SMART_PTR_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED
+#endif // #ifndef BOOST_SMART_PTR_ENABLE_GENERIC_SHARED_FROM_THIS_HPP_INCLUDED

Added: sandbox/fmhess/boost/smart_ptr/enable_shared_from_this.hpp
==============================================================================
--- (empty file)
+++ sandbox/fmhess/boost/smart_ptr/enable_shared_from_this.hpp 2009-07-21 14:29:01 EDT (Tue, 21 Jul 2009)
@@ -0,0 +1,35 @@
+#ifndef BOOST_SMART_PTR_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED
+#define BOOST_SMART_PTR_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED
+
+// Implementation of enable_shared_from_this as wrapper around
+// enable_generic_shared_from_this.
+// Written primarily to help test generic_shared using unmodified
+// shared_ptr tests.
+
+// Copyright (c) 2009 Frank Mori Hess
+//
+// 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)
+
+#include <boost/smart_ptr/enable_generic_shared_from_this.hpp>
+
+namespace boost
+{
+ template<typename T>
+ class enable_shared_from_this: public enable_generic_shared_from_this<T*>
+ {
+ typedef enable_generic_shared_from_this<T*> base_type;
+ public:
+ boost::shared_ptr<T> shared_from_this()
+ {
+ return base_type::shared_from_this();
+ }
+ boost::shared_ptr<const T> shared_from_this() const
+ {
+ return base_type::shared_from_this();
+ }
+ };
+}
+
+#endif // #ifndef BOOST_SMART_PTR_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED

Modified: sandbox/fmhess/boost/smart_ptr/generic_shared.hpp
==============================================================================
--- sandbox/fmhess/boost/smart_ptr/generic_shared.hpp (original)
+++ sandbox/fmhess/boost/smart_ptr/generic_shared.hpp 2009-07-21 14:29:01 EDT (Tue, 21 Jul 2009)
@@ -22,6 +22,7 @@
 // is_null_pointer() free function findable by ADL
 // (in)equality comparison
 // 2 argument static/const/dynamic_pointer_cast findable by ADL if you want support for casting
+// get_pointer support
 
 #include <boost/config.hpp> // for broken compiler workarounds
 
@@ -44,6 +45,8 @@
 #include <boost/smart_ptr/detail/shared_count.hpp>
 #include <boost/detail/workaround.hpp>
 #include <boost/smart_ptr/detail/sp_convertible.hpp>
+#include <boost/type_traits/remove_const.hpp>
+#include <boost/utility/enable_if.hpp>
 
 #if !defined(BOOST_SP_NO_ATOMIC_ACCESS)
 #include <boost/smart_ptr/detail/spinlock_pool.hpp>
@@ -70,17 +73,18 @@
 namespace boost
 {
 
-template<class T> class generic_shared;
-template<class T> class generic_weak;
+template<typename T> class generic_shared;
+template<typename T> class generic_weak;
+template<typename T> class enable_generic_shared_from_this;
 
-template<class T> struct smart_pointer_traits
+template<typename T> struct smart_pointer_traits
 {
     typedef typename T::value_type value_type;
     typedef typename T::pointer pointer;
     typedef typename T::reference reference;
 };
 
-template<class T> struct smart_pointer_traits<T*>
+template<typename T> struct smart_pointer_traits<T*>
 {
     typedef T value_type;
     typedef T * pointer;
@@ -115,6 +119,31 @@
     typedef void reference;
 };
 
+template<typename GenericPtr, typename ValueType>
+struct rebind_generic_ptr
+{
+ typedef typename GenericPtr::template rebind<ValueType>::other other;
+};
+
+template<typename T, typename ValueType>
+struct rebind_generic_ptr<T*, ValueType>
+{
+ typedef ValueType * other;
+};
+
+template<typename GenericPtr>
+typename smart_pointer_traits<GenericPtr>::value_type *
+ get_plain_old_pointer(GenericPtr gp)
+{
+ return get_plain_old_pointer(get_pointer(gp));
+}
+
+template<typename T>
+T * get_plain_old_pointer(T * p)
+{
+ return p;
+}
+
 template<typename T> bool is_null_pointer(const generic_shared<T> &p)
 {
     return !p;
@@ -150,11 +179,40 @@
 struct const_cast_tag {};
 struct dynamic_cast_tag {};
 
-template<typename T, typename U, typename V>
-inline void sp_enable_shared_from_this(T, U, V)
+// enable_shared_from_this support
+
+template< class X, class Y, class T > inline void sp_enable_shared_from_this( boost::generic_shared<X> const * ppx, Y const * py,
+ boost::enable_generic_shared_from_this< T > const * pe )
 {
+ if( pe != 0 )
+ {
+//FIXME: yikes! this const cast is painful
+ typedef typename rebind_generic_ptr<Y, typename remove_const<typename smart_pointer_traits<Y>::value_type>::type>::other nonconst_y_type;
+ pe->_internal_accept_owner( ppx, const_pointer_cast<typename smart_pointer_traits<nonconst_y_type>::value_type>( *py ) );
+ }
 }
 
+#ifdef _MANAGED
+
+// Avoid C4793, ... causes native code generation
+
+struct sp_any_pointer
+{
+ template<class T> sp_any_pointer( T* ) {}
+};
+
+inline void sp_enable_shared_from_this( sp_any_pointer, sp_any_pointer, sp_any_pointer )
+{
+}
+
+#else // _MANAGED
+
+inline void sp_enable_shared_from_this( ... )
+{
+}
+
+#endif // _MANAGED
+
 #if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) && !defined( BOOST_NO_AUTO_PTR )
 
 // rvalue auto_ptr support based on a technique by Dave Abrahams
@@ -210,6 +268,12 @@
     typedef typename boost::smart_pointer_traits<T>::reference reference;
     typedef generic_weak<T> weak_type;
 
+ template<typename ValueType>
+ struct rebind
+ {
+ typedef generic_shared<typename rebind_generic_ptr<pointer, ValueType>::other > other;
+ };
+
     generic_shared(): px(), pn()
     {
     }
@@ -217,7 +281,7 @@
     template<class Y>
     explicit generic_shared( Y p ): px( p ), pn( p ) // Y must be complete
     {
- boost::gs_detail::sp_enable_shared_from_this( this, p, p );
+ boost::gs_detail::sp_enable_shared_from_this( this, &p, get_plain_old_pointer(p) );
     }
 
     //
@@ -228,14 +292,14 @@
 
     template<class Y, class D> generic_shared(Y p, D d): px(p), pn(p, d)
     {
- boost::gs_detail::sp_enable_shared_from_this( this, p, p );
+ boost::gs_detail::sp_enable_shared_from_this( this, &p, get_plain_old_pointer(p) );
     }
 
     // As above, but with allocator. A's copy constructor shall not throw.
 
     template<class Y, class D, class A> generic_shared( Y p, D d, A a ): px( p ), pn( p, d, a )
     {
- boost::gs_detail::sp_enable_shared_from_this( this, p, p );
+ boost::gs_detail::sp_enable_shared_from_this( this, &p, get_plain_old_pointer(p) );
     }
 
 // generated copy constructor, destructor are fine
@@ -271,8 +335,8 @@
     }
 
     // aliasing
- template< class Y >
- generic_shared( generic_shared<Y> const & r, T p ): px( p ), pn( r.pn ) // never throws
+ template< class Y, class Z >
+ generic_shared( generic_shared<Y> const & r, Z p ): px( p ), pn( r.pn ) // never throws
     {
     }
 
@@ -309,7 +373,7 @@
     {
         Y * tmp = r.get();
         pn = boost::detail::shared_count(r);
- boost::gs_detail::sp_enable_shared_from_this( this, tmp, tmp );
+ boost::gs_detail::sp_enable_shared_from_this( this, &tmp, get_plain_old_pointer(tmp) );
     }
 
 #if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
@@ -319,7 +383,7 @@
     {
         typename Ap::element_type * tmp = r.get();
         pn = boost::detail::shared_count( r );
- boost::gs_detail::sp_enable_shared_from_this( this, tmp, tmp );
+ boost::gs_detail::sp_enable_shared_from_this( this, &tmp, get_plain_old_pointer(tmp) );
     }
 
 

Modified: sandbox/fmhess/boost/smart_ptr/shared_ptr.hpp
==============================================================================
--- sandbox/fmhess/boost/smart_ptr/shared_ptr.hpp (original)
+++ sandbox/fmhess/boost/smart_ptr/shared_ptr.hpp 2009-07-21 14:29:01 EDT (Tue, 21 Jul 2009)
@@ -15,15 +15,40 @@
 
 namespace boost
 {
+ template<typename T> class enable_shared_from_this;
+ template<typename T> class shared_ptr;
+ template<typename T> class weak_ptr;
+
         namespace detail
         {
- template<typename T, typename U, typename V>
- inline void sp_enable_shared_from_this(T, U, V)
+ // enable_shared_from_this support
+
+ template< class X, class Y, class T > inline void sp_enable_shared_from_this( boost::shared_ptr<X> const * ppx, Y const * py, boost::enable_shared_from_this< T > const * pe )
                 {
+ gs_detail::sp_enable_shared_from_this(static_cast<generic_shared<X*> const *>(ppx), &py, pe);
                 }
- }
 
- template<typename T> class weak_ptr;
+ #ifdef _MANAGED
+
+ // Avoid C4793, ... causes native code generation
+
+ struct sp_any_pointer
+ {
+ template<class T> sp_any_pointer( T* ) {}
+ };
+
+ inline void sp_enable_shared_from_this( sp_any_pointer, sp_any_pointer, sp_any_pointer )
+ {
+ }
+
+ #else // _MANAGED
+
+ inline void sp_enable_shared_from_this( ... )
+ {
+ }
+
+ #endif // _MANAGED
+ }
 
         template<typename T>
         class shared_ptr: public generic_shared<T*>


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