ICU-57165.0.1.tar.gz
[apple/icu.git] / icuSources / common / unicode / localpointer.h
CommitLineData
729e4ab9
A
1/*
2*******************************************************************************
3*
2ca993e8 4* Copyright (C) 2009-2016, International Business Machines
729e4ab9
A
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/**
2ca993e8 21 * \file
729e4ab9
A
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
43U_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
2ca993e8 55 * whether to use getAlias() (without transfer of ownership) or orphan()
729e4ab9
A
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 */
63template<typename T>
64class LocalPointerBase {
65public:
66 /**
67 * Constructor takes ownership.
68 * @param p simple pointer to an object that is adopted
69 * @stable ICU 4.4
70 */
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 */
77 ~LocalPointerBase() { /* delete ptr; */ }
78 /**
79 * NULL check.
80 * @return TRUE if ==NULL
81 * @stable ICU 4.4
82 */
83 UBool isNull() const { return ptr==NULL; }
84 /**
85 * NULL check.
86 * @return TRUE if !=NULL
87 * @stable ICU 4.4
88 */
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 */
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 */
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 */
142 void adoptInstead(T *p) {
143 // delete ptr;
144 ptr=p;
145 }
146protected:
51004dcb
A
147 /**
148 * Actual pointer.
149 * @internal
150 */
729e4ab9
A
151 T *ptr;
152private:
153 // No comparison operators with other LocalPointerBases.
2ca993e8
A
154 bool operator==(const LocalPointerBase<T> &other);
155 bool operator!=(const LocalPointerBase<T> &other);
156 // No ownership sharing: No copy constructor, no assignment operator.
157 LocalPointerBase(const LocalPointerBase<T> &other);
158 void operator=(const LocalPointerBase<T> &other);
729e4ab9
A
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 */
185template<typename T>
186class LocalPointer : public LocalPointerBase<T> {
187public:
2ca993e8
A
188 using LocalPointerBase<T>::operator*;
189 using LocalPointerBase<T>::operator->;
729e4ab9
A
190 /**
191 * Constructor takes ownership.
192 * @param p simple pointer to an object that is adopted
193 * @stable ICU 4.4
194 */
195 explicit LocalPointer(T *p=NULL) : LocalPointerBase<T>(p) {}
b331163b
A
196 /**
197 * Constructor takes ownership and reports an error if NULL.
198 *
199 * This constructor is intended to be used with other-class constructors
200 * that may report a failure UErrorCode,
201 * so that callers need to check only for U_FAILURE(errorCode)
202 * and not also separately for isNull().
203 *
204 * @param p simple pointer to an object that is adopted
205 * @param errorCode in/out UErrorCode, set to U_MEMORY_ALLOCATION_ERROR
206 * if p==NULL and no other failure code had been set
2ca993e8 207 * @stable ICU 55
b331163b
A
208 */
209 LocalPointer(T *p, UErrorCode &errorCode) : LocalPointerBase<T>(p) {
210 if(p==NULL && U_SUCCESS(errorCode)) {
211 errorCode=U_MEMORY_ALLOCATION_ERROR;
212 }
213 }
2ca993e8
A
214#ifndef U_HIDE_DRAFT_API
215#if U_HAVE_RVALUE_REFERENCES
216 /**
217 * Move constructor, leaves src with isNull().
218 * @param src source smart pointer
219 * @draft ICU 56
220 */
221 LocalPointer(LocalPointer<T> &&src) U_NOEXCEPT : LocalPointerBase<T>(src.ptr) {
222 src.ptr=NULL;
223 }
224#endif
b331163b 225#endif /* U_HIDE_DRAFT_API */
729e4ab9
A
226 /**
227 * Destructor deletes the object it owns.
228 * @stable ICU 4.4
229 */
230 ~LocalPointer() {
231 delete LocalPointerBase<T>::ptr;
232 }
2ca993e8
A
233#ifndef U_HIDE_DRAFT_API
234#if U_HAVE_RVALUE_REFERENCES
235 /**
236 * Move assignment operator, leaves src with isNull().
237 * The behavior is undefined if *this and src are the same object.
238 * @param src source smart pointer
239 * @return *this
240 * @draft ICU 56
241 */
242 LocalPointer<T> &operator=(LocalPointer<T> &&src) U_NOEXCEPT {
243 return moveFrom(src);
244 }
245#endif
246 /**
247 * Move assignment, leaves src with isNull().
248 * The behavior is undefined if *this and src are the same object.
249 *
250 * Can be called explicitly, does not need C++11 support.
251 * @param src source smart pointer
252 * @return *this
253 * @draft ICU 56
254 */
255 LocalPointer<T> &moveFrom(LocalPointer<T> &src) U_NOEXCEPT {
256 delete LocalPointerBase<T>::ptr;
257 LocalPointerBase<T>::ptr=src.ptr;
258 src.ptr=NULL;
259 return *this;
260 }
261 /**
262 * Swap pointers.
263 * @param other other smart pointer
264 * @draft ICU 56
265 */
266 void swap(LocalPointer<T> &other) U_NOEXCEPT {
267 T *temp=LocalPointerBase<T>::ptr;
268 LocalPointerBase<T>::ptr=other.ptr;
269 other.ptr=temp;
270 }
271#endif /* U_HIDE_DRAFT_API */
272 /**
273 * Non-member LocalPointer swap function.
274 * @param p1 will get p2's pointer
275 * @param p2 will get p1's pointer
276 * @draft ICU 56
277 */
278 friend inline void swap(LocalPointer<T> &p1, LocalPointer<T> &p2) U_NOEXCEPT {
279 p1.swap(p2);
280 }
729e4ab9
A
281 /**
282 * Deletes the object it owns,
283 * and adopts (takes ownership of) the one passed in.
284 * @param p simple pointer to an object that is adopted
285 * @stable ICU 4.4
286 */
287 void adoptInstead(T *p) {
288 delete LocalPointerBase<T>::ptr;
289 LocalPointerBase<T>::ptr=p;
290 }
b331163b
A
291 /**
292 * Deletes the object it owns,
293 * and adopts (takes ownership of) the one passed in.
294 *
295 * If U_FAILURE(errorCode), then the current object is retained and the new one deleted.
296 *
297 * If U_SUCCESS(errorCode) but the input pointer is NULL,
298 * then U_MEMORY_ALLOCATION_ERROR is set,
299 * the current object is deleted, and NULL is set.
300 *
301 * @param p simple pointer to an object that is adopted
302 * @param errorCode in/out UErrorCode, set to U_MEMORY_ALLOCATION_ERROR
303 * if p==NULL and no other failure code had been set
2ca993e8 304 * @stable ICU 55
b331163b
A
305 */
306 void adoptInsteadAndCheckErrorCode(T *p, UErrorCode &errorCode) {
307 if(U_SUCCESS(errorCode)) {
308 delete LocalPointerBase<T>::ptr;
309 LocalPointerBase<T>::ptr=p;
310 if(p==NULL) {
311 errorCode=U_MEMORY_ALLOCATION_ERROR;
312 }
313 } else {
314 delete p;
315 }
316 }
729e4ab9
A
317};
318
319/**
320 * "Smart pointer" class, deletes objects via the C++ array delete[] operator.
321 * For most methods see the LocalPointerBase base class.
322 * Adds operator[] for array item access.
323 *
324 * Usage example:
325 * \code
326 * LocalArray<UnicodeString> a(new UnicodeString[2]);
327 * a[0].append((UChar)0x61);
328 * if(some condition) { return; } // no need to explicitly delete the array
329 * a.adoptInstead(new UnicodeString[4]);
330 * a[3].append((UChar)0x62).append((UChar)0x63).reverse();
331 * // no need to explicitly delete the array
332 * \endcode
333 *
334 * @see LocalPointerBase
335 * @stable ICU 4.4
336 */
337template<typename T>
338class LocalArray : public LocalPointerBase<T> {
339public:
2ca993e8
A
340 using LocalPointerBase<T>::operator*;
341 using LocalPointerBase<T>::operator->;
729e4ab9
A
342 /**
343 * Constructor takes ownership.
344 * @param p simple pointer to an array of T objects that is adopted
345 * @stable ICU 4.4
346 */
347 explicit LocalArray(T *p=NULL) : LocalPointerBase<T>(p) {}
2ca993e8
A
348#ifndef U_HIDE_DRAFT_API
349 /**
350 * Constructor takes ownership and reports an error if NULL.
351 *
352 * This constructor is intended to be used with other-class constructors
353 * that may report a failure UErrorCode,
354 * so that callers need to check only for U_FAILURE(errorCode)
355 * and not also separately for isNull().
356 *
357 * @param p simple pointer to an array of T objects that is adopted
358 * @param errorCode in/out UErrorCode, set to U_MEMORY_ALLOCATION_ERROR
359 * if p==NULL and no other failure code had been set
360 * @draft ICU 56
361 */
362 LocalArray(T *p, UErrorCode &errorCode) : LocalPointerBase<T>(p) {
363 if(p==NULL && U_SUCCESS(errorCode)) {
364 errorCode=U_MEMORY_ALLOCATION_ERROR;
365 }
366 }
367#if U_HAVE_RVALUE_REFERENCES
368 /**
369 * Move constructor, leaves src with isNull().
370 * @param src source smart pointer
371 * @draft ICU 56
372 */
373 LocalArray(LocalArray<T> &&src) U_NOEXCEPT : LocalPointerBase<T>(src.ptr) {
374 src.ptr=NULL;
375 }
376#endif
377#endif /* U_HIDE_DRAFT_API */
729e4ab9
A
378 /**
379 * Destructor deletes the array it owns.
380 * @stable ICU 4.4
381 */
382 ~LocalArray() {
383 delete[] LocalPointerBase<T>::ptr;
384 }
2ca993e8
A
385#ifndef U_HIDE_DRAFT_API
386#if U_HAVE_RVALUE_REFERENCES
387 /**
388 * Move assignment operator, leaves src with isNull().
389 * The behavior is undefined if *this and src are the same object.
390 * @param src source smart pointer
391 * @return *this
392 * @draft ICU 56
393 */
394 LocalArray<T> &operator=(LocalArray<T> &&src) U_NOEXCEPT {
395 return moveFrom(src);
396 }
397#endif
398 /**
399 * Move assignment, leaves src with isNull().
400 * The behavior is undefined if *this and src are the same object.
401 *
402 * Can be called explicitly, does not need C++11 support.
403 * @param src source smart pointer
404 * @return *this
405 * @draft ICU 56
406 */
407 LocalArray<T> &moveFrom(LocalArray<T> &src) U_NOEXCEPT {
408 delete[] LocalPointerBase<T>::ptr;
409 LocalPointerBase<T>::ptr=src.ptr;
410 src.ptr=NULL;
411 return *this;
412 }
413 /**
414 * Swap pointers.
415 * @param other other smart pointer
416 * @draft ICU 56
417 */
418 void swap(LocalArray<T> &other) U_NOEXCEPT {
419 T *temp=LocalPointerBase<T>::ptr;
420 LocalPointerBase<T>::ptr=other.ptr;
421 other.ptr=temp;
422 }
423#endif /* U_HIDE_DRAFT_API */
424 /**
425 * Non-member LocalArray swap function.
426 * @param p1 will get p2's pointer
427 * @param p2 will get p1's pointer
428 * @draft ICU 56
429 */
430 friend inline void swap(LocalArray<T> &p1, LocalArray<T> &p2) U_NOEXCEPT {
431 p1.swap(p2);
432 }
729e4ab9
A
433 /**
434 * Deletes the array it owns,
435 * and adopts (takes ownership of) the one passed in.
436 * @param p simple pointer to an array of T objects that is adopted
437 * @stable ICU 4.4
438 */
439 void adoptInstead(T *p) {
440 delete[] LocalPointerBase<T>::ptr;
441 LocalPointerBase<T>::ptr=p;
442 }
2ca993e8
A
443#ifndef U_HIDE_DRAFT_API
444 /**
445 * Deletes the array it owns,
446 * and adopts (takes ownership of) the one passed in.
447 *
448 * If U_FAILURE(errorCode), then the current array is retained and the new one deleted.
449 *
450 * If U_SUCCESS(errorCode) but the input pointer is NULL,
451 * then U_MEMORY_ALLOCATION_ERROR is set,
452 * the current array is deleted, and NULL is set.
453 *
454 * @param p simple pointer to an array of T objects that is adopted
455 * @param errorCode in/out UErrorCode, set to U_MEMORY_ALLOCATION_ERROR
456 * if p==NULL and no other failure code had been set
457 * @draft ICU 56
458 */
459 void adoptInsteadAndCheckErrorCode(T *p, UErrorCode &errorCode) {
460 if(U_SUCCESS(errorCode)) {
461 delete[] LocalPointerBase<T>::ptr;
462 LocalPointerBase<T>::ptr=p;
463 if(p==NULL) {
464 errorCode=U_MEMORY_ALLOCATION_ERROR;
465 }
466 } else {
467 delete[] p;
468 }
469 }
470#endif /* U_HIDE_DRAFT_API */
729e4ab9
A
471 /**
472 * Array item access (writable).
473 * No index bounds check.
474 * @param i array index
475 * @return reference to the array item
476 * @stable ICU 4.4
477 */
478 T &operator[](ptrdiff_t i) const { return LocalPointerBase<T>::ptr[i]; }
479};
480
481/**
482 * \def U_DEFINE_LOCAL_OPEN_POINTER
483 * "Smart pointer" definition macro, deletes objects via the closeFunction.
484 * Defines a subclass of LocalPointerBase which works just
485 * like LocalPointer<Type> except that this subclass will use the closeFunction
486 * rather than the C++ delete operator.
487 *
488 * Requirement: The closeFunction must tolerate a NULL pointer.
489 * (We could add a NULL check here but it is normally redundant.)
490 *
491 * Usage example:
492 * \code
493 * LocalUCaseMapPointer csm(ucasemap_open(localeID, options, &errorCode));
494 * utf8OutLength=ucasemap_utf8ToLower(csm.getAlias(),
495 * utf8Out, (int32_t)sizeof(utf8Out),
496 * utf8In, utf8InLength, &errorCode);
497 * if(U_FAILURE(errorCode)) { return; } // no need to explicitly delete the UCaseMap
498 * \endcode
499 *
500 * @see LocalPointerBase
501 * @see LocalPointer
502 * @stable ICU 4.4
503 */
2ca993e8 504#if U_HAVE_RVALUE_REFERENCES
729e4ab9
A
505#define U_DEFINE_LOCAL_OPEN_POINTER(LocalPointerClassName, Type, closeFunction) \
506 class LocalPointerClassName : public LocalPointerBase<Type> { \
507 public: \
2ca993e8
A
508 using LocalPointerBase<Type>::operator*; \
509 using LocalPointerBase<Type>::operator->; \
729e4ab9 510 explicit LocalPointerClassName(Type *p=NULL) : LocalPointerBase<Type>(p) {} \
2ca993e8
A
511 LocalPointerClassName(LocalPointerClassName &&src) U_NOEXCEPT \
512 : LocalPointerBase<Type>(src.ptr) { \
513 src.ptr=NULL; \
514 } \
729e4ab9 515 ~LocalPointerClassName() { closeFunction(ptr); } \
2ca993e8
A
516 LocalPointerClassName &operator=(LocalPointerClassName &&src) U_NOEXCEPT { \
517 return moveFrom(src); \
518 } \
519 LocalPointerClassName &moveFrom(LocalPointerClassName &src) U_NOEXCEPT { \
520 closeFunction(ptr); \
521 LocalPointerBase<Type>::ptr=src.ptr; \
522 src.ptr=NULL; \
523 return *this; \
524 } \
525 void swap(LocalPointerClassName &other) U_NOEXCEPT { \
526 Type *temp=LocalPointerBase<Type>::ptr; \
527 LocalPointerBase<Type>::ptr=other.ptr; \
528 other.ptr=temp; \
529 } \
530 friend inline void swap(LocalPointerClassName &p1, LocalPointerClassName &p2) U_NOEXCEPT { \
531 p1.swap(p2); \
532 } \
729e4ab9
A
533 void adoptInstead(Type *p) { \
534 closeFunction(ptr); \
535 ptr=p; \
536 } \
537 }
2ca993e8
A
538#else
539#define U_DEFINE_LOCAL_OPEN_POINTER(LocalPointerClassName, Type, closeFunction) \
540 class LocalPointerClassName : public LocalPointerBase<Type> { \
541 public: \
542 using LocalPointerBase<Type>::operator*; \
543 using LocalPointerBase<Type>::operator->; \
544 explicit LocalPointerClassName(Type *p=NULL) : LocalPointerBase<Type>(p) {} \
545 ~LocalPointerClassName() { closeFunction(ptr); } \
546 LocalPointerClassName &moveFrom(LocalPointerClassName &src) U_NOEXCEPT { \
547 closeFunction(ptr); \
548 LocalPointerBase<Type>::ptr=src.ptr; \
549 src.ptr=NULL; \
550 return *this; \
551 } \
552 void swap(LocalPointerClassName &other) U_NOEXCEPT { \
553 Type *temp=LocalPointerBase<Type>::ptr; \
554 LocalPointerBase<Type>::ptr=other.ptr; \
555 other.ptr=temp; \
556 } \
557 friend inline void swap(LocalPointerClassName &p1, LocalPointerClassName &p2) U_NOEXCEPT { \
558 p1.swap(p2); \
559 } \
560 void adoptInstead(Type *p) { \
561 closeFunction(ptr); \
562 ptr=p; \
563 } \
564 }
565#endif
729e4ab9
A
566
567U_NAMESPACE_END
568
569#endif /* U_SHOW_CPLUSPLUS_API */
570#endif /* __LOCALPOINTER_H__ */