diff options
Diffstat (limited to 'src/libical/icptrholder.h')
-rw-r--r-- | src/libical/icptrholder.h | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/src/libical/icptrholder.h b/src/libical/icptrholder.h new file mode 100644 index 00000000..5f697eed --- /dev/null +++ b/src/libical/icptrholder.h @@ -0,0 +1,104 @@ +/* -*- Mode: C++ -*- */ + +/** + * @file icptrholder.h + * @author wyau (08/29/02) + * @brief C++ template classes for managing C++ pointers returned by VComponent::get_..._component, + * VComponent::get_..._property, ICalPropety::get_..._value. + * @remarks VComponent::get... functions returns a C++ oject that wraps the libical implementation. + * It is important to note that the wrapped implementation still belongs to the orginal + * component. To stop memory leak, caller must delete the pointer. However, the destructor + * will call the appropriate free function. eg. ~VComponent calls icalcomponent_free(imp). + * As stated previously, imp stil belongs to the original component. To avoid freeing the + * wrapped "imp", caller must set the "imp" to null before deleting the pointer. + * + * The template class relieves the burden of memory management when used as a stack based + * object. The class holds a pointer to the C++ Wrapper. The destructor set the imp to + * null before deleting the pointer. + * + * Each C++ Wrapper instantiates a template class in it's corresponding .h file. + * + * Usage example: + * VComponentTmpPtr p; // VComponentTmpPtr is an instantiation of this template + * for (p=component.get_first_component; p!= NULL; p=component.get_next_component) { + * + * (C) COPYRIGHT 2001, Critical Path + + This program is free software; you can redistribute it and/or modify + it under the terms of either: + + The LGPL as published by the Free Software Foundation, version + 2.1, available at: http://www.fsf.org/copyleft/lesser.html + + Or: + + The Mozilla Public License Version 1.0. You may obtain a copy of + the License at http://www.mozilla.org/MPL/ + */ + +#ifndef __ICPTRHOLDER_H__ +#define __ICPTRHOLDER_H__ + +template<class T> class ICPointerHolder { +public: + ICPointerHolder() { ptr = NULL; } + ICPointerHolder(T* p) { ptr = p; } + + // copy constructor to support assignment + ICPointerHolder(const ICPointerHolder& ip) { + ptr = ip.ptr; + + // We need to transfer ownership of ptr to this object by setting + // ip's ptr to null. Otherwise, ptr will de deleted twice. + // const ugliness requires us to do the const_cast. + ICPointerHolder *ipp = const_cast<ICPointerHolder*>(&ip); + ipp->ptr = NULL; + }; + + ~ICPointerHolder() { + release(); + } + + ICPointerHolder& operator=(T* p) { + this->release(); + ptr = p; + return *this; + } + + ICPointerHolder& operator=(ICPointerHolder& p) { + this->release(); + ptr = p.ptr; // this transfer ownership of the pointer + p.ptr = NULL; // set it to null so the pointer won't get delete twice. + return *this; + } + + int operator!=(T* p) {return (ptr != p);} + int operator==(T* p) {return (ptr == p);} + + operator T*() const { + return ptr; + } + + T* operator->() const { + assert(ptr); + return ptr; + } + + T& operator*() { + assert(ptr); + return *ptr; + } + +private: + void release() { + if (ptr != NULL) { + ptr->detach(); + delete ptr; + ptr = NULL; + } + } + + T* ptr; +}; + +#endif |