// // AutoPtr.h // // $Id: AutoPtr.h,v 1.1.1.3 2006/04/04 23:30:02 obiltschnig Exp $ // // Library: Foundation // Package: Core // Module: AutoPtr // // Definition of the AutoPtr template class. // // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // // 3. Redistributions in any form must be accompanied by information on // how to obtain complete source code for this software and any // accompanying software that uses this software. The source code // must either be included in the distribution or be available for no // more than the cost of distribution plus a nominal fee, and must be // freely redistributable under reasonable conditions. For an // executable file, complete source code means the source code for all // modules it contains. It does not include source code for modules or // files that typically accompany the major components of the operating // system on which the executable file runs. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE // COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. // #ifndef Foundation_AutoPtr_INCLUDED #define Foundation_AutoPtr_INCLUDED #ifndef Foundation_Foundation_INCLUDED #include "Foundation/Foundation.h" #endif #ifndef Foundation_Exception_INCLUDED #include "Foundation/Exception.h" #endif #ifndef STD_ALGORITHM_INCLUDED #include #define STD_ALGORITHM_INCLUDED #endif Foundation_BEGIN template class AutoPtr /// AutoPtr is a "smart" pointer for classes implementing /// reference counting based garbage collection. /// To be usable with the AutoPtr template, a class must /// implement the following behaviour: /// A class must maintain a reference count. /// The constructors of the object initialize the reference /// count to one. /// The class must implement a public duplicate() method: /// void duplicate(); /// that increments the reference count by one. /// The class must implement a public release() method: /// void release() /// that decrements the reference count by one, and, /// if the reference count reaches zero, deletes the /// class. /// AutoPtr works in the following way: /// If an AutoPtr is assigned an ordinary pointer to /// an object (via the constructor or the assignment operator), /// it takes ownership of the object and the object's reference /// count remains unchanged. /// If the AutoPtr is assigned another AutoPtr, the /// object's reference count is incremented by one by /// calling duplicate() on its object. /// The destructor of AutoPtr calls release() on its /// object. /// AutoPtr supports dereferencing with both the -> /// and the * operator. An attempt to dereference a null /// AutoPtr results in a NullPointerException being thrown. /// AutoPtr also implements all relational operators. { public: AutoPtr(): _ptr(0) { } AutoPtr(C* ptr): _ptr(ptr) { } AutoPtr(C* ptr, bool shared): _ptr(ptr) { if (shared && _ptr) _ptr->duplicate(); } AutoPtr(const AutoPtr& ptr): _ptr(ptr._ptr) { if (_ptr) _ptr->duplicate(); } template AutoPtr(const AutoPtr& ptr): _ptr(const_cast(ptr.get())) { if (_ptr) _ptr->duplicate(); } ~AutoPtr() { if (_ptr) _ptr->release(); } AutoPtr& operator = (C* ptr) { if (_ptr != ptr) { if (_ptr) _ptr->release(); _ptr = ptr; } return *this; } AutoPtr& operator = (const AutoPtr& ptr) { if (&ptr != this) { if (_ptr) _ptr->release(); _ptr = ptr._ptr; if (_ptr) _ptr->duplicate(); } return *this; } void swap(AutoPtr& ptr) { std::swap(_ptr, ptr._ptr); } template AutoPtr& operator = (const AutoPtr& ptr) { if (ptr.get() != _ptr) { if (_ptr) _ptr->release(); _ptr = const_cast(ptr.get()); if (_ptr) _ptr->duplicate(); } return *this; } C* operator -> () { if (_ptr) return _ptr; else throw NullPointerException(); } const C* operator -> () const { if (_ptr) return _ptr; else throw NullPointerException(); } C& operator * () { if (_ptr) return *_ptr; else throw NullPointerException(); } const C& operator * () const { if (_ptr) return *_ptr; else throw NullPointerException(); } C* get() { return _ptr; } operator C* () { return _ptr; } operator const C* () const { return _ptr; } const C* get() const { return _ptr; } C* duplicate() { if (_ptr) _ptr->duplicate(); return _ptr; } bool operator == (const AutoPtr& ptr) const { return _ptr == ptr._ptr; } bool operator == (const C* ptr) const { return _ptr == ptr; } bool operator == (C* ptr) const { return _ptr == ptr; } bool operator != (const AutoPtr& ptr) const { return _ptr != ptr._ptr; } bool operator != (const C* ptr) const { return _ptr != ptr; } bool operator != (C* ptr) const { return _ptr != ptr; } bool operator < (const AutoPtr& ptr) const { return _ptr < ptr._ptr; } bool operator < (const C* ptr) const { return _ptr < ptr; } bool operator < (C* ptr) const { return _ptr < ptr; } bool operator <= (const AutoPtr& ptr) const { return _ptr <= ptr._ptr; } bool operator <= (const C* ptr) const { return _ptr <= ptr; } bool operator <= (C* ptr) const { return _ptr <= ptr; } bool operator > (const AutoPtr& ptr) const { return _ptr > ptr._ptr; } bool operator > (const C* ptr) const { return _ptr > ptr; } bool operator > (C* ptr) const { return _ptr > ptr; } bool operator >= (const AutoPtr& ptr) const { return _ptr >= ptr._ptr; } bool operator >= (const C* ptr) const { return _ptr >= ptr; } bool operator >= (C* ptr) const { return _ptr >= ptr; } private: C* _ptr; }; template inline void swap(AutoPtr& p1, AutoPtr& p2) { p1.swap(p2); } Foundation_END #endif // Foundation_AutoPtr_INCLUDED