• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 *******************************************************************************
3 *
4 *   Copyright (C) 2009-2012, 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     /**
148      * Actual pointer.
149      * @internal
150      */
151     T *ptr;
152 private:
153     // No comparison operators with other LocalPointerBases.
154     bool operator==(const LocalPointerBase &other);
155     bool operator!=(const LocalPointerBase &other);
156     // No ownership transfer: No copy constructor, no assignment operator.
157     LocalPointerBase(const LocalPointerBase &other);
158     void operator=(const LocalPointerBase &other);
159     // No heap allocation. Use only on the stack.
160     static void * U_EXPORT2 operator new(size_t size);
161     static void * U_EXPORT2 operator new[](size_t size);
162 #if U_HAVE_PLACEMENT_NEW
163     static void * U_EXPORT2 operator new(size_t, void *ptr);
164 #endif
165 };
166 
167 /**
168  * "Smart pointer" class, deletes objects via the standard C++ delete operator.
169  * For most methods see the LocalPointerBase base class.
170  *
171  * Usage example:
172  * \code
173  * LocalPointer<UnicodeString> s(new UnicodeString((UChar32)0x50005));
174  * int32_t length=s->length();  // 2
175  * UChar lead=s->charAt(0);  // 0xd900
176  * if(some condition) { return; }  // no need to explicitly delete the pointer
177  * s.adoptInstead(new UnicodeString((UChar)0xfffc));
178  * length=s->length();  // 1
179  * // no need to explicitly delete the pointer
180  * \endcode
181  *
182  * @see LocalPointerBase
183  * @stable ICU 4.4
184  */
185 template<typename T>
186 class LocalPointer : public LocalPointerBase<T> {
187 public:
188     /**
189      * Constructor takes ownership.
190      * @param p simple pointer to an object that is adopted
191      * @stable ICU 4.4
192      */
193     explicit LocalPointer(T *p=NULL) : LocalPointerBase<T>(p) {}
194     /**
195      * Destructor deletes the object it owns.
196      * @stable ICU 4.4
197      */
~LocalPointer()198     ~LocalPointer() {
199         delete LocalPointerBase<T>::ptr;
200     }
201     /**
202      * Deletes the object it owns,
203      * and adopts (takes ownership of) the one passed in.
204      * @param p simple pointer to an object that is adopted
205      * @stable ICU 4.4
206      */
adoptInstead(T * p)207     void adoptInstead(T *p) {
208         delete LocalPointerBase<T>::ptr;
209         LocalPointerBase<T>::ptr=p;
210     }
211 };
212 
213 /**
214  * "Smart pointer" class, deletes objects via the C++ array delete[] operator.
215  * For most methods see the LocalPointerBase base class.
216  * Adds operator[] for array item access.
217  *
218  * Usage example:
219  * \code
220  * LocalArray<UnicodeString> a(new UnicodeString[2]);
221  * a[0].append((UChar)0x61);
222  * if(some condition) { return; }  // no need to explicitly delete the array
223  * a.adoptInstead(new UnicodeString[4]);
224  * a[3].append((UChar)0x62).append((UChar)0x63).reverse();
225  * // no need to explicitly delete the array
226  * \endcode
227  *
228  * @see LocalPointerBase
229  * @stable ICU 4.4
230  */
231 template<typename T>
232 class LocalArray : public LocalPointerBase<T> {
233 public:
234     /**
235      * Constructor takes ownership.
236      * @param p simple pointer to an array of T objects that is adopted
237      * @stable ICU 4.4
238      */
239     explicit LocalArray(T *p=NULL) : LocalPointerBase<T>(p) {}
240     /**
241      * Destructor deletes the array it owns.
242      * @stable ICU 4.4
243      */
~LocalArray()244     ~LocalArray() {
245         delete[] LocalPointerBase<T>::ptr;
246     }
247     /**
248      * Deletes the array it owns,
249      * and adopts (takes ownership of) the one passed in.
250      * @param p simple pointer to an array of T objects that is adopted
251      * @stable ICU 4.4
252      */
adoptInstead(T * p)253     void adoptInstead(T *p) {
254         delete[] LocalPointerBase<T>::ptr;
255         LocalPointerBase<T>::ptr=p;
256     }
257     /**
258      * Array item access (writable).
259      * No index bounds check.
260      * @param i array index
261      * @return reference to the array item
262      * @stable ICU 4.4
263      */
264     T &operator[](ptrdiff_t i) const { return LocalPointerBase<T>::ptr[i]; }
265 };
266 
267 /**
268  * \def U_DEFINE_LOCAL_OPEN_POINTER
269  * "Smart pointer" definition macro, deletes objects via the closeFunction.
270  * Defines a subclass of LocalPointerBase which works just
271  * like LocalPointer<Type> except that this subclass will use the closeFunction
272  * rather than the C++ delete operator.
273  *
274  * Requirement: The closeFunction must tolerate a NULL pointer.
275  * (We could add a NULL check here but it is normally redundant.)
276  *
277  * Usage example:
278  * \code
279  * LocalUCaseMapPointer csm(ucasemap_open(localeID, options, &errorCode));
280  * utf8OutLength=ucasemap_utf8ToLower(csm.getAlias(),
281  *     utf8Out, (int32_t)sizeof(utf8Out),
282  *     utf8In, utf8InLength, &errorCode);
283  * if(U_FAILURE(errorCode)) { return; }  // no need to explicitly delete the UCaseMap
284  * \endcode
285  *
286  * @see LocalPointerBase
287  * @see LocalPointer
288  * @stable ICU 4.4
289  */
290 #define U_DEFINE_LOCAL_OPEN_POINTER(LocalPointerClassName, Type, closeFunction) \
291     class LocalPointerClassName : public LocalPointerBase<Type> { \
292     public: \
293         explicit LocalPointerClassName(Type *p=NULL) : LocalPointerBase<Type>(p) {} \
294         ~LocalPointerClassName() { closeFunction(ptr); } \
295         void adoptInstead(Type *p) { \
296             closeFunction(ptr); \
297             ptr=p; \
298         } \
299     }
300 
301 U_NAMESPACE_END
302 
303 #endif  /* U_SHOW_CPLUSPLUS_API */
304 #endif  /* __LOCALPOINTER_H__ */
305