• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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