// file : Utility/ReferenceCounting/SmartPtr.tpp // author : Boris Kolpackov // copyright : Copyright (c) 2002-2003 Boris Kolpackov // license : http://kolpackov.net/license.html namespace Utility { namespace ReferenceCounting { // c-tor's & d-tor template SmartPtr:: SmartPtr () throw () : ptr_ (0) { } template SmartPtr:: SmartPtr (Type* ptr) throw () : ptr_ (ptr) { } template SmartPtr:: SmartPtr (SmartPtr const& s_ptr) throw (Interface::Exception, Interface::SystemException) : ptr_ (add_ref (s_ptr.in ())) { } template template SmartPtr:: SmartPtr (SmartPtr const& s_ptr) throw (Interface::Exception, Interface::SystemException) : ptr_ (add_ref (s_ptr.in ())) { } template SmartPtr:: ~SmartPtr () throw () { // This is an additional catch-all layer to protect from // non-conformant Type. try { if (ptr_ != 0) ptr_->remove_ref (); } catch (...) { } } // operator= template SmartPtr& SmartPtr:: operator= (Type* ptr) throw () { if (ptr_ != 0) ptr_->remove_ref (); ptr_ = ptr; return *this; } template SmartPtr& SmartPtr:: operator= (SmartPtr const& s_ptr) throw (Interface::Exception, Interface::SystemException) { Type* old_ptr (ptr_); Type* new_ptr (add_ref (s_ptr.in ())); // this can throw if (old_ptr != 0) old_ptr->remove_ref (); ptr_ = new_ptr; // commit return *this; } template template SmartPtr& SmartPtr:: operator= (SmartPtr const& s_ptr) throw (Interface::Exception, Interface::SystemException) { Type* old_ptr (ptr_); Other* new_ptr (add_ref (s_ptr.in ())); // this can throw if (old_ptr != 0) old_ptr->remove_ref (); ptr_ = new_ptr; // commit return *this; } // conversions template SmartPtr:: operator T* () const throw () { return ptr_; } // accessors template T* SmartPtr:: operator-> () const throw (NotInitialized) { if (ptr_ == 0) { throw NotInitialized( "Utility::ReferenceCounting::SmartPtr::operator-> : " "unable to dereference NULL pointer."); } return ptr_; } template T* SmartPtr:: in () const throw () { return ptr_; } template T* SmartPtr:: retn() throw () { Type* ret (ptr_); ptr_ = 0; return ret; } // Specialization of add_ref function for SmartPtr template T* add_ref (SmartPtr const& ptr) throw (Interface::Exception, Interface::SystemException) { // delegate to generic implementation return add_ref (ptr.in ()); } // Dynamic type conversion function for SmartPtr's template D* smart_cast (SmartPtr const& s) throw (Interface::Exception, Interface::SystemException) { return add_ref (dynamic_cast(s.in ())); } // Acquisition function template SmartPtr acquire (T* ptr) throw (Interface::Exception, Interface::SystemException) { return SmartPtr (ptr); } } } //$Id$