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 #include <memory>
00046
00047 U_NAMESPACE_BEGIN
00048
00067 template<typename T>
00068 class LocalPointerBase {
00069 public:
00070
00071 static void* U_EXPORT2 operator new(size_t) = delete;
00072 static void* U_EXPORT2 operator new[](size_t) = delete;
00073 #if U_HAVE_PLACEMENT_NEW
00074 static void* U_EXPORT2 operator new(size_t, void*) = delete;
00075 #endif
00076
00082 explicit LocalPointerBase(T *p=NULL) : ptr(p) {}
00088 ~LocalPointerBase() { }
00094 UBool isNull() const { return ptr==NULL; }
00100 UBool isValid() const { return ptr!=NULL; }
00108 bool operator==(const T *other) const { return ptr==other; }
00116 bool operator!=(const T *other) const { return ptr!=other; }
00122 T *getAlias() const { return ptr; }
00128 T &operator*() const { return *ptr; }
00134 T *operator->() const { return ptr; }
00141 T *orphan() {
00142 T *p=ptr;
00143 ptr=NULL;
00144 return p;
00145 }
00153 void adoptInstead(T *p) {
00154
00155 ptr=p;
00156 }
00157 protected:
00162 T *ptr;
00163 private:
00164
00165 bool operator==(const LocalPointerBase<T> &other);
00166 bool operator!=(const LocalPointerBase<T> &other);
00167
00168 LocalPointerBase(const LocalPointerBase<T> &other);
00169 void operator=(const LocalPointerBase<T> &other);
00170 };
00171
00190 template<typename T>
00191 class LocalPointer : public LocalPointerBase<T> {
00192 public:
00193 using LocalPointerBase<T>::operator*;
00194 using LocalPointerBase<T>::operator->;
00200 explicit LocalPointer(T *p=NULL) : LocalPointerBase<T>(p) {}
00214 LocalPointer(T *p, UErrorCode &errorCode) : LocalPointerBase<T>(p) {
00215 if(p==NULL && U_SUCCESS(errorCode)) {
00216 errorCode=U_MEMORY_ALLOCATION_ERROR;
00217 }
00218 }
00224 LocalPointer(LocalPointer<T> &&src) U_NOEXCEPT : LocalPointerBase<T>(src.ptr) {
00225 src.ptr=NULL;
00226 }
00227
00238 explicit LocalPointer(std::unique_ptr<T> &&p)
00239 : LocalPointerBase<T>(p.release()) {}
00240
00245 ~LocalPointer() {
00246 delete LocalPointerBase<T>::ptr;
00247 }
00255 LocalPointer<T> &operator=(LocalPointer<T> &&src) U_NOEXCEPT {
00256 delete LocalPointerBase<T>::ptr;
00257 LocalPointerBase<T>::ptr=src.ptr;
00258 src.ptr=NULL;
00259 return *this;
00260 }
00261
00270 LocalPointer<T> &operator=(std::unique_ptr<T> &&p) U_NOEXCEPT {
00271 adoptInstead(p.release());
00272 return *this;
00273 }
00274
00280 void swap(LocalPointer<T> &other) U_NOEXCEPT {
00281 T *temp=LocalPointerBase<T>::ptr;
00282 LocalPointerBase<T>::ptr=other.ptr;
00283 other.ptr=temp;
00284 }
00291 friend inline void swap(LocalPointer<T> &p1, LocalPointer<T> &p2) U_NOEXCEPT {
00292 p1.swap(p2);
00293 }
00300 void adoptInstead(T *p) {
00301 delete LocalPointerBase<T>::ptr;
00302 LocalPointerBase<T>::ptr=p;
00303 }
00319 void adoptInsteadAndCheckErrorCode(T *p, UErrorCode &errorCode) {
00320 if(U_SUCCESS(errorCode)) {
00321 delete LocalPointerBase<T>::ptr;
00322 LocalPointerBase<T>::ptr=p;
00323 if(p==NULL) {
00324 errorCode=U_MEMORY_ALLOCATION_ERROR;
00325 }
00326 } else {
00327 delete p;
00328 }
00329 }
00330
00342 operator std::unique_ptr<T> () && {
00343 return std::unique_ptr<T>(LocalPointerBase<T>::orphan());
00344 }
00345 };
00346
00365 template<typename T>
00366 class LocalArray : public LocalPointerBase<T> {
00367 public:
00368 using LocalPointerBase<T>::operator*;
00369 using LocalPointerBase<T>::operator->;
00375 explicit LocalArray(T *p=NULL) : LocalPointerBase<T>(p) {}
00389 LocalArray(T *p, UErrorCode &errorCode) : LocalPointerBase<T>(p) {
00390 if(p==NULL && U_SUCCESS(errorCode)) {
00391 errorCode=U_MEMORY_ALLOCATION_ERROR;
00392 }
00393 }
00399 LocalArray(LocalArray<T> &&src) U_NOEXCEPT : LocalPointerBase<T>(src.ptr) {
00400 src.ptr=NULL;
00401 }
00402
00413 explicit LocalArray(std::unique_ptr<T[]> &&p)
00414 : LocalPointerBase<T>(p.release()) {}
00415
00420 ~LocalArray() {
00421 delete[] LocalPointerBase<T>::ptr;
00422 }
00430 LocalArray<T> &operator=(LocalArray<T> &&src) U_NOEXCEPT {
00431 delete[] LocalPointerBase<T>::ptr;
00432 LocalPointerBase<T>::ptr=src.ptr;
00433 src.ptr=NULL;
00434 return *this;
00435 }
00436
00445 LocalArray<T> &operator=(std::unique_ptr<T[]> &&p) U_NOEXCEPT {
00446 adoptInstead(p.release());
00447 return *this;
00448 }
00449
00455 void swap(LocalArray<T> &other) U_NOEXCEPT {
00456 T *temp=LocalPointerBase<T>::ptr;
00457 LocalPointerBase<T>::ptr=other.ptr;
00458 other.ptr=temp;
00459 }
00466 friend inline void swap(LocalArray<T> &p1, LocalArray<T> &p2) U_NOEXCEPT {
00467 p1.swap(p2);
00468 }
00475 void adoptInstead(T *p) {
00476 delete[] LocalPointerBase<T>::ptr;
00477 LocalPointerBase<T>::ptr=p;
00478 }
00494 void adoptInsteadAndCheckErrorCode(T *p, UErrorCode &errorCode) {
00495 if(U_SUCCESS(errorCode)) {
00496 delete[] LocalPointerBase<T>::ptr;
00497 LocalPointerBase<T>::ptr=p;
00498 if(p==NULL) {
00499 errorCode=U_MEMORY_ALLOCATION_ERROR;
00500 }
00501 } else {
00502 delete[] p;
00503 }
00504 }
00512 T &operator[](ptrdiff_t i) const { return LocalPointerBase<T>::ptr[i]; }
00513
00525 operator std::unique_ptr<T[]> () && {
00526 return std::unique_ptr<T[]>(LocalPointerBase<T>::orphan());
00527 }
00528 };
00529
00550 #define U_DEFINE_LOCAL_OPEN_POINTER(LocalPointerClassName, Type, closeFunction) \
00551 class LocalPointerClassName : public LocalPointerBase<Type> { \
00552 public: \
00553 using LocalPointerBase<Type>::operator*; \
00554 using LocalPointerBase<Type>::operator->; \
00555 explicit LocalPointerClassName(Type *p=NULL) : LocalPointerBase<Type>(p) {} \
00556 LocalPointerClassName(LocalPointerClassName &&src) U_NOEXCEPT \
00557 : LocalPointerBase<Type>(src.ptr) { \
00558 src.ptr=NULL; \
00559 } \
00560 \
00561 explicit LocalPointerClassName(std::unique_ptr<Type, decltype(&closeFunction)> &&p) \
00562 : LocalPointerBase<Type>(p.release()) {} \
00563 ~LocalPointerClassName() { if (ptr != NULL) { closeFunction(ptr); } } \
00564 LocalPointerClassName &operator=(LocalPointerClassName &&src) U_NOEXCEPT { \
00565 if (ptr != NULL) { closeFunction(ptr); } \
00566 LocalPointerBase<Type>::ptr=src.ptr; \
00567 src.ptr=NULL; \
00568 return *this; \
00569 } \
00570 \
00571 LocalPointerClassName &operator=(std::unique_ptr<Type, decltype(&closeFunction)> &&p) { \
00572 adoptInstead(p.release()); \
00573 return *this; \
00574 } \
00575 void swap(LocalPointerClassName &other) U_NOEXCEPT { \
00576 Type *temp=LocalPointerBase<Type>::ptr; \
00577 LocalPointerBase<Type>::ptr=other.ptr; \
00578 other.ptr=temp; \
00579 } \
00580 friend inline void swap(LocalPointerClassName &p1, LocalPointerClassName &p2) U_NOEXCEPT { \
00581 p1.swap(p2); \
00582 } \
00583 void adoptInstead(Type *p) { \
00584 if (ptr != NULL) { closeFunction(ptr); } \
00585 ptr=p; \
00586 } \
00587 operator std::unique_ptr<Type, decltype(&closeFunction)> () && { \
00588 return std::unique_ptr<Type, decltype(&closeFunction)>(LocalPointerBase<Type>::orphan(), closeFunction); \
00589 } \
00590 }
00591
00592 U_NAMESPACE_END
00593
00594 #endif
00595 #endif