ENH: Implemented auto_ptr_ref in a way that allows conversion of the pointed-to type.

This commit is contained in:
Brad King 2007-03-03 15:05:52 -05:00
parent ed722cbe61
commit 8c1f9e1b83
2 changed files with 6 additions and 9 deletions

View File

@ -26,14 +26,14 @@ namespace detail
// a private namespace. // a private namespace.
template <class Y> struct auto_ptr_ref template <class Y> struct auto_ptr_ref
{ {
auto_ptr<Y>& p_; Y* p_;
// The extra constructor argument prevents implicit conversion to // The extra constructor argument prevents implicit conversion to
// auto_ptr_ref from auto_ptr through the constructor. Normally // auto_ptr_ref from auto_ptr through the constructor. Normally
// this should be done with the explicit keyword but Borland 5.x // this should be done with the explicit keyword but Borland 5.x
// generates code in the conversion operator to call itself // generates code in the conversion operator to call itself
// infinately. // infinately.
auto_ptr_ref(auto_ptr<Y>& p, int): p_(p) {} auto_ptr_ref(Y* p, int): p_(p) {}
}; };
} }
@ -136,7 +136,7 @@ public:
/** Construct from an auto_ptr_ref. This is used when the /** Construct from an auto_ptr_ref. This is used when the
constructor argument is a call to a function returning an constructor argument is a call to a function returning an
auto_ptr. */ auto_ptr. */
auto_ptr(detail::auto_ptr_ref<X> r) throw(): x_(r.p_.release()) auto_ptr(detail::auto_ptr_ref<X> r) throw(): x_(r.p_)
{ {
} }
@ -145,7 +145,7 @@ public:
another auto_ptr. */ another auto_ptr. */
template <class Y> operator detail::auto_ptr_ref<Y>() throw() template <class Y> operator detail::auto_ptr_ref<Y>() throw()
{ {
return detail::auto_ptr_ref<Y>(*this, 1); return detail::auto_ptr_ref<Y>(this->release(), 1);
} }
/** Convert to an auto_ptr holding an object of a compatible type. /** Convert to an auto_ptr holding an object of a compatible type.
@ -160,7 +160,7 @@ public:
assignment. */ assignment. */
auto_ptr& operator=(detail::auto_ptr_ref<X> r) throw() auto_ptr& operator=(detail::auto_ptr_ref<X> r) throw()
{ {
this->reset(r.p_.release()); this->reset(r.p_);
return *this; return *this;
} }
}; };

View File

@ -123,6 +123,7 @@ int testAutoPtr(int, char*[])
} }
#if 0 #if 0
// Is this allowed by the standard?
{ {
int received = function_call(generate_auto_ptr_B()); int received = function_call(generate_auto_ptr_B());
ASSERT(received, ASSERT(received,
@ -144,22 +145,18 @@ int testAutoPtr(int, char*[])
"auto_ptr empty after assignment from factory function"); "auto_ptr empty after assignment from factory function");
} }
#if 0
{ {
kwsys::auto_ptr<A> pa(generate_auto_ptr_B()); kwsys::auto_ptr<A> pa(generate_auto_ptr_B());
ASSERT(pa.get(), ASSERT(pa.get(),
"auto_ptr empty after construction from compatible factory function"); "auto_ptr empty after construction from compatible factory function");
} }
#endif
#if 0
{ {
kwsys::auto_ptr<A> pa; kwsys::auto_ptr<A> pa;
pa = generate_auto_ptr_B(); pa = generate_auto_ptr_B();
ASSERT(pa.get(), ASSERT(pa.get(),
"auto_ptr empty after assignment from compatible factory function"); "auto_ptr empty after assignment from compatible factory function");
} }
#endif
} }
ASSERT(instances == 0, "auto_ptr leaked an object"); ASSERT(instances == 0, "auto_ptr leaked an object");