Path: blob/jdk8u272-b10-aarch32-20201026/jdk/src/share/native/common/unicode/localpointer.h
48773 views
// © 2016 and later: Unicode, Inc. and others.1// License & terms of use: http://www.unicode.org/copyright.html2/*3*******************************************************************************4*5* Copyright (C) 2009-2016, International Business Machines6* Corporation and others. All Rights Reserved.7*8*******************************************************************************9* file name: localpointer.h10* encoding: UTF-811* tab size: 8 (not used)12* indentation:413*14* created on: 2009nov1315* created by: Markus W. Scherer16*/1718#ifndef __LOCALPOINTER_H__19#define __LOCALPOINTER_H__2021/**22* \file23* \brief C++ API: "Smart pointers" for use with and in ICU4C C++ code.24*25* These classes are inspired by26* - std::auto_ptr27* - boost::scoped_ptr & boost::scoped_array28* - Taligent Safe Pointers (TOnlyPointerTo)29*30* but none of those provide for all of the goals for ICU smart pointers:31* - Smart pointer owns the object and releases it when it goes out of scope.32* - No transfer of ownership via copy/assignment to reduce misuse. Simpler & more robust.33* - ICU-compatible: No exceptions.34* - Need to be able to orphan/release the pointer and its ownership.35* - Need variants for normal C++ object pointers, C++ arrays, and ICU C service objects.36*37* For details see http://site.icu-project.org/design/cpp/scoped_ptr38*/3940#include "unicode/utypes.h"4142#if U_SHOW_CPLUSPLUS_API4344#include <memory>4546U_NAMESPACE_BEGIN4748/**49* "Smart pointer" base class; do not use directly: use LocalPointer etc.50*51* Base class for smart pointer classes that do not throw exceptions.52*53* Do not use this base class directly, since it does not delete its pointer.54* A subclass must implement methods that delete the pointer:55* Destructor and adoptInstead().56*57* There is no operator T *() provided because the programmer must decide58* whether to use getAlias() (without transfer of ownership) or orphan()59* (with transfer of ownership and NULLing of the pointer).60*61* @see LocalPointer62* @see LocalArray63* @see U_DEFINE_LOCAL_OPEN_POINTER64* @stable ICU 4.465*/66template<typename T>67class LocalPointerBase {68public:69// No heap allocation. Use only on the stack.70static void* U_EXPORT2 operator new(size_t) = delete;71static void* U_EXPORT2 operator new[](size_t) = delete;72#if U_HAVE_PLACEMENT_NEW73static void* U_EXPORT2 operator new(size_t, void*) = delete;74#endif7576/**77* Constructor takes ownership.78* @param p simple pointer to an object that is adopted79* @stable ICU 4.480*/81explicit LocalPointerBase(T *p=NULL) : ptr(p) {}82/**83* Destructor deletes the object it owns.84* Subclass must override: Base class does nothing.85* @stable ICU 4.486*/87~LocalPointerBase() { /* delete ptr; */ }88/**89* NULL check.90* @return TRUE if ==NULL91* @stable ICU 4.492*/93UBool isNull() const { return ptr==NULL; }94/**95* NULL check.96* @return TRUE if !=NULL97* @stable ICU 4.498*/99UBool isValid() const { return ptr!=NULL; }100/**101* Comparison with a simple pointer, so that existing code102* with ==NULL need not be changed.103* @param other simple pointer for comparison104* @return true if this pointer value equals other105* @stable ICU 4.4106*/107bool operator==(const T *other) const { return ptr==other; }108/**109* Comparison with a simple pointer, so that existing code110* with !=NULL need not be changed.111* @param other simple pointer for comparison112* @return true if this pointer value differs from other113* @stable ICU 4.4114*/115bool operator!=(const T *other) const { return ptr!=other; }116/**117* Access without ownership change.118* @return the pointer value119* @stable ICU 4.4120*/121T *getAlias() const { return ptr; }122/**123* Access without ownership change.124* @return the pointer value as a reference125* @stable ICU 4.4126*/127T &operator*() const { return *ptr; }128/**129* Access without ownership change.130* @return the pointer value131* @stable ICU 4.4132*/133T *operator->() const { return ptr; }134/**135* Gives up ownership; the internal pointer becomes NULL.136* @return the pointer value;137* caller becomes responsible for deleting the object138* @stable ICU 4.4139*/140T *orphan() {141T *p=ptr;142ptr=NULL;143return p;144}145/**146* Deletes the object it owns,147* and adopts (takes ownership of) the one passed in.148* Subclass must override: Base class does not delete the object.149* @param p simple pointer to an object that is adopted150* @stable ICU 4.4151*/152void adoptInstead(T *p) {153// delete ptr;154ptr=p;155}156protected:157/**158* Actual pointer.159* @internal160*/161T *ptr;162private:163// No comparison operators with other LocalPointerBases.164bool operator==(const LocalPointerBase<T> &other);165bool operator!=(const LocalPointerBase<T> &other);166// No ownership sharing: No copy constructor, no assignment operator.167LocalPointerBase(const LocalPointerBase<T> &other);168void operator=(const LocalPointerBase<T> &other);169};170171/**172* "Smart pointer" class, deletes objects via the standard C++ delete operator.173* For most methods see the LocalPointerBase base class.174*175* Usage example:176* \code177* LocalPointer<UnicodeString> s(new UnicodeString((UChar32)0x50005));178* int32_t length=s->length(); // 2179* char16_t lead=s->charAt(0); // 0xd900180* if(some condition) { return; } // no need to explicitly delete the pointer181* s.adoptInstead(new UnicodeString((char16_t)0xfffc));182* length=s->length(); // 1183* // no need to explicitly delete the pointer184* \endcode185*186* @see LocalPointerBase187* @stable ICU 4.4188*/189template<typename T>190class LocalPointer : public LocalPointerBase<T> {191public:192using LocalPointerBase<T>::operator*;193using LocalPointerBase<T>::operator->;194/**195* Constructor takes ownership.196* @param p simple pointer to an object that is adopted197* @stable ICU 4.4198*/199explicit LocalPointer(T *p=NULL) : LocalPointerBase<T>(p) {}200/**201* Constructor takes ownership and reports an error if NULL.202*203* This constructor is intended to be used with other-class constructors204* that may report a failure UErrorCode,205* so that callers need to check only for U_FAILURE(errorCode)206* and not also separately for isNull().207*208* @param p simple pointer to an object that is adopted209* @param errorCode in/out UErrorCode, set to U_MEMORY_ALLOCATION_ERROR210* if p==NULL and no other failure code had been set211* @stable ICU 55212*/213LocalPointer(T *p, UErrorCode &errorCode) : LocalPointerBase<T>(p) {214if(p==NULL && U_SUCCESS(errorCode)) {215errorCode=U_MEMORY_ALLOCATION_ERROR;216}217}218/**219* Move constructor, leaves src with isNull().220* @param src source smart pointer221* @stable ICU 56222*/223LocalPointer(LocalPointer<T> &&src) U_NOEXCEPT : LocalPointerBase<T>(src.ptr) {224src.ptr=NULL;225}226227#ifndef U_HIDE_DRAFT_API228/**229* Constructs a LocalPointer from a C++11 std::unique_ptr.230* The LocalPointer steals the object owned by the std::unique_ptr.231*232* This constructor works via move semantics. If your std::unique_ptr is233* in a local variable, you must use std::move.234*235* @param p The std::unique_ptr from which the pointer will be stolen.236* @draft ICU 64237*/238explicit LocalPointer(std::unique_ptr<T> &&p)239: LocalPointerBase<T>(p.release()) {}240#endif /* U_HIDE_DRAFT_API */241242/**243* Destructor deletes the object it owns.244* @stable ICU 4.4245*/246~LocalPointer() {247delete LocalPointerBase<T>::ptr;248}249/**250* Move assignment operator, leaves src with isNull().251* The behavior is undefined if *this and src are the same object.252* @param src source smart pointer253* @return *this254* @stable ICU 56255*/256LocalPointer<T> &operator=(LocalPointer<T> &&src) U_NOEXCEPT {257delete LocalPointerBase<T>::ptr;258LocalPointerBase<T>::ptr=src.ptr;259src.ptr=NULL;260return *this;261}262263#ifndef U_HIDE_DRAFT_API264/**265* Move-assign from an std::unique_ptr to this LocalPointer.266* Steals the pointer from the std::unique_ptr.267*268* @param p The std::unique_ptr from which the pointer will be stolen.269* @return *this270* @draft ICU 64271*/272LocalPointer<T> &operator=(std::unique_ptr<T> &&p) U_NOEXCEPT {273adoptInstead(p.release());274return *this;275}276#endif /* U_HIDE_DRAFT_API */277278/**279* Swap pointers.280* @param other other smart pointer281* @stable ICU 56282*/283void swap(LocalPointer<T> &other) U_NOEXCEPT {284T *temp=LocalPointerBase<T>::ptr;285LocalPointerBase<T>::ptr=other.ptr;286other.ptr=temp;287}288/**289* Non-member LocalPointer swap function.290* @param p1 will get p2's pointer291* @param p2 will get p1's pointer292* @stable ICU 56293*/294friend inline void swap(LocalPointer<T> &p1, LocalPointer<T> &p2) U_NOEXCEPT {295p1.swap(p2);296}297/**298* Deletes the object it owns,299* and adopts (takes ownership of) the one passed in.300* @param p simple pointer to an object that is adopted301* @stable ICU 4.4302*/303void adoptInstead(T *p) {304delete LocalPointerBase<T>::ptr;305LocalPointerBase<T>::ptr=p;306}307/**308* Deletes the object it owns,309* and adopts (takes ownership of) the one passed in.310*311* If U_FAILURE(errorCode), then the current object is retained and the new one deleted.312*313* If U_SUCCESS(errorCode) but the input pointer is NULL,314* then U_MEMORY_ALLOCATION_ERROR is set,315* the current object is deleted, and NULL is set.316*317* @param p simple pointer to an object that is adopted318* @param errorCode in/out UErrorCode, set to U_MEMORY_ALLOCATION_ERROR319* if p==NULL and no other failure code had been set320* @stable ICU 55321*/322void adoptInsteadAndCheckErrorCode(T *p, UErrorCode &errorCode) {323if(U_SUCCESS(errorCode)) {324delete LocalPointerBase<T>::ptr;325LocalPointerBase<T>::ptr=p;326if(p==NULL) {327errorCode=U_MEMORY_ALLOCATION_ERROR;328}329} else {330delete p;331}332}333334#ifndef U_HIDE_DRAFT_API335/**336* Conversion operator to a C++11 std::unique_ptr.337* Disowns the object and gives it to the returned std::unique_ptr.338*339* This operator works via move semantics. If your LocalPointer is340* in a local variable, you must use std::move.341*342* @return An std::unique_ptr owning the pointer previously owned by this343* icu::LocalPointer.344* @draft ICU 64345*/346operator std::unique_ptr<T> () && {347return std::unique_ptr<T>(LocalPointerBase<T>::orphan());348}349#endif /* U_HIDE_DRAFT_API */350};351352/**353* "Smart pointer" class, deletes objects via the C++ array delete[] operator.354* For most methods see the LocalPointerBase base class.355* Adds operator[] for array item access.356*357* Usage example:358* \code359* LocalArray<UnicodeString> a(new UnicodeString[2]);360* a[0].append((char16_t)0x61);361* if(some condition) { return; } // no need to explicitly delete the array362* a.adoptInstead(new UnicodeString[4]);363* a[3].append((char16_t)0x62).append((char16_t)0x63).reverse();364* // no need to explicitly delete the array365* \endcode366*367* @see LocalPointerBase368* @stable ICU 4.4369*/370template<typename T>371class LocalArray : public LocalPointerBase<T> {372public:373using LocalPointerBase<T>::operator*;374using LocalPointerBase<T>::operator->;375/**376* Constructor takes ownership.377* @param p simple pointer to an array of T objects that is adopted378* @stable ICU 4.4379*/380explicit LocalArray(T *p=NULL) : LocalPointerBase<T>(p) {}381/**382* Constructor takes ownership and reports an error if NULL.383*384* This constructor is intended to be used with other-class constructors385* that may report a failure UErrorCode,386* so that callers need to check only for U_FAILURE(errorCode)387* and not also separately for isNull().388*389* @param p simple pointer to an array of T objects that is adopted390* @param errorCode in/out UErrorCode, set to U_MEMORY_ALLOCATION_ERROR391* if p==NULL and no other failure code had been set392* @stable ICU 56393*/394LocalArray(T *p, UErrorCode &errorCode) : LocalPointerBase<T>(p) {395if(p==NULL && U_SUCCESS(errorCode)) {396errorCode=U_MEMORY_ALLOCATION_ERROR;397}398}399/**400* Move constructor, leaves src with isNull().401* @param src source smart pointer402* @stable ICU 56403*/404LocalArray(LocalArray<T> &&src) U_NOEXCEPT : LocalPointerBase<T>(src.ptr) {405src.ptr=NULL;406}407408#ifndef U_HIDE_DRAFT_API409/**410* Constructs a LocalArray from a C++11 std::unique_ptr of an array type.411* The LocalPointer steals the array owned by the std::unique_ptr.412*413* This constructor works via move semantics. If your std::unique_ptr is414* in a local variable, you must use std::move.415*416* @param p The std::unique_ptr from which the array will be stolen.417* @draft ICU 64418*/419explicit LocalArray(std::unique_ptr<T[]> &&p)420: LocalPointerBase<T>(p.release()) {}421#endif /* U_HIDE_DRAFT_API */422423/**424* Destructor deletes the array it owns.425* @stable ICU 4.4426*/427~LocalArray() {428delete[] LocalPointerBase<T>::ptr;429}430/**431* Move assignment operator, leaves src with isNull().432* The behavior is undefined if *this and src are the same object.433* @param src source smart pointer434* @return *this435* @stable ICU 56436*/437LocalArray<T> &operator=(LocalArray<T> &&src) U_NOEXCEPT {438delete[] LocalPointerBase<T>::ptr;439LocalPointerBase<T>::ptr=src.ptr;440src.ptr=NULL;441return *this;442}443444#ifndef U_HIDE_DRAFT_API445/**446* Move-assign from an std::unique_ptr to this LocalPointer.447* Steals the array from the std::unique_ptr.448*449* @param p The std::unique_ptr from which the array will be stolen.450* @return *this451* @draft ICU 64452*/453LocalArray<T> &operator=(std::unique_ptr<T[]> &&p) U_NOEXCEPT {454adoptInstead(p.release());455return *this;456}457#endif /* U_HIDE_DRAFT_API */458459/**460* Swap pointers.461* @param other other smart pointer462* @stable ICU 56463*/464void swap(LocalArray<T> &other) U_NOEXCEPT {465T *temp=LocalPointerBase<T>::ptr;466LocalPointerBase<T>::ptr=other.ptr;467other.ptr=temp;468}469/**470* Non-member LocalArray swap function.471* @param p1 will get p2's pointer472* @param p2 will get p1's pointer473* @stable ICU 56474*/475friend inline void swap(LocalArray<T> &p1, LocalArray<T> &p2) U_NOEXCEPT {476p1.swap(p2);477}478/**479* Deletes the array it owns,480* and adopts (takes ownership of) the one passed in.481* @param p simple pointer to an array of T objects that is adopted482* @stable ICU 4.4483*/484void adoptInstead(T *p) {485delete[] LocalPointerBase<T>::ptr;486LocalPointerBase<T>::ptr=p;487}488/**489* Deletes the array it owns,490* and adopts (takes ownership of) the one passed in.491*492* If U_FAILURE(errorCode), then the current array is retained and the new one deleted.493*494* If U_SUCCESS(errorCode) but the input pointer is NULL,495* then U_MEMORY_ALLOCATION_ERROR is set,496* the current array is deleted, and NULL is set.497*498* @param p simple pointer to an array of T objects that is adopted499* @param errorCode in/out UErrorCode, set to U_MEMORY_ALLOCATION_ERROR500* if p==NULL and no other failure code had been set501* @stable ICU 56502*/503void adoptInsteadAndCheckErrorCode(T *p, UErrorCode &errorCode) {504if(U_SUCCESS(errorCode)) {505delete[] LocalPointerBase<T>::ptr;506LocalPointerBase<T>::ptr=p;507if(p==NULL) {508errorCode=U_MEMORY_ALLOCATION_ERROR;509}510} else {511delete[] p;512}513}514/**515* Array item access (writable).516* No index bounds check.517* @param i array index518* @return reference to the array item519* @stable ICU 4.4520*/521T &operator[](ptrdiff_t i) const { return LocalPointerBase<T>::ptr[i]; }522523#ifndef U_HIDE_DRAFT_API524/**525* Conversion operator to a C++11 std::unique_ptr.526* Disowns the object and gives it to the returned std::unique_ptr.527*528* This operator works via move semantics. If your LocalPointer is529* in a local variable, you must use std::move.530*531* @return An std::unique_ptr owning the pointer previously owned by this532* icu::LocalPointer.533* @draft ICU 64534*/535operator std::unique_ptr<T[]> () && {536return std::unique_ptr<T[]>(LocalPointerBase<T>::orphan());537}538#endif /* U_HIDE_DRAFT_API */539};540541/**542* \def U_DEFINE_LOCAL_OPEN_POINTER543* "Smart pointer" definition macro, deletes objects via the closeFunction.544* Defines a subclass of LocalPointerBase which works just545* like LocalPointer<Type> except that this subclass will use the closeFunction546* rather than the C++ delete operator.547*548* Usage example:549* \code550* LocalUCaseMapPointer csm(ucasemap_open(localeID, options, &errorCode));551* utf8OutLength=ucasemap_utf8ToLower(csm.getAlias(),552* utf8Out, (int32_t)sizeof(utf8Out),553* utf8In, utf8InLength, &errorCode);554* if(U_FAILURE(errorCode)) { return; } // no need to explicitly delete the UCaseMap555* \endcode556*557* @see LocalPointerBase558* @see LocalPointer559* @stable ICU 4.4560*/561#define U_DEFINE_LOCAL_OPEN_POINTER(LocalPointerClassName, Type, closeFunction) \562class LocalPointerClassName : public LocalPointerBase<Type> { \563public: \564using LocalPointerBase<Type>::operator*; \565using LocalPointerBase<Type>::operator->; \566explicit LocalPointerClassName(Type *p=NULL) : LocalPointerBase<Type>(p) {} \567LocalPointerClassName(LocalPointerClassName &&src) U_NOEXCEPT \568: LocalPointerBase<Type>(src.ptr) { \569src.ptr=NULL; \570} \571/* TODO: Be agnostic of the deleter function signature from the user-provided std::unique_ptr? */ \572explicit LocalPointerClassName(std::unique_ptr<Type, decltype(&closeFunction)> &&p) \573: LocalPointerBase<Type>(p.release()) {} \574~LocalPointerClassName() { if (ptr != NULL) { closeFunction(ptr); } } \575LocalPointerClassName &operator=(LocalPointerClassName &&src) U_NOEXCEPT { \576if (ptr != NULL) { closeFunction(ptr); } \577LocalPointerBase<Type>::ptr=src.ptr; \578src.ptr=NULL; \579return *this; \580} \581/* TODO: Be agnostic of the deleter function signature from the user-provided std::unique_ptr? */ \582LocalPointerClassName &operator=(std::unique_ptr<Type, decltype(&closeFunction)> &&p) { \583adoptInstead(p.release()); \584return *this; \585} \586void swap(LocalPointerClassName &other) U_NOEXCEPT { \587Type *temp=LocalPointerBase<Type>::ptr; \588LocalPointerBase<Type>::ptr=other.ptr; \589other.ptr=temp; \590} \591friend inline void swap(LocalPointerClassName &p1, LocalPointerClassName &p2) U_NOEXCEPT { \592p1.swap(p2); \593} \594void adoptInstead(Type *p) { \595if (ptr != NULL) { closeFunction(ptr); } \596ptr=p; \597} \598operator std::unique_ptr<Type, decltype(&closeFunction)> () && { \599return std::unique_ptr<Type, decltype(&closeFunction)>(LocalPointerBase<Type>::orphan(), closeFunction); \600} \601}602603U_NAMESPACE_END604605#endif /* U_SHOW_CPLUSPLUS_API */606#endif /* __LOCALPOINTER_H__ */607608609