This commit is contained in:
mjudge%netscape.com 1998-11-18 22:09:52 +00:00
Родитель f73f1d98c5
Коммит 2bd280d84e
2 изменённых файлов: 116 добавлений и 64 удалений

Просмотреть файл

@ -190,6 +190,10 @@
#define REINTERPRET_CAST(T,x) ((T)(x))
#endif
#ifdef NO_BOOL
typedef unsigned char bool;
#endif
#ifdef NO_MEMBER_USING_DECLARATIONS
#include "prtypes.h"
#endif
@ -289,7 +293,8 @@ class COM_auto_ptr
explicit
COM_auto_ptr( T* ptr = 0 )
: ptr_(ptr)
: ptr_(ptr),
awaiting_AddRef_(false)
{
if ( ptr_ )
ptr_->AddRef();
@ -297,13 +302,15 @@ class COM_auto_ptr
explicit
COM_auto_ptr( const dont_AddRef_t<T>& P )
: ptr_(P.ptr_)
: ptr_(P.ptr_),
awaiting_AddRef_(false)
{
// nothing else to do here
}
COM_auto_ptr( const COM_auto_ptr<T>& P )
: ptr_(P.ptr_)
: ptr_(P.ptr_),
awaiting_AddRef_(false)
{
if ( ptr_ )
ptr_->AddRef();
@ -311,7 +318,7 @@ class COM_auto_ptr
~COM_auto_ptr()
{
if ( ptr_ )
if ( ptr_ && !awaiting_AddRef_ )
ptr_->Release();
}
@ -325,8 +332,9 @@ class COM_auto_ptr
COM_auto_ptr&
operator=( const dont_AddRef_t<T>& rhs )
{
if ( ptr_ )
if ( ptr_ && !awaiting_AddRef_ )
ptr_->Release();
awaiting_AddRef_ = false;
ptr_ = rhs.ptr_;
return *this;
}
@ -342,6 +350,7 @@ class COM_auto_ptr
operator->() const
// returns a |derived_safe<T>*| to deny clients the use of |AddRef| and |Release|
{
assert( ptr_ != 0 ); // you're not allowed to dereference a NULL pointer
return get();
}
@ -369,21 +378,75 @@ class COM_auto_ptr
void
reset( T* ptr = 0 )
{
if ( ptr != ptr_ )
if ( ptr )
ptr->AddRef();
if ( ptr_ && !awaiting_AddRef_ )
ptr_->Release();
awaiting_AddRef_ = false;
ptr_ = ptr;
}
// private:
// template <class T> friend class func_AddRefs_t;
// template <class T> friend class func_doesnt_AddRef_t;
T**
start_assignment( bool awaiting_AddRef )
{
if ( ptr_ && !awaiting_AddRef_ )
ptr_->Release();
awaiting_AddRef_ = awaiting_AddRef;
ptr_ = 0;
return &ptr_;
}
void
finish_assignment()
{
if ( awaiting_AddRef_ )
{
if ( ptr )
ptr->AddRef();
if ( ptr_ )
ptr_->Release();
ptr_ = ptr;
ptr_->AddRef();
awaiting_AddRef_ = false;
}
}
private:
T* ptr_;
bool awaiting_AddRef_;
};
template <class T>
bool
operator==( const COM_auto_ptr<T>& lhs, const T*const rhs )
{
return lhs.get() == rhs;
}
template <class T>
bool
operator!=( const COM_auto_ptr<T>& lhs, const T*const rhs )
{
return lhs.get() != rhs;
}
template <class T>
bool
operator==( const T*const lhs, const COM_auto_ptr<T>& rhs )
{
return lhs == rhs.get();
}
template <class T>
bool
operator!=( const T*const lhs, const COM_auto_ptr<T>& rhs )
{
return lhs != rhs.get();
}
template <class T>
@ -410,36 +473,33 @@ class func_AddRefs_t
public:
explicit
func_AddRefs_t( COM_auto_ptr<T>& P )
: ptr_(0),
new_owner_(P)
: owner_(&P)
{
// nothing else to do
}
~func_AddRefs_t()
#if 1
operator void**()
{
new_owner_ = dont_AddRef(ptr_);
return REINTERPRET_CAST(void**, owner_->start_assignment(false));
}
#endif
T*&
operator*()
{
return ptr_;
assert(owner_);
return *(owner_->start_assignment(false));
}
operator T**()
{
return &ptr_;
assert(owner_);
return owner_->start_assignment(false);
}
operator void**()
{
return REINTERPRET_CAST(void **,&ptr_);
}
private:
T* ptr_;
COM_auto_ptr<T>& new_owner_;
private:
COM_auto_ptr<T>* owner_;
};
template <class T>
@ -463,36 +523,48 @@ class func_doesnt_AddRef_t
public:
explicit
func_doesnt_AddRef_t( COM_auto_ptr<T>& P )
: ptr_(0),
new_owner_(P)
: owner_(&P)
{
// nothing else to do
}
func_doesnt_AddRef_t( func_doesnt_AddRef_t<T>& F )
: owner_(F.owner_)
{
F.owner_ = 0;
}
~func_doesnt_AddRef_t()
{
new_owner_ = ptr_;
if ( owner_ )
owner_->finish_assignment();
}
#if 1
operator void**()
{
return REINTERPRET_CAST(void**, owner_->start_assignment(true));
}
#endif
T*&
operator*()
{
return ptr_;
assert(owner_);
return *(owner_->start_assignment(true));
}
operator T**()
{
return &ptr_;
assert(owner_);
return owner_->start_assignment(true);
}
operator void**()
{
return REINTERPRET_CAST(void **,&ptr_);
}
private:
func_doesnt_AddRef_t<T> operator=( const func_doesnt_AddRef_t<T>& ); // not to be implemented
private:
T* ptr_;
COM_auto_ptr<T>& new_owner_;
private:
COM_auto_ptr<T>* owner_;
};
template <class T>

Просмотреть файл

@ -148,21 +148,6 @@ CreateIFoo( void** result )
return 0;
}
NS_RESULT
CreateIFooVoidPtrRef( void*& result )
// a typical factory function (that calls AddRef)
{
cout << ">>CreateIFooVoidPtrRef() --> ";
IFoo* foop = new IFoo;
cout << "IFoo@" << STATIC_CAST(void*, foop) << endl;
foop->AddRef();
result = foop;
cout << "<<CreateIFooVoidPtrRef()" << endl;
return 0;
}
void
set_a_IFoo( COM_auto_ptr<IFoo>* result )
{
@ -288,10 +273,10 @@ main()
IFoo* raw_foo2p = foo2p.get();
cout << endl << "### Test 8: can you compare a |COM_auto_ptr| with a raw interface pointer [!=]?" << endl;
if ( foo1p.get() != raw_foo2p )
cout << "foo1p.get() != raw_foo2p" << endl;
if ( foo1p != raw_foo2p )
cout << "foo1p != raw_foo2p" << endl;
else
cout << "foo1p.get() == raw_foo2p" << endl;
cout << "foo1p == raw_foo2p" << endl;
cout << endl << "### Test 9: can you assign one |COM_auto_ptr| into another?" << endl;
@ -304,10 +289,10 @@ main()
cout << "foo1p != foo2p" << endl;
cout << endl << "### Test 11: can you compare a |COM_auto_ptr| with a raw interface pointer [==]?" << endl;
if ( raw_foo2p == foo2p.get() )
cout << "raw_foo2p == foo2p.get()" << endl;
if ( raw_foo2p == foo2p )
cout << "raw_foo2p == foo2p" << endl;
else
cout << "raw_foo2p != foo2p.get()" << endl;
cout << "raw_foo2p != foo2p" << endl;
cout << endl << "### Test 12: bare pointer test?" << endl;
if ( foo1p )
@ -350,21 +335,16 @@ main()
{
cout << endl << "### Test 17: basic parameter behavior?" << endl;
COM_auto_ptr<IFoo> foop;
CreateIFoo( (void **)(IFoo **)func_AddRefs_t<IFoo>(foop) );
CreateIFoo( func_AddRefs_t<IFoo>(foop) );
}
{
cout << endl << "### Test 18: basic parameter behavior, using the short form?" << endl;
COM_auto_ptr<IFoo> foop;
CreateIFoo( (void **)(IFoo **)func_AddRefs(foop) );
CreateIFoo( func_AddRefs(foop) );
}
{
cout << endl << "### Test 18: basic parameter behavior, using the short form?" << endl;
COM_auto_ptr<IFoo> foop;
CreateIFooVoidPtrRef( *(void **)func_AddRefs(foop) );
}
{
cout << endl << "### Test 19: reference parameter behavior?" << endl;