Home | History | Annotate | Download | only in unicode
      1 /*
      2 *******************************************************************************
      3 *
      4 *   Copyright (C) 2009-2014, 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      */
     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     }
    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 #ifndef U_HIDE_DRAFT_API
    195     /**
    196      * Constructor takes ownership and reports an error if NULL.
    197      *
    198      * This constructor is intended to be used with other-class constructors
    199      * that may report a failure UErrorCode,
    200      * so that callers need to check only for U_FAILURE(errorCode)
    201      * and not also separately for isNull().
    202      *
    203      * @param p simple pointer to an object that is adopted
    204      * @param errorCode in/out UErrorCode, set to U_MEMORY_ALLOCATION_ERROR
    205      *     if p==NULL and no other failure code had been set
    206      * @draft ICU 55
    207      */
    208     LocalPointer(T *p, UErrorCode &errorCode) : LocalPointerBase<T>(p) {
    209         if(p==NULL && U_SUCCESS(errorCode)) {
    210             errorCode=U_MEMORY_ALLOCATION_ERROR;
    211         }
    212     }
    213 #endif  /* U_HIDE_DRAFT_API */
    214     /**
    215      * Destructor deletes the object it owns.
    216      * @stable ICU 4.4
    217      */
    218     ~LocalPointer() {
    219         delete LocalPointerBase<T>::ptr;
    220     }
    221     /**
    222      * Deletes the object it owns,
    223      * and adopts (takes ownership of) the one passed in.
    224      * @param p simple pointer to an object that is adopted
    225      * @stable ICU 4.4
    226      */
    227     void adoptInstead(T *p) {
    228         delete LocalPointerBase<T>::ptr;
    229         LocalPointerBase<T>::ptr=p;
    230     }
    231 #ifndef U_HIDE_DRAFT_API
    232     /**
    233      * Deletes the object it owns,
    234      * and adopts (takes ownership of) the one passed in.
    235      *
    236      * If U_FAILURE(errorCode), then the current object is retained and the new one deleted.
    237      *
    238      * If U_SUCCESS(errorCode) but the input pointer is NULL,
    239      * then U_MEMORY_ALLOCATION_ERROR is set,
    240      * the current object is deleted, and NULL is set.
    241      *
    242      * @param p simple pointer to an object that is adopted
    243      * @param errorCode in/out UErrorCode, set to U_MEMORY_ALLOCATION_ERROR
    244      *     if p==NULL and no other failure code had been set
    245      * @draft ICU 55
    246      */
    247     void adoptInsteadAndCheckErrorCode(T *p, UErrorCode &errorCode) {
    248         if(U_SUCCESS(errorCode)) {
    249             delete LocalPointerBase<T>::ptr;
    250             LocalPointerBase<T>::ptr=p;
    251             if(p==NULL) {
    252                 errorCode=U_MEMORY_ALLOCATION_ERROR;
    253             }
    254         } else {
    255             delete p;
    256         }
    257     }
    258 #endif  /* U_HIDE_DRAFT_API */
    259 };
    260 
    261 /**
    262  * "Smart pointer" class, deletes objects via the C++ array delete[] operator.
    263  * For most methods see the LocalPointerBase base class.
    264  * Adds operator[] for array item access.
    265  *
    266  * Usage example:
    267  * \code
    268  * LocalArray<UnicodeString> a(new UnicodeString[2]);
    269  * a[0].append((UChar)0x61);
    270  * if(some condition) { return; }  // no need to explicitly delete the array
    271  * a.adoptInstead(new UnicodeString[4]);
    272  * a[3].append((UChar)0x62).append((UChar)0x63).reverse();
    273  * // no need to explicitly delete the array
    274  * \endcode
    275  *
    276  * @see LocalPointerBase
    277  * @stable ICU 4.4
    278  */
    279 template<typename T>
    280 class LocalArray : public LocalPointerBase<T> {
    281 public:
    282     /**
    283      * Constructor takes ownership.
    284      * @param p simple pointer to an array of T objects that is adopted
    285      * @stable ICU 4.4
    286      */
    287     explicit LocalArray(T *p=NULL) : LocalPointerBase<T>(p) {}
    288     /**
    289      * Destructor deletes the array it owns.
    290      * @stable ICU 4.4
    291      */
    292     ~LocalArray() {
    293         delete[] LocalPointerBase<T>::ptr;
    294     }
    295     /**
    296      * Deletes the array it owns,
    297      * and adopts (takes ownership of) the one passed in.
    298      * @param p simple pointer to an array of T objects that is adopted
    299      * @stable ICU 4.4
    300      */
    301     void adoptInstead(T *p) {
    302         delete[] LocalPointerBase<T>::ptr;
    303         LocalPointerBase<T>::ptr=p;
    304     }
    305     /**
    306      * Array item access (writable).
    307      * No index bounds check.
    308      * @param i array index
    309      * @return reference to the array item
    310      * @stable ICU 4.4
    311      */
    312     T &operator[](ptrdiff_t i) const { return LocalPointerBase<T>::ptr[i]; }
    313 };
    314 
    315 /**
    316  * \def U_DEFINE_LOCAL_OPEN_POINTER
    317  * "Smart pointer" definition macro, deletes objects via the closeFunction.
    318  * Defines a subclass of LocalPointerBase which works just
    319  * like LocalPointer<Type> except that this subclass will use the closeFunction
    320  * rather than the C++ delete operator.
    321  *
    322  * Requirement: The closeFunction must tolerate a NULL pointer.
    323  * (We could add a NULL check here but it is normally redundant.)
    324  *
    325  * Usage example:
    326  * \code
    327  * LocalUCaseMapPointer csm(ucasemap_open(localeID, options, &errorCode));
    328  * utf8OutLength=ucasemap_utf8ToLower(csm.getAlias(),
    329  *     utf8Out, (int32_t)sizeof(utf8Out),
    330  *     utf8In, utf8InLength, &errorCode);
    331  * if(U_FAILURE(errorCode)) { return; }  // no need to explicitly delete the UCaseMap
    332  * \endcode
    333  *
    334  * @see LocalPointerBase
    335  * @see LocalPointer
    336  * @stable ICU 4.4
    337  */
    338 #define U_DEFINE_LOCAL_OPEN_POINTER(LocalPointerClassName, Type, closeFunction) \
    339     class LocalPointerClassName : public LocalPointerBase<Type> { \
    340     public: \
    341         explicit LocalPointerClassName(Type *p=NULL) : LocalPointerBase<Type>(p) {} \
    342         ~LocalPointerClassName() { closeFunction(ptr); } \
    343         void adoptInstead(Type *p) { \
    344             closeFunction(ptr); \
    345             ptr=p; \
    346         } \
    347     }
    348 
    349 U_NAMESPACE_END
    350 
    351 #endif  /* U_SHOW_CPLUSPLUS_API */
    352 #endif  /* __LOCALPOINTER_H__ */
    353