RakNetSmartPtr.h 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. /*
  2. * Copyright (c) 2014, Oculus VR, Inc.
  3. * All rights reserved.
  4. *
  5. * This source code is licensed under the BSD-style license found in the
  6. * LICENSE file in the root directory of this source tree. An additional grant
  7. * of patent rights can be found in the PATENTS file in the same directory.
  8. *
  9. */
  10. #ifndef __RAKNET_SMART_PTR_H
  11. #define __RAKNET_SMART_PTR_H
  12. // From http://www.codeproject.com/KB/cpp/SmartPointers.aspx
  13. // with bugs fixed
  14. #include "RakMemoryOverride.h"
  15. #include "Export.h"
  16. //static int allocCount=0;
  17. //static int deallocCount=0;
  18. namespace RakNet
  19. {
  20. class RAK_DLL_EXPORT ReferenceCounter
  21. {
  22. private:
  23. int refCount;
  24. public:
  25. ReferenceCounter() {refCount=0;}
  26. ~ReferenceCounter() {}
  27. void AddRef() {refCount++;}
  28. int Release() {return --refCount;}
  29. int GetRefCount(void) const {return refCount;}
  30. };
  31. template < typename T > class RAK_DLL_EXPORT RakNetSmartPtr
  32. {
  33. private:
  34. T* ptr; // pointer
  35. ReferenceCounter* reference; // Reference refCount
  36. public:
  37. RakNetSmartPtr() : ptr(0), reference(0)
  38. {
  39. // Do not allocate by default, wasteful if we just have a list of preallocated and unassigend smart pointers
  40. }
  41. RakNetSmartPtr(T* pValue) : ptr(pValue)
  42. {
  43. reference = RakNet::OP_NEW<ReferenceCounter>(_FILE_AND_LINE_);
  44. reference->AddRef();
  45. // allocCount+=2;
  46. // printf("allocCount=%i deallocCount=%i Line=%i\n",allocCount, deallocCount, __LINE__);
  47. }
  48. RakNetSmartPtr(const RakNetSmartPtr<T>& sp) : ptr(sp.ptr), reference(sp.reference)
  49. {
  50. if (reference)
  51. reference->AddRef();
  52. }
  53. ~RakNetSmartPtr()
  54. {
  55. if(reference && reference->Release() == 0)
  56. {
  57. RakNet::OP_DELETE(ptr, _FILE_AND_LINE_);
  58. RakNet::OP_DELETE(reference, _FILE_AND_LINE_);
  59. // deallocCount+=2;
  60. // printf("allocCount=%i deallocCount=%i Line=%i\n",allocCount, deallocCount, __LINE__);
  61. }
  62. }
  63. bool IsNull(void) const
  64. {
  65. return ptr==0;
  66. }
  67. void SetNull(void)
  68. {
  69. if(reference && reference->Release() == 0)
  70. {
  71. RakNet::OP_DELETE(ptr, _FILE_AND_LINE_);
  72. RakNet::OP_DELETE(reference, _FILE_AND_LINE_);
  73. // deallocCount+=2;
  74. // printf("allocCount=%i deallocCount=%i Line=%i\n",allocCount, deallocCount, __LINE__);
  75. }
  76. ptr=0;
  77. reference=0;
  78. }
  79. bool IsUnique(void) const
  80. {
  81. return reference->GetRefCount()==1;
  82. }
  83. // Allow you to change the values of the internal contents of the pointer, without changing what is pointed to by other instances of the smart pointer
  84. void Clone(bool copyContents)
  85. {
  86. if (IsUnique()==false)
  87. {
  88. reference->Release();
  89. reference = RakNet::OP_NEW<ReferenceCounter>(_FILE_AND_LINE_);
  90. reference->AddRef();
  91. T* oldPtr=ptr;
  92. ptr=RakNet::OP_NEW<T>(_FILE_AND_LINE_);
  93. if (copyContents)
  94. *ptr=*oldPtr;
  95. }
  96. }
  97. int GetRefCount(void) const
  98. {
  99. return reference->GetRefCount();
  100. }
  101. T& operator* ()
  102. {
  103. return *ptr;
  104. }
  105. const T& operator* () const
  106. {
  107. return *ptr;
  108. }
  109. T* operator-> ()
  110. {
  111. return ptr;
  112. }
  113. const T* operator-> () const
  114. {
  115. return ptr;
  116. }
  117. bool operator == (const RakNetSmartPtr<T>& sp)
  118. {
  119. return ptr == sp.ptr;
  120. }
  121. bool operator<( const RakNetSmartPtr<T> &right ) {return ptr < right.ptr;}
  122. bool operator>( const RakNetSmartPtr<T> &right ) {return ptr > right.ptr;}
  123. bool operator != (const RakNetSmartPtr<T>& sp)
  124. {
  125. return ptr != sp.ptr;
  126. }
  127. RakNetSmartPtr<T>& operator = (const RakNetSmartPtr<T>& sp)
  128. {
  129. // Assignment operator
  130. if (this != &sp) // Avoid self assignment
  131. {
  132. if(reference && reference->Release() == 0)
  133. {
  134. RakNet::OP_DELETE(ptr, _FILE_AND_LINE_);
  135. RakNet::OP_DELETE(reference, _FILE_AND_LINE_);
  136. // deallocCount+=2;
  137. // printf("allocCount=%i deallocCount=%i Line=%i\n",allocCount, deallocCount, __LINE__);
  138. }
  139. ptr = sp.ptr;
  140. reference = sp.reference;
  141. if (reference)
  142. reference->AddRef();
  143. }
  144. return *this;
  145. }
  146. };
  147. } // namespace RakNet
  148. #endif
粤ICP备19079148号