#pragma once namespace BWTA { /** * Template used for work with dynamically initialized array with dimension 2. */ template class RectangleArray { public : /** * Creates the array with the specified proportions. * @param width Width of the new array. * @param height Height of the new array. */ RectangleArray(unsigned int width = 1, unsigned int height = 1, Type* data = NULL); /** Copy constructor */ RectangleArray(const RectangleArray& rectangleArray); /** Destorys the array and deletes all content of array. */ ~RectangleArray(void); /** * Gets the width of the array. * @return width of the array. */ unsigned int getWidth(void) const; /** * Gets the height of the array. * @return height of the array. */ unsigned int getHeight(void) const; /** * Gets item of the array on the specified position. * @param x horizontal index of the array position. * @param y vertical index of the array position. * @return item on the specified position. */ Type getItem(unsigned int x, unsigned int y); Type getItemSafe(unsigned int x, unsigned int y); inline Type* operator[](int i) { return this->getColumn(i); } inline Type const * const operator[](int i) const {return this->getColumn(i); } /** * Sets item of the array on the specified position. * @param x horizontal index of the array position. * @param y vertical index of the array position. * @param item new value of the field. */ void setItem(unsigned int x, unsigned int y, Type *item); void resize(unsigned int width, unsigned int height); void printToFile(FILE* f); void saveToFile(const std::string& fileName); /** Sets all fields of the array to the specified value */ void setTo(const Type& value); void setBorderTo(const Type& value); private : bool owner; /** width of array */ unsigned int width; /** height of array */ unsigned int height; /** Array data, stored as linear array of size width*height */ Type *data; /** Pointers to begins of lines*/ Type **columns; /** * Gets data item on the specified index * @param index index of the data to be returned. */ Type getData(unsigned int index); /** * Gets the pointer in data to the beginning of line with the specified * index. * @param index index of the line. */ Type *getColumn(unsigned int index); /** * Gets the pointer in data to the beginning of line with the specified * index. * @param index index of the line. */ const Type *getColumn(unsigned int index) const; /** * Sets the width of the array. * @param width New width of the array. */ void setWidth(unsigned int width); /** * Sets the height of the array. * @param height New height of the array. */ void setHeight(unsigned int height); }; //---------------------------------------------- CONSTRUCTOR ----------------------------------------------- template RectangleArray::RectangleArray(unsigned int width, unsigned int height, Type* data) { this->setWidth(width); this->setHeight(height); this->owner = (data == NULL); if (this->owner) this->data = new Type[this->getWidth()*this->getHeight()]; else this->data = data; columns = new Type*[this->getWidth()]; unsigned int i = 0; for (unsigned int position = 0;i < width; i ++,position += height) columns[i] = &this->data[position]; } //---------------------------------------------- CONSTRUCTOR ----------------------------------------------- template RectangleArray::RectangleArray(const RectangleArray& rectangleArray) :owner(true) { this->setWidth(rectangleArray.getWidth()); this->setHeight(rectangleArray.getHeight()); this->data = new Type[this->getWidth()*this->getHeight()]; columns = new Type*[this->getWidth()]; unsigned int i = 0; for (unsigned int position = 0;i < width; i ++,position += height) columns[i] = &data[position]; memcpy(this->data, rectangleArray.data, sizeof(Type)*this->getWidth()*this->getHeight()); } //----------------------------------------------- DESTRUCTOR ----------------------------------------------- template RectangleArray::~RectangleArray(void) { delete [] columns; if (this->owner) delete [] data; } //----------------------------------------------- GET WIDTH ------------------------------------------------ template unsigned int RectangleArray::getWidth(void) const { return this->width; } //----------------------------------------------- SET WIDTH ------------------------------------------------ template void RectangleArray::setWidth(unsigned int width) { this->width = width; } //----------------------------------------------- GET HEIGHT ----------------------------------------------- template unsigned int RectangleArray::getHeight(void) const { return this->height; } //----------------------------------------------- SET HEIGHT ----------------------------------------------- template void RectangleArray::setHeight(unsigned int height) { this->height = height; } //------------------------------------------------ GET ITEM ------------------------------------------------ template Type RectangleArray::getItem(unsigned int x, unsigned int y) { return this->getColumn(x)[y]; } //------------------------------------------------ GET ITEM ------------------------------------------------ template Type RectangleArray::getItemSafe(unsigned int x, unsigned int y) { if (x<0 || y<0 || x>=this->width || y>=this->height) { return (Type)NULL; } return this->getColumn(x)[y]; } //------------------------------------------------ SET ITEM ------------------------------------------------ template void RectangleArray::setItem(unsigned int x, unsigned int y, Type* item) { this->getColumn(x)[y] = item; } //------------------------------------------------ GET LINE ------------------------------------------------ template Type* RectangleArray::getColumn(unsigned int index) { return columns[index]; } //------------------------------------------------ GET LINE ------------------------------------------------ template const Type* RectangleArray::getColumn(unsigned int index) const { return columns[index]; } //------------------------------------------------- RESIZE ------------------------------------------------- template void RectangleArray::resize(unsigned int width, unsigned int height) { if (this->getWidth() == width && this->getHeight() == height) return; delete [] this->columns; delete [] this->data; this->setWidth(width); this->setHeight(height); this->data = new Type[this->width * this->height]; this->columns = new Type*[this->width]; unsigned int i = 0; for (unsigned int position = 0;i < this->width; i ++,position += this->height) columns[i] = &data[position]; } //--------------------------------------------- PRINT TO FILE ---------------------------------------------- template void RectangleArray::printToFile(FILE* f) { for (unsigned int y = 0; y < this->getHeight(); y++) { for (unsigned int x = 0; x < this->getWidth(); x++) { char ch = this->getColumn(x)[y]; fprintf_s(f, "%c", ch); } fprintf_s(f, "\n"); } } //---------------------------------------------- SAVE TO FILE ---------------------------------------------- template void RectangleArray::saveToFile(const std::string& fileName) { FILE* f = fopen(fileName.c_str(), "wt"); if (!f) exit(1); this->printToFile(f); fclose(f); } //------------------------------------------------- SET TO ------------------------------------------------- template void RectangleArray::setTo(const Type& value) { for (unsigned int i = 0; i < this->getWidth()*this->getHeight(); i++) this->data[i] = value; } //--------------------------------------------- SET BORDER TO ---------------------------------------------- template void RectangleArray::setBorderTo(const Type& value) { for (unsigned int i = 0; i < this->width; i++) { this->getColumn(i)[0] = value; this->getColumn(i)[this->height - 1] = value; } for (unsigned int i = 0; i < this->height; i++) { this->getColumn(0)[i] = value; this->getColumn(this->width - 1)[i] = value; } } //---------------------------------------------------------------------------------------------------------- }