This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[v3] tr1::smart_ptr: fix return types, fix casts, etc.


Hi,

unfortunately, in order to fix some return types (see testcases) and obtain a good quality of the generated code (thus, no conversions from __shared_ptr and __weak_ptr to shared_ptr and weak_ptr) I have to add some lines of code, in particular a separate enable_shared_from_this, not deriving from __enable_shared_from_this. I'm not sure we can clean-up much in time for 4.2.0, maybe...

Tested x86/ia64-linux, committed to mainline.

Paolo.

////////////////
2006-09-24  Paolo Carlini  <pcarlini@suse.de>

	* include/tr1/boost_shared_ptr.h (shared_ptr<>::shared_ptr(const
	__shared_ptr<>&), shared_ptr(const __weak_ptr<>&),
	shared_ptr(const __shared_ptr<>&, __static_cast_tag),
	shared_ptr(const __shared_ptr<>&, __const_cast_tag),
	shared_ptr(const __shared_ptr<>&, __dynamic_cast_tag),
	weak_ptr<>::weak_ptr(const __shared_ptr<>&), weak_ptr(const
	__weak_ptr<>&)): Remove.
	(shared_ptr<>::shared_ptr(const shared_ptr<>&),
	shared_ptr(const weak_ptr<>&), shared_ptr(const shared_ptr<>&,
	__static_cast_tag), shared_ptr(const shared_ptr<>&,
	__const_cast_tag), shared_ptr(const shared_ptr<>&,
	__dynamic_cast_tag), static_pointer_cast(const shared_ptr<>&),
	const_pointer_cast(const shared_ptr<>&), dynamic_pointer_cast(const
	shared_ptr<>&), weak_ptr<>::weak_ptr(const shared_ptr<>&),
	weak_ptr(const weak_ptr<>&), weak_ptr<>::lock(), 
	__enable_shared_from_this_helper(const __shared_count<>&, const
	enable_shared_from_this<>*, const _Tp2*)): Add. 
	(class enable_shared_from_this): Add.
	* testsuite/tr1/2_general_utilities/memory/enable_shared_from_this/
	1.cc: New.
	* testsuite/tr1/2_general_utilities/memory/shared_ptr/casts/1.cc:
	Likewise.
	* testsuite/tr1/2_general_utilities/memory/weak_ptr/lock/1.cc:
	Likewise.

	* include/tr1/boost_shared_ptr.h: Further formatting and
	uglification fixes.
Index: include/tr1/boost_shared_ptr.h
===================================================================
--- include/tr1/boost_shared_ptr.h	(revision 117179)
+++ include/tr1/boost_shared_ptr.h	(working copy)
@@ -46,7 +46,7 @@
 
 // GCC Note:  based on version 1.32.0 of the Boost library.
 
-/** @file boost_memory.h
+/** @file boost_shared_ptr.h
  *  This is an internal header file, included by other library headers.
  *  You should not attempt to use it directly.
  */
@@ -100,11 +100,13 @@
     { };
 
   template<>
-    class _Mutex_base<_S_mutex> : public __gnu_cxx::__mutex
+    class _Mutex_base<_S_mutex>
+    : public __gnu_cxx::__mutex
     { };
 
   template<_Lock_policy _Lp = __default_lock_policy>
-    class _Sp_counted_base : public _Mutex_base<_Lp>
+    class _Sp_counted_base
+    : public _Mutex_base<_Lp>
     {
     public:  
       _Sp_counted_base() : _M_use_count(1), _M_weak_count(1) { }
@@ -116,44 +118,44 @@
       // Called when _M_use_count drops to zero, to release the resources
       // managed by *this.
       virtual void
-      dispose() = 0; // nothrow
+      _M_dispose() = 0; // nothrow
       
       // Called when _M_weak_count drops to zero.
       virtual void
-      destroy() // nothrow
+      _M_destroy() // nothrow
       { delete this; }
       
       virtual void*
-      get_deleter(const std::type_info&) = 0;
-      
+      _M_get_deleter(const std::type_info&) = 0;
+
       void
-      add_ref_copy()
+      _M_add_ref_copy()
       { __gnu_cxx::__atomic_add(&_M_use_count, 1); }
   
       void
-      add_ref_lock();
+      _M_add_ref_lock();
       
       void
-      release() // nothrow
+      _M_release() // nothrow
       {
 	if (__gnu_cxx::__exchange_and_add(&_M_use_count, -1) == 1)
 	  {
-	    dispose();
+	    _M_dispose();
 #ifdef __GTHREADS	
 	    _GLIBCXX_READ_MEM_BARRIER;
 	    _GLIBCXX_WRITE_MEM_BARRIER;
 #endif
 	    if (__gnu_cxx::__exchange_and_add(&_M_weak_count, -1) == 1)
-	      destroy();
+	      _M_destroy();
 	  }
       }
   
       void
-      weak_add_ref() // nothrow
+      _M_weak_add_ref() // nothrow
       { __gnu_cxx::__atomic_add(&_M_weak_count, 1); }
-  
+
       void
-      weak_release() // nothrow
+      _M_weak_release() // nothrow
       {
 	if (__gnu_cxx::__exchange_and_add(&_M_weak_count, -1) == 1)
 	  {
@@ -161,25 +163,26 @@
 	    _GLIBCXX_READ_MEM_BARRIER;
 	    _GLIBCXX_WRITE_MEM_BARRIER;
 #endif
-	    destroy();
+	    _M_destroy();
 	  }
       }
   
       long
-      use_count() const // nothrow
+      _M_get_use_count() const // nothrow
       { return _M_use_count; }  // XXX is this MT safe? 
       
     private:  
       _Sp_counted_base(_Sp_counted_base const&);
       _Sp_counted_base& operator=(_Sp_counted_base const&);
-      
-      _Atomic_word _M_use_count;        // #shared
-      _Atomic_word _M_weak_count;       // #weak + (#shared != 0)
+
+      _Atomic_word  _M_use_count;     // #shared
+      _Atomic_word  _M_weak_count;    // #weak + (#shared != 0)
     };
 
   template<>
     inline void
-    _Sp_counted_base<_S_single>::add_ref_lock()
+    _Sp_counted_base<_S_single>::
+    _M_add_ref_lock()
     {
       if (__gnu_cxx::__exchange_and_add(&_M_use_count, 1) == 0)
 	{
@@ -191,7 +194,8 @@
 #ifdef __GTHREADS
   template<>
     inline void
-    _Sp_counted_base<_S_mutex>::add_ref_lock()
+    _Sp_counted_base<_S_mutex>::
+    _M_add_ref_lock()
     {
       __gnu_cxx::__scoped_lock sentry(*this);
       if (__gnu_cxx::__exchange_and_add(&_M_use_count, 1) == 0)
@@ -204,7 +208,8 @@
 
   template<> 
     inline void
-    _Sp_counted_base<_S_atomic>::add_ref_lock()
+    _Sp_counted_base<_S_atomic>::
+    _M_add_ref_lock()
     {
       // Perform lock-free add-if-not-zero operation.
       _Atomic_word __count;
@@ -227,44 +232,40 @@
     public:
       /**
        *  @brief   
-       *  @pre     d(p) must not throw.
+       *  @pre     __d(__p) must not throw.
        */
       _Sp_counted_base_impl(_Ptr __p, _Deleter __d)
       : _M_ptr(__p), _M_del(__d) { }
     
       virtual void
-      dispose() // nothrow
+      _M_dispose() // nothrow
       { _M_del(_M_ptr); }
       
       virtual void*
-      get_deleter(const std::type_info& __ti)
+      _M_get_deleter(const std::type_info& __ti)
       { return __ti == typeid(_Deleter) ? &_M_del : 0; }
       
     private:
       _Sp_counted_base_impl(const _Sp_counted_base_impl&);
       _Sp_counted_base_impl& operator=(const _Sp_counted_base_impl&);
       
-      _Ptr     _M_ptr; // copy constructor must not throw
-      _Deleter _M_del; // copy constructor must not throw
+      _Ptr      _M_ptr;  // copy constructor must not throw
+      _Deleter  _M_del;  // copy constructor must not throw
     };
 
   template<_Lock_policy _Lp = __default_lock_policy>
-    class weak_count;
+    class __weak_count;
 
   template<_Lock_policy _Lp = __default_lock_policy>
-    class shared_count
+    class __shared_count
     {
-    private:  
-      _Sp_counted_base<_Lp>* _M_pi;
-  
-      friend class weak_count<_Lp>;
-  
     public: 
-      shared_count() : _M_pi(0) // nothrow
+      __shared_count()
+      : _M_pi(0) // nothrow
       { }
   
       template<typename _Ptr, typename _Deleter>
-        shared_count(_Ptr __p, _Deleter __d) : _M_pi(0)
+        __shared_count(_Ptr __p, _Deleter __d) : _M_pi(0)
         {
 	  try
 	    {
@@ -276,48 +277,49 @@
 	      __throw_exception_again;
 	    }
 	}
-      
+
       // Special case for auto_ptr<_Tp> to provide the strong guarantee.
       template<typename _Tp>
         explicit
-        shared_count(std::auto_ptr<_Tp>& __r)
+        __shared_count(std::auto_ptr<_Tp>& __r)
 	: _M_pi(new _Sp_counted_base_impl<_Tp*,
 		_Sp_deleter<_Tp>, _Lp >(__r.get(), _Sp_deleter<_Tp>()))
         { __r.release(); }
   
-      // Throw bad_weak_ptr when __r.use_count() == 0.
-      explicit shared_count(const weak_count<_Lp>& __r);
+      // Throw bad_weak_ptr when __r._M_get_use_count() == 0.
+      explicit
+      __shared_count(const __weak_count<_Lp>& __r);
   
-      ~shared_count() // nothrow
+      ~__shared_count() // nothrow
       {
 	if (_M_pi != 0)
-	  _M_pi->release();
+	  _M_pi->_M_release();
       }
       
-      shared_count(const shared_count& __r)
+      __shared_count(const __shared_count& __r)
       : _M_pi(__r._M_pi) // nothrow
       {
 	if (_M_pi != 0)
-	  _M_pi->add_ref_copy();
+	  _M_pi->_M_add_ref_copy();
       }
   
-      shared_count&
-      operator=(const shared_count& __r) // nothrow
+      __shared_count&
+      operator=(const __shared_count& __r) // nothrow
       {
 	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
 	if (__tmp != _M_pi)
 	  {
 	    if (__tmp != 0)
-	      __tmp->add_ref_copy();
+	      __tmp->_M_add_ref_copy();
 	    if (_M_pi != 0)
-	      _M_pi->release();
+	      _M_pi->_M_release();
 	    _M_pi = __tmp;
 	  }
 	return *this;
       }
   
       void
-      swap(shared_count& __r) // nothrow
+      _M_swap(__shared_count& __r) // nothrow
       {
 	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
 	__r._M_pi = _M_pi;
@@ -325,148 +327,167 @@
       }
   
       long
-      use_count() const // nothrow
-      { return _M_pi != 0 ? _M_pi->use_count() : 0; }
-      
+      _M_get_use_count() const // nothrow
+      { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
+
       bool
-      unique() const // nothrow
-      { return this->use_count() == 1; }
+      _M_unique() const // nothrow
+      { return this->_M_get_use_count() == 1; }
       
       friend inline bool
-      operator==(const shared_count& __a, const shared_count& __b)
+      operator==(const __shared_count& __a, const __shared_count& __b)
       { return __a._M_pi == __b._M_pi; }
   
       friend inline bool
-      operator<(const shared_count& __a, const shared_count& __b)
+      operator<(const __shared_count& __a, const __shared_count& __b)
       { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); }
   
       void*
-      get_deleter(const std::type_info& __ti) const
-      { return _M_pi ? _M_pi->get_deleter(__ti) : 0; }
+      _M_get_deleter(const std::type_info& __ti) const
+      { return _M_pi ? _M_pi->_M_get_deleter(__ti) : 0; }
+
+    private:
+      friend class __weak_count<_Lp>;
+
+      _Sp_counted_base<_Lp>*  _M_pi;
     };
 
   template<_Lock_policy _Lp>
-    class weak_count
+    class __weak_count
     {
-    private:  
-      _Sp_counted_base<_Lp>* _M_pi;
-      
-      friend class shared_count<_Lp>;
-      
-    public:  
-      weak_count()
+    public:
+      __weak_count()
       : _M_pi(0) // nothrow
       { }
   
-      weak_count(const shared_count<_Lp>& __r)
+      __weak_count(const __shared_count<_Lp>& __r)
       : _M_pi(__r._M_pi) // nothrow
       {
 	if (_M_pi != 0)
-	  _M_pi->weak_add_ref();
+	  _M_pi->_M_weak_add_ref();
       }
       
-      weak_count(const weak_count<_Lp>& __r)
+      __weak_count(const __weak_count<_Lp>& __r)
       : _M_pi(__r._M_pi) // nothrow
       {
 	if (_M_pi != 0)
-	  _M_pi->weak_add_ref();
+	  _M_pi->_M_weak_add_ref();
       }
       
-      ~weak_count() // nothrow
+      ~__weak_count() // nothrow
       {
 	if (_M_pi != 0)
-	  _M_pi->weak_release();
+	  _M_pi->_M_weak_release();
       }
       
-      weak_count<_Lp>&
-      operator=(const shared_count<_Lp>& __r) // nothrow
+      __weak_count<_Lp>&
+      operator=(const __shared_count<_Lp>& __r) // nothrow
       {
 	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
 	if (__tmp != 0)
-	  __tmp->weak_add_ref();
+	  __tmp->_M_weak_add_ref();
 	if (_M_pi != 0)
-	  _M_pi->weak_release();
+	  _M_pi->_M_weak_release();
 	_M_pi = __tmp;  
 	return *this;
       }
       
-      weak_count<_Lp>&
-      operator=(const weak_count<_Lp>& __r) // nothrow
+      __weak_count<_Lp>&
+      operator=(const __weak_count<_Lp>& __r) // nothrow
       {
-	_Sp_counted_base<_Lp> * __tmp = __r._M_pi;
+	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
 	if (__tmp != 0)
-	  __tmp->weak_add_ref();
+	  __tmp->_M_weak_add_ref();
 	if (_M_pi != 0)
-	  _M_pi->weak_release();
+	  _M_pi->_M_weak_release();
 	_M_pi = __tmp;
 	return *this;
       }
-  
+
       void
-      swap(weak_count<_Lp>& __r) // nothrow
+      _M_swap(__weak_count<_Lp>& __r) // nothrow
       {
-	_Sp_counted_base<_Lp> * __tmp = __r._M_pi;
+	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
 	__r._M_pi = _M_pi;
 	_M_pi = __tmp;
       }
   
       long
-      use_count() const // nothrow
-      { return _M_pi != 0 ? _M_pi->use_count() : 0; }
-      
+      _M_get_use_count() const // nothrow
+      { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
+
       friend inline bool
-      operator==(const weak_count<_Lp>& __a, const weak_count<_Lp>& __b)
+      operator==(const __weak_count<_Lp>& __a, const __weak_count<_Lp>& __b)
       { return __a._M_pi == __b._M_pi; }
       
       friend inline bool
-      operator<(const weak_count<_Lp>& __a, const weak_count<_Lp>& __b)
+      operator<(const __weak_count<_Lp>& __a, const __weak_count<_Lp>& __b)
       { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); }
+
+    private:
+      friend class __shared_count<_Lp>;
+
+      _Sp_counted_base<_Lp>*  _M_pi;
     };
 
   template<_Lock_policy _Lp>
     inline
-    shared_count<_Lp>::
-    shared_count(const weak_count<_Lp>& __r)
+    __shared_count<_Lp>::
+    __shared_count(const __weak_count<_Lp>& __r)
     : _M_pi(__r._M_pi)
     {
       if (_M_pi != 0)
-	_M_pi->add_ref_lock();
+	_M_pi->_M_add_ref_lock();
       else
 	__throw_bad_weak_ptr();
     }
   
 
-  // Forward decls.
+  // Forward declarations.
   template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
     class __shared_ptr;
   
   template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
     class __weak_ptr;
 
-  template<typename _Tp, _Lock_policy _Lp>
+  template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
     class __enable_shared_from_this;
 
-  struct __static_cast_tag { };
-  struct __const_cast_tag { };
-  struct __dynamic_cast_tag { };
-  struct __polymorphic_cast_tag { };
+  template<typename _Tp>
+    class shared_ptr;
+  
+  template<typename _Tp>
+    class weak_ptr;
 
+  template<typename _Tp>
+    class enable_shared_from_this;
 
   // Support for enable_shared_from_this.
 
   // Friend of __enable_shared_from_this.
   template<_Lock_policy _Lp, typename _Tp1, typename _Tp2>
     void
-    __enable_shared_from_this_helper(const shared_count<_Lp>&,
+    __enable_shared_from_this_helper(const __shared_count<_Lp>&,
 				     const __enable_shared_from_this<_Tp1,
 				     _Lp>*, const _Tp2*);
 
+  // Friend of enable_shared_from_this.
+  template<typename _Tp1, typename _Tp2>
+    void
+    __enable_shared_from_this_helper(const __shared_count<>&,
+				     const enable_shared_from_this<_Tp1>*,
+				     const _Tp2*);
+
   template<_Lock_policy _Lp>
     inline void
-    __enable_shared_from_this_helper(const shared_count<_Lp>&, ...)
+    __enable_shared_from_this_helper(const __shared_count<_Lp>&, ...)
     { }
 
 
+  struct __static_cast_tag { };
+  struct __const_cast_tag { };
+  struct __dynamic_cast_tag { };
+
   /**
    *  @class shared_ptr <tr1/memory>
    *
@@ -487,10 +508,10 @@
       : _M_ptr(0), _M_refcount() // never throws
       { }
 
-      /** @brief  Construct a %__shared_ptr that owns the pointer @a p.
-       *  @param  p  A pointer that is convertible to element_type*.
-       *  @post   use_count() == 1 && get() == p
-       *  @throw  std::bad_alloc, in which case @c delete @a p is called.
+      /** @brief  Construct a %__shared_ptr that owns the pointer @a __p.
+       *  @param  __p  A pointer that is convertible to element_type*.
+       *  @post   use_count() == 1 && get() == __p
+       *  @throw  std::bad_alloc, in which case @c delete @a __p is called.
        */
       template<typename _Tp1>
         explicit
@@ -499,37 +520,37 @@
         {
 	  __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
 	  // __glibcxx_function_requires(_CompleteConcept<_Tp1*>)
-	  __enable_shared_from_this_helper( _M_refcount, __p, __p );
+	  __enable_shared_from_this_helper(_M_refcount, __p, __p);
 	}
 
       //
-      // Requirements: D's copy constructor and destructor must not throw
+      // Requirements: _Deleter' copy constructor and destructor must not throw
       //
-      // __shared_ptr will release p by calling d(p)
+      // __shared_ptr will release __p by calling __d(__p)
       //
-      /** @brief  Construct a %__shared_ptr that owns the pointer @a p
-       *          and the deleter @a d.
-       *  @param  p  A pointer.
-       *  @param  d  A deleter.
-       *  @post   use_count() == 1 && get() == p
-       *  @throw  std::bad_alloc, in which case @a d(p) is called.
+      /** @brief  Construct a %__shared_ptr that owns the pointer @a __p
+       *          and the deleter @a __d.
+       *  @param  __p  A pointer.
+       *  @param  __d  A deleter.
+       *  @post   use_count() == 1 && get() == __p
+       *  @throw  std::bad_alloc, in which case @a __d(__p) is called.
        */
       template<typename _Tp1, typename _Deleter>
         __shared_ptr(_Tp1* __p, _Deleter __d)
 	: _M_ptr(__p), _M_refcount(__p, __d)
         {
 	  __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
-	  // TODO requires D is CopyConstructible and d(p) well-formed
-	  __enable_shared_from_this_helper( _M_refcount, __p, __p );
+	  // TODO requires _Deleter CopyConstructible and __d(__p) well-formed
+	  __enable_shared_from_this_helper(_M_refcount, __p, __p);
 	}
       
       //  generated copy constructor, assignment, destructor are fine.
       
-      /** @brief  If @a r is empty, constructs an empty %__shared_ptr;
+      /** @brief  If @a __r is empty, constructs an empty %__shared_ptr;
        *          otherwise construct a %__shared_ptr that shares ownership
-       *          with @a r.
-       *  @param  r  A %__shared_ptr.
-       *  @post   get() == r.get() && use_count() == r.use_count()
+       *          with @a __r.
+       *  @param  __r  A %__shared_ptr.
+       *  @post   get() == __r.get() && use_count() == __r.use_count()
        *  @throw  std::bad_alloc, in which case 
        */
       template<typename _Tp1>
@@ -537,11 +558,11 @@
 	: _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
         { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) }
 
-      /** @brief  Constructs a %__shared_ptr that shares ownership with @a r
-       *          and stores a copy of the pointer stored in @a r.
-       *  @param  r  A weak_ptr.
-       *  @post   use_count() == r.use_count()
-       *  @throw  bad_weak_ptr when r.expired(),
+      /** @brief  Constructs a %__shared_ptr that shares ownership with @a __r
+       *          and stores a copy of the pointer stored in @a __r.
+       *  @param  __r  A weak_ptr.
+       *  @post   use_count() == __r.use_count()
+       *  @throw  bad_weak_ptr when __r.expired(),
        *          in which case the constructor has no effect.
        */
       template<typename _Tp1>
@@ -550,24 +571,24 @@
 	: _M_refcount(__r._M_refcount) // may throw
         {
 	  __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
-	  // It is now safe to copy r__._M_ptr, as _M_refcount(__r._M_refcount)
+	  // It is now safe to copy __r._M_ptr, as _M_refcount(__r._M_refcount)
 	  // did not throw.
 	  _M_ptr = __r._M_ptr;
 	}
 
       /**
-       * @post use_count() == 1 and r.get() == 0
+       * @post use_count() == 1 and __r.get() == 0
        */
       template<typename _Tp1>
         explicit
         __shared_ptr(std::auto_ptr<_Tp1>& __r)
 	: _M_ptr(__r.get()), _M_refcount()
         {
-	  // TODO requires r.release() convertible to _Tp*, Tp1 is complete,
-	  // delete r.release() well-formed
-	  _Tp1 * __tmp = __r.get();
-	  _M_refcount = shared_count<_Lp>(__r);
-	  __enable_shared_from_this_helper(_M_refcount, __tmp, __tmp );
+	  // TODO requires __r.release() convertible to _Tp*, _Tp1 is complete,
+	  // delete __r.release() well-formed
+	  _Tp1* __tmp = __r.get();
+	  _M_refcount = __shared_count<_Lp>(__r);
+	  __enable_shared_from_this_helper(_M_refcount, __tmp, __tmp);
 	}
 
       template<typename _Tp1>
@@ -588,7 +609,7 @@
 	  _M_refcount(__r._M_refcount)
         {
 	  if (_M_ptr == 0) // need to allocate new counter -- the cast failed
-	    _M_refcount = shared_count<_Lp>();
+	    _M_refcount = __shared_count<_Lp>();
 	}
       
       template<typename _Tp1>
@@ -596,7 +617,7 @@
         operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws
         {
 	  _M_ptr = __r._M_ptr;
-	  _M_refcount = __r._M_refcount; // shared_count::op= doesn't throw
+	  _M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw
 	  return *this;
 	}
 
@@ -623,10 +644,10 @@
 
       template<typename _Tp1, typename _Deleter>
         void
-        reset(_Tp1 * __p, _Deleter __d)
+        reset(_Tp1* __p, _Deleter __d)
         { __shared_ptr(__p, __d).swap(*this); }
 
-      // Allow instantiation when _Tp is [cv-qual] void.
+      // Allow class instantiation when _Tp is [cv-qual] void.
       typename add_reference<_Tp>::type
       operator*() const // never throws
       {
@@ -655,23 +676,23 @@
 
       bool
       unique() const // never throws
-      { return _M_refcount.unique(); }
+      { return _M_refcount._M_unique(); }
 
       long
       use_count() const // never throws
-      { return _M_refcount.use_count(); }
+      { return _M_refcount._M_get_use_count(); }
 
       void
       swap(__shared_ptr<_Tp, _Lp>& __other) // never throws
       {
 	std::swap(_M_ptr, __other._M_ptr);
-	_M_refcount.swap(__other._M_refcount);
+	_M_refcount._M_swap(__other._M_refcount);
       }
 
     private:
       void*
       _M_get_deleter(const std::type_info& __ti) const
-      { return _M_refcount.get_deleter(__ti); }
+      { return _M_refcount._M_get_deleter(__ti); }
 
       template<typename _Tp1, _Lock_policy _Lp1>
         bool
@@ -700,8 +721,8 @@
         operator<(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
         { return __a._M_less(__b); }
 
-      _Tp*         	        _M_ptr;         // Contained pointer.
-      shared_count<_Lp> 	_M_refcount;    // Reference counter.
+      _Tp*         	   _M_ptr;         // Contained pointer.
+      __shared_count<_Lp>  _M_refcount;    // Reference counter.
     };
 
   // 2.2.3.8 shared_ptr specialized algorithms.
@@ -712,7 +733,7 @@
 
   // 2.2.3.9 shared_ptr casts
   /** @warning The seemingly equivalent
-   *           <code>shared_ptr<T>(static_cast<T*>(r.get()))</code>
+   *           <code>shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get()))</code>
    *           will eventually result in undefined behaviour,
    *           attempting to delete the same object twice.
    */
@@ -722,7 +743,7 @@
     { return __shared_ptr<_Tp, _Lp>(__r, __static_cast_tag()); }
 
   /** @warning The seemingly equivalent
-   *           <code>shared_ptr<T>(const_cast<T*>(r.get()))</code>
+   *           <code>shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get()))</code>
    *           will eventually result in undefined behaviour,
    *           attempting to delete the same object twice.
    */
@@ -732,7 +753,7 @@
     { return __shared_ptr<_Tp, _Lp>(__r, __const_cast_tag()); }
 
   /** @warning The seemingly equivalent
-   *           <code>shared_ptr<T>(dynamic_cast<T*>(r.get()))</code>
+   *           <code>shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get()))</code>
    *           will eventually result in undefined behaviour,
    *           attempting to delete the same object twice.
    */
@@ -764,31 +785,32 @@
     public:
       typedef _Tp element_type;
       
-      __weak_ptr() : _M_ptr(0), _M_refcount() // never throws
+      __weak_ptr()
+      : _M_ptr(0), _M_refcount() // never throws
       { }
 
       // Generated copy constructor, assignment, destructor are fine.
       
       // The "obvious" converting constructor implementation:
       //
-      //  template<class Y>
-      //    __weak_ptr(__weak_ptr<Y> const & r)
-      //    : _M_ptr(r._M_ptr), _M_refcount(r._M_refcount) // never throws
+      //  template<typename _Tp1>
+      //    __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
+      //    : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
       //    { }
       //
       // has a serious problem.
       //
-      //  r._M_ptr may already have been invalidated. The _M_ptr(r._M_ptr)
-      //  conversion may require access to *r._M_ptr (virtual inheritance).
+      //  __r._M_ptr may already have been invalidated. The _M_ptr(__r._M_ptr)
+      //  conversion may require access to *__r._M_ptr (virtual inheritance).
       //
       // It is not possible to avoid spurious access violations since
-      // in multithreaded programs r._M_ptr may be invalidated at any point.
+      // in multithreaded programs __r._M_ptr may be invalidated at any point.
       template<typename _Tp1>
         __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
 	: _M_refcount(__r._M_refcount) // never throws
         {
 	  __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
-	    _M_ptr = __r.lock().get();
+	  _M_ptr = __r.lock().get();
 	}
 
       template<typename _Tp1>
@@ -821,12 +843,12 @@
 	// Optimization: avoid throw overhead.
 	if (expired())
 	  return __shared_ptr<element_type, _Lp>();
-      
+
 	try
 	  {
 	    return __shared_ptr<element_type, _Lp>(*this);
 	  }
-	catch (const bad_weak_ptr&)
+	catch(const bad_weak_ptr&)
 	  {
 	    // Q: How can we get here?
 	    // A: Another thread may have invalidated r after the
@@ -844,11 +866,11 @@
 
       long
       use_count() const // never throws
-      { return _M_refcount.use_count(); }
+      { return _M_refcount._M_get_use_count(); }
 
       bool
       expired() const // never throws
-      { return _M_refcount.use_count() == 0; }
+      { return _M_refcount._M_get_use_count() == 0; }
       
       void
       reset() // never throws
@@ -858,45 +880,46 @@
       swap(__weak_ptr& __s) // never throws
       {
 	std::swap(_M_ptr, __s._M_ptr);
-	_M_refcount.swap(__s._M_refcount);
+	_M_refcount._M_swap(__s._M_refcount);
       }
 
     private:
-      template<typename _Tp1>
-        bool
-        _M_less(const __weak_ptr<_Tp1, _Lp>& __rhs) const
-        { return _M_refcount < __rhs._M_refcount; }
-
       // Used by __enable_shared_from_this.
       void
-      _M_assign(_Tp* __ptr, const shared_count<_Lp>& __refcount)
+      _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount)
       {
 	_M_ptr = __ptr;
 	_M_refcount = __refcount;
       }
 
+      template<typename _Tp1>
+        bool
+        _M_less(const __weak_ptr<_Tp1, _Lp>& __rhs) const
+        { return _M_refcount < __rhs._M_refcount; }
+
+      template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
+      template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
+      friend class __enable_shared_from_this<_Tp, _Lp>;
+      friend class enable_shared_from_this<_Tp>;
+
       // Friend injected into namespace and found by ADL.
       template<typename _Tp1>
         friend inline bool
         operator<(const __weak_ptr& __lhs, const __weak_ptr<_Tp1, _Lp>& __rhs)
         { return __lhs._M_less(__rhs); }
-      
-      template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
-      template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
-      friend class __enable_shared_from_this<_Tp, _Lp>;
-      
-      _Tp*       		_M_ptr;           // Contained pointer.
-      weak_count<_Lp> 	        _M_refcount;      // Reference counter.
+
+      _Tp*       	 _M_ptr;         // Contained pointer.
+      __weak_count<_Lp>  _M_refcount;    // Reference counter.
     };
 
   // 2.2.4.7 weak_ptr specialized algorithms.
   template<typename _Tp, _Lock_policy _Lp>
-    void
+    inline void
     swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b)
     { __a.swap(__b); }
 
 
-  template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
+  template<typename _Tp, _Lock_policy _Lp>
     class __enable_shared_from_this
     {
     protected:
@@ -913,121 +936,80 @@
     public:
       __shared_ptr<_Tp, _Lp>
       shared_from_this()
-      {
-	__shared_ptr<_Tp, _Lp> __p(this->_M_weak_this);
-	return __p;
-      }
-      
+      { return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); }
+
       __shared_ptr<const _Tp, _Lp>
       shared_from_this() const
-      {
-	__shared_ptr<const _Tp, _Lp> __p(this->_M_weak_this);
-	return __p;
-      }
-      
+      { return __shared_ptr<const _Tp, _Lp>(this->_M_weak_this); }
+
     private:
       template<typename _Tp1>
         void
-        _M_weak_assign(_Tp1* __p, const shared_count<_Lp>& __n) const
+        _M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const
         { _M_weak_this._M_assign(__p, __n); }
 
       template<typename _Tp1>
         friend void
-        __enable_shared_from_this_helper(const shared_count<_Lp>& __pn,
+        __enable_shared_from_this_helper(const __shared_count<_Lp>& __pn,
 					 const __enable_shared_from_this* __pe,
 					 const _Tp1* __px)
         {
 	  if (__pe != 0)
 	    __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
 	}
-      
-      mutable __weak_ptr<_Tp, _Lp> _M_weak_this;
+
+      mutable __weak_ptr<_Tp, _Lp>  _M_weak_this;
     };
 
-  template<typename _Tp>
-    class shared_ptr;
 
-  // The actual TR1 weak_ptr, with forwarding constructors and
+  // The actual TR1 shared_ptr, with forwarding constructors and
   // assignment operators.
   template<typename _Tp>
-    class weak_ptr : public __weak_ptr<_Tp>
+    class shared_ptr
+    : public __shared_ptr<_Tp>
     {
     public:
-      weak_ptr()
-      : __weak_ptr<_Tp>() { }
-      
-      template<typename _Tp1>
-        weak_ptr(const __weak_ptr<_Tp1>& __r)
-	: __weak_ptr<_Tp>(__r) { }
-    
-      template<typename _Tp1>
-        weak_ptr(const __shared_ptr<_Tp1>& __r)
-	: __weak_ptr<_Tp>(__r) { }
+      shared_ptr()
+      : __shared_ptr<_Tp>() { }
 
       template<typename _Tp1>
-        weak_ptr&
-        operator=(const weak_ptr<_Tp1>& __r) // never throws
-        {
-	  this->__weak_ptr<_Tp>::operator=(__r);
-	  return *this;
-	}
-
-      template<typename _Tp1>
-        weak_ptr&
-        operator=(const shared_ptr<_Tp1>& __r) // never throws
-        {
-	  this->__weak_ptr<_Tp>::operator=(__r);
-	  return *this;
-	}
-    };
-
-  // The actual TR1 shared_ptr, with forwarding constructors and
-  // assignment operators.
-  template<typename _Tp>
-    class shared_ptr : public __shared_ptr<_Tp>
-    {
-    public:
-      shared_ptr() : __shared_ptr<_Tp>() { }
-      
-      template<typename _Tp1>
         explicit
         shared_ptr(_Tp1* __p)
 	: __shared_ptr<_Tp>(__p) { }
-    
+
       template<typename _Tp1, typename _Deleter>
         shared_ptr(_Tp1* __p, _Deleter __d)
 	: __shared_ptr<_Tp>(__p, __d) { }
-    
+
       template<typename _Tp1>
-        shared_ptr(const __shared_ptr<_Tp1>& __r)
+        shared_ptr(const shared_ptr<_Tp1>& __r)
 	: __shared_ptr<_Tp>(__r) { }
-    
+
       template<typename _Tp1>
         explicit
-        shared_ptr(const __weak_ptr<_Tp1>& __r)
+        shared_ptr(const weak_ptr<_Tp1>& __r)
 	: __shared_ptr<_Tp>(__r) { }
-    
+
       template<typename _Tp1>
         explicit
         shared_ptr(std::auto_ptr<_Tp1>& __r)
 	: __shared_ptr<_Tp>(__r) { }
 
       template<typename _Tp1>
-        shared_ptr(const __shared_ptr<_Tp1>& __r, __static_cast_tag)
+        shared_ptr(const shared_ptr<_Tp1>& __r, __static_cast_tag)
 	: __shared_ptr<_Tp>(__r, __static_cast_tag()) { }
 
       template<typename _Tp1>
-        shared_ptr(const __shared_ptr<_Tp1>& __r, __const_cast_tag)
+        shared_ptr(const shared_ptr<_Tp1>& __r, __const_cast_tag)
 	: __shared_ptr<_Tp>(__r, __const_cast_tag()) { }
-    
+
       template<typename _Tp1>
-        shared_ptr(const __shared_ptr<_Tp1>& __r, __dynamic_cast_tag)
+        shared_ptr(const shared_ptr<_Tp1>& __r, __dynamic_cast_tag)
 	: __shared_ptr<_Tp>(__r, __dynamic_cast_tag()) { }
 
-      // Additional non-base assignment operators to avoid excessive errors.
       template<typename _Tp1>
         shared_ptr&
-        operator=(std::auto_ptr<_Tp1>& __r)
+        operator=(const shared_ptr<_Tp1>& __r) // never throws
         {
 	  this->__shared_ptr<_Tp>::operator=(__r);
 	  return *this;
@@ -1035,24 +1017,128 @@
 
       template<typename _Tp1>
         shared_ptr&
-        operator=(const shared_ptr<_Tp1>& __r) // never throws
+        operator=(std::auto_ptr<_Tp1>& __r)
         {
 	  this->__shared_ptr<_Tp>::operator=(__r);
 	  return *this;
 	}
     };
 
+  template<typename _Tp, typename _Tp1>
+    shared_ptr<_Tp>
+    static_pointer_cast(const shared_ptr<_Tp1>& __r)
+    { return shared_ptr<_Tp>(__r, __static_cast_tag()); }
+
+  template<typename _Tp, typename _Tp1>
+    shared_ptr<_Tp>
+    const_pointer_cast(const shared_ptr<_Tp1>& __r)
+    { return shared_ptr<_Tp>(__r, __const_cast_tag()); }
+
+  template<typename _Tp, typename _Tp1>
+    shared_ptr<_Tp>
+    dynamic_pointer_cast(const shared_ptr<_Tp1>& __r)
+    { return shared_ptr<_Tp>(__r, __dynamic_cast_tag()); }
+
+
+  // The actual TR1 weak_ptr, with forwarding constructors and
+  // assignment operators.
   template<typename _Tp>
-    class enable_shared_from_this : public __enable_shared_from_this<_Tp>
+    class weak_ptr
+    : public __weak_ptr<_Tp>
     {
+    public:
+      weak_ptr()
+      : __weak_ptr<_Tp>() { }
+      
+      template<typename _Tp1>
+        weak_ptr(const weak_ptr<_Tp1>& __r)
+	: __weak_ptr<_Tp>(__r) { }
+
+      template<typename _Tp1>
+        weak_ptr(const shared_ptr<_Tp1>& __r)
+	: __weak_ptr<_Tp>(__r) { }
+
+      template<typename _Tp1>
+        weak_ptr&
+        operator=(const weak_ptr<_Tp1>& __r) // never throws
+        {
+	  this->__weak_ptr<_Tp>::operator=(__r);
+	  return *this;
+	}
+
+      template<typename _Tp1>
+        weak_ptr&
+        operator=(const shared_ptr<_Tp1>& __r) // never throws
+        {
+	  this->__weak_ptr<_Tp>::operator=(__r);
+	  return *this;
+	}
+
+      shared_ptr<_Tp>
+      lock() const // never throws
+      {
+#ifdef __GTHREADS
+	if (this->expired())
+	  return shared_ptr<_Tp>();
+
+	try
+	  {
+	    return shared_ptr<_Tp>(*this);
+	  }
+	catch(const bad_weak_ptr&)
+	  {
+	    return shared_ptr<_Tp>();
+	  }
+#else
+	return this->expired() ? shared_ptr<_Tp>()
+	                       : shared_ptr<_Tp>(*this);
+#endif
+      }
+    };
+
+
+  template<typename _Tp>
+    class enable_shared_from_this
+    {
     protected:
-      enable_shared_from_this()
-      : __enable_shared_from_this<_Tp>() { }
+      enable_shared_from_this() { }
       
-      enable_shared_from_this(const enable_shared_from_this&)
-      : __enable_shared_from_this<_Tp>(enable_shared_from_this<_Tp>()) { }
+      enable_shared_from_this(const enable_shared_from_this&) { }
+
+      enable_shared_from_this&
+      operator=(const enable_shared_from_this&)
+      { return *this; }
+
+      ~enable_shared_from_this() { }
+
+    public:
+      shared_ptr<_Tp>
+      shared_from_this()
+      { return shared_ptr<_Tp>(this->_M_weak_this); }
+
+      shared_ptr<const _Tp>
+      shared_from_this() const
+      { return shared_ptr<const _Tp>(this->_M_weak_this); }
+
+    private:
+      template<typename _Tp1>
+        void
+        _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const
+        { _M_weak_this._M_assign(__p, __n); }
+
+      template<typename _Tp1>
+        friend void
+        __enable_shared_from_this_helper(const __shared_count<>& __pn,
+					 const enable_shared_from_this* __pe,
+					 const _Tp1* __px)
+        {
+	  if (__pe != 0)
+	    __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
+	}
+
+      mutable weak_ptr<_Tp>  _M_weak_this;
     };
-  
+
 _GLIBCXX_END_NAMESPACE
 } // namespace std
 
Index: testsuite/tr1/2_general_utilities/memory/enable_shared_from_this/1.cc
===================================================================
--- testsuite/tr1/2_general_utilities/memory/enable_shared_from_this/1.cc	(revision 0)
+++ testsuite/tr1/2_general_utilities/memory/enable_shared_from_this/1.cc	(revision 0)
@@ -0,0 +1,39 @@
+// 2006-09-24  Paolo Carlini  <pcarlini@suse.de>
+
+// Copyright (C) 2006 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 2.2.5 Template class enable_shared_from_this [tr.util.smartptr.enab]
+
+#include <tr1/memory>
+#include <testsuite_tr1.h>
+
+// { dg-do compile }
+
+struct X : public std::tr1::enable_shared_from_this<X>
+{
+};
+
+int main()
+{
+  using __gnu_test::check_ret_type;
+  using std::tr1::shared_ptr;
+
+  shared_ptr<X> spx(new X);
+  check_ret_type<shared_ptr<X> >(spx->shared_from_this());
+}
Index: testsuite/tr1/2_general_utilities/memory/shared_ptr/casts/1.cc
===================================================================
--- testsuite/tr1/2_general_utilities/memory/shared_ptr/casts/1.cc	(revision 0)
+++ testsuite/tr1/2_general_utilities/memory/shared_ptr/casts/1.cc	(revision 0)
@@ -0,0 +1,46 @@
+// 2006-09-24  Paolo Carlini  <pcarlini@suse.de>
+
+// Copyright (C) 2006 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// TR1 2.2.3.9 shared_ptr casts [tr.util.smartptr.shared.cast]
+
+#include <tr1/memory>
+#include <testsuite_tr1.h>
+
+// { dg-do compile }
+
+struct MyP { virtual ~MyP() { }; };
+struct MyDP : MyP { };
+
+int main()
+{
+  using __gnu_test::check_ret_type;
+  using std::tr1::shared_ptr;
+  using std::tr1::static_pointer_cast;
+  using std::tr1::const_pointer_cast;
+  using std::tr1::dynamic_pointer_cast;
+
+  shared_ptr<double> spd;
+  shared_ptr<const int> spci;
+  shared_ptr<MyP> spa;
+
+  check_ret_type<shared_ptr<void> >(static_pointer_cast<void>(spd));
+  check_ret_type<shared_ptr<int> >(const_pointer_cast<int>(spci));
+  check_ret_type<shared_ptr<MyDP> >(static_pointer_cast<MyDP>(spa));  
+}
Index: testsuite/tr1/2_general_utilities/memory/weak_ptr/lock/1.cc
===================================================================
--- testsuite/tr1/2_general_utilities/memory/weak_ptr/lock/1.cc	(revision 0)
+++ testsuite/tr1/2_general_utilities/memory/weak_ptr/lock/1.cc	(revision 0)
@@ -0,0 +1,36 @@
+// 2006-09-24  Paolo Carlini  <pcarlini@suse.de>
+
+// Copyright (C) 2006 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// TR1 2.2.4 Template class weak_ptr [tr.util.smartptr.weak]
+
+#include <tr1/memory>
+#include <testsuite_tr1.h>
+
+// { dg-do compile }
+
+int main()
+{
+  using __gnu_test::check_ret_type;
+  using std::tr1::weak_ptr;
+  using std::tr1::shared_ptr;
+
+  weak_ptr<int> wp;
+  check_ret_type<shared_ptr<int> >(wp.lock());
+}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]