BWAPI
|
00001 #pragma once 00002 00003 #include <stdio.h> 00004 #include <string.h> 00005 #include "Exceptions.h" 00006 00007 namespace Util 00008 { 00012 template <class Type> 00013 class RectangleArray 00014 { 00015 public : 00021 RectangleArray(unsigned int width = 1, unsigned int height = 1, Type* data = NULL); 00023 RectangleArray(const RectangleArray<Type>& rectangleArray); 00025 ~RectangleArray(void); 00030 unsigned int getWidth(void) const; 00035 unsigned int getHeight(void) const; 00042 Type* getItem(unsigned int x, unsigned int y); 00043 inline Type* operator[](int i) { return this->getColumn(i); } 00044 inline Type const * const operator[](int i) const {return this->getColumn(i); } 00051 void setItem(unsigned int x, unsigned int y, Type *item); 00052 void resize(unsigned int width, unsigned int height); 00053 void printToFile(FILE* f); 00054 void saveToFile(const std::string& fileName); 00056 void setTo(const Type& value); 00057 void setBorderTo(const Type& value); 00058 private : 00059 bool owner; 00061 unsigned int width; 00063 unsigned int height; 00065 Type *data; 00067 Type **columns; 00072 Type getData(unsigned int index); 00078 Type *getColumn(unsigned int index); 00084 const Type *getColumn(unsigned int index) const; 00089 void setWidth(unsigned int width); 00094 void setHeight(unsigned int height); 00095 }; 00096 //---------------------------------------------- CONSTRUCTOR ----------------------------------------------- 00097 template <class Type> 00098 RectangleArray<Type>::RectangleArray(unsigned int width, unsigned int height, Type* data) 00099 { 00100 this->setWidth(width); 00101 this->setHeight(height); 00102 this->owner = (data == NULL); 00103 if (this->owner) 00104 this->data = new Type[this->getWidth()*this->getHeight()]; 00105 else 00106 this->data = data; 00107 00108 columns = new Type*[this->getWidth()]; 00109 unsigned int i = 0; 00110 for (unsigned int position = 0; i < width; i++, position += height) 00111 columns[i] = &this->data[position]; 00112 } 00113 //---------------------------------------------- CONSTRUCTOR ----------------------------------------------- 00114 template <class Type> 00115 RectangleArray<Type>::RectangleArray(const RectangleArray<Type>& rectangleArray) 00116 :owner(true) 00117 { 00118 this->setWidth(rectangleArray.getWidth()); 00119 this->setHeight(rectangleArray.getHeight()); 00120 this->data = new Type[this->getWidth()*this->getHeight()]; 00121 columns = new Type*[this->getWidth()]; 00122 00123 unsigned int i = 0; 00124 for (unsigned int position = 0; i < width; i++, position += height) 00125 columns[i] = &data[position]; 00126 memcpy(this->data, rectangleArray.data, sizeof(Type)*this->getWidth()*this->getHeight()); 00127 } 00128 //----------------------------------------------- DESTRUCTOR ----------------------------------------------- 00129 template <class Type> 00130 RectangleArray<Type>::~RectangleArray(void) 00131 { 00132 delete [] columns; 00133 if (this->owner) 00134 delete [] data; 00135 } 00136 //----------------------------------------------- GET WIDTH ------------------------------------------------ 00137 template <class Type> 00138 unsigned int RectangleArray<Type>::getWidth(void) const 00139 { 00140 return this->width; 00141 } 00142 //----------------------------------------------- SET WIDTH ------------------------------------------------ 00143 template <class Type> 00144 void RectangleArray<Type>::setWidth(unsigned int width) 00145 { 00146 this->width = width; 00147 } 00148 //----------------------------------------------- GET HEIGHT ----------------------------------------------- 00149 template <class Type> 00150 unsigned int RectangleArray<Type>::getHeight(void) const 00151 { 00152 return this->height; 00153 } 00154 //----------------------------------------------- SET HEIGHT ----------------------------------------------- 00155 template <class Type> 00156 void RectangleArray<Type>::setHeight(unsigned int height) 00157 { 00158 this->height = height; 00159 } 00160 //------------------------------------------------ GET ITEM ------------------------------------------------ 00161 template <class Type> 00162 Type* RectangleArray<Type>::getItem(unsigned int x, unsigned int y) 00163 { 00164 return this->getColumn(x)[y]; 00165 } 00166 //------------------------------------------------ SET ITEM ------------------------------------------------ 00167 template <class Type> 00168 void RectangleArray<Type>::setItem(unsigned int x, unsigned int y, Type* item) 00169 { 00170 this->getColumn(x)[y] = item; 00171 } 00172 //------------------------------------------------ GET LINE ------------------------------------------------ 00173 template <class Type> 00174 Type* RectangleArray<Type>::getColumn(unsigned int index) 00175 { 00176 return columns[index]; 00177 } 00178 //------------------------------------------------ GET LINE ------------------------------------------------ 00179 template <class Type> 00180 const Type* RectangleArray<Type>::getColumn(unsigned int index) const 00181 { 00182 return columns[index]; 00183 } 00184 //------------------------------------------------- RESIZE ------------------------------------------------- 00185 template <class Type> 00186 void RectangleArray<Type>::resize(unsigned int width, unsigned int height) 00187 { 00188 if (!this->owner) 00189 throw GeneralException("Can't resize array that doesn't own the data"); 00190 if (this->getWidth() == width && 00191 this->getHeight() == height) 00192 return; 00193 00194 delete [] this->columns; 00195 delete [] this->data; 00196 00197 this->setWidth(width); 00198 this->setHeight(height); 00199 00200 this->data = new Type[this->width * this->height]; 00201 00202 this->columns = new Type*[this->width]; 00203 unsigned int i = 0; 00204 for (unsigned int position = 0; i < this->width; i++, position += this->height) 00205 columns[i] = &data[position]; 00206 } 00207 //--------------------------------------------- PRINT TO FILE ---------------------------------------------- 00208 template <class Type> 00209 void RectangleArray<Type>::printToFile(FILE* f) 00210 { 00211 for (unsigned int y = 0; y < this->getHeight(); ++y) 00212 { 00213 for (unsigned int x = 0; x < this->getWidth(); ++x) 00214 { 00215 char ch = this->getColumn(x)[y]; 00216 fprintf(f, "%c", ch); 00217 } 00218 fprintf(f, "\n"); 00219 } 00220 } 00221 //---------------------------------------------- SAVE TO FILE ---------------------------------------------- 00222 template <class Type> 00223 void RectangleArray<Type>::saveToFile(const std::string& fileName) 00224 { 00225 FILE* f = fopen(fileName.c_str(), "wt"); 00226 if (!f) 00227 throw FileException("RectangleArray::saveToFile Couldn't open file " + fileName + "for writing"); 00228 this->printToFile(f); 00229 fclose(f); 00230 } 00231 //------------------------------------------------- SET TO ------------------------------------------------- 00232 template <class Type> 00233 void RectangleArray<Type>::setTo(const Type& value) 00234 { 00235 for (unsigned int i = 0; i < this->getWidth()*this->getHeight(); ++i) 00236 this->data[i] = value; 00237 } 00238 //--------------------------------------------- SET BORDER TO ---------------------------------------------- 00239 template <class Type> 00240 void RectangleArray<Type>::setBorderTo(const Type& value) 00241 { 00242 for (unsigned int i = 0; i < this->width; ++i) 00243 { 00244 this->getColumn(i)[0] = value; 00245 this->getColumn(i)[this->height - 1] = value; 00246 } 00247 for (unsigned int i = 0; i < this->height; ++i) 00248 { 00249 this->getColumn(0)[i] = value; 00250 this->getColumn(this->width - 1)[i] = value; 00251 } 00252 } 00253 //---------------------------------------------------------------------------------------------------------- 00254 }