diff --git a/o3tl/inc/o3tl/heap_ptr.hxx b/o3tl/inc/o3tl/heap_ptr.hxx new file mode 100644 index 000000000000..4bd05be7d8f0 --- /dev/null +++ b/o3tl/inc/o3tl/heap_ptr.hxx @@ -0,0 +1,319 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: heap_ptr.hxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: ihi $ $Date: 2007-08-20 15:50:08 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#ifndef INCLUDED_O3TL_HEAP_PTR_HXX +#define INCLUDED_O3TL_HEAP_PTR_HXX + + +#include +#include + + +namespace o3tl +{ +/** heap_ptr<> owns an object on the heap, which will be automatically + deleted, when ~heap_ptr<>() is called. + + Applicability + ------------- + heap_ptr<> can be used for class members on the heap. + - One cannot forget to delete them in the destructor. + - Constness will be transfered from the owning instance. + + heap_ptr<> can also be used as smart pointer in function bodies to + ensure exception safety. + + Special Characteristics + ----------------------- + - heap_ptr<> transfers constness from the owning object to + the pointed to object. Such it behaves like if *get() would be + a normal member of the owning object, not a pointer member. + This is preferable to the normal pointer behaviour, because + if an object is owned by another one, it is normally part of + its state. + + - heap_ptr<> provides a ->release() function + + - For reasons of simplicity and portability ->is() + is preferred over the safe-bool idiom. + + Copyability + ----------- + heap_ptr is non copyable. + - It forbids the copyconstructor and operator=(self). + + - Owning classes will automatically be non copyable, if they do not + redefine those two functions themselves. + + Incomplete Types + ---------------- + heap_ptr<> also works with incomplete types. You only need to write + class T; + but need not include .hxx. + + If you use heap_ptr<> with an incomplete type, the owning class + needs to define a non-inline destructor. Else the compiler will + complain. +*/ +template +class heap_ptr +{ + public: + typedef T element_type; /// Provided for generic programming. + typedef heap_ptr self; + +#ifndef __SUNPRO_CC + typedef T * (self::* safe_bool )(); +#endif + + /// Now, pass_heapObject is owned by this. + explicit heap_ptr( + T * pass_heapObject = 0 ); + ~heap_ptr(); + + + /** Identical to reset(), except of the return value. + @see heap_ptr<>::reset() + */ + self & operator=( + T * pass_heapObject ); + const T & operator*() const; + T & operator*(); + const T * operator->() const; + T * operator->(); + + /// True, if pHeapObject != 0. +#ifndef __SUNPRO_CC + operator safe_bool() const; +#else // workaround opt bug of Sun C++ compiler, when compiling with -xO3 + operator bool() const; +#endif + + + /** This deletes any prevoiusly existing ->pHeapObject. + Now, pass_heapObject, if != 0, is owned by this. + + @onerror + Ignores self-assignment. + Such, multiple assignment of the same pointer to the same + instance of heap_ptr<> is possible (though not recommended). + */ + void reset( + T * pass_heapObject ); + /** @return An object on the heap that must be deleted by the caller, + or 0. + + @postcond get() == 0; + */ + T * release(); + void swap( + self & io_other ); + + /// True, if pHeapObject != 0. + bool is() const; + const T * get() const; + T * get(); + + private: + // Forbidden functions: + heap_ptr( const self & ); /// Prevent copies. + self & operator=( const self & ); /// Prevent copies. + + /// @attention Does not set ->pHeapObject = 0. + void internal_delete(); + + // DATA + /// Will be deleted, when *this is destroyed. + T * pHeapObject; +}; + + +/** Supports the semantic of std::swap(). Provided as an aid to + generic programming. +*/ +template +inline void +swap( heap_ptr & io_a, + heap_ptr & io_b ) +{ + io_a.swap(io_b); +} + + + +// IMPLEMENTATION + +template +inline void +heap_ptr::internal_delete() +{ + ::boost::checked_delete(pHeapObject); + + // Do not set pHeapObject to 0, because + // that is reset to a value in all code + // where internal_delete() is used. +} + +template +inline +heap_ptr::heap_ptr( T * pass_heapObject ) + : pHeapObject(pass_heapObject) +{ +} + +template +inline +heap_ptr::~heap_ptr() +{ + internal_delete(); +} + +template +inline heap_ptr & +heap_ptr::operator=(T * pass_heapObject) +{ + reset(pass_heapObject); + return *this; +} + +template +inline const T & +heap_ptr::operator*() const +{ + BOOST_ASSERT( pHeapObject != 0 + && "Accessing a heap_ptr<>(0)." ); + return *pHeapObject; +} + +template +inline T & +heap_ptr::operator*() +{ + BOOST_ASSERT( pHeapObject != 0 + && "Accessing a heap_ptr<>(0)." ); + return *pHeapObject; +} + +template +inline const T * +heap_ptr::operator->() const +{ + return pHeapObject; +} + +template +inline T * +heap_ptr::operator->() +{ + return pHeapObject; +} + +#ifndef __SUNPRO_CC + +template +inline +heap_ptr::operator typename heap_ptr::safe_bool() const +{ + return is() + ? safe_bool(&self::get) + : safe_bool(0); +} + +#else + +template +inline heap_ptr::operator bool() const +{ + return is(); +} + +#endif // !defined(__SUNPRO_CC) + + + +template +void +heap_ptr::reset(T * pass_heapObject) +{ + if ( pHeapObject != 0 + && pHeapObject == pass_heapObject) + return; + + internal_delete(); + pHeapObject = pass_heapObject; +} + +template +T * +heap_ptr::release() +{ + T * ret = pHeapObject; + pHeapObject = 0; + return ret; +} + +template +void +heap_ptr::swap(self & io_other) +{ + T * temp = io_other.pHeapObject; + io_other.pHeapObject = pHeapObject; + pHeapObject = temp; +} + +template +inline bool +heap_ptr::is() const +{ + return pHeapObject != 0; +} + +template +inline const T * +heap_ptr::get() const +{ + return pHeapObject; +} + +template +inline T * +heap_ptr::get() +{ + return pHeapObject; +} + + +} // namespace o3tl +#endif