// -*- c++ -*- //------------------------------------------------------------------------------ // AutoPtr.h //------------------------------------------------------------------------------ // Copyright (C) 1999,2005 Vladislav Grinchenko // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Library General Public // License as published by the Free Software Foundation; either // version 2 of the License, or (at your option) any later version. //------------------------------------------------------------------------------ #ifndef AUTO_PTR_H #define AUTO_PTR_H #include // NULL definition /** @file AutoPtr.h AutoPtr is a local implementation of STL's auto_ptr that makes dynamic memory handling a bit easier. */ namespace ASSA { /** * @class AutoPtrRef * * A wrapper class to provide AutoPtr with reference semantics. * An AutoPtr can be assigned (or constructed from) the result of * a function which returns an AutoPtr by value (rvalue). */ template class AutoPtrRef { public: explicit AutoPtrRef (R* p_) : m_ptr (p_) { /* no-op */ } R* m_ptr; }; /** @class AutoPtr AutoPtr is based on SGI implementation of a auto_ptr template that makes memory handling a little bit easier. AutoPtr interface does not completely confirm to that of auto_ptr as specified in C++ Standard. */ template class AutoPtr { private: /// Pointer to the object we own X* m_ptr; public: /** * Construct an AutoPtr from a raw pointer. * The word 'explicit' disallows implicit construction of objects, * for example in function calls. * @param p_ pointer (defaults to NULL) to assume ownerwhip for. */ explicit AutoPtr (X* p_ = 0) : m_ptr (p_) { /* no-op */ } /** * Construct AutoPtr from another AutoPtr. * @param a_ AutoPtr object that gives up its ownership. */ AutoPtr (AutoPtr& a_) : m_ptr (a_.release ()) {/* no-op */ } /** * Construct AutoPtr from another AutoPtr of different (but related) * type. A pointer to T must be convertible to a pointer to X. * @note Nonconstant parameter * @param a_ AutoPtr object that is released of ownership. */ template AutoPtr (AutoPtr& a_) : m_ptr (a_.release ()) { /* no-op */ } /** * Assignment operator deletes memory it owns * and transfers the ownership from a_ to itself. * @param a_ another AutoPtr of the same type. */ AutoPtr& operator= (AutoPtr& a_) { reset (a_.release ()); return *this; } /** * Assignment from another AutoPtr of a different but related type. * @note Nonconstant parameter * @param a_ AutoPtr to assume ownership of */ template AutoPtr& operator=(AutoPtr& a_) { reset (a_.release ()); return *this; } /** * When AutoPtr goes out of scope, the object it owns is deleted. * Not owning anything has no effect. */ ~AutoPtr () { if (m_ptr) { delete m_ptr; } } /** * Smart pointer dereferencing. */ X& operator*() const { return *m_ptr; } /** * Smart pointer dereferencing. */ X* operator->() const { return m_ptr; } /** * Get a raw memory pointer without changing ownership status. * Usefull when you need to pass a pointer to the function. * @return The raw pointer being managed. */ X* get () const { return m_ptr; } /** * Give up the ownership of the memory. When AutoPtr gets * out of scope, nothing happens. The caller becomes responsible * for the memory management. */ X* release () { X* tmp = m_ptr; m_ptr = NULL; return tmp; } /** * Forcibly delete the managed object and assume the ownership * of a_. */ void reset (X* p_ = 0) { if (p_ != m_ptr) { delete m_ptr; m_ptr = p_; } } /** @{ * @brief Automagic conversions * * These operations convert an AutoPtr into/from an AutoPtrRef * as needed. This allows on-the-fly conversion between AutoPtr * of different but related types (parent/child): * @code * AutoPtr FooReturnsAutoPtr () { ... }; * * AutoPtr aptr = FooReturnsAutoPtr (); * @endcode */ AutoPtr (AutoPtrRef ref_) : m_ptr (ref_.m_ptr) { /* no-op */ } AutoPtr& operator=(AutoPtrRef ref_) { if (ref_.m_ptr != get ()) { delete m_ptr; m_ptr = ref_.m_ptr; } return *this; } template operator AutoPtrRef () { return AutoPtrRef (release ()); } template operator AutoPtr () { return AutoPtr (release ()); } /** @} */ }; /** * @class AutoPtrArrayRef * * A wrapper class to provide AutoPtr with reference semantics. * An AutoPtr can be assigned (or constructed from) the result of * a function which returns an AutoPtr by value (rvalue). */ template class AutoPtrArrayRef { public: explicit AutoPtrArrayRef (R* p_) : m_ptr (p_) { /* no-op */ } R* m_ptr; }; /** @class AutoPtrArray @brief AutoPtrArray handles memory management of an array of objects. */ template class AutoPtrArray { private: /// Pointer to the object we own X* m_ptr; public: /** * Construct an AutoPtrArray from a raw pointer. * The word 'explicit' disallows implicit construction of objects, * for example in function calls. * @param p_ pointer (defaults to NULL) to assume ownerwhip for. */ explicit AutoPtrArray (X* p_ = 0) : m_ptr (p_) { /* no-op */ } /** * Construct AutoPtrArray from another AutoPtrArray. * @param a_ AutoPtrArray object that gives up its ownership. */ AutoPtrArray (AutoPtrArray& a_) : m_ptr (a_.release ()) {/* no-op */ } /** * Construct AutoPtrArray from another AutoPtrArray of different * (but related) type. A pointer to T must be convertible to a * pointer to X. * @note Nonconstant paramenter * @param a_ AutoPtrArray object that is released of ownership. */ template AutoPtrArray (AutoPtrArray& a_) : m_ptr (a_.release ()) { /* no-op */ } /** * Assignment operator deletes memory it owns * and transfers the ownership from a_ to itself. * @note Nonconstant parameter * @param a_ another AutoPtrArray of the same type. */ AutoPtrArray& operator= (AutoPtrArray& a_) { reset (a_.release ()); return *this; } /** * Assignment from another AutoPtrArray of a different but related type. * @note Nonconstant parameter * @param a_ AutoPtrArray to assume ownership of */ template AutoPtrArray& operator=(AutoPtrArray& a_) { reset (a_.release ()); return *this; } /** * When AutoPtrArray goes out of scope, the object it owns is deleted. * Not owning anything has no effect. */ ~AutoPtrArray () { if (m_ptr) { delete [] m_ptr; } } /** * Smart pointer dereferencing. */ X& operator*() const { return *m_ptr; } /** * Smart pointer dereferencing. */ X* operator->() const { return m_ptr; } /** * Access operator */ X& operator[] (int i) const { X* array = get (); return (array [i]); } /** * Get a raw memory pointer without changing ownership status. * Usefull when you need to pass a pointer to the function. * @return The raw pointer being managed. */ X* get () const { return m_ptr; } /** * Give up the ownership of the memory. When AutoPtrArray gets * out of scope, nothing happens. The caller becomes responsible * for the memory management. */ X* release () { X* tmp = m_ptr; m_ptr = NULL; return tmp; } /** * Forcibly delete the managed object and assume the ownership * of a_. */ void reset (X* p_ = 0) { if (p_ != m_ptr) { delete [] m_ptr; m_ptr = p_; } } /** @{ * @brief Automagic conversions * * These operations convert an AutoPtrArray into/from an AutoPtrArrayRef * as needed. This allows on-the-fly conversion between AutoPtrArray * of different but related types (parent/child): * @code * AutoPtrArray FooReturnsAutoPtrArray () { ... }; * * AutoPtrArray aptr = FooReturnsAutoPtrArray (); * @endcode */ AutoPtrArray (AutoPtrArrayRef ref_) : m_ptr (ref_.m_ptr) { /* no-op */ } AutoPtrArray& operator=(AutoPtrArrayRef ref_) { if (ref_.m_ptr != get ()) { delete [] m_ptr; m_ptr = ref_.m_ptr; } return *this; } template operator AutoPtrArrayRef () { return AutoPtrArrayRef (release ()); } template operator AutoPtrArray () { return AutoPtrArray (release ()); } /** @} */ }; } // end namespace ASSA #endif /* AUTO_PTR_H */