michael@0: /* michael@0: ******************************************************************************* michael@0: * michael@0: * Copyright (C) 2009-2012, International Business Machines michael@0: * Corporation and others. All Rights Reserved. michael@0: * michael@0: ******************************************************************************* michael@0: * file name: localpointer.h michael@0: * encoding: US-ASCII michael@0: * tab size: 8 (not used) michael@0: * indentation:4 michael@0: * michael@0: * created on: 2009nov13 michael@0: * created by: Markus W. Scherer michael@0: */ michael@0: michael@0: #ifndef __LOCALPOINTER_H__ michael@0: #define __LOCALPOINTER_H__ michael@0: michael@0: /** michael@0: * \file michael@0: * \brief C++ API: "Smart pointers" for use with and in ICU4C C++ code. michael@0: * michael@0: * These classes are inspired by michael@0: * - std::auto_ptr michael@0: * - boost::scoped_ptr & boost::scoped_array michael@0: * - Taligent Safe Pointers (TOnlyPointerTo) michael@0: * michael@0: * but none of those provide for all of the goals for ICU smart pointers: michael@0: * - Smart pointer owns the object and releases it when it goes out of scope. michael@0: * - No transfer of ownership via copy/assignment to reduce misuse. Simpler & more robust. michael@0: * - ICU-compatible: No exceptions. michael@0: * - Need to be able to orphan/release the pointer and its ownership. michael@0: * - Need variants for normal C++ object pointers, C++ arrays, and ICU C service objects. michael@0: * michael@0: * For details see http://site.icu-project.org/design/cpp/scoped_ptr michael@0: */ michael@0: michael@0: #include "unicode/utypes.h" michael@0: michael@0: #if U_SHOW_CPLUSPLUS_API michael@0: michael@0: U_NAMESPACE_BEGIN michael@0: michael@0: /** michael@0: * "Smart pointer" base class; do not use directly: use LocalPointer etc. michael@0: * michael@0: * Base class for smart pointer classes that do not throw exceptions. michael@0: * michael@0: * Do not use this base class directly, since it does not delete its pointer. michael@0: * A subclass must implement methods that delete the pointer: michael@0: * Destructor and adoptInstead(). michael@0: * michael@0: * There is no operator T *() provided because the programmer must decide michael@0: * whether to use getAlias() (without transfer of ownership) or orpan() michael@0: * (with transfer of ownership and NULLing of the pointer). michael@0: * michael@0: * @see LocalPointer michael@0: * @see LocalArray michael@0: * @see U_DEFINE_LOCAL_OPEN_POINTER michael@0: * @stable ICU 4.4 michael@0: */ michael@0: template michael@0: class LocalPointerBase { michael@0: public: michael@0: /** michael@0: * Constructor takes ownership. michael@0: * @param p simple pointer to an object that is adopted michael@0: * @stable ICU 4.4 michael@0: */ michael@0: explicit LocalPointerBase(T *p=NULL) : ptr(p) {} michael@0: /** michael@0: * Destructor deletes the object it owns. michael@0: * Subclass must override: Base class does nothing. michael@0: * @stable ICU 4.4 michael@0: */ michael@0: ~LocalPointerBase() { /* delete ptr; */ } michael@0: /** michael@0: * NULL check. michael@0: * @return TRUE if ==NULL michael@0: * @stable ICU 4.4 michael@0: */ michael@0: UBool isNull() const { return ptr==NULL; } michael@0: /** michael@0: * NULL check. michael@0: * @return TRUE if !=NULL michael@0: * @stable ICU 4.4 michael@0: */ michael@0: UBool isValid() const { return ptr!=NULL; } michael@0: /** michael@0: * Comparison with a simple pointer, so that existing code michael@0: * with ==NULL need not be changed. michael@0: * @param other simple pointer for comparison michael@0: * @return true if this pointer value equals other michael@0: * @stable ICU 4.4 michael@0: */ michael@0: bool operator==(const T *other) const { return ptr==other; } michael@0: /** michael@0: * Comparison with a simple pointer, so that existing code michael@0: * with !=NULL need not be changed. michael@0: * @param other simple pointer for comparison michael@0: * @return true if this pointer value differs from other michael@0: * @stable ICU 4.4 michael@0: */ michael@0: bool operator!=(const T *other) const { return ptr!=other; } michael@0: /** michael@0: * Access without ownership change. michael@0: * @return the pointer value michael@0: * @stable ICU 4.4 michael@0: */ michael@0: T *getAlias() const { return ptr; } michael@0: /** michael@0: * Access without ownership change. michael@0: * @return the pointer value as a reference michael@0: * @stable ICU 4.4 michael@0: */ michael@0: T &operator*() const { return *ptr; } michael@0: /** michael@0: * Access without ownership change. michael@0: * @return the pointer value michael@0: * @stable ICU 4.4 michael@0: */ michael@0: T *operator->() const { return ptr; } michael@0: /** michael@0: * Gives up ownership; the internal pointer becomes NULL. michael@0: * @return the pointer value; michael@0: * caller becomes responsible for deleting the object michael@0: * @stable ICU 4.4 michael@0: */ michael@0: T *orphan() { michael@0: T *p=ptr; michael@0: ptr=NULL; michael@0: return p; michael@0: } michael@0: /** michael@0: * Deletes the object it owns, michael@0: * and adopts (takes ownership of) the one passed in. michael@0: * Subclass must override: Base class does not delete the object. michael@0: * @param p simple pointer to an object that is adopted michael@0: * @stable ICU 4.4 michael@0: */ michael@0: void adoptInstead(T *p) { michael@0: // delete ptr; michael@0: ptr=p; michael@0: } michael@0: protected: michael@0: /** michael@0: * Actual pointer. michael@0: * @internal michael@0: */ michael@0: T *ptr; michael@0: private: michael@0: // No comparison operators with other LocalPointerBases. michael@0: bool operator==(const LocalPointerBase &other); michael@0: bool operator!=(const LocalPointerBase &other); michael@0: // No ownership transfer: No copy constructor, no assignment operator. michael@0: LocalPointerBase(const LocalPointerBase &other); michael@0: void operator=(const LocalPointerBase &other); michael@0: // No heap allocation. Use only on the stack. michael@0: static void * U_EXPORT2 operator new(size_t size); michael@0: static void * U_EXPORT2 operator new[](size_t size); michael@0: #if U_HAVE_PLACEMENT_NEW michael@0: static void * U_EXPORT2 operator new(size_t, void *ptr); michael@0: #endif michael@0: }; michael@0: michael@0: /** michael@0: * "Smart pointer" class, deletes objects via the standard C++ delete operator. michael@0: * For most methods see the LocalPointerBase base class. michael@0: * michael@0: * Usage example: michael@0: * \code michael@0: * LocalPointer s(new UnicodeString((UChar32)0x50005)); michael@0: * int32_t length=s->length(); // 2 michael@0: * UChar lead=s->charAt(0); // 0xd900 michael@0: * if(some condition) { return; } // no need to explicitly delete the pointer michael@0: * s.adoptInstead(new UnicodeString((UChar)0xfffc)); michael@0: * length=s->length(); // 1 michael@0: * // no need to explicitly delete the pointer michael@0: * \endcode michael@0: * michael@0: * @see LocalPointerBase michael@0: * @stable ICU 4.4 michael@0: */ michael@0: template michael@0: class LocalPointer : public LocalPointerBase { michael@0: public: michael@0: /** michael@0: * Constructor takes ownership. michael@0: * @param p simple pointer to an object that is adopted michael@0: * @stable ICU 4.4 michael@0: */ michael@0: explicit LocalPointer(T *p=NULL) : LocalPointerBase(p) {} michael@0: /** michael@0: * Destructor deletes the object it owns. michael@0: * @stable ICU 4.4 michael@0: */ michael@0: ~LocalPointer() { michael@0: delete LocalPointerBase::ptr; michael@0: } michael@0: /** michael@0: * Deletes the object it owns, michael@0: * and adopts (takes ownership of) the one passed in. michael@0: * @param p simple pointer to an object that is adopted michael@0: * @stable ICU 4.4 michael@0: */ michael@0: void adoptInstead(T *p) { michael@0: delete LocalPointerBase::ptr; michael@0: LocalPointerBase::ptr=p; michael@0: } michael@0: }; michael@0: michael@0: /** michael@0: * "Smart pointer" class, deletes objects via the C++ array delete[] operator. michael@0: * For most methods see the LocalPointerBase base class. michael@0: * Adds operator[] for array item access. michael@0: * michael@0: * Usage example: michael@0: * \code michael@0: * LocalArray a(new UnicodeString[2]); michael@0: * a[0].append((UChar)0x61); michael@0: * if(some condition) { return; } // no need to explicitly delete the array michael@0: * a.adoptInstead(new UnicodeString[4]); michael@0: * a[3].append((UChar)0x62).append((UChar)0x63).reverse(); michael@0: * // no need to explicitly delete the array michael@0: * \endcode michael@0: * michael@0: * @see LocalPointerBase michael@0: * @stable ICU 4.4 michael@0: */ michael@0: template michael@0: class LocalArray : public LocalPointerBase { michael@0: public: michael@0: /** michael@0: * Constructor takes ownership. michael@0: * @param p simple pointer to an array of T objects that is adopted michael@0: * @stable ICU 4.4 michael@0: */ michael@0: explicit LocalArray(T *p=NULL) : LocalPointerBase(p) {} michael@0: /** michael@0: * Destructor deletes the array it owns. michael@0: * @stable ICU 4.4 michael@0: */ michael@0: ~LocalArray() { michael@0: delete[] LocalPointerBase::ptr; michael@0: } michael@0: /** michael@0: * Deletes the array it owns, michael@0: * and adopts (takes ownership of) the one passed in. michael@0: * @param p simple pointer to an array of T objects that is adopted michael@0: * @stable ICU 4.4 michael@0: */ michael@0: void adoptInstead(T *p) { michael@0: delete[] LocalPointerBase::ptr; michael@0: LocalPointerBase::ptr=p; michael@0: } michael@0: /** michael@0: * Array item access (writable). michael@0: * No index bounds check. michael@0: * @param i array index michael@0: * @return reference to the array item michael@0: * @stable ICU 4.4 michael@0: */ michael@0: T &operator[](ptrdiff_t i) const { return LocalPointerBase::ptr[i]; } michael@0: }; michael@0: michael@0: /** michael@0: * \def U_DEFINE_LOCAL_OPEN_POINTER michael@0: * "Smart pointer" definition macro, deletes objects via the closeFunction. michael@0: * Defines a subclass of LocalPointerBase which works just michael@0: * like LocalPointer except that this subclass will use the closeFunction michael@0: * rather than the C++ delete operator. michael@0: * michael@0: * Requirement: The closeFunction must tolerate a NULL pointer. michael@0: * (We could add a NULL check here but it is normally redundant.) michael@0: * michael@0: * Usage example: michael@0: * \code michael@0: * LocalUCaseMapPointer csm(ucasemap_open(localeID, options, &errorCode)); michael@0: * utf8OutLength=ucasemap_utf8ToLower(csm.getAlias(), michael@0: * utf8Out, (int32_t)sizeof(utf8Out), michael@0: * utf8In, utf8InLength, &errorCode); michael@0: * if(U_FAILURE(errorCode)) { return; } // no need to explicitly delete the UCaseMap michael@0: * \endcode michael@0: * michael@0: * @see LocalPointerBase michael@0: * @see LocalPointer michael@0: * @stable ICU 4.4 michael@0: */ michael@0: #define U_DEFINE_LOCAL_OPEN_POINTER(LocalPointerClassName, Type, closeFunction) \ michael@0: class LocalPointerClassName : public LocalPointerBase { \ michael@0: public: \ michael@0: explicit LocalPointerClassName(Type *p=NULL) : LocalPointerBase(p) {} \ michael@0: ~LocalPointerClassName() { closeFunction(ptr); } \ michael@0: void adoptInstead(Type *p) { \ michael@0: closeFunction(ptr); \ michael@0: ptr=p; \ michael@0: } \ michael@0: } michael@0: michael@0: U_NAMESPACE_END michael@0: michael@0: #endif /* U_SHOW_CPLUSPLUS_API */ michael@0: #endif /* __LOCALPOINTER_H__ */