XDWHolder.tli 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. // XDWHolder.tli
  2. //
  3. #pragma once
  4. #ifndef ASSERT
  5. #include <assert.h>
  6. #define ASSERT assert
  7. #endif
  8. #include "XDWHolder.tlh"
  9. #define Datanullptr nullptr
  10. template <typename T>
  11. XDWHolder <T>::XDWHolder ()
  12. {
  13. Init ();
  14. }
  15. template <typename T>
  16. XDWHolder <T>::~XDWHolder ()
  17. {
  18. if (GetData () != Datanullptr)
  19. {
  20. if (InterlockedDecrement (&GetData ()->nRefs) <= 0)
  21. {
  22. delete m_pMetaData;
  23. delete m_pObject;
  24. }
  25. }
  26. }
  27. template <typename T>
  28. void XDWHolder <T>::Init (void)
  29. {
  30. m_pObject = nullptr;
  31. m_pMetaData = (MetaData *) Datanullptr;
  32. }
  33. template <typename T>
  34. XDWHolder <T>::XDWHolder (const XDWHolder <T> & h)
  35. {
  36. Init ();
  37. ShadowCopyFrom (h);
  38. }
  39. template <typename T>
  40. XDWHolder <T>::XDWHolder (XDWHolder <T> && h)
  41. {
  42. m_pObject = h.m_pObject;
  43. m_pMetaData = h.m_pMetaData;
  44. h.Init ();
  45. }
  46. template <typename T>
  47. XDWHolder <T>::XDWHolder (T * object)
  48. {
  49. Init ();
  50. Attach (object);
  51. }
  52. template <typename T>
  53. void XDWHolder <T>::Attach (T * object)
  54. {
  55. Release ();
  56. if (object == nullptr)
  57. return;
  58. m_pObject = object;
  59. m_pMetaData = new MetaData;
  60. m_pMetaData->nRefs = 1;
  61. }
  62. template <typename T>
  63. T * XDWHolder <T>::Detach ()
  64. {
  65. T * over = m_pObject;
  66. m_pObject = nullptr;
  67. Release ();
  68. return over;
  69. }
  70. template <typename T>
  71. void XDWHolder <T>::Release ()
  72. {
  73. if (GetData () == Datanullptr) return;
  74. ASSERT (GetData ()->nRefs != 0);
  75. if (InterlockedDecrement (&GetData ()->nRefs) <= 0)
  76. {
  77. if (m_pObject)
  78. delete (m_pObject);
  79. delete m_pMetaData;
  80. m_pMetaData = nullptr;
  81. }
  82. Init ();
  83. }
  84. template <typename T>
  85. void XDWHolder <T>::CopyFrom (const XDWHolder <T> & h)
  86. {
  87. Release ();
  88. if (! h.m_pObject) return;
  89. T * object = h.NewObject (h.m_pObject);
  90. ASSERT (object);
  91. Attach (object);
  92. }
  93. template <typename T>
  94. void XDWHolder <T>::ShadowCopyFrom (const XDWHolder <T> & h)
  95. {
  96. if (m_pObject == h.m_pObject)
  97. return;
  98. if (h.GetData () == Datanullptr)
  99. {
  100. Release ();
  101. return;
  102. }
  103. if (GetData () != Datanullptr)
  104. if (GetData ()->nRefs < 0)
  105. {
  106. CopyFrom (h);
  107. return;
  108. }
  109. if (h.GetData ()->nRefs < 0)
  110. {
  111. CopyFrom (h);
  112. return;
  113. }
  114. // else
  115. {
  116. // can just copy references around
  117. Release ();
  118. m_pObject = h.m_pObject;
  119. m_pMetaData = h.m_pMetaData;
  120. InterlockedIncrement (&GetData ()->nRefs);
  121. }
  122. }
  123. template <typename T>
  124. T * XDWHolder <T>::NewObject (const T * fromObject) const
  125. {
  126. // T * object = new T (* fromObject);
  127. // return object
  128. return nullptr;
  129. }
  130. template <typename T>
  131. XDWHolder <T> & XDWHolder <T>::operator = (const XDWHolder <T> & h)
  132. {
  133. ShadowCopyFrom (h);
  134. return *this;
  135. }
  136. template <typename T>
  137. XDWHolder <T> & XDWHolder <T>::operator = (T * object)
  138. {
  139. Attach (object);
  140. return *this;
  141. }
  142. template <typename T>
  143. XDWHolder <T>::operator bool () const
  144. {
  145. return m_pObject;
  146. }
  147. template <typename T>
  148. XDWHolder <T>::operator T * ()
  149. {
  150. return m_pObject;
  151. }
  152. template <typename T>
  153. XDWHolder <T>::operator const T * () const
  154. {
  155. return m_pObject;
  156. }
  157. template <typename T>
  158. bool XDWHolder <T>::IsEmpty () const
  159. {
  160. return (m_pObject == nullptr);
  161. }