Home | History | Annotate | Download | only in unicode
      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      */
     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     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      */
    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      */
    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      */
    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      */
    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