udf_ptr.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. #pragma once
  2. #include <util/system/yassert.h> // Y_ASSERT
  3. namespace NYql {
  4. namespace NUdf {
  5. namespace NDetails {
  6. struct TDelete {
  7. template <typename T>
  8. static void DoDelete(T* ptr) {
  9. delete ptr;
  10. }
  11. };
  12. }
  13. ///////////////////////////////////////////////////////////////////////////////
  14. // TUniquePtr
  15. ///////////////////////////////////////////////////////////////////////////////
  16. template <typename T, typename D = NDetails::TDelete>
  17. class TUniquePtr
  18. {
  19. public:
  20. inline TUniquePtr(T* ptr = nullptr)
  21. : Ptr_(ptr)
  22. {
  23. }
  24. inline TUniquePtr(TUniquePtr&& rhs)
  25. : Ptr_(rhs.Release())
  26. {
  27. }
  28. inline TUniquePtr& operator=(TUniquePtr&& rhs) {
  29. if (this != &rhs) {
  30. Reset(rhs.Release());
  31. }
  32. return *this;
  33. }
  34. TUniquePtr(const TUniquePtr& rhs) = delete;
  35. TUniquePtr& operator=(const TUniquePtr& rhs) = delete;
  36. inline ~TUniquePtr() {
  37. DoDestroy();
  38. }
  39. inline T* Release() {
  40. T* tmp = Ptr_;
  41. Ptr_ = nullptr;
  42. return tmp;
  43. }
  44. inline void Reset(T* ptr = nullptr) {
  45. if (Ptr_ != ptr) {
  46. DoDestroy();
  47. Ptr_ = ptr;
  48. }
  49. }
  50. inline void Swap(TUniquePtr& rhs) {
  51. T* tmp = Ptr_;
  52. Ptr_ = rhs.Ptr_;
  53. rhs.Ptr_ = tmp;
  54. }
  55. inline T* Get() const { return Ptr_; }
  56. inline T& operator*() const { return *Ptr_; }
  57. inline T* operator->() const { return Ptr_; }
  58. inline explicit operator bool() const { return Ptr_ != nullptr; }
  59. private:
  60. inline void DoDestroy() {
  61. if (Ptr_)
  62. D::DoDelete(Ptr_);
  63. }
  64. private:
  65. T* Ptr_;
  66. };
  67. ///////////////////////////////////////////////////////////////////////////////
  68. // TRefCountedPtr
  69. ///////////////////////////////////////////////////////////////////////////////
  70. template <class T>
  71. class TDefaultRefCountedPtrOps
  72. {
  73. public:
  74. static inline void Ref(T* t) {
  75. Y_ASSERT(t);
  76. t->Ref();
  77. }
  78. static inline void UnRef(T* t) {
  79. Y_ASSERT(t);
  80. t->UnRef();
  81. }
  82. static inline ui32 RefCount(const T* t) {
  83. Y_ASSERT(t);
  84. return t->RefCount();
  85. }
  86. };
  87. template <typename T, typename Ops = TDefaultRefCountedPtrOps<T>>
  88. class TRefCountedPtr
  89. {
  90. public:
  91. enum AddRef { ADD_REF };
  92. enum StealRef { STEAL_REF };
  93. public:
  94. inline TRefCountedPtr(T* ptr = nullptr)
  95. : Ptr_(ptr)
  96. {
  97. Ref();
  98. }
  99. inline TRefCountedPtr(T* ptr, StealRef)
  100. : Ptr_(ptr)
  101. {
  102. // do not call Ref() on new pointer
  103. }
  104. inline TRefCountedPtr(const TRefCountedPtr& rhs)
  105. : Ptr_(rhs.Ptr_)
  106. {
  107. Ref();
  108. }
  109. inline TRefCountedPtr(TRefCountedPtr&& rhs)
  110. : Ptr_(rhs.Ptr_)
  111. {
  112. rhs.Ptr_ = nullptr;
  113. }
  114. inline TRefCountedPtr& operator=(const TRefCountedPtr& rhs) {
  115. if (this != &rhs) {
  116. UnRef();
  117. Ptr_ = rhs.Ptr_;
  118. Ref();
  119. }
  120. return *this;
  121. }
  122. inline TRefCountedPtr& operator=(TRefCountedPtr&& rhs) {
  123. if (this != &rhs) {
  124. UnRef();
  125. Ptr_ = rhs.Ptr_;
  126. rhs.Ptr_ = nullptr;
  127. }
  128. return *this;
  129. }
  130. inline ~TRefCountedPtr() {
  131. UnRef();
  132. }
  133. inline void Reset(T* ptr = nullptr) {
  134. if (Ptr_ != ptr) {
  135. UnRef();
  136. Ptr_ = ptr;
  137. Ref();
  138. }
  139. }
  140. inline void Reset(T* ptr, StealRef) {
  141. if (Ptr_ != ptr) {
  142. UnRef();
  143. Ptr_ = ptr;
  144. }
  145. }
  146. inline void Swap(TRefCountedPtr& rhs) {
  147. T* tmp = Ptr_;
  148. Ptr_ = rhs.Ptr_;
  149. rhs.Ptr_ = tmp;
  150. }
  151. inline T* Release() {
  152. // do not decrement ref counter here. just send ownership to caller
  153. T* tmp = Ptr_;
  154. Ptr_ = nullptr;
  155. return tmp;
  156. }
  157. inline T* Get() const { return Ptr_; }
  158. inline T& operator*() const { return *Ptr_; }
  159. inline T* operator->() const { return Ptr_; }
  160. inline explicit operator bool() const { return Ptr_ != nullptr; }
  161. inline ui32 RefCount() const {
  162. return Ptr_ ? Ops::RefCount(Ptr_) : 0;
  163. }
  164. private:
  165. inline void Ref() {
  166. if (Ptr_){
  167. Ops::Ref(Ptr_);
  168. }
  169. }
  170. inline void UnRef() {
  171. if (Ptr_) {
  172. Ops::UnRef(Ptr_);
  173. Ptr_ = nullptr;
  174. }
  175. }
  176. private:
  177. T* Ptr_;
  178. };
  179. } // namspace NUdf
  180. } // namspace NYql