diff --git a/array.h b/array.h deleted file mode 100644 index c63a5f8..0000000 --- a/array.h +++ /dev/null @@ -1,152 +0,0 @@ -#pragma once -#include - -template -class Array -{ -private: - unsigned size, num; //Size and number of elements - T* arr; - - void copy(const Array &other); -public: - - - Array(); - Array(unsigned S); - // - Array& operator=(const Array &other); - ~Array(); - - void resize(unsigned toAdd = 0); - unsigned gSize()const; - unsigned gNum()const; - void sNum(unsigned); - void push(const T&); - void remove(const unsigned id); - - T& operator[](const unsigned i); - T& operator[](const unsigned i)const; - Array& operator+=(const Array &other); -}; - - - -template -Array::Array() : - size(0), - num(0), - arr(nullptr) -{} - -template -Array::Array(unsigned S) : - size(S), - num(0) -{ - arr = new T[S]; -} - -template -Array& Array::operator=(const Array &other) -{ - copy(other); - return *this; -} - -template -Array::~Array() -{ - delete[] arr; -} - - - -template -void Array::resize(unsigned toAdd) -{ - toAdd = toAdd ? toAdd : size / 2; - T *temp = new T[num]; - for (unsigned i = 0; i < num; ++i) - temp[i] = arr[i]; - delete[] arr; - arr = new T[size + toAdd + 1]; - for (unsigned i = 0; i < num; ++i) - arr[i]=temp[i]; - size += toAdd + 1; - delete[] temp; -} - -template -unsigned Array::gSize()const -{ - return size; -} - -template -unsigned Array::gNum()const -{ - return num; -} - -template -void Array::sNum(unsigned newNum) -{ - num = newNum; -} - -template -void Array::copy(const Array &other) -{ - if (size < other.num) - { - delete[] arr; - arr = new T[other.num]; - size = other.num; - } - for (unsigned i = 0; i < other.num; ++i) - arr[i] = other.arr[i]; - num = other.num; -} - -template -void Array::push(const T& newEl) -{ - if (num >= size) - resize(); - arr[num] = newEl; - ++num; -} - -template -void Array::remove(const unsigned id) -{ - --num; - arr[id] = arr[num]; -} - - - -template -T& Array::operator[](const unsigned i) -{ - return arr[i]; -} - -template -T& Array::operator[](const unsigned i)const -{ - return arr[i]; -} - -template -Array& Array::operator+=(const Array &other) -{ - if (size < other.num + num) - resize(other.num); - unsigned i = 0; - for (; i < other.num; ++i) - arr[num + i] = other.arr[i]; - num += i; - return *this; -} diff --git a/help.cpp b/help.cpp index 8eeba0e..1a1a38b 100644 --- a/help.cpp +++ b/help.cpp @@ -1,40 +1 @@ -#include"help.h" -#include"tree.h" - -unsigned strLen(const char* str) -{ - unsigned len = 0; - for (; str[len] != '\0'; ++len) - ; - return len; -} - -void strCopy(char *to, const char* from) -{ - unsigned i = 0; - for (; from[i] != '\0'; ++i) - to[i] = from[i]; - to[i] = '\0'; -} - -bool strComp(const char* first, const char* second) -{ - for (unsigned i = 0; first[i] != '\0' || second[i] != '\0'; ++i) - { - if (first[i] != second[i]) - return 0; - } - return 1; -} - -char* mergeStr(const char* first, const char* second) //Create new string from 2 existing and return it -{ - char *result = new char[strLen(first) + strLen(second) + 1]; - unsigned j = 0; - for (unsigned i = 0; first[i] != '\0'; ++i, ++j) - result[j] = first[i]; - for (unsigned i = 0; second[i] != '\0'; ++i, ++j) - result[j] = second[i]; - result[j] = '\0'; - return result; -} +/* #include"help.h" */ diff --git a/help.h b/help.h index ca2b394..d1c1387 100644 --- a/help.h +++ b/help.h @@ -1,11 +1,34 @@ #pragma once #include "common/basicTypes.h" +#include -unsigned strLen(const char* str); -void strCopy(char *to, const char* from); -bool strComp(const char* firts, const char* second); //0 - diffrent 1 - same -char* mergeStr(const char* first, const char* second); +template inline +Vec& operator+=(Vec& lhs, Vec&& rhs) // Combine 2 vectors +{ + lhs.reserve(lhs.size() + rhs.size()); + + for(auto& el: rhs) + lhs.push_back( std::forward(el) ); + return lhs; +} + +template inline +Vec& operator+=(Vec& lhs, const Vec& rhs) // Combine 2 vectors +{ + lhs.reserve(lhs.size() + rhs.size()); + + for(const auto& el: rhs) + lhs.push_back( std::forward(el) ); + return lhs; +} + +template inline +void remove(Vec& vec, size_t pos) /* Remove from vector by moving the last element in its place */ +{ + vec[pos] = vec[vec.size() - 1]; + vec.pop_back(); +} inline I32 max(I32 a, I32 b) { diff --git a/main.cpp b/main.cpp index 34f61a0..c1504ca 100644 --- a/main.cpp +++ b/main.cpp @@ -93,7 +93,7 @@ int main() /* ====================================================== */ - Array trees; + std::vector trees; bool quit = false; char input[128]; diff --git a/person.cpp b/person.cpp index fcc53cb..4a55e28 100644 --- a/person.cpp +++ b/person.cpp @@ -144,7 +144,7 @@ void Person::print()const getch(); /* waint press */ werase(info_tab); - wrefresh(info_tab); + wrefresh(info_tab); /* todo: dont update */ delwin(info_tab); /* cout << name_ << '\n'; */ diff --git a/tree.cpp b/tree.cpp index 0bc89eb..f175acf 100644 --- a/tree.cpp +++ b/tree.cpp @@ -1,21 +1,21 @@ #include #include -#include #include #include"tree.h" #include"person.h" #include"help.h" using std::cout; - +using std::vector; Tree Tree::operator+ (const Tree& other)// { Tree result(treeName + other.treeName); //The tree resulting from the addition - unsigned *newId = new unsigned[other.numPeople]; //The indexes members of the II tree will have in result + vector newId; //The indexes members of the II tree will have in result + newId.reserve(other.numPeople); - unsigned idCounter = numPeople; - for (unsigned i = 0, j; i < other.numPeople; ++i) //Searches for people present in both trees and gives them the same index in result + U32 idCounter = numPeople; + for (U32 i = 0, j; i < other.numPeople; ++i) //Searches for people present in both trees and gives them the same index in result { for (j = 0; j < numPeople; ++j) { @@ -30,22 +30,22 @@ Tree Tree::operator+ (const Tree& other)// } result.numPeople = idCounter; //The number of members the resulting tree has - result.people.resize(result.numPeople); + result.people.reserve(result.numPeople); result.people = people; //Adds the members of the I tree to the resulting tree - for (unsigned i=0; i < other.numPeople; ++i) //Adds the members of the II tree to the resulting tree + for (U32 i=0; i < other.numPeople; ++i) //Adds the members of the II tree to the resulting tree { if (newId[i] >= numPeople) - result.people.push(other.people[i]); + result.people.push_back(other.people[i]); } - result.relations.resize(result.numPeople); + result.relations.reserve(result.numPeople); result.relations = relations; - for (unsigned i=0; i < other.numPeople; ++i) //Adds the relatives from the II tree + for (U32 i=0; i < other.numPeople; ++i) //Adds the relatives from the II tree { if (newId[i] >= numPeople) //If the member is found in the II tree but not in the I { - result.relations.push(other.relations[i]); + result.relations.push_back(other.relations[i]); } else //If he's found in both { @@ -55,7 +55,7 @@ Tree Tree::operator+ (const Tree& other)// ++result.people[newId[i]].numRel_; } - result.relations[newId[i]].resize(result.people[newId[i]].numRel_); + result.relations[newId[i]].reserve(result.people[newId[i]].numRel_); result.relations[newId[i]] = relations[newId[i]]; @@ -63,16 +63,16 @@ Tree Tree::operator+ (const Tree& other)// } } - delete[]newId; return result; } Tree& Tree::operator+=(const Tree& other) { - unsigned *newId = new unsigned[other.numPeople]; //The indexes people from II tree will have in I tree + vector newId; //The indexes people from II tree will have in I tree + newId.reserve(other.numPeople); - unsigned idCounter = numPeople; - for (unsigned i = 0, j; i < other.numPeople; ++i) //Searches for people present in both trees and gives them the same index in I + U32 idCounter = numPeople; + for (U32 i = 0, j; i < other.numPeople; ++i) //Searches for people present in both trees and gives them the same index in I { for (j = 0; j < numPeople; ++j) { @@ -86,32 +86,32 @@ Tree& Tree::operator+=(const Tree& other) newId[i] = idCounter++; } - people.resize(idCounter); - for (unsigned i = 0; i < other.numPeople; ++i) //Adds the member personal data of II tree to I tree + people.reserve(idCounter); + for (U32 i = 0; i < other.numPeople; ++i) //Adds the member personal data of II tree to I tree { if (newId[i] >= numPeople) - people.push(other.people[i]); + people.push_back(other.people[i]); } - relations.resize(idCounter); - for (unsigned i = 0; i < other.numPeople; ++i) //Merges the relative data + relations.reserve(idCounter); + for (U32 i = 0; i < other.numPeople; ++i) //Merges the relative data { if (newId[i] >= numPeople) { - relations.push(other.relations[i]); - for (unsigned j = 0; j < other.people[i].numRel_; ++j) + relations.push_back(other.relations[i]); + for (U32 j = 0; j < other.people[i].numRel_; ++j) relations[newId[i]][j].id = newId[ relations[newId[i]][j].id ]; } else //If the member is present in both trees { - for (unsigned j = 0; j < other.people[i].numRel_; ++j) //Adds the number of relatives from the II to the number in the I + for (U32 j = 0; j < other.people[i].numRel_; ++j) //Adds the number of relatives from the II to the number in the I { if (newId[other.relations[i][j].id] >= numPeople) ++people[newId[i]].numRel_; } - relations[newId[i]].resize(people[newId[i]].numRel_); - for (unsigned j = 0; j < other.people[i].numRel_; ++j) + relations[newId[i]].reserve(people[newId[i]].numRel_); + for (U32 j = 0; j < other.people[i].numRel_; ++j) { relations[newId[i]][j + people[newId[i]].numRel_ - other.people[i].numRel_].id = newId[other.relations[i][j].id]; relations[newId[i]][j + people[newId[i]].numRel_ - other.people[i].numRel_].type = other.relations[i][j].type; @@ -119,18 +119,17 @@ Tree& Tree::operator+=(const Tree& other) } } - delete[]newId; numPeople = idCounter; //Number of members in I tree return *this; } Tree& Tree::operator-= (const Tree& other) { - for (unsigned i = 0; i < numPeople; ++i) + for (U32 i = 0; i < numPeople; ++i) { - for (unsigned j = 0; j < other.numPeople; ++j) + for (const Person& othPers: other.people) { - if (people[i] == other.people[j]) + if (people[i] == othPers) { removePerson(i); --i; @@ -152,7 +151,7 @@ unsigned Tree::findId(const char* name, const short year, const unsigned char mo { //TODO //Person sought(name, day, month, year,) - for (unsigned i = 0; i < numPeople; ++i) + for (person_id i = 0; i < numPeople; ++i) { if (name == people[i].name_) //&& (year == people[i].year || !year || !people[i].year) && (month == people[i].month || !month || !people[i].month) && (day == people[i].day || !day || people[i].day)) return i; @@ -172,7 +171,7 @@ unsigned Tree::findOldestAncestor(unsigned id, bool isMale)const unsigned Tree::findCommonAncestor(const unsigned firstId, const unsigned secondId)const { - Array visited(numPeople); //if a member is visited twice he's a common ancestor + vector visited(numPeople); //if a member is visited twice he's a common ancestor for (unsigned i = 0; i < numPeople; ++i) visited[i] = 0; commonAncestorRec(firstId, visited); @@ -194,7 +193,7 @@ unsigned Tree::findCommonAncestor(const unsigned firstId, const unsigned secondI /* person_id Tree::findRelation(person_id first, person_id second) const */ /* { */ /* const auto& curRels = relations[first]; */ -/* for(auto i =0; i(&relations[i][j]), sizeof(relations[i][j])); + relationFile.write(reinterpret_cast(&relations[i][j]), sizeof(relations[i][j])); } relationFile.close(); } @@ -235,7 +234,6 @@ bool Tree::loadTree() people.resize(numPeople); for (unsigned i = 0; i < numPeople; ++i) people[i].load(peopleFile); - people.sNum(numPeople); peopleFile.close(); @@ -246,9 +244,7 @@ bool Tree::loadTree() relations[i].resize(people[i].numRel_); for (unsigned j = 0; j < people[i].numRel_; ++j) relationFile.read(reinterpret_cast(&relations[i][j]), sizeof(relations[i][j])); - relations[i].sNum(people[i].numRel_); } - relations.sNum(numPeople); relationFile.close(); return 1; } @@ -256,10 +252,10 @@ bool Tree::loadTree() void Tree::addPerson(const char* name, bool isMale, unsigned father, unsigned mother, EventTime birth, EventTime death) { Person newPerson(name, birth, isMale, death); - people.push(newPerson); + people.push_back(newPerson); - Array newRels; - relations.push(newRels); + vector newRels; + relations.push_back(newRels); ++numPeople; addRelation(father, Parent, numPeople - 1); @@ -288,7 +284,7 @@ bool Tree::addRelation(const unsigned firstId, const RelType type, const unsigne } if (i >= people[firstId].numRel_) { - relations[firstId].push({secondId, type}); + relations[firstId].push_back({secondId, type}); ++people[firstId].numRel_; } @@ -318,23 +314,22 @@ void Tree::removeRelation(const char* firstName, const char* secondName) removeRelation(findId(firstName), findId(secondName)); } -void Tree::removePerson(const unsigned id) +void Tree::removePerson(const person_id id) { - unsigned relId; //Íoìåð íà òåêóùèÿ ðîäíèíàòà - for (unsigned i = 0; i < people[id].numRel_; ++i) //Ïðåìàõâàò ñå âðúçêèòå íà ÷ëåíà çà ïðåìàõâàíå + person_id relId; //Íoìåð íà òåêóùèÿ ðîäíèíàòà + for (Relation rel: relations[id]) //Remove all of his relations { - relId = relations[id][i].id; - for (unsigned j = 0; j < people[relId].numRel_; ++j) + relId = rel.id; + for (U32 j = 0; j < relations[relId].size(); ++j) { if (relations[relId][j].id == id) { - relations[relId].remove(j); + remove(relations[relId], j); break; } } - --people[relId].numRel_; } - for (unsigned i = 0; i < people[numPeople - 2].numRel_; ++i) //Ïîñëåäíèÿò ÷ëåí âçåìà íîìåðà íà ïðåìàõíàòèÿ + for (unsigned i = 0; i < people[numPeople - 2].numRel_; ++i) //Move the last in his place and update IDs { relId = relations[numPeople - 1][i].id; for (unsigned j = 0; j < people[relId].numRel_; ++j) @@ -346,8 +341,8 @@ void Tree::removePerson(const unsigned id) } } } - relations.remove(id); - people.remove(id); + remove(relations, id); + remove(people, id); --numPeople; } @@ -358,21 +353,19 @@ void Tree::removePerson(const char* personName, short year, unsigned char month, void Tree::removeRelation(const unsigned firstId, const unsigned secondId) { - for (unsigned i = 0; i < people[firstId].numRel_; ++i) + for (unsigned i = 0; i < relations[firstId].size(); ++i) { if (relations[firstId][i].id == secondId) { - relations[firstId].remove(i); - --people[firstId].numRel_; + remove(relations[firstId], i); break; } } - for (unsigned i = 0; i < people[secondId].numRel_; ++i) + for (unsigned i = 0; i < relations[secondId].size(); ++i) { if (relations[secondId][i].id == firstId) { - relations[secondId].remove(i); - --people[secondId].numRel_; + remove(relations[secondId], i); break; } } @@ -399,6 +392,16 @@ void Tree::display() case KEY_UP: selectUp(); break; + case 'j': + selectDown(); + break; + case 'k': + selectUp(); + break; + case 'i': + people[selected_].print(); + draw(); + break; default: break; } } @@ -419,10 +422,8 @@ void Tree::draw() const void Tree::print() const { - //for(const auto& member: people) - // member.print(); - for(int i=0; i &visited)const +void Tree::commonAncestorRec(person_id id, vector &visited)const { auto& curRels = relations[id]; - for (unsigned i = 0; i < curRels.gNum(); ++i) + for (auto& rel: curRels) { - if (curRels[i].type == Child) + if (rel.type == Child) { - ++visited[curRels[i].id]; - commonAncestorRec(curRels[i].id, visited); + ++visited[rel.id]; + commonAncestorRec(rel.id, visited); } } } @@ -547,7 +548,7 @@ static U8 linkToChild(I16 startY, I16 startX, I16 endX, bool moreSiblings) /* people[id].draw(drawY, drawX, true, false, true); */ /* std::vector children; */ -/* for(U32 i=0; i children; - for(person_id i = 0; i < rels.gNum(); ++i) + for(const auto& rel: rels) { - if(rels[i].type == RelType::Parent) - children.push_back(rels[i].id); + if(rel.type == RelType::Parent) + children.push_back(rel.id); - else if(rels[i].type == RelType::Spouse && spouse == Nobody) - spouse = rels[i].id; + else if(rel.type == RelType::Spouse && spouse == Nobody) + spouse = rel.id; } const size_t numKids = children.size(); person.draw(drawY, drawX, @@ -625,7 +626,7 @@ void Tree::selectLeft() /* todo */ { const auto& curRel = relations[selected_]; - for(U32 i = 0; i < curRel.gNum(); ++i) + for(U32 i = 0; i < curRel.size(); ++i) { if(curRel[i].type == Sibling) { @@ -638,13 +639,13 @@ void Tree::selectLeft() /* todo */ void Tree::selectDown() { - const auto& curRel = relations[selected_]; + const auto& curRels = relations[selected_]; - for(U32 i = 0; i < curRel.gNum(); ++i) + for(const auto& rel: curRels) { - if(curRel[i].type == Parent) + if(rel.type == Parent) { - selected_ = curRel[i].id; + selected_ = rel.id; draw(); return; } @@ -653,13 +654,13 @@ void Tree::selectDown() void Tree::selectUp() { - const auto& curRel = relations[selected_]; + const auto& curRels = relations[selected_]; - for(U32 i = 0; i < curRel.gNum(); ++i) + for(const auto& rel: curRels) { - if(curRel[i].type == Child && (people[curRel[i].id].isMale() || curRel[i].id == focused_)) + if(rel.type == Child && (people[rel.id].isMale() || rel.id == focused_)) { - selected_ = curRel[i].id; + selected_ = rel.id; draw(); return; } diff --git a/tree.h b/tree.h index 009fec0..90229a9 100644 --- a/tree.h +++ b/tree.h @@ -1,7 +1,7 @@ #pragma once #include -#include "array.h" +#include #include "person.h" using person_id = U32; @@ -58,7 +58,7 @@ public: void printOldestAncestors(person_id id)const;// private: - void commonAncestorRec(person_id id, const Array &visited)const; + void commonAncestorRec(person_id id, std::vector &visited)const; void draw() const; /* draw a line of people starting from person with id @@ -74,8 +74,8 @@ private: std::string treeName = "Unnamed"; unsigned numPeople = 0; - Array people; //The data for each member - Array> relations; //The relatives of each member + std::vector people; //The data for each member + std::vector> relations; //The relatives of each member person_id focused_ = 0; /* the tree was draw based on this person */ person_id selected_ = 0;