sharedptr.h 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name: wx/sharedptr.h
  3. // Purpose: Shared pointer based on the counted_ptr<> template, which
  4. // is in the public domain
  5. // Author: Robert Roebling, Yonat Sharon
  6. // Copyright: Robert Roebling
  7. // Licence: wxWindows licence
  8. /////////////////////////////////////////////////////////////////////////////
  9. #ifndef _WX_SHAREDPTR_H_
  10. #define _WX_SHAREDPTR_H_
  11. #include "wx/defs.h"
  12. #include "wx/atomic.h"
  13. // ----------------------------------------------------------------------------
  14. // wxSharedPtr: A smart pointer with non-intrusive reference counting.
  15. // ----------------------------------------------------------------------------
  16. template <class T>
  17. class wxSharedPtr
  18. {
  19. public:
  20. typedef T element_type;
  21. wxEXPLICIT wxSharedPtr( T* ptr = NULL )
  22. : m_ref(NULL)
  23. {
  24. if (ptr)
  25. m_ref = new reftype(ptr);
  26. }
  27. template<typename Deleter>
  28. wxEXPLICIT wxSharedPtr(T* ptr, Deleter d)
  29. : m_ref(NULL)
  30. {
  31. if (ptr)
  32. m_ref = new reftype_with_deleter<Deleter>(ptr, d);
  33. }
  34. ~wxSharedPtr() { Release(); }
  35. wxSharedPtr(const wxSharedPtr& tocopy) { Acquire(tocopy.m_ref); }
  36. wxSharedPtr& operator=( const wxSharedPtr& tocopy )
  37. {
  38. if (this != &tocopy)
  39. {
  40. Release();
  41. Acquire(tocopy.m_ref);
  42. }
  43. return *this;
  44. }
  45. wxSharedPtr& operator=( T* ptr )
  46. {
  47. if (get() != ptr)
  48. {
  49. Release();
  50. if (ptr)
  51. m_ref = new reftype(ptr);
  52. }
  53. return *this;
  54. }
  55. // test for pointer validity: defining conversion to unspecified_bool_type
  56. // and not more obvious bool to avoid implicit conversions to integer types
  57. typedef T *(wxSharedPtr<T>::*unspecified_bool_type)() const;
  58. operator unspecified_bool_type() const
  59. {
  60. if (m_ref && m_ref->m_ptr)
  61. return &wxSharedPtr<T>::get;
  62. else
  63. return NULL;
  64. }
  65. T& operator*() const
  66. {
  67. wxASSERT(m_ref != NULL);
  68. wxASSERT(m_ref->m_ptr != NULL);
  69. return *(m_ref->m_ptr);
  70. }
  71. T* operator->() const
  72. {
  73. wxASSERT(m_ref != NULL);
  74. wxASSERT(m_ref->m_ptr != NULL);
  75. return m_ref->m_ptr;
  76. }
  77. T* get() const
  78. {
  79. return m_ref ? m_ref->m_ptr : NULL;
  80. }
  81. void reset( T* ptr = NULL )
  82. {
  83. Release();
  84. if (ptr)
  85. m_ref = new reftype(ptr);
  86. }
  87. template<typename Deleter>
  88. void reset(T* ptr, Deleter d)
  89. {
  90. Release();
  91. if (ptr)
  92. m_ref = new reftype_with_deleter<Deleter>(ptr, d);
  93. }
  94. bool unique() const { return (m_ref ? m_ref->m_count == 1 : true); }
  95. long use_count() const { return (m_ref ? (long)m_ref->m_count : 0); }
  96. private:
  97. struct reftype
  98. {
  99. reftype(T* ptr) : m_ptr(ptr), m_count(1) {}
  100. virtual ~reftype() {}
  101. virtual void delete_ptr() { delete m_ptr; }
  102. T* m_ptr;
  103. wxAtomicInt m_count;
  104. };
  105. template<typename Deleter>
  106. struct reftype_with_deleter : public reftype
  107. {
  108. reftype_with_deleter(T* ptr, Deleter d) : reftype(ptr), m_deleter(d) {}
  109. virtual void delete_ptr() { m_deleter(this->m_ptr); }
  110. Deleter m_deleter;
  111. };
  112. reftype* m_ref;
  113. void Acquire(reftype* ref)
  114. {
  115. m_ref = ref;
  116. if (ref)
  117. wxAtomicInc( ref->m_count );
  118. }
  119. void Release()
  120. {
  121. if (m_ref)
  122. {
  123. if (!wxAtomicDec( m_ref->m_count ))
  124. {
  125. m_ref->delete_ptr();
  126. delete m_ref;
  127. }
  128. m_ref = NULL;
  129. }
  130. }
  131. };
  132. template <class T, class U>
  133. bool operator == (wxSharedPtr<T> const &a, wxSharedPtr<U> const &b )
  134. {
  135. return a.get() == b.get();
  136. }
  137. template <class T, class U>
  138. bool operator != (wxSharedPtr<T> const &a, wxSharedPtr<U> const &b )
  139. {
  140. return a.get() != b.get();
  141. }
  142. #endif // _WX_SHAREDPTR_H_