00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef __LOCALPOINTER_H__
00020 #define __LOCALPOINTER_H__
00021
00041 #include "unicode/utypes.h"
00042
00043 #if U_SHOW_CPLUSPLUS_API
00044
00045 U_NAMESPACE_BEGIN
00046
00065 template<typename T>
00066 class LocalPointerBase {
00067 public:
00073 explicit LocalPointerBase(T *p=NULL) : ptr(p) {}
00079 ~LocalPointerBase() { }
00085 UBool isNull() const { return ptr==NULL; }
00091 UBool isValid() const { return ptr!=NULL; }
00099 bool operator==(const T *other) const { return ptr==other; }
00107 bool operator!=(const T *other) const { return ptr!=other; }
00113 T *getAlias() const { return ptr; }
00119 T &operator*() const { return *ptr; }
00125 T *operator->() const { return ptr; }
00132 T *orphan() {
00133 T *p=ptr;
00134 ptr=NULL;
00135 return p;
00136 }
00144 void adoptInstead(T *p) {
00145
00146 ptr=p;
00147 }
00148 protected:
00153 T *ptr;
00154 private:
00155
00156 bool operator==(const LocalPointerBase<T> &other);
00157 bool operator!=(const LocalPointerBase<T> &other);
00158
00159 LocalPointerBase(const LocalPointerBase<T> &other);
00160 void operator=(const LocalPointerBase<T> &other);
00161
00162 static void * U_EXPORT2 operator new(size_t size);
00163 static void * U_EXPORT2 operator new[](size_t size);
00164 #if U_HAVE_PLACEMENT_NEW
00165 static void * U_EXPORT2 operator new(size_t, void *ptr);
00166 #endif
00167 };
00168
00187 template<typename T>
00188 class LocalPointer : public LocalPointerBase<T> {
00189 public:
00190 using LocalPointerBase<T>::operator*;
00191 using LocalPointerBase<T>::operator->;
00197 explicit LocalPointer(T *p=NULL) : LocalPointerBase<T>(p) {}
00211 LocalPointer(T *p, UErrorCode &errorCode) : LocalPointerBase<T>(p) {
00212 if(p==NULL && U_SUCCESS(errorCode)) {
00213 errorCode=U_MEMORY_ALLOCATION_ERROR;
00214 }
00215 }
00221 LocalPointer(LocalPointer<T> &&src) U_NOEXCEPT : LocalPointerBase<T>(src.ptr) {
00222 src.ptr=NULL;
00223 }
00228 ~LocalPointer() {
00229 delete LocalPointerBase<T>::ptr;
00230 }
00238 LocalPointer<T> &operator=(LocalPointer<T> &&src) U_NOEXCEPT {
00239 return moveFrom(src);
00240 }
00241
00251 LocalPointer<T> &moveFrom(LocalPointer<T> &src) U_NOEXCEPT {
00252 delete LocalPointerBase<T>::ptr;
00253 LocalPointerBase<T>::ptr=src.ptr;
00254 src.ptr=NULL;
00255 return *this;
00256 }
00262 void swap(LocalPointer<T> &other) U_NOEXCEPT {
00263 T *temp=LocalPointerBase<T>::ptr;
00264 LocalPointerBase<T>::ptr=other.ptr;
00265 other.ptr=temp;
00266 }
00273 friend inline void swap(LocalPointer<T> &p1, LocalPointer<T> &p2) U_NOEXCEPT {
00274 p1.swap(p2);
00275 }
00282 void adoptInstead(T *p) {
00283 delete LocalPointerBase<T>::ptr;
00284 LocalPointerBase<T>::ptr=p;
00285 }
00301 void adoptInsteadAndCheckErrorCode(T *p, UErrorCode &errorCode) {
00302 if(U_SUCCESS(errorCode)) {
00303 delete LocalPointerBase<T>::ptr;
00304 LocalPointerBase<T>::ptr=p;
00305 if(p==NULL) {
00306 errorCode=U_MEMORY_ALLOCATION_ERROR;
00307 }
00308 } else {
00309 delete p;
00310 }
00311 }
00312 };
00313
00332 template<typename T>
00333 class LocalArray : public LocalPointerBase<T> {
00334 public:
00335 using LocalPointerBase<T>::operator*;
00336 using LocalPointerBase<T>::operator->;
00342 explicit LocalArray(T *p=NULL) : LocalPointerBase<T>(p) {}
00356 LocalArray(T *p, UErrorCode &errorCode) : LocalPointerBase<T>(p) {
00357 if(p==NULL && U_SUCCESS(errorCode)) {
00358 errorCode=U_MEMORY_ALLOCATION_ERROR;
00359 }
00360 }
00366 LocalArray(LocalArray<T> &&src) U_NOEXCEPT : LocalPointerBase<T>(src.ptr) {
00367 src.ptr=NULL;
00368 }
00373 ~LocalArray() {
00374 delete[] LocalPointerBase<T>::ptr;
00375 }
00383 LocalArray<T> &operator=(LocalArray<T> &&src) U_NOEXCEPT {
00384 return moveFrom(src);
00385 }
00386
00396 LocalArray<T> &moveFrom(LocalArray<T> &src) U_NOEXCEPT {
00397 delete[] LocalPointerBase<T>::ptr;
00398 LocalPointerBase<T>::ptr=src.ptr;
00399 src.ptr=NULL;
00400 return *this;
00401 }
00407 void swap(LocalArray<T> &other) U_NOEXCEPT {
00408 T *temp=LocalPointerBase<T>::ptr;
00409 LocalPointerBase<T>::ptr=other.ptr;
00410 other.ptr=temp;
00411 }
00418 friend inline void swap(LocalArray<T> &p1, LocalArray<T> &p2) U_NOEXCEPT {
00419 p1.swap(p2);
00420 }
00427 void adoptInstead(T *p) {
00428 delete[] LocalPointerBase<T>::ptr;
00429 LocalPointerBase<T>::ptr=p;
00430 }
00446 void adoptInsteadAndCheckErrorCode(T *p, UErrorCode &errorCode) {
00447 if(U_SUCCESS(errorCode)) {
00448 delete[] LocalPointerBase<T>::ptr;
00449 LocalPointerBase<T>::ptr=p;
00450 if(p==NULL) {
00451 errorCode=U_MEMORY_ALLOCATION_ERROR;
00452 }
00453 } else {
00454 delete[] p;
00455 }
00456 }
00464 T &operator[](ptrdiff_t i) const { return LocalPointerBase<T>::ptr[i]; }
00465 };
00466
00487 #define U_DEFINE_LOCAL_OPEN_POINTER(LocalPointerClassName, Type, closeFunction) \
00488 class LocalPointerClassName : public LocalPointerBase<Type> { \
00489 public: \
00490 using LocalPointerBase<Type>::operator*; \
00491 using LocalPointerBase<Type>::operator->; \
00492 explicit LocalPointerClassName(Type *p=NULL) : LocalPointerBase<Type>(p) {} \
00493 LocalPointerClassName(LocalPointerClassName &&src) U_NOEXCEPT \
00494 : LocalPointerBase<Type>(src.ptr) { \
00495 src.ptr=NULL; \
00496 } \
00497 ~LocalPointerClassName() { if (ptr != NULL) { closeFunction(ptr); } } \
00498 LocalPointerClassName &operator=(LocalPointerClassName &&src) U_NOEXCEPT { \
00499 return moveFrom(src); \
00500 } \
00501 LocalPointerClassName &moveFrom(LocalPointerClassName &src) U_NOEXCEPT { \
00502 if (ptr != NULL) { closeFunction(ptr); } \
00503 LocalPointerBase<Type>::ptr=src.ptr; \
00504 src.ptr=NULL; \
00505 return *this; \
00506 } \
00507 void swap(LocalPointerClassName &other) U_NOEXCEPT { \
00508 Type *temp=LocalPointerBase<Type>::ptr; \
00509 LocalPointerBase<Type>::ptr=other.ptr; \
00510 other.ptr=temp; \
00511 } \
00512 friend inline void swap(LocalPointerClassName &p1, LocalPointerClassName &p2) U_NOEXCEPT { \
00513 p1.swap(p2); \
00514 } \
00515 void adoptInstead(Type *p) { \
00516 if (ptr != NULL) { closeFunction(ptr); } \
00517 ptr=p; \
00518 } \
00519 }
00520
00521 U_NAMESPACE_END
00522
00523 #endif
00524 #endif