Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

182 lines
3.4 KiB

  1. //
  2. // This file contains another implementation of smart pointers. It is
  3. // different from the implementation found in smartptr.h because the
  4. // object itself deletes itself when its reference count hits 0. This
  5. // is similar to the way COM objects are written.
  6. //
  7. #ifndef _SMARTP2_H_
  8. #define _SMARTP2_H_
  9. #include <dbgtrace.h>
  10. //
  11. // A reference counting implementation
  12. //
  13. class CRefCount2 {
  14. protected:
  15. LONG m_cRefs;
  16. public:
  17. CRefCount2() {
  18. m_cRefs = 1;
  19. }
  20. virtual ~CRefCount2() {
  21. }
  22. LONG AddRef() {
  23. return InterlockedIncrement(&m_cRefs);
  24. }
  25. void Release() {
  26. LONG r = InterlockedDecrement(&m_cRefs);
  27. _ASSERT(r >= 0);
  28. if (r == 0) delete this;
  29. }
  30. };
  31. template<class Type> class CRefPtr2;
  32. //
  33. // This is a type of pointer which can be returned by functions. The only
  34. // valid operation on it is to copy it to a CRefPtr2<Type> pointer. It
  35. // tells the CRefPtr2 not to do an AddRef.
  36. //
  37. template<class Type>
  38. class CRefPtr2HasRef {
  39. protected:
  40. Type *m_p;
  41. CRefPtr2HasRef<Type>& operator=(const CRefPtr2HasRef<Type>& rhs) {
  42. _ASSERT(FALSE);
  43. return *this;
  44. }
  45. BOOL operator==(CRefPtr2<Type>&rhs) {
  46. _ASSERT(FALSE);
  47. return m_p == rhs.m_p;
  48. }
  49. BOOL operator!=(CRefPtr2<Type>&rhs) {
  50. _ASSERT(FALSE);
  51. return m_p != rhs.m_p;
  52. }
  53. public:
  54. //
  55. // Do nothing protected constructor !
  56. //
  57. CRefPtr2HasRef() : m_p( 0 ) {
  58. }
  59. CRefPtr2HasRef(const Type *p ) :
  60. m_p( (Type*)p ) {
  61. if (m_p) m_p->AddRef();
  62. }
  63. ~CRefPtr2HasRef() {
  64. // this pointer always needs to be copied to a CRefPtr2, which
  65. // should set m_p to NULL
  66. _ASSERT(m_p == NULL);
  67. }
  68. friend class CRefPtr2<Type>;
  69. };
  70. template<class Type, BOOL fAddRef>
  71. class CHasRef : public CRefPtr2HasRef<Type> {
  72. public :
  73. CHasRef( const Type* p = 0 ) {
  74. m_p = (Type*)p ;
  75. if( fAddRef ) {
  76. if( m_p )
  77. m_p->AddRef() ;
  78. }
  79. }
  80. } ;
  81. template< class Type >
  82. class CRefPtr2 {
  83. private:
  84. Type* m_p ;
  85. public :
  86. CRefPtr2(const CRefPtr2<Type>& ref) {
  87. m_p = ref.m_p;
  88. if (m_p) m_p->AddRef();
  89. }
  90. // copy from an intermediate pointer -- we don't need to do an addref
  91. CRefPtr2(CRefPtr2HasRef<Type> &ref) {
  92. m_p = ref.m_p;
  93. ref.m_p = NULL;
  94. }
  95. CRefPtr2(const Type *p = 0) {
  96. m_p = (Type *) p;
  97. if (m_p) m_p->AddRef();
  98. }
  99. ~CRefPtr2() {
  100. if (m_p) m_p->Release();
  101. }
  102. CRefPtr2<Type>& operator=(const CRefPtr2<Type>& rhs) {
  103. if (m_p != rhs.m_p) {
  104. Type *pTemp = m_p;
  105. m_p = rhs.m_p;
  106. if (m_p) m_p->AddRef();
  107. if (pTemp) pTemp->Release();
  108. }
  109. return *this;
  110. }
  111. // copy from an intermediate pointer -- we don't need to do an addref
  112. CRefPtr2<Type>& operator=(CRefPtr2HasRef<Type>& rhs) {
  113. Type *pTemp = m_p;
  114. m_p = rhs.m_p;
  115. if (pTemp) pTemp->Release();
  116. rhs.m_p = NULL;
  117. return *this;
  118. }
  119. CRefPtr2<Type>& operator=(const Type *rhs) {
  120. if (m_p != rhs) {
  121. Type *pTemp = m_p;
  122. m_p = (Type *) rhs;
  123. if (m_p) m_p->AddRef();
  124. if (pTemp) pTemp->Release();
  125. }
  126. return *this;
  127. }
  128. BOOL operator==(CRefPtr2<Type>&rhs) {
  129. return m_p == rhs.m_p;
  130. }
  131. BOOL operator!=(CRefPtr2<Type>&rhs) {
  132. return m_p != rhs.m_p;
  133. }
  134. BOOL operator==(Type *p) {
  135. return m_p == p;
  136. }
  137. BOOL operator!=(Type *p) {
  138. return m_p != p;
  139. }
  140. Type *operator->() const {
  141. return m_p ;
  142. }
  143. operator Type*() const {
  144. return m_p ;
  145. }
  146. BOOL operator!() const {
  147. return !m_p ;
  148. }
  149. };
  150. #endif