1 /* 2 ******************************************************************************* 3 * 4 * Copyright (C) 2009-2010, International Business Machines 5 * Corporation and others. All Rights Reserved. 6 * 7 ******************************************************************************* 8 * file name: localpointer.h 9 * encoding: US-ASCII 10 * tab size: 8 (not used) 11 * indentation:4 12 * 13 * created on: 2009nov13 14 * created by: Markus W. Scherer 15 */ 16 17 #ifndef __LOCALPOINTER_H__ 18 #define __LOCALPOINTER_H__ 19 20 /** 21 * \file 22 * \brief C++ API: "Smart pointers" for use with and in ICU4C C++ code. 23 * 24 * These classes are inspired by 25 * - std::auto_ptr 26 * - boost::scoped_ptr & boost::scoped_array 27 * - Taligent Safe Pointers (TOnlyPointerTo) 28 * 29 * but none of those provide for all of the goals for ICU smart pointers: 30 * - Smart pointer owns the object and releases it when it goes out of scope. 31 * - No transfer of ownership via copy/assignment to reduce misuse. Simpler & more robust. 32 * - ICU-compatible: No exceptions. 33 * - Need to be able to orphan/release the pointer and its ownership. 34 * - Need variants for normal C++ object pointers, C++ arrays, and ICU C service objects. 35 * 36 * For details see http://site.icu-project.org/design/cpp/scoped_ptr 37 */ 38 39 #include "unicode/utypes.h" 40 41 #if U_SHOW_CPLUSPLUS_API 42 43 U_NAMESPACE_BEGIN 44 45 /** 46 * "Smart pointer" base class; do not use directly: use LocalPointer etc. 47 * 48 * Base class for smart pointer classes that do not throw exceptions. 49 * 50 * Do not use this base class directly, since it does not delete its pointer. 51 * A subclass must implement methods that delete the pointer: 52 * Destructor and adoptInstead(). 53 * 54 * There is no operator T *() provided because the programmer must decide 55 * whether to use getAlias() (without transfer of ownership) or orpan() 56 * (with transfer of ownership and NULLing of the pointer). 57 * 58 * @see LocalPointer 59 * @see LocalArray 60 * @see U_DEFINE_LOCAL_OPEN_POINTER 61 * @stable ICU 4.4 62 */ 63 template<typename T> 64 class LocalPointerBase { 65 public: 66 /** 67 * Constructor takes ownership. 68 * @param p simple pointer to an object that is adopted 69 * @stable ICU 4.4 70 */ ptr(p)71 explicit LocalPointerBase(T *p=NULL) : ptr(p) {} 72 /** 73 * Destructor deletes the object it owns. 74 * Subclass must override: Base class does nothing. 75 * @stable ICU 4.4 76 */ ~LocalPointerBase()77 ~LocalPointerBase() { /* delete ptr; */ } 78 /** 79 * NULL check. 80 * @return TRUE if ==NULL 81 * @stable ICU 4.4 82 */ isNull()83 UBool isNull() const { return ptr==NULL; } 84 /** 85 * NULL check. 86 * @return TRUE if !=NULL 87 * @stable ICU 4.4 88 */ isValid()89 UBool isValid() const { return ptr!=NULL; } 90 /** 91 * Comparison with a simple pointer, so that existing code 92 * with ==NULL need not be changed. 93 * @param other simple pointer for comparison 94 * @return true if this pointer value equals other 95 * @stable ICU 4.4 96 */ 97 bool operator==(const T *other) const { return ptr==other; } 98 /** 99 * Comparison with a simple pointer, so that existing code 100 * with !=NULL need not be changed. 101 * @param other simple pointer for comparison 102 * @return true if this pointer value differs from other 103 * @stable ICU 4.4 104 */ 105 bool operator!=(const T *other) const { return ptr!=other; } 106 /** 107 * Access without ownership change. 108 * @return the pointer value 109 * @stable ICU 4.4 110 */ getAlias()111 T *getAlias() const { return ptr; } 112 /** 113 * Access without ownership change. 114 * @return the pointer value as a reference 115 * @stable ICU 4.4 116 */ 117 T &operator*() const { return *ptr; } 118 /** 119 * Access without ownership change. 120 * @return the pointer value 121 * @stable ICU 4.4 122 */ 123 T *operator->() const { return ptr; } 124 /** 125 * Gives up ownership; the internal pointer becomes NULL. 126 * @return the pointer value; 127 * caller becomes responsible for deleting the object 128 * @stable ICU 4.4 129 */ orphan()130 T *orphan() { 131 T *p=ptr; 132 ptr=NULL; 133 return p; 134 } 135 /** 136 * Deletes the object it owns, 137 * and adopts (takes ownership of) the one passed in. 138 * Subclass must override: Base class does not delete the object. 139 * @param p simple pointer to an object that is adopted 140 * @stable ICU 4.4 141 */ adoptInstead(T * p)142 void adoptInstead(T *p) { 143 // delete ptr; 144 ptr=p; 145 } 146 protected: 147 T *ptr; 148 private: 149 // No comparison operators with other LocalPointerBases. 150 bool operator==(const LocalPointerBase &other); 151 bool operator!=(const LocalPointerBase &other); 152 // No ownership transfer: No copy constructor, no assignment operator. 153 LocalPointerBase(const LocalPointerBase &other); 154 void operator=(const LocalPointerBase &other); 155 // No heap allocation. Use only on the stack. 156 static void * U_EXPORT2 operator new(size_t size); 157 static void * U_EXPORT2 operator new[](size_t size); 158 #if U_HAVE_PLACEMENT_NEW 159 static void * U_EXPORT2 operator new(size_t, void *ptr); 160 #endif 161 }; 162 163 /** 164 * "Smart pointer" class, deletes objects via the standard C++ delete operator. 165 * For most methods see the LocalPointerBase base class. 166 * 167 * Usage example: 168 * \code 169 * LocalPointer<UnicodeString> s(new UnicodeString((UChar32)0x50005)); 170 * int32_t length=s->length(); // 2 171 * UChar lead=s->charAt(0); // 0xd900 172 * if(some condition) { return; } // no need to explicitly delete the pointer 173 * s.adoptInstead(new UnicodeString((UChar)0xfffc)); 174 * length=s->length(); // 1 175 * // no need to explicitly delete the pointer 176 * \endcode 177 * 178 * @see LocalPointerBase 179 * @stable ICU 4.4 180 */ 181 template<typename T> 182 class LocalPointer : public LocalPointerBase<T> { 183 public: 184 /** 185 * Constructor takes ownership. 186 * @param p simple pointer to an object that is adopted 187 * @stable ICU 4.4 188 */ 189 explicit LocalPointer(T *p=NULL) : LocalPointerBase<T>(p) {} 190 /** 191 * Destructor deletes the object it owns. 192 * @stable ICU 4.4 193 */ ~LocalPointer()194 ~LocalPointer() { 195 delete LocalPointerBase<T>::ptr; 196 } 197 /** 198 * Deletes the object it owns, 199 * and adopts (takes ownership of) the one passed in. 200 * @param p simple pointer to an object that is adopted 201 * @stable ICU 4.4 202 */ adoptInstead(T * p)203 void adoptInstead(T *p) { 204 delete LocalPointerBase<T>::ptr; 205 LocalPointerBase<T>::ptr=p; 206 } 207 }; 208 209 /** 210 * "Smart pointer" class, deletes objects via the C++ array delete[] operator. 211 * For most methods see the LocalPointerBase base class. 212 * Adds operator[] for array item access. 213 * 214 * Usage example: 215 * \code 216 * LocalArray<UnicodeString> a(new UnicodeString[2]); 217 * a[0].append((UChar)0x61); 218 * if(some condition) { return; } // no need to explicitly delete the array 219 * a.adoptInstead(new UnicodeString[4]); 220 * a[3].append((UChar)0x62).append((UChar)0x63).reverse(); 221 * // no need to explicitly delete the array 222 * \endcode 223 * 224 * @see LocalPointerBase 225 * @stable ICU 4.4 226 */ 227 template<typename T> 228 class LocalArray : public LocalPointerBase<T> { 229 public: 230 /** 231 * Constructor takes ownership. 232 * @param p simple pointer to an array of T objects that is adopted 233 * @stable ICU 4.4 234 */ 235 explicit LocalArray(T *p=NULL) : LocalPointerBase<T>(p) {} 236 /** 237 * Destructor deletes the array it owns. 238 * @stable ICU 4.4 239 */ ~LocalArray()240 ~LocalArray() { 241 delete[] LocalPointerBase<T>::ptr; 242 } 243 /** 244 * Deletes the array it owns, 245 * and adopts (takes ownership of) the one passed in. 246 * @param p simple pointer to an array of T objects that is adopted 247 * @stable ICU 4.4 248 */ adoptInstead(T * p)249 void adoptInstead(T *p) { 250 delete[] LocalPointerBase<T>::ptr; 251 LocalPointerBase<T>::ptr=p; 252 } 253 /** 254 * Array item access (writable). 255 * No index bounds check. 256 * @param i array index 257 * @return reference to the array item 258 * @stable ICU 4.4 259 */ 260 T &operator[](ptrdiff_t i) const { return LocalPointerBase<T>::ptr[i]; } 261 }; 262 263 /** 264 * \def U_DEFINE_LOCAL_OPEN_POINTER 265 * "Smart pointer" definition macro, deletes objects via the closeFunction. 266 * Defines a subclass of LocalPointerBase which works just 267 * like LocalPointer<Type> except that this subclass will use the closeFunction 268 * rather than the C++ delete operator. 269 * 270 * Requirement: The closeFunction must tolerate a NULL pointer. 271 * (We could add a NULL check here but it is normally redundant.) 272 * 273 * Usage example: 274 * \code 275 * LocalUCaseMapPointer csm(ucasemap_open(localeID, options, &errorCode)); 276 * utf8OutLength=ucasemap_utf8ToLower(csm.getAlias(), 277 * utf8Out, (int32_t)sizeof(utf8Out), 278 * utf8In, utf8InLength, &errorCode); 279 * if(U_FAILURE(errorCode)) { return; } // no need to explicitly delete the UCaseMap 280 * \endcode 281 * 282 * @see LocalPointerBase 283 * @see LocalPointer 284 * @stable ICU 4.4 285 */ 286 #define U_DEFINE_LOCAL_OPEN_POINTER(LocalPointerClassName, Type, closeFunction) \ 287 class LocalPointerClassName : public LocalPointerBase<Type> { \ 288 public: \ 289 explicit LocalPointerClassName(Type *p=NULL) : LocalPointerBase<Type>(p) {} \ 290 ~LocalPointerClassName() { closeFunction(ptr); } \ 291 void adoptInstead(Type *p) { \ 292 closeFunction(ptr); \ 293 ptr=p; \ 294 } \ 295 } 296 297 U_NAMESPACE_END 298 299 #endif /* U_SHOW_CPLUSPLUS_API */ 300 #endif /* __LOCALPOINTER_H__ */ 301