///////////////////////////////////////////////////////////////////////////// // Name: Matrix.cpp // Purpose: A 2D vector class // Author: Ben Boeckel // Modified by: Ben Boeckel // Created: Sun Apr 8 12:51:20 2007 // Copyright: ©2007 Ben Boeckel and Nerdy Productions // Licence: // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ///////////////////////////////////////////////////////////////////////////// #include "Matrix.h" template PokeMod::Matrix::Matrix(unsigned w, unsigned h, T &d) { matrix.resize(w, std::vector(h, d)); width = w; height = h; } template PokeMod::Matrix::Matrix(XmlElement &x) { ImportXml(xml); } template void PokeMod::Matrix::AddRow(T &d) { for (std::vector *i = matrix.begin(); i != matrix.end(); ++i) i->push_back(d); ++height; } template void PokeMod::Matrix::ImportXml(XmlElement &xml) { LogImportStart("Matrix"); String curName; width = 0; height = 0; bool haveHeight = false; bool haveWidth = false; xml.ClearCounter(); for (XmlElement *child = xml.NextElement(); child; child = xml.NextElement()) { curName = child->GetName(); if (curName == "height") { child->GetValue(height); if (height) haveHeight = true; } else if (curName == "width") { if (haveHeight) { child->GetValue(width); if (width) haveWidth = true; matrix.resize(w, std::vector(h, T())); } else Log("Matrix Import: Elements out of order", PM_DEBUG_ERROR); } else if (curName == "col") { if (height && width) { unsigned colNum; unsigned rowNum; child->GetValue(colNum); if (colNum < width) { child->ClearCounter(); for (XmlElement *item = child->NextElement(); item; item = child->NextElement()) { item->GetValue(rowNum); if ((item->GetName() == "item") && (rowNum < height)) matrix[colNum][rowNum].ImportXml(*item); else Log("Matrix Import: Item out of bounds", PM_DEBUG_ERROR); } } else Log("Matrix Import: Column out of bounds", PM_DEBUG_ERROR); } else Log("Matrix Import: Elements out of order", PM_DEBUG_ERROR); } else LogUnknownXml("Matrix", curName); } LogImportOver("Matrix", id, name); } template PokeMod::XmlElement PokeMod::Matrix::ExportXml(const String &val) { Log(String("Matrix Export: Starting %s", val.c_str()), PM_DEBUG_INFO); // Declare the elements XmlElement exMatrix(val, 0, true); exMatrix.AddElement("height", height); exMatrix.AddElement("width", width); for (int i = 0; i < width; ++i) { XmlElement col("column", i, true); for (int j = 0; j < height; ++j) { XmlElement item("item", j, true); item.AddElement(matrix[i][j].ExportXml()); } exMatrix.AddElement(col); } Log(String("Matrix Export: Finished %s", val.c_str()), PM_DEBUG_INFO); return exMatrix; } template void PokeMod::Matrix::AddCol(T &d) { matrix.push_back(std::vector(GetHeight(), d)); ++width; } template bool PokeMod::Matrix::InsertRow(unsigned pos, T &d) { if (height < pos) return false; for (std::vector *i = matrix.begin(); i != matrix.end(); ++i) i->insert(pos, d); ++height; return true; } template bool PokeMod::Matrix::InsertCol(unsigned pos, T &d) { if (width < pos) return false; matrix.insert(pos, std::vector(GetHeight(), d)); ++width; return true; } template bool PokeMod::Matrix::DeleteRow(unsigned pos) { if (height <= pos) return false; for (std::vector *i = matrix.begin(); i != matrix.end(); ++i) i->erase(i->begin() + pos); --height; return true; } template bool PokeMod::Matrix::DeleteCol(unsigned pos) { if (width <= pos) return false; matrix.erase(matrix.begin() + pos); --width; return true; } template bool PokeMod::Matrix::Set(unsigned row, unsigned col, T &s) { if ((width <= col) || (height <= col)) return false; (matrix.begin() + col)->assign(row, s); return true; } template T PokeMod::Matrix::Get(unsigned row, unsigned col) { if ((width <= col) || (height <= col)) return T(); return matrix[col][row]; } template std::vector PokeMod::Matrix::GetRow(unsigned row) { std::vector r; for (std::vector *i = matrix.begin(); i != matrix.end(); ++i) r.push_back(i->at(row)); return r; } template std::vector PokeMod::Matrix::GetCol(unsigned col) { return matrix[col]; } template unsigned PokeMod::Matrix::GetHeight() { return height; } template unsigned PokeMod::Matrix::GetWidth() { return width; } template T PokeMod::Matrix::operator[](Point &p) { return matrix[p.GetY()][p.GetX()]; } template std::vector PokeMod::Matrix::operator[](int col) { return matrix[col]; }