|
ICU 73.2
73.2
|
00001 // © 2016 and later: Unicode, Inc. and others. 00002 // License & terms of use: http://www.unicode.org/copyright.html 00003 /* 00004 ******************************************************************************* 00005 * 00006 * Copyright (C) 2009-2016, International Business Machines 00007 * Corporation and others. All Rights Reserved. 00008 * 00009 ******************************************************************************* 00010 * file name: localpointer.h 00011 * encoding: UTF-8 00012 * tab size: 8 (not used) 00013 * indentation:4 00014 * 00015 * created on: 2009nov13 00016 * created by: Markus W. Scherer 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 // No heap allocation. Use only on the stack. 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=nullptr) : ptr(p) {} 00088 ~LocalPointerBase() { /* delete ptr; */ } 00094 UBool isNull() const { return ptr==nullptr; } 00100 UBool isValid() const { return ptr!=nullptr; } 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=nullptr; 00144 return p; 00145 } 00153 void adoptInstead(T *p) { 00154 // delete ptr; 00155 ptr=p; 00156 } 00157 protected: 00162 T *ptr; 00163 private: 00164 // No comparison operators with other LocalPointerBases. 00165 bool operator==(const LocalPointerBase<T> &other); 00166 bool operator!=(const LocalPointerBase<T> &other); 00167 // No ownership sharing: No copy constructor, no assignment operator. 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=nullptr) : LocalPointerBase<T>(p) {} 00214 LocalPointer(T *p, UErrorCode &errorCode) : LocalPointerBase<T>(p) { 00215 if(p==nullptr && U_SUCCESS(errorCode)) { 00216 errorCode=U_MEMORY_ALLOCATION_ERROR; 00217 } 00218 } 00224 LocalPointer(LocalPointer<T> &&src) noexcept : LocalPointerBase<T>(src.ptr) { 00225 src.ptr=nullptr; 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) noexcept { 00256 delete LocalPointerBase<T>::ptr; 00257 LocalPointerBase<T>::ptr=src.ptr; 00258 src.ptr=nullptr; 00259 return *this; 00260 } 00261 00270 LocalPointer<T> &operator=(std::unique_ptr<T> &&p) noexcept { 00271 adoptInstead(p.release()); 00272 return *this; 00273 } 00274 00280 void swap(LocalPointer<T> &other) 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) 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==nullptr) { 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=nullptr) : LocalPointerBase<T>(p) {} 00389 LocalArray(T *p, UErrorCode &errorCode) : LocalPointerBase<T>(p) { 00390 if(p==nullptr && U_SUCCESS(errorCode)) { 00391 errorCode=U_MEMORY_ALLOCATION_ERROR; 00392 } 00393 } 00399 LocalArray(LocalArray<T> &&src) noexcept : LocalPointerBase<T>(src.ptr) { 00400 src.ptr=nullptr; 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) noexcept { 00431 delete[] LocalPointerBase<T>::ptr; 00432 LocalPointerBase<T>::ptr=src.ptr; 00433 src.ptr=nullptr; 00434 return *this; 00435 } 00436 00445 LocalArray<T> &operator=(std::unique_ptr<T[]> &&p) noexcept { 00446 adoptInstead(p.release()); 00447 return *this; 00448 } 00449 00455 void swap(LocalArray<T> &other) 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) 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==nullptr) { 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=nullptr) : LocalPointerBase<Type>(p) {} \ 00556 LocalPointerClassName(LocalPointerClassName &&src) noexcept \ 00557 : LocalPointerBase<Type>(src.ptr) { \ 00558 src.ptr=nullptr; \ 00559 } \ 00560 /* TODO: Be agnostic of the deleter function signature from the user-provided std::unique_ptr? */ \ 00561 explicit LocalPointerClassName(std::unique_ptr<Type, decltype(&closeFunction)> &&p) \ 00562 : LocalPointerBase<Type>(p.release()) {} \ 00563 ~LocalPointerClassName() { if (ptr != nullptr) { closeFunction(ptr); } } \ 00564 LocalPointerClassName &operator=(LocalPointerClassName &&src) noexcept { \ 00565 if (ptr != nullptr) { closeFunction(ptr); } \ 00566 LocalPointerBase<Type>::ptr=src.ptr; \ 00567 src.ptr=nullptr; \ 00568 return *this; \ 00569 } \ 00570 /* TODO: Be agnostic of the deleter function signature from the user-provided std::unique_ptr? */ \ 00571 LocalPointerClassName &operator=(std::unique_ptr<Type, decltype(&closeFunction)> &&p) { \ 00572 adoptInstead(p.release()); \ 00573 return *this; \ 00574 } \ 00575 void swap(LocalPointerClassName &other) 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) noexcept { \ 00581 p1.swap(p2); \ 00582 } \ 00583 void adoptInstead(Type *p) { \ 00584 if (ptr != nullptr) { 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 /* U_SHOW_CPLUSPLUS_API */ 00595 #endif /* __LOCALPOINTER_H__ */
1.7.6.1