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.

169 lines
4.3 KiB

  1. /*
  2. * counted_ptr - simple reference counted pointer.
  3. *
  4. * The is a non-intrusive implementation that allocates an additional
  5. * int and pointer for every counted object.
  6. */
  7. #ifndef COUNTED_PTR_H
  8. #define COUNTED_PTR_H
  9. /* For ANSI-challenged compilers, you may want to #define
  10. * NO_MEMBER_TEMPLATES or explicit */
  11. #define NO_MEMBER_TEMPLATES
  12. #include "MemDeleteQueue.h"
  13. template <class X> class counted_ptr
  14. {
  15. public:
  16. typedef X element_type;
  17. explicit counted_ptr(X* p=NULL) // allocate a new counter
  18. : itsCounter(0) {if (p) itsCounter = new counter(p);}
  19. virtual ~counted_ptr()
  20. {release();}
  21. counted_ptr(const counted_ptr& r) /*throw()*/
  22. {acquire(r.itsCounter);}
  23. counted_ptr& operator=(const counted_ptr& r)
  24. {
  25. if (this != &r) {
  26. release();
  27. acquire(r.itsCounter);
  28. }
  29. return *this;
  30. }
  31. #ifndef NO_MEMBER_TEMPLATES
  32. template <class Y> friend class counted_ptr<Y>;
  33. template <class Y> counted_ptr(const counted_ptr<Y>& r) throw()
  34. {acquire(r.itsCounter);}
  35. template <class Y> counted_ptr& operator=(const counted_ptr<Y>& r)
  36. {
  37. if (this != &r) {
  38. release();
  39. acquire(r.itsCounter);
  40. }
  41. return *this;
  42. }
  43. #endif // NO_MEMBER_TEMPLATES
  44. X& operator*() const/* throw()*/ {return *itsCounter->ptr;}
  45. X* operator->() const/* throw()*/ {return itsCounter->ptr;}
  46. X* get() const/* throw()*/ {return itsCounter ? itsCounter->ptr : 0;}
  47. bool unique() const/* throw()*/
  48. {return (itsCounter ? itsCounter->count == 1 : true);}
  49. bool IsNull()
  50. {return (get() == NULL);}
  51. protected:
  52. struct counter {
  53. counter(X* p = 0, unsigned c = 1) : ptr(p), count(c) {}
  54. X* ptr;
  55. unsigned count;
  56. }* itsCounter;
  57. void acquire(counter* c) /*throw()*/
  58. { // increment the count
  59. itsCounter = c;
  60. if (c) ++c->count;
  61. }
  62. void release()
  63. { // decrement the count, delete if it is 0
  64. if (itsCounter) {
  65. if (--itsCounter->count == 0) {
  66. delete itsCounter->ptr;
  67. // g_DelQueue.Delete(itsCounter->ptr);
  68. delete itsCounter;
  69. // g_DelQueue.Delete(itsCounter);
  70. }
  71. itsCounter = 0;
  72. }
  73. }
  74. };
  75. template <class X> class counted_ptrA
  76. {
  77. public:
  78. typedef X element_type;
  79. explicit counted_ptrA(X* p=NULL) // allocate a new counter
  80. : itsCounter(0) {if (p) itsCounter = new counter(p);}
  81. virtual ~counted_ptrA()
  82. {release();}
  83. counted_ptrA(const counted_ptrA& r) /*throw()*/
  84. {acquire(r.itsCounter);}
  85. counted_ptrA& operator=(const counted_ptrA& r)
  86. {
  87. if (this != &r) {
  88. release();
  89. acquire(r.itsCounter);
  90. }
  91. return *this;
  92. }
  93. #ifndef NO_MEMBER_TEMPLATES
  94. template <class Y> friend class counted_ptrA<Y>;
  95. template <class Y> counted_ptrA(const counted_ptrA<Y>& r) throw()
  96. {acquire(r.itsCounter);}
  97. template <class Y> counted_ptrA& operator=(const counted_ptrA<Y>& r)
  98. {
  99. if (this != &r) {
  100. release();
  101. acquire(r.itsCounter);
  102. }
  103. return *this;
  104. }
  105. #endif // NO_MEMBER_TEMPLATES
  106. X& operator*() const/* throw()*/ {return *itsCounter->ptr;}
  107. X* operator->() const/* throw()*/ {return itsCounter->ptr;}
  108. X* get() const/* throw()*/ {return itsCounter ? itsCounter->ptr : 0;}
  109. bool unique() const/* throw()*/
  110. {return (itsCounter ? itsCounter->count == 1 : true);}
  111. protected:
  112. struct counter {
  113. counter(X* p = 0, unsigned c = 1) : ptr(p), count(c) {}
  114. X* ptr;
  115. unsigned count;
  116. }* itsCounter;
  117. void acquire(counter* c) /*throw()*/
  118. { // increment the count
  119. itsCounter = c;
  120. if (c) ++c->count;
  121. }
  122. void release()
  123. { // decrement the count, delete if it is 0
  124. if (itsCounter) {
  125. if (--itsCounter->count == 0) {
  126. // delete [] itsCounter->ptr;
  127. g_DelQueue.DeleteArray(itsCounter->ptr);
  128. delete itsCounter;
  129. // g_DelQueue.Delete(itsCounter);
  130. }
  131. itsCounter = 0;
  132. }
  133. }
  134. };
  135. #endif // COUNTED_PTR_H