1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /*
4 *******************************************************************************
5 *
6 *   Copyright (C) 2009-2016, International Business Machines
7 *   Corporation and others.  All Rights Reserved.
8 *
9 *******************************************************************************
10 *   file name:  localpointer.h
11 *   encoding:   UTF-8
12 *   tab size:   8 (not used)
13 *   indentation:4
14 *
15 *   created on: 2009nov13
16 *   created by: Markus W. Scherer
17 */
18 
19 #ifndef __LOCALPOINTER_H__
20 #define __LOCALPOINTER_H__
21 
22 /**
23  * \file
24  * \brief C++ API: "Smart pointers" for use with and in ICU4C C++ code.
25  *
26  * These classes are inspired by
27  * - std::auto_ptr
28  * - boost::scoped_ptr & boost::scoped_array
29  * - Taligent Safe Pointers (TOnlyPointerTo)
30  *
31  * but none of those provide for all of the goals for ICU smart pointers:
32  * - Smart pointer owns the object and releases it when it goes out of scope.
33  * - No transfer of ownership via copy/assignment to reduce misuse. Simpler & more robust.
34  * - ICU-compatible: No exceptions.
35  * - Need to be able to orphan/release the pointer and its ownership.
36  * - Need variants for normal C++ object pointers, C++ arrays, and ICU C service objects.
37  *
38  * For details see http://site.icu-project.org/design/cpp/scoped_ptr
39  */
40 
41 #include "unicode/utypes.h"
42 
43 #if U_SHOW_CPLUSPLUS_API
44 
45 #include <memory>
46 
47 U_NAMESPACE_BEGIN
48 
49 /**
50  * "Smart pointer" base class; do not use directly: use LocalPointer etc.
51  *
52  * Base class for smart pointer classes that do not throw exceptions.
53  *
54  * Do not use this base class directly, since it does not delete its pointer.
55  * A subclass must implement methods that delete the pointer:
56  * Destructor and adoptInstead().
57  *
58  * There is no operator T *() provided because the programmer must decide
59  * whether to use getAlias() (without transfer of ownership) or orphan()
60  * (with transfer of ownership and NULLing of the pointer).
61  *
62  * @see LocalPointer
63  * @see LocalArray
64  * @see U_DEFINE_LOCAL_OPEN_POINTER
65  * @stable ICU 4.4
66  */
67 template<typename T>
68 class LocalPointerBase {
69 public:
70     // No heap allocation. Use only on the stack.
71     static void* U_EXPORT2 operator new(size_t) = delete;
72     static void* U_EXPORT2 operator new[](size_t) = delete;
73 #if U_HAVE_PLACEMENT_NEW
74     static void* U_EXPORT2 operator new(size_t, void*) = delete;
75 #endif
76 
77     /**
78      * Constructor takes ownership.
79      * @param p simple pointer to an object that is adopted
80      * @stable ICU 4.4
81      */
ptr(p)82     explicit LocalPointerBase(T *p=NULL) : ptr(p) {}
83     /**
84      * Destructor deletes the object it owns.
85      * Subclass must override: Base class does nothing.
86      * @stable ICU 4.4
87      */
~LocalPointerBase()88     ~LocalPointerBase() { /* delete ptr; */ }
89     /**
90      * NULL check.
91      * @return TRUE if ==NULL
92      * @stable ICU 4.4
93      */
isNull()94     UBool isNull() const { return ptr==NULL; }
95     /**
96      * NULL check.
97      * @return TRUE if !=NULL
98      * @stable ICU 4.4
99      */
isValid()100     UBool isValid() const { return ptr!=NULL; }
101     /**
102      * Comparison with a simple pointer, so that existing code
103      * with ==NULL need not be changed.
104      * @param other simple pointer for comparison
105      * @return true if this pointer value equals other
106      * @stable ICU 4.4
107      */
108     bool operator==(const T *other) const { return ptr==other; }
109     /**
110      * Comparison with a simple pointer, so that existing code
111      * with !=NULL need not be changed.
112      * @param other simple pointer for comparison
113      * @return true if this pointer value differs from other
114      * @stable ICU 4.4
115      */
116     bool operator!=(const T *other) const { return ptr!=other; }
117     /**
118      * Access without ownership change.
119      * @return the pointer value
120      * @stable ICU 4.4
121      */
getAlias()122     T *getAlias() const { return ptr; }
123     /**
124      * Access without ownership change.
125      * @return the pointer value as a reference
126      * @stable ICU 4.4
127      */
128     T &operator*() const { return *ptr; }
129     /**
130      * Access without ownership change.
131      * @return the pointer value
132      * @stable ICU 4.4
133      */
134     T *operator->() const { return ptr; }
135     /**
136      * Gives up ownership; the internal pointer becomes NULL.
137      * @return the pointer value;
138      *         caller becomes responsible for deleting the object
139      * @stable ICU 4.4
140      */
orphan()141     T *orphan() {
142         T *p=ptr;
143         ptr=NULL;
144         return p;
145     }
146     /**
147      * Deletes the object it owns,
148      * and adopts (takes ownership of) the one passed in.
149      * Subclass must override: Base class does not delete the object.
150      * @param p simple pointer to an object that is adopted
151      * @stable ICU 4.4
152      */
adoptInstead(T * p)153     void adoptInstead(T *p) {
154         // delete ptr;
155         ptr=p;
156     }
157 protected:
158     /**
159      * Actual pointer.
160      * @internal
161      */
162     T *ptr;
163 private:
164     // No comparison operators with other LocalPointerBases.
165     bool operator==(const LocalPointerBase<T> &other);
166     bool operator!=(const LocalPointerBase<T> &other);
167     // No ownership sharing: No copy constructor, no assignment operator.
168     LocalPointerBase(const LocalPointerBase<T> &other);
169     void operator=(const LocalPointerBase<T> &other);
170 };
171 
172 /**
173  * "Smart pointer" class, deletes objects via the standard C++ delete operator.
174  * For most methods see the LocalPointerBase base class.
175  *
176  * Usage example:
177  * \code
178  * LocalPointer<UnicodeString> s(new UnicodeString((UChar32)0x50005));
179  * int32_t length=s->length();  // 2
180  * char16_t lead=s->charAt(0);  // 0xd900
181  * if(some condition) { return; }  // no need to explicitly delete the pointer
182  * s.adoptInstead(new UnicodeString((char16_t)0xfffc));
183  * length=s->length();  // 1
184  * // no need to explicitly delete the pointer
185  * \endcode
186  *
187  * @see LocalPointerBase
188  * @stable ICU 4.4
189  */
190 template<typename T>
191 class LocalPointer : public LocalPointerBase<T> {
192 public:
193     using LocalPointerBase<T>::operator*;
194     using LocalPointerBase<T>::operator->;
195     /**
196      * Constructor takes ownership.
197      * @param p simple pointer to an object that is adopted
198      * @stable ICU 4.4
199      */
200     explicit LocalPointer(T *p=NULL) : LocalPointerBase<T>(p) {}
201     /**
202      * Constructor takes ownership and reports an error if NULL.
203      *
204      * This constructor is intended to be used with other-class constructors
205      * that may report a failure UErrorCode,
206      * so that callers need to check only for U_FAILURE(errorCode)
207      * and not also separately for isNull().
208      *
209      * @param p simple pointer to an object that is adopted
210      * @param errorCode in/out UErrorCode, set to U_MEMORY_ALLOCATION_ERROR
211      *     if p==NULL and no other failure code had been set
212      * @stable ICU 55
213      */
LocalPointer(T * p,UErrorCode & errorCode)214     LocalPointer(T *p, UErrorCode &errorCode) : LocalPointerBase<T>(p) {
215         if(p==NULL && U_SUCCESS(errorCode)) {
216             errorCode=U_MEMORY_ALLOCATION_ERROR;
217         }
218     }
219     /**
220      * Move constructor, leaves src with isNull().
221      * @param src source smart pointer
222      * @stable ICU 56
223      */
LocalPointer(LocalPointer<T> && src)224     LocalPointer(LocalPointer<T> &&src) U_NOEXCEPT : LocalPointerBase<T>(src.ptr) {
225         src.ptr=NULL;
226     }
227 
228 #ifndef U_HIDE_DRAFT_API
229     /**
230      * Constructs a LocalPointer from a C++11 std::unique_ptr.
231      * The LocalPointer steals the object owned by the std::unique_ptr.
232      *
233      * This constructor works via move semantics. If your std::unique_ptr is
234      * in a local variable, you must use std::move.
235      *
236      * @param p The std::unique_ptr from which the pointer will be stolen.
237      * @draft ICU 64
238      */
LocalPointer(std::unique_ptr<T> && p)239     explicit LocalPointer(std::unique_ptr<T> &&p)
240         : LocalPointerBase<T>(p.release()) {}
241 #endif  /* U_HIDE_DRAFT_API */
242 
243     /**
244      * Destructor deletes the object it owns.
245      * @stable ICU 4.4
246      */
~LocalPointer()247     ~LocalPointer() {
248         delete LocalPointerBase<T>::ptr;
249     }
250     /**
251      * Move assignment operator, leaves src with isNull().
252      * The behavior is undefined if *this and src are the same object.
253      * @param src source smart pointer
254      * @return *this
255      * @stable ICU 56
256      */
257     LocalPointer<T> &operator=(LocalPointer<T> &&src) U_NOEXCEPT {
258         delete LocalPointerBase<T>::ptr;
259         LocalPointerBase<T>::ptr=src.ptr;
260         src.ptr=NULL;
261         return *this;
262     }
263 
264 #ifndef U_HIDE_DRAFT_API
265     /**
266      * Move-assign from an std::unique_ptr to this LocalPointer.
267      * Steals the pointer from the std::unique_ptr.
268      *
269      * @param p The std::unique_ptr from which the pointer will be stolen.
270      * @return *this
271      * @draft ICU 64
272      */
273     LocalPointer<T> &operator=(std::unique_ptr<T> &&p) U_NOEXCEPT {
274         adoptInstead(p.release());
275         return *this;
276     }
277 #endif  /* U_HIDE_DRAFT_API */
278 
279     /**
280      * Swap pointers.
281      * @param other other smart pointer
282      * @stable ICU 56
283      */
swap(LocalPointer<T> & other)284     void swap(LocalPointer<T> &other) U_NOEXCEPT {
285         T *temp=LocalPointerBase<T>::ptr;
286         LocalPointerBase<T>::ptr=other.ptr;
287         other.ptr=temp;
288     }
289     /**
290      * Non-member LocalPointer swap function.
291      * @param p1 will get p2's pointer
292      * @param p2 will get p1's pointer
293      * @stable ICU 56
294      */
swap(LocalPointer<T> & p1,LocalPointer<T> & p2)295     friend inline void swap(LocalPointer<T> &p1, LocalPointer<T> &p2) U_NOEXCEPT {
296         p1.swap(p2);
297     }
298     /**
299      * Deletes the object it owns,
300      * and adopts (takes ownership of) the one passed in.
301      * @param p simple pointer to an object that is adopted
302      * @stable ICU 4.4
303      */
adoptInstead(T * p)304     void adoptInstead(T *p) {
305         delete LocalPointerBase<T>::ptr;
306         LocalPointerBase<T>::ptr=p;
307     }
308     /**
309      * Deletes the object it owns,
310      * and adopts (takes ownership of) the one passed in.
311      *
312      * If U_FAILURE(errorCode), then the current object is retained and the new one deleted.
313      *
314      * If U_SUCCESS(errorCode) but the input pointer is NULL,
315      * then U_MEMORY_ALLOCATION_ERROR is set,
316      * the current object is deleted, and NULL is set.
317      *
318      * @param p simple pointer to an object that is adopted
319      * @param errorCode in/out UErrorCode, set to U_MEMORY_ALLOCATION_ERROR
320      *     if p==NULL and no other failure code had been set
321      * @stable ICU 55
322      */
adoptInsteadAndCheckErrorCode(T * p,UErrorCode & errorCode)323     void adoptInsteadAndCheckErrorCode(T *p, UErrorCode &errorCode) {
324         if(U_SUCCESS(errorCode)) {
325             delete LocalPointerBase<T>::ptr;
326             LocalPointerBase<T>::ptr=p;
327             if(p==NULL) {
328                 errorCode=U_MEMORY_ALLOCATION_ERROR;
329             }
330         } else {
331             delete p;
332         }
333     }
334 
335 #ifndef U_HIDE_DRAFT_API
336     /**
337      * Conversion operator to a C++11 std::unique_ptr.
338      * Disowns the object and gives it to the returned std::unique_ptr.
339      *
340      * This operator works via move semantics. If your LocalPointer is
341      * in a local variable, you must use std::move.
342      *
343      * @return An std::unique_ptr owning the pointer previously owned by this
344      *         icu::LocalPointer.
345      * @draft ICU 64
346      */
347     operator std::unique_ptr<T> () && {
348         return std::unique_ptr<T>(LocalPointerBase<T>::orphan());
349     }
350 #endif  /* U_HIDE_DRAFT_API */
351 };
352 
353 /**
354  * "Smart pointer" class, deletes objects via the C++ array delete[] operator.
355  * For most methods see the LocalPointerBase base class.
356  * Adds operator[] for array item access.
357  *
358  * Usage example:
359  * \code
360  * LocalArray<UnicodeString> a(new UnicodeString[2]);
361  * a[0].append((char16_t)0x61);
362  * if(some condition) { return; }  // no need to explicitly delete the array
363  * a.adoptInstead(new UnicodeString[4]);
364  * a[3].append((char16_t)0x62).append((char16_t)0x63).reverse();
365  * // no need to explicitly delete the array
366  * \endcode
367  *
368  * @see LocalPointerBase
369  * @stable ICU 4.4
370  */
371 template<typename T>
372 class LocalArray : public LocalPointerBase<T> {
373 public:
374     using LocalPointerBase<T>::operator*;
375     using LocalPointerBase<T>::operator->;
376     /**
377      * Constructor takes ownership.
378      * @param p simple pointer to an array of T objects that is adopted
379      * @stable ICU 4.4
380      */
381     explicit LocalArray(T *p=NULL) : LocalPointerBase<T>(p) {}
382     /**
383      * Constructor takes ownership and reports an error if NULL.
384      *
385      * This constructor is intended to be used with other-class constructors
386      * that may report a failure UErrorCode,
387      * so that callers need to check only for U_FAILURE(errorCode)
388      * and not also separately for isNull().
389      *
390      * @param p simple pointer to an array of T objects that is adopted
391      * @param errorCode in/out UErrorCode, set to U_MEMORY_ALLOCATION_ERROR
392      *     if p==NULL and no other failure code had been set
393      * @stable ICU 56
394      */
LocalArray(T * p,UErrorCode & errorCode)395     LocalArray(T *p, UErrorCode &errorCode) : LocalPointerBase<T>(p) {
396         if(p==NULL && U_SUCCESS(errorCode)) {
397             errorCode=U_MEMORY_ALLOCATION_ERROR;
398         }
399     }
400     /**
401      * Move constructor, leaves src with isNull().
402      * @param src source smart pointer
403      * @stable ICU 56
404      */
LocalArray(LocalArray<T> && src)405     LocalArray(LocalArray<T> &&src) U_NOEXCEPT : LocalPointerBase<T>(src.ptr) {
406         src.ptr=NULL;
407     }
408 
409 #ifndef U_HIDE_DRAFT_API
410     /**
411      * Constructs a LocalArray from a C++11 std::unique_ptr of an array type.
412      * The LocalPointer steals the array owned by the std::unique_ptr.
413      *
414      * This constructor works via move semantics. If your std::unique_ptr is
415      * in a local variable, you must use std::move.
416      *
417      * @param p The std::unique_ptr from which the array will be stolen.
418      * @draft ICU 64
419      */
LocalArray(std::unique_ptr<T[]> && p)420     explicit LocalArray(std::unique_ptr<T[]> &&p)
421         : LocalPointerBase<T>(p.release()) {}
422 #endif  /* U_HIDE_DRAFT_API */
423 
424     /**
425      * Destructor deletes the array it owns.
426      * @stable ICU 4.4
427      */
~LocalArray()428     ~LocalArray() {
429         delete[] LocalPointerBase<T>::ptr;
430     }
431     /**
432      * Move assignment operator, leaves src with isNull().
433      * The behavior is undefined if *this and src are the same object.
434      * @param src source smart pointer
435      * @return *this
436      * @stable ICU 56
437      */
438     LocalArray<T> &operator=(LocalArray<T> &&src) U_NOEXCEPT {
439         delete[] LocalPointerBase<T>::ptr;
440         LocalPointerBase<T>::ptr=src.ptr;
441         src.ptr=NULL;
442         return *this;
443     }
444 
445 #ifndef U_HIDE_DRAFT_API
446     /**
447      * Move-assign from an std::unique_ptr to this LocalPointer.
448      * Steals the array from the std::unique_ptr.
449      *
450      * @param p The std::unique_ptr from which the array will be stolen.
451      * @return *this
452      * @draft ICU 64
453      */
454     LocalArray<T> &operator=(std::unique_ptr<T[]> &&p) U_NOEXCEPT {
455         adoptInstead(p.release());
456         return *this;
457     }
458 #endif  /* U_HIDE_DRAFT_API */
459 
460     /**
461      * Swap pointers.
462      * @param other other smart pointer
463      * @stable ICU 56
464      */
swap(LocalArray<T> & other)465     void swap(LocalArray<T> &other) U_NOEXCEPT {
466         T *temp=LocalPointerBase<T>::ptr;
467         LocalPointerBase<T>::ptr=other.ptr;
468         other.ptr=temp;
469     }
470     /**
471      * Non-member LocalArray swap function.
472      * @param p1 will get p2's pointer
473      * @param p2 will get p1's pointer
474      * @stable ICU 56
475      */
swap(LocalArray<T> & p1,LocalArray<T> & p2)476     friend inline void swap(LocalArray<T> &p1, LocalArray<T> &p2) U_NOEXCEPT {
477         p1.swap(p2);
478     }
479     /**
480      * Deletes the array it owns,
481      * and adopts (takes ownership of) the one passed in.
482      * @param p simple pointer to an array of T objects that is adopted
483      * @stable ICU 4.4
484      */
adoptInstead(T * p)485     void adoptInstead(T *p) {
486         delete[] LocalPointerBase<T>::ptr;
487         LocalPointerBase<T>::ptr=p;
488     }
489     /**
490      * Deletes the array it owns,
491      * and adopts (takes ownership of) the one passed in.
492      *
493      * If U_FAILURE(errorCode), then the current array is retained and the new one deleted.
494      *
495      * If U_SUCCESS(errorCode) but the input pointer is NULL,
496      * then U_MEMORY_ALLOCATION_ERROR is set,
497      * the current array is deleted, and NULL is set.
498      *
499      * @param p simple pointer to an array of T objects that is adopted
500      * @param errorCode in/out UErrorCode, set to U_MEMORY_ALLOCATION_ERROR
501      *     if p==NULL and no other failure code had been set
502      * @stable ICU 56
503      */
adoptInsteadAndCheckErrorCode(T * p,UErrorCode & errorCode)504     void adoptInsteadAndCheckErrorCode(T *p, UErrorCode &errorCode) {
505         if(U_SUCCESS(errorCode)) {
506             delete[] LocalPointerBase<T>::ptr;
507             LocalPointerBase<T>::ptr=p;
508             if(p==NULL) {
509                 errorCode=U_MEMORY_ALLOCATION_ERROR;
510             }
511         } else {
512             delete[] p;
513         }
514     }
515     /**
516      * Array item access (writable).
517      * No index bounds check.
518      * @param i array index
519      * @return reference to the array item
520      * @stable ICU 4.4
521      */
522     T &operator[](ptrdiff_t i) const { return LocalPointerBase<T>::ptr[i]; }
523 
524 #ifndef U_HIDE_DRAFT_API
525     /**
526      * Conversion operator to a C++11 std::unique_ptr.
527      * Disowns the object and gives it to the returned std::unique_ptr.
528      *
529      * This operator works via move semantics. If your LocalPointer is
530      * in a local variable, you must use std::move.
531      *
532      * @return An std::unique_ptr owning the pointer previously owned by this
533      *         icu::LocalPointer.
534      * @draft ICU 64
535      */
536     operator std::unique_ptr<T[]> () && {
537         return std::unique_ptr<T[]>(LocalPointerBase<T>::orphan());
538     }
539 #endif  /* U_HIDE_DRAFT_API */
540 };
541 
542 /**
543  * \def U_DEFINE_LOCAL_OPEN_POINTER
544  * "Smart pointer" definition macro, deletes objects via the closeFunction.
545  * Defines a subclass of LocalPointerBase which works just
546  * like LocalPointer<Type> except that this subclass will use the closeFunction
547  * rather than the C++ delete operator.
548  *
549  * Usage example:
550  * \code
551  * LocalUCaseMapPointer csm(ucasemap_open(localeID, options, &errorCode));
552  * utf8OutLength=ucasemap_utf8ToLower(csm.getAlias(),
553  *     utf8Out, (int32_t)sizeof(utf8Out),
554  *     utf8In, utf8InLength, &errorCode);
555  * if(U_FAILURE(errorCode)) { return; }  // no need to explicitly delete the UCaseMap
556  * \endcode
557  *
558  * @see LocalPointerBase
559  * @see LocalPointer
560  * @stable ICU 4.4
561  */
562 #define U_DEFINE_LOCAL_OPEN_POINTER(LocalPointerClassName, Type, closeFunction) \
563     class LocalPointerClassName : public LocalPointerBase<Type> { \
564     public: \
565         using LocalPointerBase<Type>::operator*; \
566         using LocalPointerBase<Type>::operator->; \
567         explicit LocalPointerClassName(Type *p=NULL) : LocalPointerBase<Type>(p) {} \
568         LocalPointerClassName(LocalPointerClassName &&src) U_NOEXCEPT \
569                 : LocalPointerBase<Type>(src.ptr) { \
570             src.ptr=NULL; \
571         } \
572         /* TODO: Be agnostic of the deleter function signature from the user-provided std::unique_ptr? */ \
573         explicit LocalPointerClassName(std::unique_ptr<Type, decltype(&closeFunction)> &&p) \
574                 : LocalPointerBase<Type>(p.release()) {} \
575         ~LocalPointerClassName() { if (ptr != NULL) { closeFunction(ptr); } } \
576         LocalPointerClassName &operator=(LocalPointerClassName &&src) U_NOEXCEPT { \
577             if (ptr != NULL) { closeFunction(ptr); } \
578             LocalPointerBase<Type>::ptr=src.ptr; \
579             src.ptr=NULL; \
580             return *this; \
581         } \
582         /* TODO: Be agnostic of the deleter function signature from the user-provided std::unique_ptr? */ \
583         LocalPointerClassName &operator=(std::unique_ptr<Type, decltype(&closeFunction)> &&p) { \
584             adoptInstead(p.release()); \
585             return *this; \
586         } \
587         void swap(LocalPointerClassName &other) U_NOEXCEPT { \
588             Type *temp=LocalPointerBase<Type>::ptr; \
589             LocalPointerBase<Type>::ptr=other.ptr; \
590             other.ptr=temp; \
591         } \
592         friend inline void swap(LocalPointerClassName &p1, LocalPointerClassName &p2) U_NOEXCEPT { \
593             p1.swap(p2); \
594         } \
595         void adoptInstead(Type *p) { \
596             if (ptr != NULL) { closeFunction(ptr); } \
597             ptr=p; \
598         } \
599         operator std::unique_ptr<Type, decltype(&closeFunction)> () && { \
600             return std::unique_ptr<Type, decltype(&closeFunction)>(LocalPointerBase<Type>::orphan(), closeFunction); \
601         } \
602     }
603 
604 U_NAMESPACE_END
605 
606 #endif  /* U_SHOW_CPLUSPLUS_API */
607 #endif  /* __LOCALPOINTER_H__ */
608