This is the mail archive of the
libstdc++@sourceware.cygnus.com
mailing list for the libstdc++ project.
Patch for auto_ptr + test
- To: libstdc++ at sourceware dot cygnus dot com
- Subject: Patch for auto_ptr + test
- From: Branko Čibej <branko dot cibej at hermes dot si>
- Date: Tue, 13 Jun 2000 15:33:30 +0200
- Organization: HERMES SoftLab
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