00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef __LOCALPOINTER_H__
00018 #define __LOCALPOINTER_H__
00019
00039 #include "unicode/utypes.h"
00040
00041 #if U_SHOW_CPLUSPLUS_API
00042
00043 U_NAMESPACE_BEGIN
00044
00063 template<typename T>
00064 class LocalPointerBase {
00065 public:
00071 explicit LocalPointerBase(T *p=NULL) : ptr(p) {}
00077 ~LocalPointerBase() { }
00083 UBool isNull() const { return ptr==NULL; }
00089 UBool isValid() const { return ptr!=NULL; }
00097 bool operator==(const T *other) const { return ptr==other; }
00105 bool operator!=(const T *other) const { return ptr!=other; }
00111 T *getAlias() const { return ptr; }
00117 T &operator*() const { return *ptr; }
00123 T *operator->() const { return ptr; }
00130 T *orphan() {
00131 T *p=ptr;
00132 ptr=NULL;
00133 return p;
00134 }
00142 void adoptInstead(T *p) {
00143
00144 ptr=p;
00145 }
00146 protected:
00151 T *ptr;
00152 private:
00153
00154 bool operator==(const LocalPointerBase<T> &other);
00155 bool operator!=(const LocalPointerBase<T> &other);
00156
00157 LocalPointerBase(const LocalPointerBase<T> &other);
00158 void operator=(const LocalPointerBase<T> &other);
00159
00160 static void * U_EXPORT2 operator new(size_t size);
00161 static void * U_EXPORT2 operator new[](size_t size);
00162 #if U_HAVE_PLACEMENT_NEW
00163 static void * U_EXPORT2 operator new(size_t, void *ptr);
00164 #endif
00165 };
00166
00185 template<typename T>
00186 class LocalPointer : public LocalPointerBase<T> {
00187 public:
00188 using LocalPointerBase<T>::operator*;
00189 using LocalPointerBase<T>::operator->;
00195 explicit LocalPointer(T *p=NULL) : LocalPointerBase<T>(p) {}
00209 LocalPointer(T *p, UErrorCode &errorCode) : LocalPointerBase<T>(p) {
00210 if(p==NULL && U_SUCCESS(errorCode)) {
00211 errorCode=U_MEMORY_ALLOCATION_ERROR;
00212 }
00213 }
00214 #ifndef U_HIDE_DRAFT_API
00215 #if U_HAVE_RVALUE_REFERENCES
00216
00221 LocalPointer(LocalPointer<T> &&src) U_NOEXCEPT : LocalPointerBase<T>(src.ptr) {
00222 src.ptr=NULL;
00223 }
00224 #endif
00225 #endif
00226
00230 ~LocalPointer() {
00231 delete LocalPointerBase<T>::ptr;
00232 }
00233 #ifndef U_HIDE_DRAFT_API
00234 #if U_HAVE_RVALUE_REFERENCES
00235
00242 LocalPointer<T> &operator=(LocalPointer<T> &&src) U_NOEXCEPT {
00243 return moveFrom(src);
00244 }
00245 #endif
00246
00255 LocalPointer<T> &moveFrom(LocalPointer<T> &src) U_NOEXCEPT {
00256 delete LocalPointerBase<T>::ptr;
00257 LocalPointerBase<T>::ptr=src.ptr;
00258 src.ptr=NULL;
00259 return *this;
00260 }
00266 void swap(LocalPointer<T> &other) U_NOEXCEPT {
00267 T *temp=LocalPointerBase<T>::ptr;
00268 LocalPointerBase<T>::ptr=other.ptr;
00269 other.ptr=temp;
00270 }
00271 #endif
00272
00278 friend inline void swap(LocalPointer<T> &p1, LocalPointer<T> &p2) U_NOEXCEPT {
00279 p1.swap(p2);
00280 }
00287 void adoptInstead(T *p) {
00288 delete LocalPointerBase<T>::ptr;
00289 LocalPointerBase<T>::ptr=p;
00290 }
00306 void adoptInsteadAndCheckErrorCode(T *p, UErrorCode &errorCode) {
00307 if(U_SUCCESS(errorCode)) {
00308 delete LocalPointerBase<T>::ptr;
00309 LocalPointerBase<T>::ptr=p;
00310 if(p==NULL) {
00311 errorCode=U_MEMORY_ALLOCATION_ERROR;
00312 }
00313 } else {
00314 delete p;
00315 }
00316 }
00317 };
00318
00337 template<typename T>
00338 class LocalArray : public LocalPointerBase<T> {
00339 public:
00340 using LocalPointerBase<T>::operator*;
00341 using LocalPointerBase<T>::operator->;
00347 explicit LocalArray(T *p=NULL) : LocalPointerBase<T>(p) {}
00348 #ifndef U_HIDE_DRAFT_API
00349
00362 LocalArray(T *p, UErrorCode &errorCode) : LocalPointerBase<T>(p) {
00363 if(p==NULL && U_SUCCESS(errorCode)) {
00364 errorCode=U_MEMORY_ALLOCATION_ERROR;
00365 }
00366 }
00367 #if U_HAVE_RVALUE_REFERENCES
00368
00373 LocalArray(LocalArray<T> &&src) U_NOEXCEPT : LocalPointerBase<T>(src.ptr) {
00374 src.ptr=NULL;
00375 }
00376 #endif
00377 #endif
00378
00382 ~LocalArray() {
00383 delete[] LocalPointerBase<T>::ptr;
00384 }
00385 #ifndef U_HIDE_DRAFT_API
00386 #if U_HAVE_RVALUE_REFERENCES
00387
00394 LocalArray<T> &operator=(LocalArray<T> &&src) U_NOEXCEPT {
00395 return moveFrom(src);
00396 }
00397 #endif
00398
00407 LocalArray<T> &moveFrom(LocalArray<T> &src) U_NOEXCEPT {
00408 delete[] LocalPointerBase<T>::ptr;
00409 LocalPointerBase<T>::ptr=src.ptr;
00410 src.ptr=NULL;
00411 return *this;
00412 }
00418 void swap(LocalArray<T> &other) U_NOEXCEPT {
00419 T *temp=LocalPointerBase<T>::ptr;
00420 LocalPointerBase<T>::ptr=other.ptr;
00421 other.ptr=temp;
00422 }
00423 #endif
00424
00430 friend inline void swap(LocalArray<T> &p1, LocalArray<T> &p2) U_NOEXCEPT {
00431 p1.swap(p2);
00432 }
00439 void adoptInstead(T *p) {
00440 delete[] LocalPointerBase<T>::ptr;
00441 LocalPointerBase<T>::ptr=p;
00442 }
00443 #ifndef U_HIDE_DRAFT_API
00444
00459 void adoptInsteadAndCheckErrorCode(T *p, UErrorCode &errorCode) {
00460 if(U_SUCCESS(errorCode)) {
00461 delete[] LocalPointerBase<T>::ptr;
00462 LocalPointerBase<T>::ptr=p;
00463 if(p==NULL) {
00464 errorCode=U_MEMORY_ALLOCATION_ERROR;
00465 }
00466 } else {
00467 delete[] p;
00468 }
00469 }
00470 #endif
00471
00478 T &operator[](ptrdiff_t i) const { return LocalPointerBase<T>::ptr[i]; }
00479 };
00480
00504 #if U_HAVE_RVALUE_REFERENCES
00505 #define U_DEFINE_LOCAL_OPEN_POINTER(LocalPointerClassName, Type, closeFunction) \
00506 class LocalPointerClassName : public LocalPointerBase<Type> { \
00507 public: \
00508 using LocalPointerBase<Type>::operator*; \
00509 using LocalPointerBase<Type>::operator->; \
00510 explicit LocalPointerClassName(Type *p=NULL) : LocalPointerBase<Type>(p) {} \
00511 LocalPointerClassName(LocalPointerClassName &&src) U_NOEXCEPT \
00512 : LocalPointerBase<Type>(src.ptr) { \
00513 src.ptr=NULL; \
00514 } \
00515 ~LocalPointerClassName() { closeFunction(ptr); } \
00516 LocalPointerClassName &operator=(LocalPointerClassName &&src) U_NOEXCEPT { \
00517 return moveFrom(src); \
00518 } \
00519 LocalPointerClassName &moveFrom(LocalPointerClassName &src) U_NOEXCEPT { \
00520 closeFunction(ptr); \
00521 LocalPointerBase<Type>::ptr=src.ptr; \
00522 src.ptr=NULL; \
00523 return *this; \
00524 } \
00525 void swap(LocalPointerClassName &other) U_NOEXCEPT { \
00526 Type *temp=LocalPointerBase<Type>::ptr; \
00527 LocalPointerBase<Type>::ptr=other.ptr; \
00528 other.ptr=temp; \
00529 } \
00530 friend inline void swap(LocalPointerClassName &p1, LocalPointerClassName &p2) U_NOEXCEPT { \
00531 p1.swap(p2); \
00532 } \
00533 void adoptInstead(Type *p) { \
00534 closeFunction(ptr); \
00535 ptr=p; \
00536 } \
00537 }
00538 #else
00539 #define U_DEFINE_LOCAL_OPEN_POINTER(LocalPointerClassName, Type, closeFunction) \
00540 class LocalPointerClassName : public LocalPointerBase<Type> { \
00541 public: \
00542 using LocalPointerBase<Type>::operator*; \
00543 using LocalPointerBase<Type>::operator->; \
00544 explicit LocalPointerClassName(Type *p=NULL) : LocalPointerBase<Type>(p) {} \
00545 ~LocalPointerClassName() { closeFunction(ptr); } \
00546 LocalPointerClassName &moveFrom(LocalPointerClassName &src) U_NOEXCEPT { \
00547 closeFunction(ptr); \
00548 LocalPointerBase<Type>::ptr=src.ptr; \
00549 src.ptr=NULL; \
00550 return *this; \
00551 } \
00552 void swap(LocalPointerClassName &other) U_NOEXCEPT { \
00553 Type *temp=LocalPointerBase<Type>::ptr; \
00554 LocalPointerBase<Type>::ptr=other.ptr; \
00555 other.ptr=temp; \
00556 } \
00557 friend inline void swap(LocalPointerClassName &p1, LocalPointerClassName &p2) U_NOEXCEPT { \
00558 p1.swap(p2); \
00559 } \
00560 void adoptInstead(Type *p) { \
00561 closeFunction(ptr); \
00562 ptr=p; \
00563 } \
00564 }
00565 #endif
00566
00567 U_NAMESPACE_END
00568
00569 #endif
00570 #endif