Home | History | Annotate | Download | only in unicode
      1 /*
      2 *******************************************************************************
      3 *
      4 *   Copyright (C) 2009-2012, 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     /**
    195      * Destructor deletes the object it owns.
    196      * @stable ICU 4.4
    197      */
    198     ~LocalPointer() {
    199         delete LocalPointerBase<T>::ptr;
    200     }
    201     /**
    202      * Deletes the object it owns,
    203      * and adopts (takes ownership of) the one passed in.
    204      * @param p simple pointer to an object that is adopted
    205      * @stable ICU 4.4
    206      */
    207     void adoptInstead(T *p) {
    208         delete LocalPointerBase<T>::ptr;
    209         LocalPointerBase<T>::ptr=p;
    210     }
    211 };
    212 
    213 /**
    214  * "Smart pointer" class, deletes objects via the C++ array delete[] operator.
    215  * For most methods see the LocalPointerBase base class.
    216  * Adds operator[] for array item access.
    217  *
    218  * Usage example:
    219  * \code
    220  * LocalArray<UnicodeString> a(new UnicodeString[2]);
    221  * a[0].append((UChar)0x61);
    222  * if(some condition) { return; }  // no need to explicitly delete the array
    223  * a.adoptInstead(new UnicodeString[4]);
    224  * a[3].append((UChar)0x62).append((UChar)0x63).reverse();
    225  * // no need to explicitly delete the array
    226  * \endcode
    227  *
    228  * @see LocalPointerBase
    229  * @stable ICU 4.4
    230  */
    231 template<typename T>
    232 class LocalArray : public LocalPointerBase<T> {
    233 public:
    234     /**
    235      * Constructor takes ownership.
    236      * @param p simple pointer to an array of T objects that is adopted
    237      * @stable ICU 4.4
    238      */
    239     explicit LocalArray(T *p=NULL) : LocalPointerBase<T>(p) {}
    240     /**
    241      * Destructor deletes the array it owns.
    242      * @stable ICU 4.4
    243      */
    244     ~LocalArray() {
    245         delete[] LocalPointerBase<T>::ptr;
    246     }
    247     /**
    248      * Deletes the array it owns,
    249      * and adopts (takes ownership of) the one passed in.
    250      * @param p simple pointer to an array of T objects that is adopted
    251      * @stable ICU 4.4
    252      */
    253     void adoptInstead(T *p) {
    254         delete[] LocalPointerBase<T>::ptr;
    255         LocalPointerBase<T>::ptr=p;
    256     }
    257     /**
    258      * Array item access (writable).
    259      * No index bounds check.
    260      * @param i array index
    261      * @return reference to the array item
    262      * @stable ICU 4.4
    263      */
    264     T &operator[](ptrdiff_t i) const { return LocalPointerBase<T>::ptr[i]; }
    265 };
    266 
    267 /**
    268  * \def U_DEFINE_LOCAL_OPEN_POINTER
    269  * "Smart pointer" definition macro, deletes objects via the closeFunction.
    270  * Defines a subclass of LocalPointerBase which works just
    271  * like LocalPointer<Type> except that this subclass will use the closeFunction
    272  * rather than the C++ delete operator.
    273  *
    274  * Requirement: The closeFunction must tolerate a NULL pointer.
    275  * (We could add a NULL check here but it is normally redundant.)
    276  *
    277  * Usage example:
    278  * \code
    279  * LocalUCaseMapPointer csm(ucasemap_open(localeID, options, &errorCode));
    280  * utf8OutLength=ucasemap_utf8ToLower(csm.getAlias(),
    281  *     utf8Out, (int32_t)sizeof(utf8Out),
    282  *     utf8In, utf8InLength, &errorCode);
    283  * if(U_FAILURE(errorCode)) { return; }  // no need to explicitly delete the UCaseMap
    284  * \endcode
    285  *
    286  * @see LocalPointerBase
    287  * @see LocalPointer
    288  * @stable ICU 4.4
    289  */
    290 #define U_DEFINE_LOCAL_OPEN_POINTER(LocalPointerClassName, Type, closeFunction) \
    291     class LocalPointerClassName : public LocalPointerBase<Type> { \
    292     public: \
    293         explicit LocalPointerClassName(Type *p=NULL) : LocalPointerBase<Type>(p) {} \
    294         ~LocalPointerClassName() { closeFunction(ptr); } \
    295         void adoptInstead(Type *p) { \
    296             closeFunction(ptr); \
    297             ptr=p; \
    298         } \
    299     }
    300 
    301 U_NAMESPACE_END
    302 
    303 #endif  /* U_SHOW_CPLUSPLUS_API */
    304 #endif  /* __LOCALPOINTER_H__ */
    305