Source code of Windows XP (NT5)
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.

189 lines
3.8 KiB

  1. /*===================================================================
  2. Microsoft Denali
  3. Microsoft Confidential.
  4. Copyright 1997 Microsoft Corporation. All Rights Reserved.
  5. Component: misc
  6. File: vector.h
  7. Owner: DGottner
  8. This file contains a dynamic array
  9. ===================================================================*/
  10. /*
  11. * This file is derived from software bearing the following
  12. * restrictions:
  13. *
  14. * Copyright 1994, David Gottner
  15. *
  16. * All Rights Reserved
  17. *
  18. * Permission to use, copy, modify, and distribute this software and its
  19. * documentation for any purpose and without fee is hereby granted,
  20. * provided that the above copyright notice, this permission notice and
  21. * the following disclaimer notice appear unmodified in all copies.
  22. *
  23. * I DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  24. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL I
  25. * BE LIABLE FOR ANY SPECIAL, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
  26. * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA, OR PROFITS, WHETHER
  27. * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
  28. * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  29. *
  30. */
  31. #ifndef VECIMPL_H
  32. #define VECIMPL_H
  33. #define VEC_GROW_SIZE 64 // grow in chunks of this many items
  34. #define __vec_rounded_size(s) \
  35. (((s) + (VEC_GROW_SIZE - 1)) & ~(VEC_GROW_SIZE - 1))
  36. template <class TYPE>
  37. vector<TYPE>::vector() : m_rgData(NULL), m_cItems(0), m_cCells(0)
  38. {
  39. }
  40. template <class TYPE>
  41. HRESULT vector<TYPE>::Init(const TYPE *anArray, size_t theSize)
  42. {
  43. m_cCells = __vec_rounded_size(theSize);
  44. register size_t n = m_cItems = theSize;
  45. register TYPE * pDest = m_rgData = new TYPE[m_cCells];
  46. register const TYPE *pSrc = anArray;
  47. if (pDest == NULL)
  48. {
  49. m_cItems = m_cCells = 0;
  50. return E_OUTOFMEMORY;
  51. }
  52. while (n--)
  53. *pDest++ = *pSrc++;
  54. return S_OK;
  55. }
  56. template <class TYPE>
  57. HRESULT vector<TYPE>::Init(size_t n)
  58. {
  59. m_rgData = new TYPE[m_cCells = __vec_rounded_size(m_cItems = n)];
  60. if (m_rgData == NULL)
  61. {
  62. m_cItems = m_cCells = 0;
  63. return E_OUTOFMEMORY;
  64. }
  65. return S_OK;
  66. }
  67. template <class TYPE>
  68. vector<TYPE>::~vector()
  69. {
  70. delete[] m_rgData;
  71. }
  72. template <class TYPE>
  73. HRESULT vector<TYPE>::resize(size_t cNewCells)
  74. {
  75. cNewCells = __vec_rounded_size(cNewCells);
  76. if (m_cCells == cNewCells)
  77. return S_OK;
  78. TYPE *rgData = new TYPE[cNewCells];
  79. if (rgData == NULL)
  80. return E_OUTOFMEMORY;
  81. register size_t n = (m_cItems < cNewCells)? m_cItems : cNewCells;
  82. register TYPE * pDest = rgData;
  83. register const TYPE *pSrc = m_rgData;
  84. m_cItems = n;
  85. m_cCells = cNewCells;
  86. while (n--)
  87. *pDest++ = *pSrc++;
  88. delete[] m_rgData;
  89. m_rgData = rgData;
  90. return S_OK;
  91. }
  92. template <class TYPE>
  93. HRESULT vector<TYPE>::reshape(size_t cNewItems)
  94. {
  95. HRESULT hrRet = S_OK;
  96. if (cNewItems > m_cCells)
  97. hrRet = resize(cNewItems);
  98. if (SUCCEEDED(hrRet))
  99. m_cItems = cNewItems;
  100. return hrRet;
  101. }
  102. template <class TYPE>
  103. HRESULT vector<TYPE>::insertAt(size_t pos, const TYPE &item)
  104. {
  105. Assert (pos <= m_cItems);
  106. HRESULT hrRet = S_OK;
  107. if ((m_cItems + 1) > m_cCells)
  108. hrRet = resize(m_cCells + VEC_GROW_SIZE);
  109. if (SUCCEEDED(hrRet))
  110. {
  111. TYPE *pDest = &m_rgData[pos];
  112. for (register TYPE *ptr = &m_rgData[m_cItems];
  113. ptr > pDest;
  114. --ptr)
  115. *ptr = *(ptr - 1);
  116. *pDest = item;
  117. ++m_cItems;
  118. }
  119. return hrRet;
  120. }
  121. template <class TYPE>
  122. TYPE vector<TYPE>::removeAt(size_t pos)
  123. {
  124. Assert (pos < m_cItems);
  125. TYPE * end = &m_rgData[--m_cItems];
  126. register TYPE *ptr = &m_rgData[pos];
  127. TYPE val = *ptr;
  128. for (; ptr < end; ++ptr)
  129. *ptr = *(ptr + 1);
  130. return val;
  131. }
  132. template <class TYPE>
  133. int vector<TYPE>::find(const TYPE &item) const
  134. {
  135. for (register unsigned i = 0; i < m_cItems; ++i)
  136. if (item == m_rgData[i])
  137. return i;
  138. return -1;
  139. }
  140. #endif /* VECIMPL */