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.

154 lines
4.2 KiB

  1. //--------------------------------------------------------------------
  2. // Reference-counted pointer implementation.
  3. // Copyright (C) Microsoft Corporation, 2000-2001
  4. //
  5. // Created by: Duncan Bryce (duncanb), 12-09-2000
  6. //
  7. #ifndef _MY_AUTO_PTR_H_
  8. #define _MY_AUTO_PTR_H_ 1
  9. template <class T>
  10. class Ref {
  11. public:
  12. Ref(T *pT) : m_pT(pT), m_nRefCount(NULL == pT ? 0 : 1) { };
  13. ~Ref() { delete (m_pT); }
  14. volatile long m_nRefCount;
  15. T * m_pT;
  16. private:
  17. Ref();
  18. Ref(const Ref & rhs);
  19. Ref & operator=(const Ref & rhs);
  20. };
  21. //
  22. // The AutoPtr class implements a reference-counting wrapper for
  23. // pointer types.
  24. //
  25. // The requirements for use are:
  26. // * class T must implement operator ==
  27. // * class T must implement operator <
  28. //
  29. // Furthermore, for an AutoPtr, a, such that NULL == a, none of the operations
  30. // in this class are valid except
  31. // * operator!=
  32. // * operator==
  33. //
  34. template <class T>
  35. class AutoPtr {
  36. public:
  37. AutoPtr(T * pT = NULL) {
  38. if (NULL == pT) {
  39. m_pRef = NULL;
  40. } else {
  41. m_pRef = new Ref<T>(pT);
  42. if (NULL == m_pRef) {
  43. // Delete pT since we can't create a reference to it,
  44. // and the caller is not going to delete it.
  45. delete (pT);
  46. }
  47. }
  48. }
  49. AutoPtr(const AutoPtr & rhs) : m_pRef(rhs.m_pRef) {
  50. if (NULL != m_pRef) {
  51. InterlockedIncrement(&m_pRef->m_nRefCount);
  52. }
  53. }
  54. ~AutoPtr() {
  55. if (NULL != m_pRef) {
  56. if (0 == InterlockedDecrement(&m_pRef->m_nRefCount)) {
  57. delete (m_pRef);
  58. }
  59. }
  60. }
  61. AutoPtr & operator=(const AutoPtr & rhs) {
  62. if (m_pRef == rhs.m_pRef) {
  63. return *this;
  64. }
  65. if (NULL != m_pRef) {
  66. if (0 == InterlockedDecrement(&m_pRef->m_nRefCount)) {
  67. delete (m_pRef);
  68. }
  69. }
  70. m_pRef = rhs.m_pRef;
  71. if (NULL != rhs.m_pRef) {
  72. InterlockedIncrement(&m_pRef->m_nRefCount);
  73. }
  74. return *this;
  75. }
  76. //
  77. // If both this and rhs reference non-NULL pointers,
  78. // forward the == operation to the == operator in class T.
  79. // Otherwise, return true iff both this AutoPtr and rhs reference
  80. // the same pointer.
  81. //
  82. BOOL operator==(const AutoPtr & rhs) {
  83. if (NULL == m_pRef || NULL == rhs.m_pRef) {
  84. return m_pRef == rhs.m_pRef;
  85. } else {
  86. return m_pRef->m_pT->operator==(*(rhs.m_pRef->m_pT));
  87. }
  88. }
  89. //
  90. // If both this AutoPtr and rhs point to non-NULL pointers,
  91. // forward the < operation to the < operator in class T.
  92. // Otherwise, operator < returns TRUE iff this AutoPtr pointers
  93. // to a non-NULL pointer, but rhs points to a NULL pointer.
  94. //
  95. BOOL operator<(const AutoPtr & rhs) {
  96. if (NULL == m_pRef || NULL == rhs.m_pRef) {
  97. return NULL != m_pRef && NULL == rhs.m_pRef;
  98. } else {
  99. return m_pRef->m_pT->operator<(*(rhs.m_pRef->m_pT));
  100. }
  101. }
  102. T * operator->() const { return m_pRef->m_pT; }
  103. T & operator*() const { return *m_pRef->m_pT; }
  104. //
  105. // Overloading == and != to allow AutoPtrs to be NULL checked transparently.
  106. //
  107. // Note, however, that this allows some code to compile which
  108. // might not make sense:
  109. //
  110. // LPWSTR pwsz;
  111. // NtpPeerPtr npp;
  112. // if (npp == pwsz) { // no compile error
  113. // ...
  114. //
  115. friend BOOL operator==(const AutoPtr & ap, const void * pv) {
  116. return (NULL == ap.m_pRef && NULL == pv) ||(ap.m_pRef->m_pT == pv);
  117. }
  118. friend BOOL operator==(const void * pv, const AutoPtr & ap) {
  119. return ap == pv;
  120. }
  121. friend BOOL operator!=(const AutoPtr & ap, const void * pv) {
  122. return !(ap == pv);
  123. }
  124. friend BOOL operator!=(const void * pv, const AutoPtr & ap) {
  125. return !(ap == pv);
  126. }
  127. private:
  128. Ref<T> *m_pRef;
  129. };
  130. #endif // #ifndef _MY_AUTO_PTR_H_