This is the mail archive of the libstdc++@sourceware.cygnus.com mailing list for the libstdc++ project.


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

Patch for auto_ptr + test


Hi,

I had a look at the implementation of auto_ptr, and I think it's
not conformant in the following details:

    - struct auto_ptr_ref is defined outside class auto_ptr; it should
      be a private nested struct (20.4.5p1);
    - auto_ptr::operator auto_ptr_ref releases the pointer too soon;
      it should be released by auto_ptr::auto_ptr(auto_ptr_ref)
      (20.4.5.3p1,2,3);
    - assignment from auto_ptr_ref shouldn't be defined.

I've attached a patch for bits/std_memory.h that fixes these problems,
as well as a test case for auto_ptr that should go into testsuite/20_utilities.


2000-06-13  Branko Cibej  <branko.cibej@hermes.si>

	* bits/std_memory.h (auto_ptr_ref): Removed.
	(auto_ptr): Define conversions only if __STL_MEMBER_TEMPLATE_CLASSES.
	 Added private template struct auto_ptr_ref.
	(auto_ptr::auto_ptr(auto_ptr_ref)): Release the pointer held by
	the auto_ptr in the auto_ptr_ref.
	(auto_ptr::operator auto_ptr_ref): Don't call this->release().
	Added references to sections in the standard.

	* testsuite/20_utilities/auto_ptr.cc: New file.


-- 
Branko Čibej                 <branko.cibej@hermes.si>
HERMES SoftLab, Litijska 51, 1000 Ljubljana, Slovenia
voice: (+386 1) 586 53 49     fax: (+386 1) 586 52 70
Index: bits/std_memory.h
===================================================================
RCS file: /cvs/gcc/egcs/libstdc++-v3/bits/std_memory.h,v
retrieving revision 1.1
diff -c -p -r1.1 std_memory.h
*** std_memory.h	2000/04/21 20:33:28	1.1
--- std_memory.h	2000/06/13 13:07:13
***************
*** 25,39 ****
  
  __STL_BEGIN_NAMESPACE
  
! #if defined(__SGI_STL_USE_AUTO_PTR_CONVERSIONS) && \
!      defined(__STL_MEMBER_TEMPLATES)
!  
!  template<class _Tp1> struct auto_ptr_ref {
!    _Tp1* _M_ptr;
!    auto_ptr_ref(_Tp1* __p) : _M_ptr(__p) {}
! };
! 
! #endif
  
  template <class _Tp> class auto_ptr {
  private:
--- 25,31 ----
  
  __STL_BEGIN_NAMESPACE
  
! // 20.4.5 Template class auto_ptr [lib.auto.ptr]
  
  template <class _Tp> class auto_ptr {
  private:
*************** private:
*** 42,47 ****
--- 34,41 ----
  public:
    typedef _Tp element_type;
  
+   // 20.4.5.1 auto_ptr constructors [lib.auto.ptr.cons]
+   
    explicit auto_ptr(_Tp* __p = 0) __STL_NOTHROW : _M_ptr(__p) {}
    auto_ptr(auto_ptr& __a) __STL_NOTHROW : _M_ptr(__a.release()) {}
  
*************** public:
*** 65,70 ****
--- 59,66 ----
  
    ~auto_ptr() __STL_NOTHROW { delete _M_ptr; }
  
+   // 20.4.5.2 auto_ptr members [lib.auto.ptr.members]
+ 
    _Tp& operator*() const __STL_NOTHROW {
      return *_M_ptr;
    }
*************** public:
*** 86,113 ****
      }    
    }
  
    // According to the C++ standard, these conversions are required.  Most
    // present-day compilers, however, do not enforce that requirement---and, 
    // in fact, most present-day compilers do not support the language 
    // features that these conversions rely on.
    
  #if defined(__SGI_STL_USE_AUTO_PTR_CONVERSIONS) && \
      defined(__STL_MEMBER_TEMPLATES)
  
  public:
    auto_ptr(auto_ptr_ref<_Tp> __ref) __STL_NOTHROW
!     : _M_ptr(__ref._M_ptr) {}
! 
!   auto_ptr& operator=(auto_ptr_ref<_Tp> __ref) __STL_NOTHROW {
!     if (__ref._M_ptr != this->get()) {
!       delete _M_ptr;
!       _M_ptr = __ref._M_ptr;
!     }
!     return *this;
!   }
! 
    template <class _Tp1> operator auto_ptr_ref<_Tp1>() __STL_NOTHROW 
!     { return auto_ptr_ref<_Tp>(this->release()); }
    template <class _Tp1> operator auto_ptr<_Tp1>() __STL_NOTHROW
      { return auto_ptr<_Tp1>(this->release()); }
  
--- 82,109 ----
      }    
    }
  
+   // 20.4.5.3 auto_ptr conversions [lib.auto.ptr.conv]
+ 
    // According to the C++ standard, these conversions are required.  Most
    // present-day compilers, however, do not enforce that requirement---and, 
    // in fact, most present-day compilers do not support the language 
    // features that these conversions rely on.
    
  #if defined(__SGI_STL_USE_AUTO_PTR_CONVERSIONS) && \
+     defined(__STL_MEMBER_TEMPLATE_CLASSES) && \
      defined(__STL_MEMBER_TEMPLATES)
  
+ private:
+   template <class _Tp1> struct auto_ptr_ref {
+     auto_ptr<_Tp1>& _M_auto_ptr;
+     auto_ptr_ref(auto_ptr<_Tp1>* __p) : _M_auto_ptr(*__p) {}
+   };
+ 
  public:
    auto_ptr(auto_ptr_ref<_Tp> __ref) __STL_NOTHROW
!     : _M_ptr(__ref._M_auto_ptr.release()) {}
    template <class _Tp1> operator auto_ptr_ref<_Tp1>() __STL_NOTHROW 
!     { return auto_ptr_ref<_Tp>(this); }
    template <class _Tp1> operator auto_ptr<_Tp1>() __STL_NOTHROW
      { return auto_ptr<_Tp1>(this->release()); }
  

auto_ptr.tar


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