150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/* 250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho******************************************************************************* 350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho* 4c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert* Copyright (C) 2009-2015, International Business Machines 550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho* Corporation and others. All Rights Reserved. 650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho* 750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho******************************************************************************* 850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho* file name: localpointer.h 950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho* encoding: US-ASCII 1050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho* tab size: 8 (not used) 1150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho* indentation:4 1250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho* 1350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho* created on: 2009nov13 1450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho* created by: Markus W. Scherer 1550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*/ 1650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 1750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#ifndef __LOCALPOINTER_H__ 1850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#define __LOCALPOINTER_H__ 1950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 2050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/** 2150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * \file 2250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * \brief C++ API: "Smart pointers" for use with and in ICU4C C++ code. 2350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * 2450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * These classes are inspired by 2550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * - std::auto_ptr 2650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * - boost::scoped_ptr & boost::scoped_array 2750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * - Taligent Safe Pointers (TOnlyPointerTo) 2850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * 2950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * but none of those provide for all of the goals for ICU smart pointers: 3050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * - Smart pointer owns the object and releases it when it goes out of scope. 3150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * - No transfer of ownership via copy/assignment to reduce misuse. Simpler & more robust. 3250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * - ICU-compatible: No exceptions. 3350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * - Need to be able to orphan/release the pointer and its ownership. 3450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * - Need variants for normal C++ object pointers, C++ arrays, and ICU C service objects. 3550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * 3650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * For details see http://site.icu-project.org/design/cpp/scoped_ptr 3750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 3850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 3950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "unicode/utypes.h" 4050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 4150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#if U_SHOW_CPLUSPLUS_API 4250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 4350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_NAMESPACE_BEGIN 4450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 4550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/** 4650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * "Smart pointer" base class; do not use directly: use LocalPointer etc. 4750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * 4850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Base class for smart pointer classes that do not throw exceptions. 4950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * 5050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Do not use this base class directly, since it does not delete its pointer. 5150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * A subclass must implement methods that delete the pointer: 5250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Destructor and adoptInstead(). 5350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * 5450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * There is no operator T *() provided because the programmer must decide 5550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * whether to use getAlias() (without transfer of ownership) or orpan() 5650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * (with transfer of ownership and NULLing of the pointer). 5750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * 5850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @see LocalPointer 5950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @see LocalArray 6050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @see U_DEFINE_LOCAL_OPEN_POINTER 6127f654740f2a26ad62a5c155af9199af9e69b889claireho * @stable ICU 4.4 6250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 6350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehotemplate<typename T> 6450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoclass LocalPointerBase { 6550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehopublic: 6650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /** 6750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Constructor takes ownership. 6850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param p simple pointer to an object that is adopted 6927f654740f2a26ad62a5c155af9199af9e69b889claireho * @stable ICU 4.4 7050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 7150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho explicit LocalPointerBase(T *p=NULL) : ptr(p) {} 7250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /** 7350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Destructor deletes the object it owns. 7450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Subclass must override: Base class does nothing. 7527f654740f2a26ad62a5c155af9199af9e69b889claireho * @stable ICU 4.4 7650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 7750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ~LocalPointerBase() { /* delete ptr; */ } 7850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /** 7950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * NULL check. 8050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @return TRUE if ==NULL 8127f654740f2a26ad62a5c155af9199af9e69b889claireho * @stable ICU 4.4 8250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 8350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UBool isNull() const { return ptr==NULL; } 8450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /** 8550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * NULL check. 8650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @return TRUE if !=NULL 8727f654740f2a26ad62a5c155af9199af9e69b889claireho * @stable ICU 4.4 8850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 8950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UBool isValid() const { return ptr!=NULL; } 9050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /** 9150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Comparison with a simple pointer, so that existing code 9250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * with ==NULL need not be changed. 9350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param other simple pointer for comparison 9450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @return true if this pointer value equals other 9527f654740f2a26ad62a5c155af9199af9e69b889claireho * @stable ICU 4.4 9650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 9750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho bool operator==(const T *other) const { return ptr==other; } 9850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /** 9950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Comparison with a simple pointer, so that existing code 10050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * with !=NULL need not be changed. 10150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param other simple pointer for comparison 10250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @return true if this pointer value differs from other 10327f654740f2a26ad62a5c155af9199af9e69b889claireho * @stable ICU 4.4 10450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 10550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho bool operator!=(const T *other) const { return ptr!=other; } 10650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /** 10750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Access without ownership change. 10850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @return the pointer value 10927f654740f2a26ad62a5c155af9199af9e69b889claireho * @stable ICU 4.4 11050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 11150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho T *getAlias() const { return ptr; } 11250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /** 11350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Access without ownership change. 11450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @return the pointer value as a reference 11527f654740f2a26ad62a5c155af9199af9e69b889claireho * @stable ICU 4.4 11650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 11750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho T &operator*() const { return *ptr; } 11850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /** 11950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Access without ownership change. 12050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @return the pointer value 12127f654740f2a26ad62a5c155af9199af9e69b889claireho * @stable ICU 4.4 12250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 12350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho T *operator->() const { return ptr; } 12450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /** 12550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Gives up ownership; the internal pointer becomes NULL. 12650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @return the pointer value; 12750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * caller becomes responsible for deleting the object 12827f654740f2a26ad62a5c155af9199af9e69b889claireho * @stable ICU 4.4 12950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 13050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho T *orphan() { 13150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho T *p=ptr; 13250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ptr=NULL; 13350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return p; 13450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 13550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /** 13650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Deletes the object it owns, 13750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * and adopts (takes ownership of) the one passed in. 13850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Subclass must override: Base class does not delete the object. 13950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param p simple pointer to an object that is adopted 14027f654740f2a26ad62a5c155af9199af9e69b889claireho * @stable ICU 4.4 14150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 14250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho void adoptInstead(T *p) { 14350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // delete ptr; 14450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ptr=p; 14550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 14650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoprotected: 14754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius /** 14854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius * Actual pointer. 14954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius * @internal 15054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius */ 15150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho T *ptr; 15250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoprivate: 15350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // No comparison operators with other LocalPointerBases. 154c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert bool operator==(const LocalPointerBase<T> &other); 155c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert bool operator!=(const LocalPointerBase<T> &other); 156c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert // No ownership sharing: No copy constructor, no assignment operator. 157c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert LocalPointerBase(const LocalPointerBase<T> &other); 158c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert void operator=(const LocalPointerBase<T> &other); 15950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // No heap allocation. Use only on the stack. 16050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho static void * U_EXPORT2 operator new(size_t size); 16150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho static void * U_EXPORT2 operator new[](size_t size); 16250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#if U_HAVE_PLACEMENT_NEW 16350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho static void * U_EXPORT2 operator new(size_t, void *ptr); 16450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif 16550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}; 16650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 16750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/** 16850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * "Smart pointer" class, deletes objects via the standard C++ delete operator. 16950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * For most methods see the LocalPointerBase base class. 17050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * 17150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Usage example: 17250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * \code 17350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * LocalPointer<UnicodeString> s(new UnicodeString((UChar32)0x50005)); 17450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * int32_t length=s->length(); // 2 17550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * UChar lead=s->charAt(0); // 0xd900 17650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * if(some condition) { return; } // no need to explicitly delete the pointer 17750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * s.adoptInstead(new UnicodeString((UChar)0xfffc)); 17850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * length=s->length(); // 1 17950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * // no need to explicitly delete the pointer 18050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * \endcode 18150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * 18250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @see LocalPointerBase 18327f654740f2a26ad62a5c155af9199af9e69b889claireho * @stable ICU 4.4 18450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 18550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehotemplate<typename T> 18650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoclass LocalPointer : public LocalPointerBase<T> { 18750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehopublic: 18850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /** 18950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Constructor takes ownership. 19050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param p simple pointer to an object that is adopted 19127f654740f2a26ad62a5c155af9199af9e69b889claireho * @stable ICU 4.4 19250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 19350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho explicit LocalPointer(T *p=NULL) : LocalPointerBase<T>(p) {} 1941b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert#ifndef U_HIDE_DRAFT_API 1951b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert /** 1961b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert * Constructor takes ownership and reports an error if NULL. 1971b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert * 1981b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert * This constructor is intended to be used with other-class constructors 1991b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert * that may report a failure UErrorCode, 2001b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert * so that callers need to check only for U_FAILURE(errorCode) 2011b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert * and not also separately for isNull(). 2021b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert * 2031b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert * @param p simple pointer to an object that is adopted 2041b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert * @param errorCode in/out UErrorCode, set to U_MEMORY_ALLOCATION_ERROR 2051b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert * if p==NULL and no other failure code had been set 2061b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert * @draft ICU 55 2071b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert */ 2081b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert LocalPointer(T *p, UErrorCode &errorCode) : LocalPointerBase<T>(p) { 2091b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert if(p==NULL && U_SUCCESS(errorCode)) { 2101b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert errorCode=U_MEMORY_ALLOCATION_ERROR; 2111b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert } 2121b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert } 213c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert#if U_HAVE_RVALUE_REFERENCES 214c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert /** 215c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * Move constructor, leaves src with isNull(). 216c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * @param src source smart pointer 217c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * @draft ICU 56 218c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert */ 219c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert LocalPointer(LocalPointer<T> &&src) U_NOEXCEPT : LocalPointerBase<T>(src.ptr) { 220c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert src.ptr=NULL; 221c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert } 222c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert#endif 2231b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert#endif /* U_HIDE_DRAFT_API */ 22450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /** 22550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Destructor deletes the object it owns. 22627f654740f2a26ad62a5c155af9199af9e69b889claireho * @stable ICU 4.4 22750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 22850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ~LocalPointer() { 22950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho delete LocalPointerBase<T>::ptr; 23050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 231c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert#ifndef U_HIDE_DRAFT_API 232c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert#if U_HAVE_RVALUE_REFERENCES 233c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert /** 234c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * Move assignment operator, leaves src with isNull(). 235c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * The behavior is undefined if *this and src are the same object. 236c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * @param src source smart pointer 237c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * @return *this 238c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * @draft ICU 56 239c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert */ 240c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert LocalPointer<T> &operator=(LocalPointer<T> &&src) U_NOEXCEPT { 241c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert return moveFrom(src); 242c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert } 243c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert#endif 244c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert /** 245c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * Move assignment, leaves src with isNull(). 246c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * The behavior is undefined if *this and src are the same object. 247c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * 248c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * Can be called explicitly, does not need C++11 support. 249c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * @param src source smart pointer 250c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * @return *this 251c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * @draft ICU 56 252c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert */ 253c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert LocalPointer<T> &moveFrom(LocalPointer<T> &src) U_NOEXCEPT { 254c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert delete LocalPointerBase<T>::ptr; 255c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert LocalPointerBase<T>::ptr=src.ptr; 256c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert src.ptr=NULL; 257c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert return *this; 258c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert } 259c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert /** 260c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * Swap pointers. 261c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * @param other other smart pointer 262c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * @draft ICU 56 263c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert */ 264c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert void swap(LocalPointer<T> &other) U_NOEXCEPT { 265c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert T *temp=LocalPointerBase<T>::ptr; 266c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert LocalPointerBase<T>::ptr=other.ptr; 267c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert other.ptr=temp; 268c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert } 269c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert /** 270c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * Non-member LocalPointer swap function. 271c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * @param p1 will get p2's pointer 272c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * @param p2 will get p1's pointer 273c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * @draft ICU 56 274c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert */ 275c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert friend inline void swap(LocalPointer<T> &p1, LocalPointer<T> &p2) U_NOEXCEPT { 276c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert p1.swap(p2); 277c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert } 278c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert#endif /* U_HIDE_DRAFT_API */ 27950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /** 28050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Deletes the object it owns, 28150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * and adopts (takes ownership of) the one passed in. 28250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param p simple pointer to an object that is adopted 28327f654740f2a26ad62a5c155af9199af9e69b889claireho * @stable ICU 4.4 28450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 28550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho void adoptInstead(T *p) { 28650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho delete LocalPointerBase<T>::ptr; 28750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho LocalPointerBase<T>::ptr=p; 28850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 2891b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert#ifndef U_HIDE_DRAFT_API 2901b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert /** 2911b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert * Deletes the object it owns, 2921b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert * and adopts (takes ownership of) the one passed in. 2931b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert * 2941b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert * If U_FAILURE(errorCode), then the current object is retained and the new one deleted. 2951b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert * 2961b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert * If U_SUCCESS(errorCode) but the input pointer is NULL, 2971b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert * then U_MEMORY_ALLOCATION_ERROR is set, 2981b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert * the current object is deleted, and NULL is set. 2991b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert * 3001b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert * @param p simple pointer to an object that is adopted 3011b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert * @param errorCode in/out UErrorCode, set to U_MEMORY_ALLOCATION_ERROR 3021b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert * if p==NULL and no other failure code had been set 3031b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert * @draft ICU 55 3041b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert */ 3051b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert void adoptInsteadAndCheckErrorCode(T *p, UErrorCode &errorCode) { 3061b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert if(U_SUCCESS(errorCode)) { 3071b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert delete LocalPointerBase<T>::ptr; 3081b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert LocalPointerBase<T>::ptr=p; 3091b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert if(p==NULL) { 3101b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert errorCode=U_MEMORY_ALLOCATION_ERROR; 3111b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert } 3121b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert } else { 3131b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert delete p; 3141b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert } 3151b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert } 3161b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert#endif /* U_HIDE_DRAFT_API */ 31750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}; 31850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 31950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/** 32050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * "Smart pointer" class, deletes objects via the C++ array delete[] operator. 32150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * For most methods see the LocalPointerBase base class. 32250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Adds operator[] for array item access. 32350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * 32450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Usage example: 32550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * \code 32650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * LocalArray<UnicodeString> a(new UnicodeString[2]); 32750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * a[0].append((UChar)0x61); 32850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * if(some condition) { return; } // no need to explicitly delete the array 32950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * a.adoptInstead(new UnicodeString[4]); 33050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * a[3].append((UChar)0x62).append((UChar)0x63).reverse(); 33150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * // no need to explicitly delete the array 33250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * \endcode 33350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * 33450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @see LocalPointerBase 33527f654740f2a26ad62a5c155af9199af9e69b889claireho * @stable ICU 4.4 33650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 33750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehotemplate<typename T> 33850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoclass LocalArray : public LocalPointerBase<T> { 33950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehopublic: 34050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /** 34150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Constructor takes ownership. 34250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param p simple pointer to an array of T objects that is adopted 34327f654740f2a26ad62a5c155af9199af9e69b889claireho * @stable ICU 4.4 34450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 34550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho explicit LocalArray(T *p=NULL) : LocalPointerBase<T>(p) {} 346c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert#ifndef U_HIDE_DRAFT_API 347c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert /** 348c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * Constructor takes ownership and reports an error if NULL. 349c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * 350c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * This constructor is intended to be used with other-class constructors 351c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * that may report a failure UErrorCode, 352c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * so that callers need to check only for U_FAILURE(errorCode) 353c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * and not also separately for isNull(). 354c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * 355c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * @param p simple pointer to an array of T objects that is adopted 356c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * @param errorCode in/out UErrorCode, set to U_MEMORY_ALLOCATION_ERROR 357c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * if p==NULL and no other failure code had been set 358c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * @draft ICU 56 359c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert */ 360c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert LocalArray(T *p, UErrorCode &errorCode) : LocalPointerBase<T>(p) { 361c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert if(p==NULL && U_SUCCESS(errorCode)) { 362c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert errorCode=U_MEMORY_ALLOCATION_ERROR; 363c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert } 364c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert } 365c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert#if U_HAVE_RVALUE_REFERENCES 366c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert /** 367c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * Move constructor, leaves src with isNull(). 368c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * @param src source smart pointer 369c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * @draft ICU 56 370c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert */ 371c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert LocalArray(LocalArray<T> &&src) U_NOEXCEPT : LocalPointerBase<T>(src.ptr) { 372c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert src.ptr=NULL; 373c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert } 374c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert#endif 375c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert#endif /* U_HIDE_DRAFT_API */ 37650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /** 37750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Destructor deletes the array it owns. 37827f654740f2a26ad62a5c155af9199af9e69b889claireho * @stable ICU 4.4 37950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 38050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ~LocalArray() { 38150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho delete[] LocalPointerBase<T>::ptr; 38250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 383c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert#ifndef U_HIDE_DRAFT_API 384c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert#if U_HAVE_RVALUE_REFERENCES 385c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert /** 386c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * Move assignment operator, leaves src with isNull(). 387c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * The behavior is undefined if *this and src are the same object. 388c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * @param src source smart pointer 389c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * @return *this 390c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * @draft ICU 56 391c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert */ 392c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert LocalArray<T> &operator=(LocalArray<T> &&src) U_NOEXCEPT { 393c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert return moveFrom(src); 394c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert } 395c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert#endif 396c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert /** 397c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * Move assignment, leaves src with isNull(). 398c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * The behavior is undefined if *this and src are the same object. 399c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * 400c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * Can be called explicitly, does not need C++11 support. 401c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * @param src source smart pointer 402c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * @return *this 403c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * @draft ICU 56 404c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert */ 405c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert LocalArray<T> &moveFrom(LocalArray<T> &src) U_NOEXCEPT { 406c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert delete[] LocalPointerBase<T>::ptr; 407c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert LocalPointerBase<T>::ptr=src.ptr; 408c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert src.ptr=NULL; 409c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert return *this; 410c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert } 411c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert /** 412c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * Swap pointers. 413c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * @param other other smart pointer 414c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * @draft ICU 56 415c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert */ 416c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert void swap(LocalArray<T> &other) U_NOEXCEPT { 417c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert T *temp=LocalPointerBase<T>::ptr; 418c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert LocalPointerBase<T>::ptr=other.ptr; 419c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert other.ptr=temp; 420c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert } 421c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert /** 422c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * Non-member LocalArray swap function. 423c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * @param p1 will get p2's pointer 424c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * @param p2 will get p1's pointer 425c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * @draft ICU 56 426c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert */ 427c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert friend inline void swap(LocalArray<T> &p1, LocalArray<T> &p2) U_NOEXCEPT { 428c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert p1.swap(p2); 429c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert } 430c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert#endif /* U_HIDE_DRAFT_API */ 43150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /** 43250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Deletes the array it owns, 43350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * and adopts (takes ownership of) the one passed in. 43450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param p simple pointer to an array of T objects that is adopted 43527f654740f2a26ad62a5c155af9199af9e69b889claireho * @stable ICU 4.4 43650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 43750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho void adoptInstead(T *p) { 43850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho delete[] LocalPointerBase<T>::ptr; 43950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho LocalPointerBase<T>::ptr=p; 44050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 441c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert#ifndef U_HIDE_DRAFT_API 442c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert /** 443c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * Deletes the array it owns, 444c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * and adopts (takes ownership of) the one passed in. 445c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * 446c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * If U_FAILURE(errorCode), then the current array is retained and the new one deleted. 447c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * 448c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * If U_SUCCESS(errorCode) but the input pointer is NULL, 449c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * then U_MEMORY_ALLOCATION_ERROR is set, 450c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * the current array is deleted, and NULL is set. 451c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * 452c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * @param p simple pointer to an array of T objects that is adopted 453c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * @param errorCode in/out UErrorCode, set to U_MEMORY_ALLOCATION_ERROR 454c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * if p==NULL and no other failure code had been set 455c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * @draft ICU 56 456c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert */ 457c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert void adoptInsteadAndCheckErrorCode(T *p, UErrorCode &errorCode) { 458c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert if(U_SUCCESS(errorCode)) { 459c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert delete[] LocalPointerBase<T>::ptr; 460c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert LocalPointerBase<T>::ptr=p; 461c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert if(p==NULL) { 462c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert errorCode=U_MEMORY_ALLOCATION_ERROR; 463c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert } 464c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert } else { 465c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert delete[] p; 466c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert } 467c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert } 468c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert#endif /* U_HIDE_DRAFT_API */ 46950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /** 47050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Array item access (writable). 47150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * No index bounds check. 47250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param i array index 47350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @return reference to the array item 47427f654740f2a26ad62a5c155af9199af9e69b889claireho * @stable ICU 4.4 47550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 47650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho T &operator[](ptrdiff_t i) const { return LocalPointerBase<T>::ptr[i]; } 47750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}; 47850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 47950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/** 48050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * \def U_DEFINE_LOCAL_OPEN_POINTER 48150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * "Smart pointer" definition macro, deletes objects via the closeFunction. 48250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Defines a subclass of LocalPointerBase which works just 48350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * like LocalPointer<Type> except that this subclass will use the closeFunction 48450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * rather than the C++ delete operator. 48550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * 48650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Requirement: The closeFunction must tolerate a NULL pointer. 48750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * (We could add a NULL check here but it is normally redundant.) 48850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * 48950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Usage example: 49050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * \code 49150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * LocalUCaseMapPointer csm(ucasemap_open(localeID, options, &errorCode)); 49250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * utf8OutLength=ucasemap_utf8ToLower(csm.getAlias(), 49350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * utf8Out, (int32_t)sizeof(utf8Out), 49450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * utf8In, utf8InLength, &errorCode); 49550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * if(U_FAILURE(errorCode)) { return; } // no need to explicitly delete the UCaseMap 49650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * \endcode 49750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * 49850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @see LocalPointerBase 49950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @see LocalPointer 50027f654740f2a26ad62a5c155af9199af9e69b889claireho * @stable ICU 4.4 50150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 502c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert#if U_HAVE_RVALUE_REFERENCES 503c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert#define U_DEFINE_LOCAL_OPEN_POINTER(LocalPointerClassName, Type, closeFunction) \ 504c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert class LocalPointerClassName : public LocalPointerBase<Type> { \ 505c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert public: \ 506c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert explicit LocalPointerClassName(Type *p=NULL) : LocalPointerBase<Type>(p) {} \ 507c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert LocalPointerClassName(LocalPointerClassName &&src) U_NOEXCEPT \ 508c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert : LocalPointerBase<Type>(src.ptr) { \ 509c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert src.ptr=NULL; \ 510c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert } \ 511c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert ~LocalPointerClassName() { closeFunction(ptr); } \ 512c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert LocalPointerClassName &operator=(LocalPointerClassName &&src) U_NOEXCEPT { \ 513c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert return moveFrom(src); \ 514c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert } \ 515c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert LocalPointerClassName &moveFrom(LocalPointerClassName &src) U_NOEXCEPT { \ 516c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert closeFunction(ptr); \ 517c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert LocalPointerBase<Type>::ptr=src.ptr; \ 518c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert src.ptr=NULL; \ 519c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert return *this; \ 520c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert } \ 521c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert void swap(LocalPointerClassName &other) U_NOEXCEPT { \ 522c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert Type *temp=LocalPointerBase<Type>::ptr; \ 523c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert LocalPointerBase<Type>::ptr=other.ptr; \ 524c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert other.ptr=temp; \ 525c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert } \ 526c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert friend inline void swap(LocalPointerClassName &p1, LocalPointerClassName &p2) U_NOEXCEPT { \ 527c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert p1.swap(p2); \ 528c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert } \ 529c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert void adoptInstead(Type *p) { \ 530c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert closeFunction(ptr); \ 531c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert ptr=p; \ 532c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert } \ 533c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert } 534c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert#else 53550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#define U_DEFINE_LOCAL_OPEN_POINTER(LocalPointerClassName, Type, closeFunction) \ 53650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho class LocalPointerClassName : public LocalPointerBase<Type> { \ 53750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho public: \ 53850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho explicit LocalPointerClassName(Type *p=NULL) : LocalPointerBase<Type>(p) {} \ 53950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ~LocalPointerClassName() { closeFunction(ptr); } \ 540c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert LocalPointerClassName &moveFrom(LocalPointerClassName &src) U_NOEXCEPT { \ 541c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert closeFunction(ptr); \ 542c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert LocalPointerBase<Type>::ptr=src.ptr; \ 543c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert src.ptr=NULL; \ 544c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert return *this; \ 545c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert } \ 546c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert void swap(LocalPointerClassName &other) U_NOEXCEPT { \ 547c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert Type *temp=LocalPointerBase<Type>::ptr; \ 548c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert LocalPointerBase<Type>::ptr=other.ptr; \ 549c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert other.ptr=temp; \ 550c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert } \ 551c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert friend inline void swap(LocalPointerClassName &p1, LocalPointerClassName &p2) U_NOEXCEPT { \ 552c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert p1.swap(p2); \ 553c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert } \ 55450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho void adoptInstead(Type *p) { \ 55550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho closeFunction(ptr); \ 55650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ptr=p; \ 55750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } \ 55850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 559c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert#endif 56050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 56150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_NAMESPACE_END 56250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 56350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif /* U_SHOW_CPLUSPLUS_API */ 56450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif /* __LOCALPOINTER_H__ */ 565