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
00228 #ifndef U_HIDE_DRAFT_API
00229
00239 explicit LocalPointer(std::unique_ptr<T> &&p)
00240 : LocalPointerBase<T>(p.release()) {}
00241 #endif
00242
00247 ~LocalPointer() {
00248 delete LocalPointerBase<T>::ptr;
00249 }
00257 LocalPointer<T> &operator=(LocalPointer<T> &&src) U_NOEXCEPT {
00258 delete LocalPointerBase<T>::ptr;
00259 LocalPointerBase<T>::ptr=src.ptr;
00260 src.ptr=NULL;
00261 return *this;
00262 }
00263
00264 #ifndef U_HIDE_DRAFT_API
00265
00273 LocalPointer<T> &operator=(std::unique_ptr<T> &&p) U_NOEXCEPT {
00274 adoptInstead(p.release());
00275 return *this;
00276 }
00277 #endif
00278
00284 void swap(LocalPointer<T> &other) U_NOEXCEPT {
00285 T *temp=LocalPointerBase<T>::ptr;
00286 LocalPointerBase<T>::ptr=other.ptr;
00287 other.ptr=temp;
00288 }
00295 friend inline void swap(LocalPointer<T> &p1, LocalPointer<T> &p2) U_NOEXCEPT {
00296 p1.swap(p2);
00297 }
00304 void adoptInstead(T *p) {
00305 delete LocalPointerBase<T>::ptr;
00306 LocalPointerBase<T>::ptr=p;
00307 }
00323 void adoptInsteadAndCheckErrorCode(T *p, UErrorCode &errorCode) {
00324 if(U_SUCCESS(errorCode)) {
00325 delete LocalPointerBase<T>::ptr;
00326 LocalPointerBase<T>::ptr=p;
00327 if(p==NULL) {
00328 errorCode=U_MEMORY_ALLOCATION_ERROR;
00329 }
00330 } else {
00331 delete p;
00332 }
00333 }
00334
00335 #ifndef U_HIDE_DRAFT_API
00336
00347 operator std::unique_ptr<T> () && {
00348 return std::unique_ptr<T>(LocalPointerBase<T>::orphan());
00349 }
00350 #endif
00351 };
00352
00371 template<typename T>
00372 class LocalArray : public LocalPointerBase<T> {
00373 public:
00374 using LocalPointerBase<T>::operator*;
00375 using LocalPointerBase<T>::operator->;
00381 explicit LocalArray(T *p=NULL) : LocalPointerBase<T>(p) {}
00395 LocalArray(T *p, UErrorCode &errorCode) : LocalPointerBase<T>(p) {
00396 if(p==NULL && U_SUCCESS(errorCode)) {
00397 errorCode=U_MEMORY_ALLOCATION_ERROR;
00398 }
00399 }
00405 LocalArray(LocalArray<T> &&src) U_NOEXCEPT : LocalPointerBase<T>(src.ptr) {
00406 src.ptr=NULL;
00407 }
00408
00409 #ifndef U_HIDE_DRAFT_API
00410
00420 explicit LocalArray(std::unique_ptr<T[]> &&p)
00421 : LocalPointerBase<T>(p.release()) {}
00422 #endif
00423
00428 ~LocalArray() {
00429 delete[] LocalPointerBase<T>::ptr;
00430 }
00438 LocalArray<T> &operator=(LocalArray<T> &&src) U_NOEXCEPT {
00439 delete[] LocalPointerBase<T>::ptr;
00440 LocalPointerBase<T>::ptr=src.ptr;
00441 src.ptr=NULL;
00442 return *this;
00443 }
00444
00445 #ifndef U_HIDE_DRAFT_API
00446
00454 LocalArray<T> &operator=(std::unique_ptr<T[]> &&p) U_NOEXCEPT {
00455 adoptInstead(p.release());
00456 return *this;
00457 }
00458 #endif
00459
00465 void swap(LocalArray<T> &other) U_NOEXCEPT {
00466 T *temp=LocalPointerBase<T>::ptr;
00467 LocalPointerBase<T>::ptr=other.ptr;
00468 other.ptr=temp;
00469 }
00476 friend inline void swap(LocalArray<T> &p1, LocalArray<T> &p2) U_NOEXCEPT {
00477 p1.swap(p2);
00478 }
00485 void adoptInstead(T *p) {
00486 delete[] LocalPointerBase<T>::ptr;
00487 LocalPointerBase<T>::ptr=p;
00488 }
00504 void adoptInsteadAndCheckErrorCode(T *p, UErrorCode &errorCode) {
00505 if(U_SUCCESS(errorCode)) {
00506 delete[] LocalPointerBase<T>::ptr;
00507 LocalPointerBase<T>::ptr=p;
00508 if(p==NULL) {
00509 errorCode=U_MEMORY_ALLOCATION_ERROR;
00510 }
00511 } else {
00512 delete[] p;
00513 }
00514 }
00522 T &operator[](ptrdiff_t i) const { return LocalPointerBase<T>::ptr[i]; }
00523
00524 #ifndef U_HIDE_DRAFT_API
00525
00536 operator std::unique_ptr<T[]> () && {
00537 return std::unique_ptr<T[]>(LocalPointerBase<T>::orphan());
00538 }
00539 #endif
00540 };
00541
00562 #define U_DEFINE_LOCAL_OPEN_POINTER(LocalPointerClassName, Type, closeFunction) \
00563 class LocalPointerClassName : public LocalPointerBase<Type> { \
00564 public: \
00565 using LocalPointerBase<Type>::operator*; \
00566 using LocalPointerBase<Type>::operator->; \
00567 explicit LocalPointerClassName(Type *p=NULL) : LocalPointerBase<Type>(p) {} \
00568 LocalPointerClassName(LocalPointerClassName &&src) U_NOEXCEPT \
00569 : LocalPointerBase<Type>(src.ptr) { \
00570 src.ptr=NULL; \
00571 } \
00572 \
00573 explicit LocalPointerClassName(std::unique_ptr<Type, decltype(&closeFunction)> &&p) \
00574 : LocalPointerBase<Type>(p.release()) {} \
00575 ~LocalPointerClassName() { if (ptr != NULL) { closeFunction(ptr); } } \
00576 LocalPointerClassName &operator=(LocalPointerClassName &&src) U_NOEXCEPT { \
00577 if (ptr != NULL) { closeFunction(ptr); } \
00578 LocalPointerBase<Type>::ptr=src.ptr; \
00579 src.ptr=NULL; \
00580 return *this; \
00581 } \
00582 \
00583 LocalPointerClassName &operator=(std::unique_ptr<Type, decltype(&closeFunction)> &&p) { \
00584 adoptInstead(p.release()); \
00585 return *this; \
00586 } \
00587 void swap(LocalPointerClassName &other) U_NOEXCEPT { \
00588 Type *temp=LocalPointerBase<Type>::ptr; \
00589 LocalPointerBase<Type>::ptr=other.ptr; \
00590 other.ptr=temp; \
00591 } \
00592 friend inline void swap(LocalPointerClassName &p1, LocalPointerClassName &p2) U_NOEXCEPT { \
00593 p1.swap(p2); \
00594 } \
00595 void adoptInstead(Type *p) { \
00596 if (ptr != NULL) { closeFunction(ptr); } \
00597 ptr=p; \
00598 } \
00599 operator std::unique_ptr<Type, decltype(&closeFunction)> () && { \
00600 return std::unique_ptr<Type, decltype(&closeFunction)>(LocalPointerBase<Type>::orphan(), closeFunction); \
00601 } \
00602 }
00603
00604 U_NAMESPACE_END
00605
00606 #endif
00607 #endif