00001 #ifndef __CHM_VECTOR__
00002 #define __CHM_VECTOR__
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <CHM/CHMerrorClass.h>
00023
00024 template<class Item>
00025 class CHMvector
00026 {
00027 public:
00028 CHMvector(size_t GrowFactor = 10,
00029 size_t InitialSize=0,
00030 CHMboolean GrowByDouble=false);
00031 ~CHMvector();
00032
00033 Item& operator[](size_t Index);
00034 const Item& operator[](size_t Index) const;
00035
00036 void insert(const Item& Value, size_t Index);
00037
00038 void remove(size_t Index);
00039
00040 size_t size() const;
00041
00042 void resize(size_t NewSize);
00043
00044 void clear();
00045
00046 void push_back(const Item& Value);
00047 Item& pop_back();
00048 Item& back();
00049 CHMvector<Item>& operator=(const CHMvector<Item>& Original);
00050 private:
00051 size_t m_GrowBy;
00052 size_t m_Size;
00053 size_t m_Capacity;
00054
00055 CHMboolean m_GrowByDouble;
00056
00057 Item* m_pData;
00058
00059 void grow(size_t RequiredSize);
00060
00061 CHMvector(const CHMvector<Item>& Original) {}
00062 };
00063
00064 template<class Item>
00065 CHMvector<Item>::CHMvector
00066 (
00067 size_t GrowBy,
00068 size_t InitialSize,
00069 CHMboolean GrowByDouble
00070 ) : m_GrowBy(GrowBy),
00071 m_Size(InitialSize),
00072 m_Capacity(InitialSize),
00073 m_GrowByDouble(GrowByDouble)
00074 {
00075 CHM_ASSERT(GrowBy > 0);
00076 if (m_Capacity > 0)
00077 {
00078 m_pData = new Item[m_Capacity];
00079 }
00080 else
00081 {
00082 m_pData = NULL;
00083 }
00084 }
00085
00086 template<class Item>
00087 CHMvector<Item>::~CHMvector()
00088 {
00089 delete []m_pData;
00090 }
00091
00092 template<class Item>
00093 void CHMvector<Item>::clear()
00094 {
00095 m_Size = 0;
00096 }
00097
00098 template<class Item>
00099 Item& CHMvector<Item>::operator[](size_t Index)
00100 {
00101 CHM_ASSERT(Index < m_Size);
00102 return m_pData[Index];
00103 }
00104
00105 template<class Item>
00106 const Item& CHMvector<Item>::operator[](size_t Index) const
00107 {
00108 CHM_ASSERT(Index < m_Size);
00109 return m_pData[Index];
00110 }
00111
00112 template<class Item>
00113 size_t CHMvector<Item>::size() const
00114 {
00115 return m_Size;
00116 }
00117
00118 template<class Item>
00119 void CHMvector<Item>::resize(size_t NewSize)
00120 {
00121 CHM_ASSERT(NewSize >= m_Size);
00122 if (NewSize == m_Size)
00123 {
00124
00125 return;
00126 }
00127 if (m_Capacity < NewSize)
00128 {
00129 grow(NewSize);
00130 }
00131 m_Size = NewSize;
00132 }
00133
00134 template<class Item>
00135 void CHMvector<Item>::remove(size_t Index)
00136 {
00137 CHM_ASSERT(Index < m_Size);
00138 for(size_t ItemIndex = Index;
00139 ItemIndex < m_Size-1;
00140 ++ItemIndex)
00141 {
00142 m_pData[ItemIndex] = m_pData[ItemIndex+1];
00143 }
00144 m_Size--;
00145 }
00146
00147 template<class Item>
00148 void CHMvector<Item>::insert(const Item& Value, size_t Index)
00149 {
00150 CHM_ASSERT(Index <= m_Size)
00151 if (m_Size == m_Capacity)
00152 {
00153 grow(m_Capacity+1);
00154 }
00155 CHM_ASSERT(m_Size < m_Capacity);
00156
00157
00158 for (size_t CopyIndex = m_Size;
00159 CopyIndex > Index;
00160 --CopyIndex)
00161 {
00162 m_pData[CopyIndex] = m_pData[CopyIndex-1];
00163 }
00164 m_pData[Index] = Value;
00165 m_Size++;
00166 }
00167
00168 template<class Item>
00169 void CHMvector<Item>::push_back(const Item& Value)
00170 {
00171 if (m_Size == m_Capacity)
00172 {
00173 grow(m_Capacity+1);
00174 }
00175 CHM_ASSERT(m_Size < m_Capacity);
00176
00177 m_pData[m_Size] = Value;
00178 m_Size++;
00179 }
00180
00181 template<class Item>
00182 Item& CHMvector<Item>::pop_back()
00183 {
00184 CHM_ASSERT(m_Size > 0);
00185 m_Size--;
00186 return m_pData[m_Size];
00187 }
00188
00189 template<class Item>
00190 Item& CHMvector<Item>::back()
00191 {
00192 CHM_ASSERT(m_Size > 0);
00193 return m_pData[m_Size-1];
00194 }
00195
00196 template<class Item>
00197 void CHMvector<Item>::grow(size_t RequiredSize)
00198 {
00199 CHM_ASSERT(RequiredSize > 0);
00200 CHM_ASSERT(m_GrowBy > 0);
00201 size_t NewCapacity(m_Capacity);
00202 if (m_GrowByDouble)
00203 {
00204 if (NewCapacity == 0)
00205 {
00206 NewCapacity = 1;
00207 }
00208 while (NewCapacity < RequiredSize)
00209 {
00210 NewCapacity = m_GrowBy * NewCapacity;
00211 }
00212 }
00213 else
00214 {
00215 while (NewCapacity < RequiredSize)
00216 {
00217 NewCapacity = m_GrowBy + NewCapacity;
00218 }
00219 }
00220
00221 Item* pNewData = new Item[NewCapacity];
00222 size_t ItemIndex;
00223 for(ItemIndex = 0;
00224 ItemIndex < m_Size;
00225 ItemIndex++)
00226 {
00227 pNewData[ItemIndex] = m_pData[ItemIndex];
00228 }
00229 delete []m_pData;
00230 m_pData = pNewData;
00231 m_Capacity = NewCapacity;
00232 }
00233
00234 template<class Item>
00235 CHMvector<Item>& CHMvector<Item>::operator=(const CHMvector<Item>& Original)
00236 {
00237 m_GrowBy = Original.m_GrowBy;
00238 m_Size = Original.m_Size;
00239 m_Capacity = Original.m_Capacity;
00240 m_GrowByDouble = Original.m_GrowByDouble;
00241 CHM_ASSERT(m_Size <= m_Capacity);
00242 delete []m_pData;
00243 m_pData = new Item[m_Capacity];
00244 for (size_t DataIndex = 0; DataIndex < m_Size; ++DataIndex)
00245 {
00246 m_pData[DataIndex] = Original.m_pData[DataIndex];
00247 }
00248 return *this;
00249 }
00250 #endif // end of defensive include