Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/native/common/unicode/localpointer.h
38827 views
/*1*******************************************************************************2*3* Copyright (C) 2009-2016, International Business Machines4* Corporation and others. All Rights Reserved.5*6*******************************************************************************7* file name: localpointer.h8* encoding: US-ASCII9* tab size: 8 (not used)10* indentation:411*12* created on: 2009nov1313* created by: Markus W. Scherer14*/1516#ifndef __LOCALPOINTER_H__17#define __LOCALPOINTER_H__1819/**20* \file21* \brief C++ API: "Smart pointers" for use with and in ICU4C C++ code.22*23* These classes are inspired by24* - std::auto_ptr25* - boost::scoped_ptr & boost::scoped_array26* - Taligent Safe Pointers (TOnlyPointerTo)27*28* but none of those provide for all of the goals for ICU smart pointers:29* - Smart pointer owns the object and releases it when it goes out of scope.30* - No transfer of ownership via copy/assignment to reduce misuse. Simpler & more robust.31* - ICU-compatible: No exceptions.32* - Need to be able to orphan/release the pointer and its ownership.33* - Need variants for normal C++ object pointers, C++ arrays, and ICU C service objects.34*35* For details see http://site.icu-project.org/design/cpp/scoped_ptr36*/3738#include "unicode/utypes.h"3940#if U_SHOW_CPLUSPLUS_API4142U_NAMESPACE_BEGIN4344/**45* "Smart pointer" base class; do not use directly: use LocalPointer etc.46*47* Base class for smart pointer classes that do not throw exceptions.48*49* Do not use this base class directly, since it does not delete its pointer.50* A subclass must implement methods that delete the pointer:51* Destructor and adoptInstead().52*53* There is no operator T *() provided because the programmer must decide54* whether to use getAlias() (without transfer of ownership) or orphan()55* (with transfer of ownership and NULLing of the pointer).56*57* @see LocalPointer58* @see LocalArray59* @see U_DEFINE_LOCAL_OPEN_POINTER60* @stable ICU 4.461*/62template<typename T>63class LocalPointerBase {64public:65/**66* Constructor takes ownership.67* @param p simple pointer to an object that is adopted68* @stable ICU 4.469*/70explicit LocalPointerBase(T *p=NULL) : ptr(p) {}71/**72* Destructor deletes the object it owns.73* Subclass must override: Base class does nothing.74* @stable ICU 4.475*/76~LocalPointerBase() { /* delete ptr; */ }77/**78* NULL check.79* @return TRUE if ==NULL80* @stable ICU 4.481*/82UBool isNull() const { return ptr==NULL; }83/**84* NULL check.85* @return TRUE if !=NULL86* @stable ICU 4.487*/88UBool isValid() const { return ptr!=NULL; }89/**90* Comparison with a simple pointer, so that existing code91* with ==NULL need not be changed.92* @param other simple pointer for comparison93* @return true if this pointer value equals other94* @stable ICU 4.495*/96bool operator==(const T *other) const { return ptr==other; }97/**98* Comparison with a simple pointer, so that existing code99* with !=NULL need not be changed.100* @param other simple pointer for comparison101* @return true if this pointer value differs from other102* @stable ICU 4.4103*/104bool operator!=(const T *other) const { return ptr!=other; }105/**106* Access without ownership change.107* @return the pointer value108* @stable ICU 4.4109*/110T *getAlias() const { return ptr; }111/**112* Access without ownership change.113* @return the pointer value as a reference114* @stable ICU 4.4115*/116T &operator*() const { return *ptr; }117/**118* Access without ownership change.119* @return the pointer value120* @stable ICU 4.4121*/122T *operator->() const { return ptr; }123/**124* Gives up ownership; the internal pointer becomes NULL.125* @return the pointer value;126* caller becomes responsible for deleting the object127* @stable ICU 4.4128*/129T *orphan() {130T *p=ptr;131ptr=NULL;132return p;133}134/**135* Deletes the object it owns,136* and adopts (takes ownership of) the one passed in.137* Subclass must override: Base class does not delete the object.138* @param p simple pointer to an object that is adopted139* @stable ICU 4.4140*/141void adoptInstead(T *p) {142// delete ptr;143ptr=p;144}145protected:146/**147* Actual pointer.148* @internal149*/150T *ptr;151private:152// No comparison operators with other LocalPointerBases.153bool operator==(const LocalPointerBase<T> &other);154bool operator!=(const LocalPointerBase<T> &other);155// No ownership sharing: No copy constructor, no assignment operator.156LocalPointerBase(const LocalPointerBase<T> &other);157void operator=(const LocalPointerBase<T> &other);158// No heap allocation. Use only on the stack.159static void * U_EXPORT2 operator new(size_t size);160static void * U_EXPORT2 operator new[](size_t size);161#if U_HAVE_PLACEMENT_NEW162static void * U_EXPORT2 operator new(size_t, void *ptr);163#endif164};165166/**167* "Smart pointer" class, deletes objects via the standard C++ delete operator.168* For most methods see the LocalPointerBase base class.169*170* Usage example:171* \code172* LocalPointer<UnicodeString> s(new UnicodeString((UChar32)0x50005));173* int32_t length=s->length(); // 2174* UChar lead=s->charAt(0); // 0xd900175* if(some condition) { return; } // no need to explicitly delete the pointer176* s.adoptInstead(new UnicodeString((UChar)0xfffc));177* length=s->length(); // 1178* // no need to explicitly delete the pointer179* \endcode180*181* @see LocalPointerBase182* @stable ICU 4.4183*/184template<typename T>185class LocalPointer : public LocalPointerBase<T> {186public:187using LocalPointerBase<T>::operator*;188using LocalPointerBase<T>::operator->;189/**190* Constructor takes ownership.191* @param p simple pointer to an object that is adopted192* @stable ICU 4.4193*/194explicit LocalPointer(T *p=NULL) : LocalPointerBase<T>(p) {}195/**196* Constructor takes ownership and reports an error if NULL.197*198* This constructor is intended to be used with other-class constructors199* 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 adopted204* @param errorCode in/out UErrorCode, set to U_MEMORY_ALLOCATION_ERROR205* if p==NULL and no other failure code had been set206* @stable ICU 55207*/208LocalPointer(T *p, UErrorCode &errorCode) : LocalPointerBase<T>(p) {209if(p==NULL && U_SUCCESS(errorCode)) {210errorCode=U_MEMORY_ALLOCATION_ERROR;211}212}213#ifndef U_HIDE_DRAFT_API214#if U_HAVE_RVALUE_REFERENCES215/**216* Move constructor, leaves src with isNull().217* @param src source smart pointer218* @draft ICU 56219*/220LocalPointer(LocalPointer<T> &&src) U_NOEXCEPT : LocalPointerBase<T>(src.ptr) {221src.ptr=NULL;222}223#endif224#endif /* U_HIDE_DRAFT_API */225/**226* Destructor deletes the object it owns.227* @stable ICU 4.4228*/229~LocalPointer() {230delete LocalPointerBase<T>::ptr;231}232#ifndef U_HIDE_DRAFT_API233#if U_HAVE_RVALUE_REFERENCES234/**235* Move assignment operator, leaves src with isNull().236* The behavior is undefined if *this and src are the same object.237* @param src source smart pointer238* @return *this239* @draft ICU 56240*/241LocalPointer<T> &operator=(LocalPointer<T> &&src) U_NOEXCEPT {242return moveFrom(src);243}244#endif245/**246* Move assignment, leaves src with isNull().247* The behavior is undefined if *this and src are the same object.248*249* Can be called explicitly, does not need C++11 support.250* @param src source smart pointer251* @return *this252* @draft ICU 56253*/254LocalPointer<T> &moveFrom(LocalPointer<T> &src) U_NOEXCEPT {255delete LocalPointerBase<T>::ptr;256LocalPointerBase<T>::ptr=src.ptr;257src.ptr=NULL;258return *this;259}260/**261* Swap pointers.262* @param other other smart pointer263* @draft ICU 56264*/265void swap(LocalPointer<T> &other) U_NOEXCEPT {266T *temp=LocalPointerBase<T>::ptr;267LocalPointerBase<T>::ptr=other.ptr;268other.ptr=temp;269}270#endif /* U_HIDE_DRAFT_API */271/**272* Non-member LocalPointer swap function.273* @param p1 will get p2's pointer274* @param p2 will get p1's pointer275* @draft ICU 56276*/277friend inline void swap(LocalPointer<T> &p1, LocalPointer<T> &p2) U_NOEXCEPT {278p1.swap(p2);279}280/**281* Deletes the object it owns,282* and adopts (takes ownership of) the one passed in.283* @param p simple pointer to an object that is adopted284* @stable ICU 4.4285*/286void adoptInstead(T *p) {287delete LocalPointerBase<T>::ptr;288LocalPointerBase<T>::ptr=p;289}290/**291* Deletes the object it owns,292* and adopts (takes ownership of) the one passed in.293*294* If U_FAILURE(errorCode), then the current object is retained and the new one deleted.295*296* If U_SUCCESS(errorCode) but the input pointer is NULL,297* then U_MEMORY_ALLOCATION_ERROR is set,298* the current object is deleted, and NULL is set.299*300* @param p simple pointer to an object that is adopted301* @param errorCode in/out UErrorCode, set to U_MEMORY_ALLOCATION_ERROR302* if p==NULL and no other failure code had been set303* @stable ICU 55304*/305void adoptInsteadAndCheckErrorCode(T *p, UErrorCode &errorCode) {306if(U_SUCCESS(errorCode)) {307delete LocalPointerBase<T>::ptr;308LocalPointerBase<T>::ptr=p;309if(p==NULL) {310errorCode=U_MEMORY_ALLOCATION_ERROR;311}312} else {313delete p;314}315}316};317318/**319* "Smart pointer" class, deletes objects via the C++ array delete[] operator.320* For most methods see the LocalPointerBase base class.321* Adds operator[] for array item access.322*323* Usage example:324* \code325* LocalArray<UnicodeString> a(new UnicodeString[2]);326* a[0].append((UChar)0x61);327* if(some condition) { return; } // no need to explicitly delete the array328* a.adoptInstead(new UnicodeString[4]);329* a[3].append((UChar)0x62).append((UChar)0x63).reverse();330* // no need to explicitly delete the array331* \endcode332*333* @see LocalPointerBase334* @stable ICU 4.4335*/336template<typename T>337class LocalArray : public LocalPointerBase<T> {338public:339using LocalPointerBase<T>::operator*;340using LocalPointerBase<T>::operator->;341/**342* Constructor takes ownership.343* @param p simple pointer to an array of T objects that is adopted344* @stable ICU 4.4345*/346explicit LocalArray(T *p=NULL) : LocalPointerBase<T>(p) {}347#ifndef U_HIDE_DRAFT_API348/**349* Constructor takes ownership and reports an error if NULL.350*351* This constructor is intended to be used with other-class constructors352* that may report a failure UErrorCode,353* so that callers need to check only for U_FAILURE(errorCode)354* and not also separately for isNull().355*356* @param p simple pointer to an array of T objects that is adopted357* @param errorCode in/out UErrorCode, set to U_MEMORY_ALLOCATION_ERROR358* if p==NULL and no other failure code had been set359* @draft ICU 56360*/361LocalArray(T *p, UErrorCode &errorCode) : LocalPointerBase<T>(p) {362if(p==NULL && U_SUCCESS(errorCode)) {363errorCode=U_MEMORY_ALLOCATION_ERROR;364}365}366#if U_HAVE_RVALUE_REFERENCES367/**368* Move constructor, leaves src with isNull().369* @param src source smart pointer370* @draft ICU 56371*/372LocalArray(LocalArray<T> &&src) U_NOEXCEPT : LocalPointerBase<T>(src.ptr) {373src.ptr=NULL;374}375#endif376#endif /* U_HIDE_DRAFT_API */377/**378* Destructor deletes the array it owns.379* @stable ICU 4.4380*/381~LocalArray() {382delete[] LocalPointerBase<T>::ptr;383}384#ifndef U_HIDE_DRAFT_API385#if U_HAVE_RVALUE_REFERENCES386/**387* Move assignment operator, leaves src with isNull().388* The behavior is undefined if *this and src are the same object.389* @param src source smart pointer390* @return *this391* @draft ICU 56392*/393LocalArray<T> &operator=(LocalArray<T> &&src) U_NOEXCEPT {394return moveFrom(src);395}396#endif397/**398* Move assignment, leaves src with isNull().399* The behavior is undefined if *this and src are the same object.400*401* Can be called explicitly, does not need C++11 support.402* @param src source smart pointer403* @return *this404* @draft ICU 56405*/406LocalArray<T> &moveFrom(LocalArray<T> &src) U_NOEXCEPT {407delete[] LocalPointerBase<T>::ptr;408LocalPointerBase<T>::ptr=src.ptr;409src.ptr=NULL;410return *this;411}412/**413* Swap pointers.414* @param other other smart pointer415* @draft ICU 56416*/417void swap(LocalArray<T> &other) U_NOEXCEPT {418T *temp=LocalPointerBase<T>::ptr;419LocalPointerBase<T>::ptr=other.ptr;420other.ptr=temp;421}422#endif /* U_HIDE_DRAFT_API */423/**424* Non-member LocalArray swap function.425* @param p1 will get p2's pointer426* @param p2 will get p1's pointer427* @draft ICU 56428*/429friend inline void swap(LocalArray<T> &p1, LocalArray<T> &p2) U_NOEXCEPT {430p1.swap(p2);431}432/**433* Deletes the array it owns,434* and adopts (takes ownership of) the one passed in.435* @param p simple pointer to an array of T objects that is adopted436* @stable ICU 4.4437*/438void adoptInstead(T *p) {439delete[] LocalPointerBase<T>::ptr;440LocalPointerBase<T>::ptr=p;441}442#ifndef U_HIDE_DRAFT_API443/**444* Deletes the array it owns,445* and adopts (takes ownership of) the one passed in.446*447* If U_FAILURE(errorCode), then the current array is retained and the new one deleted.448*449* If U_SUCCESS(errorCode) but the input pointer is NULL,450* then U_MEMORY_ALLOCATION_ERROR is set,451* the current array is deleted, and NULL is set.452*453* @param p simple pointer to an array of T objects that is adopted454* @param errorCode in/out UErrorCode, set to U_MEMORY_ALLOCATION_ERROR455* if p==NULL and no other failure code had been set456* @draft ICU 56457*/458void adoptInsteadAndCheckErrorCode(T *p, UErrorCode &errorCode) {459if(U_SUCCESS(errorCode)) {460delete[] LocalPointerBase<T>::ptr;461LocalPointerBase<T>::ptr=p;462if(p==NULL) {463errorCode=U_MEMORY_ALLOCATION_ERROR;464}465} else {466delete[] p;467}468}469#endif /* U_HIDE_DRAFT_API */470/**471* Array item access (writable).472* No index bounds check.473* @param i array index474* @return reference to the array item475* @stable ICU 4.4476*/477T &operator[](ptrdiff_t i) const { return LocalPointerBase<T>::ptr[i]; }478};479480/**481* \def U_DEFINE_LOCAL_OPEN_POINTER482* "Smart pointer" definition macro, deletes objects via the closeFunction.483* Defines a subclass of LocalPointerBase which works just484* like LocalPointer<Type> except that this subclass will use the closeFunction485* rather than the C++ delete operator.486*487* Requirement: The closeFunction must tolerate a NULL pointer.488* (We could add a NULL check here but it is normally redundant.)489*490* Usage example:491* \code492* LocalUCaseMapPointer csm(ucasemap_open(localeID, options, &errorCode));493* utf8OutLength=ucasemap_utf8ToLower(csm.getAlias(),494* utf8Out, (int32_t)sizeof(utf8Out),495* utf8In, utf8InLength, &errorCode);496* if(U_FAILURE(errorCode)) { return; } // no need to explicitly delete the UCaseMap497* \endcode498*499* @see LocalPointerBase500* @see LocalPointer501* @stable ICU 4.4502*/503#if U_HAVE_RVALUE_REFERENCES504#define U_DEFINE_LOCAL_OPEN_POINTER(LocalPointerClassName, Type, closeFunction) \505class LocalPointerClassName : public LocalPointerBase<Type> { \506public: \507using LocalPointerBase<Type>::operator*; \508using LocalPointerBase<Type>::operator->; \509explicit LocalPointerClassName(Type *p=NULL) : LocalPointerBase<Type>(p) {} \510LocalPointerClassName(LocalPointerClassName &&src) U_NOEXCEPT \511: LocalPointerBase<Type>(src.ptr) { \512src.ptr=NULL; \513} \514~LocalPointerClassName() { closeFunction(ptr); } \515LocalPointerClassName &operator=(LocalPointerClassName &&src) U_NOEXCEPT { \516return moveFrom(src); \517} \518LocalPointerClassName &moveFrom(LocalPointerClassName &src) U_NOEXCEPT { \519closeFunction(ptr); \520LocalPointerBase<Type>::ptr=src.ptr; \521src.ptr=NULL; \522return *this; \523} \524void swap(LocalPointerClassName &other) U_NOEXCEPT { \525Type *temp=LocalPointerBase<Type>::ptr; \526LocalPointerBase<Type>::ptr=other.ptr; \527other.ptr=temp; \528} \529friend inline void swap(LocalPointerClassName &p1, LocalPointerClassName &p2) U_NOEXCEPT { \530p1.swap(p2); \531} \532void adoptInstead(Type *p) { \533closeFunction(ptr); \534ptr=p; \535} \536}537#else538#define U_DEFINE_LOCAL_OPEN_POINTER(LocalPointerClassName, Type, closeFunction) \539class LocalPointerClassName : public LocalPointerBase<Type> { \540public: \541using LocalPointerBase<Type>::operator*; \542using LocalPointerBase<Type>::operator->; \543explicit LocalPointerClassName(Type *p=NULL) : LocalPointerBase<Type>(p) {} \544~LocalPointerClassName() { closeFunction(ptr); } \545LocalPointerClassName &moveFrom(LocalPointerClassName &src) U_NOEXCEPT { \546closeFunction(ptr); \547LocalPointerBase<Type>::ptr=src.ptr; \548src.ptr=NULL; \549return *this; \550} \551void swap(LocalPointerClassName &other) U_NOEXCEPT { \552Type *temp=LocalPointerBase<Type>::ptr; \553LocalPointerBase<Type>::ptr=other.ptr; \554other.ptr=temp; \555} \556friend inline void swap(LocalPointerClassName &p1, LocalPointerClassName &p2) U_NOEXCEPT { \557p1.swap(p2); \558} \559void adoptInstead(Type *p) { \560closeFunction(ptr); \561ptr=p; \562} \563}564#endif565566U_NAMESPACE_END567568#endif /* U_SHOW_CPLUSPLUS_API */569#endif /* __LOCALPOINTER_H__ */570571572