SharedPtr.h 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. /* Copyright The kNet Project.
  2. Licensed under the Apache License, Version 2.0 (the "License");
  3. you may not use this file except in compliance with the License.
  4. You may obtain a copy of the License at
  5. http://www.apache.org/licenses/LICENSE-2.0
  6. Unless required by applicable law or agreed to in writing, software
  7. distributed under the License is distributed on an "AS IS" BASIS,
  8. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  9. See the License for the specific language governing permissions and
  10. limitations under the License. */
  11. #pragma once
  12. /** @file SharedPtr.h
  13. @brief SharedPtr, intrusive reference counting for multiple pointer owners. */
  14. // Modified by Yao Wei Tjong for Urho3D
  15. #include <cstdlib>
  16. #include <cassert>
  17. /// Smart pointer for dynamic single object allocations on the heap.
  18. #define Ptr(type) kNet::SharedPtr< type >
  19. namespace kNet
  20. {
  21. /// Objects that require reference count tracking derive publicly from this.
  22. /// \note The dtor of RefCountable is not virtual. NEVER manage pointers to RefCountables
  23. /// and never delete a pointer to a RefCountable.
  24. class RefCountable
  25. {
  26. public:
  27. RefCountable()
  28. :refCount(0)
  29. {
  30. }
  31. ~RefCountable()
  32. {
  33. refCount = -100000; // Mark the refCount to an arbitrary negative value so that any increments or decrements will catch an assertion failure.
  34. }
  35. void AddRef()
  36. {
  37. assert(refCount >= 0);
  38. ++refCount;
  39. }
  40. void DecRef()
  41. {
  42. assert(refCount > 0);
  43. --refCount;
  44. }
  45. int RefCount() const
  46. {
  47. return refCount;
  48. }
  49. private:
  50. int refCount;
  51. };
  52. /** @brief SharedPtr is an intrusive refcount-tracked single-object lifetime-manager.
  53. SharedPtr wraps raw pointers to objects and manages reference
  54. counting on the number of users on the pointer. When all users abandon the object,
  55. FreeFunc::free(T*) is called to clean up the memory used by the resource. */
  56. template<typename T>
  57. class SharedPtr
  58. {
  59. public:
  60. /// Constructs a zero pointer.
  61. SharedPtr():dataPtr(0) {}
  62. /// Constructs from a raw pointer.
  63. SharedPtr(T *ptr);
  64. /// Constructs from an existing SharedPtr.
  65. SharedPtr(const SharedPtr<T> &rhs);
  66. /// Template copy constructor for types that allow conversions to other types.
  67. template<typename T2>
  68. SharedPtr(const SharedPtr<T2> &rhs);
  69. /// Assignment from another SharedPtr.
  70. SharedPtr<T> &operator=(const SharedPtr<T> &rhs);
  71. /// Assignment from a raw ptr.
  72. SharedPtr<T> &operator=(T *ptr);
  73. // Releases use of the object.
  74. ~SharedPtr();
  75. unsigned int RefCount() const; ///< Returns the reference count of the currently held object.
  76. const T *ptr() const; ///< Const access to the pointer.
  77. const T *operator->() const; ///< Const dereference and access object.
  78. const T &operator*() const; ///< Const dereference object.
  79. operator T*(); ///< Implicit conversion to a raw pointer.
  80. T *ptr(); ///< Returns a pointer to the object or 0 if empty.
  81. T *operator->(); ///< Dereference and access object.
  82. T &operator*(); ///< Dereference object.
  83. operator bool() const; ///< Test if pointer is good.
  84. operator bool(); ///< Test if pointer is good.
  85. private:
  86. T *dataPtr; ///< Pointer to the actual data.
  87. void AddRef(); ///< Increases reference count.
  88. void Release(); ///< Decreases reference count and deletes the object if 0.
  89. };
  90. /** Equality comparison for two SharedPtr. Note that the types must match.
  91. @param a First operand
  92. @param b Second operand
  93. @return true if the objects point to the same object, false otherwise. */
  94. template<typename T>
  95. bool operator==(const SharedPtr<T> &a, const SharedPtr<T> &b)
  96. {
  97. if (a.ptr() == b.ptr())
  98. return true;
  99. else
  100. return false;
  101. }
  102. } // ~kNet
  103. // Urho3D: use relative path
  104. #include "SharedPtr.inl"