williamr@2: /*
williamr@2:  * © Portions copyright (c) 2006-2007 Nokia Corporation.  All rights reserved.
williamr@2:  * Copyright (c) 1997-1999
williamr@2:  * Silicon Graphics Computer Systems, Inc.
williamr@2:  *
williamr@2:  * Copyright (c) 1999
williamr@2:  * Boris Fomitchev
williamr@2:  *
williamr@2:  * This material is provided "as is", with absolutely no warranty expressed
williamr@2:  * or implied. Any use is at your own risk.
williamr@2:  *
williamr@2:  * Permission to use or copy this software for any purpose is hereby granted
williamr@2:  * without fee, provided the above notices are retained on all copies.
williamr@2:  * Permission to modify the code and to distribute modified code is granted,
williamr@2:  * provided the above notices are retained, and a notice that the code was
williamr@2:  * modified is included with the above copyright notice.
williamr@2:  *
williamr@2:  */
williamr@2: 
williamr@2: #ifndef _STLP_AUTO_PTR_H
williamr@2: # define _STLP_AUTO_PTR_H
williamr@2: 
williamr@2: _STLP_BEGIN_NAMESPACE
williamr@2: // implementation primitive
williamr@2: class __ptr_base {
williamr@2: public:
williamr@2:   void* _M_p;
williamr@2:   void  __set(const void* __p) { _M_p = __CONST_CAST(void*,__p); }
williamr@2:   void  __set(void* __p) { _M_p = __p; }
williamr@2: };
williamr@2: 
williamr@2: template <class _Tp> class auto_ptr_ref {
williamr@2: public:
williamr@2:   __ptr_base& _M_r;
williamr@2:   _Tp* const _M_p;
williamr@2: 
williamr@2:   auto_ptr_ref(__ptr_base& __r, _Tp* __p) : _M_r(__r), _M_p(__p) {  }
williamr@2: 
williamr@2:   _Tp* release() const { _M_r.__set((void*)0); return _M_p; }
williamr@2: 
williamr@2: };
williamr@2: 
williamr@2: template<class _Tp> class auto_ptr :  public __ptr_base {
williamr@2: public:
williamr@2:   typedef _Tp element_type;
williamr@2:   typedef auto_ptr<_Tp>           _Self;
williamr@2: 
williamr@2:   _Tp* release() {
williamr@2:     _Tp* __px = this->get();
williamr@2:     this->_M_p = 0;
williamr@2:     return __px;
williamr@2:   }
williamr@2: 
williamr@2:   void reset(_Tp* __px=0) {
williamr@2:     _Tp* __pt = this->get();
williamr@2:     if (__px != __pt)
williamr@2:       delete __pt;
williamr@2:     this->__set(__px);
williamr@2:   }
williamr@2: 
williamr@2:   _Tp* get() const { return __REINTERPRET_CAST(_Tp*,__CONST_CAST(void*,_M_p)); }
williamr@2: 
williamr@2: # if !defined (_STLP_NO_ARROW_OPERATOR)
williamr@2:   _Tp* operator->() const {
williamr@2:     _STLP_VERBOSE_ASSERT(get()!=0, _StlMsg_AUTO_PTR_NULL)
williamr@2:     return get();
williamr@2:   }
williamr@2: # endif
williamr@2:   _Tp& operator*() const  {
williamr@2:     _STLP_VERBOSE_ASSERT(get()!=0, _StlMsg_AUTO_PTR_NULL)
williamr@2:     return *get();
williamr@2:   }
williamr@2: 
williamr@2:   auto_ptr() {
williamr@2:     this->_M_p = 0;
williamr@2: # ifdef _STLP_USE_TRAP_LEAVE
williamr@2:     CleanupStack::PushL(TCleanupItem(Close, (void*)this));
williamr@2: # endif
williamr@2:   }
williamr@2: 
williamr@2:   explicit auto_ptr(_Tp* __px) {
williamr@2:     this->__set(__px);
williamr@2: # ifdef _STLP_USE_TRAP_LEAVE
williamr@2:     CleanupStack::PushL(TCleanupItem(Close, (void*)this));
williamr@2: # endif
williamr@2:   }
williamr@2: 
williamr@2: #if defined (_STLP_MEMBER_TEMPLATES)
williamr@2: # if !defined (_STLP_NO_TEMPLATE_CONVERSIONS)
williamr@2:   template<class _Tp1> auto_ptr(auto_ptr<_Tp1>& __r) {
williamr@2:     _Tp* __conversionCheck = __r.release();
williamr@2:     this->__set(__conversionCheck);
williamr@2: # ifdef _STLP_USE_TRAP_LEAVE
williamr@2:     CleanupStack::PushL(TCleanupItem(Close, (void*)this));
williamr@2: # endif
williamr@2:   }
williamr@2: # endif
williamr@2:   template<class _Tp1> auto_ptr<_Tp>& operator=(auto_ptr<_Tp1>& __r) {
williamr@2:     _Tp* __conversionCheck = __r.release();
williamr@2:     reset(__conversionCheck);
williamr@2:     return *this;
williamr@2:   }
williamr@2: #endif /* _STLP_MEMBER_TEMPLATES */
williamr@2: 
williamr@2:   auto_ptr(_Self& __r)
williamr@2:   { this->__set(__r.release());
williamr@2: # ifdef _STLP_USE_TRAP_LEAVE
williamr@2:     CleanupStack::PushL(TCleanupItem(Close, (void*)this));
williamr@2: # endif
williamr@2:   }
williamr@2: 
williamr@2:   _Self& operator=(_Self& __r)  {
williamr@2:     reset(__r.release());
williamr@2:     return *this;
williamr@2:   }
williamr@2: 
williamr@2:   ~auto_ptr() { _STLP_POP_ITEM reset(0); }
williamr@2: 
williamr@2:   auto_ptr(auto_ptr_ref<_Tp> __r) {
williamr@2:     this->__set(__r.release());
williamr@2: # ifdef _STLP_USE_TRAP_LEAVE
williamr@2:     CleanupStack::PushL(TCleanupItem(Close, (void*)this));
williamr@2: # endif
williamr@2:   }
williamr@2: 
williamr@2:   _Self& operator=(auto_ptr_ref<_Tp> __r) {
williamr@2:     reset(__r.release());
williamr@2:     return *this;
williamr@2:   }
williamr@2: 
williamr@2: 
williamr@2:   _Self& operator=(_Tp* __px) {
williamr@2:   	reset(__px);
williamr@2:     return *this;
williamr@2:   }
williamr@2: 
williamr@2: 
williamr@2: 
williamr@2: # if defined(_STLP_MEMBER_TEMPLATES) && !defined(_STLP_NO_TEMPLATE_CONVERSIONS)
williamr@2:   template<class _Tp1> operator auto_ptr_ref<_Tp1>() {
williamr@2:     return auto_ptr_ref<_Tp1>(*this, this->get());
williamr@2:   }
williamr@2:   template<class _Tp1> operator auto_ptr<_Tp1>() {
williamr@2:     return auto_ptr<_Tp1>(release());
williamr@2:   }
williamr@2: # else
williamr@2:   operator auto_ptr_ref<_Tp>()
williamr@2:   { return auto_ptr_ref<_Tp>(*this, this->get()); }
williamr@2: # endif
williamr@2: 
williamr@2: # ifdef _STLP_USE_TRAP_LEAVE
williamr@2:   static void Close(void* aPtr);
williamr@2: # endif
williamr@2: 
williamr@2: };
williamr@2: 
williamr@2: # ifdef _STLP_USE_TRAP_LEAVE
williamr@2: template <class _Tp>
williamr@2: void
williamr@2: auto_ptr<_Tp>::Close(void* aPtr)
williamr@2: {
williamr@2:   auto_ptr<_Tp>* self = (auto_ptr<_Tp>*)aPtr;
williamr@2:   self->reset(0);
williamr@2: }
williamr@2: # endif
williamr@2: 
williamr@2: 
williamr@2: _STLP_END_NAMESPACE
williamr@2: 
williamr@2: #endif /* _STLP_AUTO_PTR_H */
williamr@2: 
williamr@2: // Local Variables:
williamr@2: // mode:C++
williamr@2: // End:
williamr@2: