ReferenceArray.h 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. // Copyright (C) 2000 Sean Cavanaugh
  2. // This file is licensed under the terms of the Lesser GNU Public License
  3. // (see LPGL.txt, or http://www.gnu.org/copyleft/lesser.txt)
  4. #if !defined(AFX_ReferenceArray_H__BAEBCE9D_CD68_40AF_8A54_B23A0D14E807__INCLUDED_)
  5. #define AFX_ReferenceArray_H__BAEBCE9D_CD68_40AF_8A54_B23A0D14E807__INCLUDED_
  6. #if _MSC_VER > 1000
  7. #pragma once
  8. #endif // _MSC_VER > 1000
  9. #ifdef WIN32
  10. #define WIN32_LEAN_AND_MEAN
  11. #include "windows.h"
  12. #endif
  13. #include "assert.h"
  14. #include "limits.h"
  15. #include "ReferenceCounter.h"
  16. /*!
  17. \author Sean Cavanaugh
  18. \email [email protected]
  19. \cvsauthor $Author: sean $
  20. \date $Date: 2000/09/11 20:28:24 $
  21. \version $Revision: 1.1 $
  22. \brief ReferenceArray is exactly the same as ReferencePtr, except it expects
  23. the objects pointing to it to be allocated with new[] instead (and thusly
  24. the object is deleted with delete[] when the reference count hits zero)
  25. Additionally it provides a [] operator which returns a refernece to the
  26. item in the list. No bounds checking is performed.
  27. Arrays of basic data types (char, int, float, etc) should use ReferencePtr,
  28. as delete[] is not required for them. ReferencePtr can also handle void types
  29. as a template parameter.
  30. */
  31. template<class DATA_T>
  32. class ReferenceArrayBlock
  33. {
  34. public:
  35. DATA_T* pData; // User defined data block
  36. mutable ReferenceCounter ReferenceCount;
  37. };
  38. template<class DATA_T>
  39. class ReferenceArray
  40. {
  41. public:
  42. // Construction
  43. ReferenceArray();
  44. ReferenceArray(DATA_T* other);
  45. ReferenceArray(const ReferenceArray<DATA_T>& other);
  46. virtual ~ReferenceArray();
  47. // Assignment
  48. ReferenceArray<DATA_T>& operator=(const ReferenceArray<DATA_T>& other);
  49. ReferenceArray<DATA_T>& operator=(DATA_T* other);
  50. // Dereferencing
  51. operator DATA_T*() const {return m_pData->pData;}
  52. DATA_T& operator[](unsigned int offset) const {return m_pData->pData[offset];}
  53. DATA_T& operator[](int offset) const {return m_pData->pData[offset];}
  54. protected:
  55. // Internal methods
  56. void Alloc(); // Allocate the m_pData
  57. void Release(); // Releases a reference count (possibly freeing memory)
  58. protected:
  59. // Member data
  60. ReferenceArrayBlock<DATA_T>* m_pData;
  61. };
  62. template<class DATA_T>
  63. ReferenceArray<DATA_T>::ReferenceArray()
  64. {
  65. Alloc();
  66. }
  67. template<class DATA_T>
  68. ReferenceArray<DATA_T>::ReferenceArray(DATA_T* other)
  69. {
  70. Alloc();
  71. m_pData->pData = other;
  72. m_pData->ReferenceCount = 1;
  73. }
  74. template<class DATA_T>
  75. ReferenceArray<DATA_T>::ReferenceArray(const ReferenceArray<DATA_T>& other)
  76. {
  77. m_pData = other.m_pData;
  78. m_pData->ReferenceCount++;
  79. }
  80. template<class DATA_T>
  81. ReferenceArray<DATA_T>::~ReferenceArray()
  82. {
  83. Release();
  84. }
  85. template<class DATA_T>
  86. ReferenceArray<DATA_T>& ReferenceArray<DATA_T>::operator=(const ReferenceArray<DATA_T>& other)
  87. {
  88. if (m_pData != other.m_pData)
  89. {
  90. Release();
  91. m_pData = other.m_pData;
  92. m_pData->ReferenceCount++;
  93. }
  94. return *this;
  95. }
  96. template<class DATA_T>
  97. ReferenceArray<DATA_T>& ReferenceArray<DATA_T>::operator=(DATA_T* other)
  98. {
  99. if (m_pData->ReferenceCount.dec() <= 0)
  100. {
  101. delete[] m_pData->pData;
  102. m_pData->pData = other;
  103. m_pData->ReferenceCount = 1;
  104. }
  105. else
  106. {
  107. Alloc();
  108. m_pData->pData = other;
  109. }
  110. return *this;
  111. }
  112. template<class DATA_T>
  113. void ReferenceArray<DATA_T>::Alloc()
  114. {
  115. m_pData = new ReferenceArrayBlock<DATA_T>;
  116. m_pData->ReferenceCount = 1;
  117. m_pData->pData = NULL;
  118. }
  119. template<class DATA_T>
  120. void ReferenceArray<DATA_T>::Release()
  121. {
  122. assert(m_pData != NULL);
  123. if (m_pData->ReferenceCount.dec() <= 0)
  124. {
  125. delete[] m_pData->pData;
  126. m_pData->pData = NULL;
  127. delete m_pData;
  128. m_pData = NULL;
  129. }
  130. }
  131. #endif // !defined(AFX_ReferenceArray_H__BAEBCE9D_CD68_40AF_8A54_B23A0D14E807__INCLUDED_)