use typedefed types, BirthTime

This commit is contained in:
vrd
2022-08-27 16:35:40 +03:00
parent fbfe017284
commit 1bf0a7f6a4
8 changed files with 397 additions and 385 deletions
+1 -1
View File
@@ -1 +1 @@
g++ -Ofast -flto -fipa-pta -s *.cpp\ g++ -std=gnu++20 -Ofast -flto -fipa-pta -s -DNDEBUG *.cpp\
+1 -1
View File
@@ -1 +1 @@
g++ *.cpp g++ -std=gnu++20 -g -Og -Wall *.cpp
+3 -1
View File
@@ -1,6 +1,8 @@
#pragma once #pragma once
enum Relation : char; #include "common/basicTypes.h"
enum Relation : U8;
unsigned strLen(const char* str); unsigned strLen(const char* str);
void strCopy(char *to, const char* from); void strCopy(char *to, const char* from);
+54 -31
View File
@@ -2,6 +2,9 @@
#include "tree.h" #include "tree.h"
#include "help.h" #include "help.h"
using std::cin;
using std::cout;
int main() int main()
{ {
/*Tree test1("Dechkovi"); //addTree Dechkovi addTree Karamanovi load 0 load 1 (to work with these example trees) /*Tree test1("Dechkovi"); //addTree Dechkovi addTree Karamanovi load 0 load 1 (to work with these example trees)
@@ -32,52 +35,67 @@ int main()
test1.saveTree(); test1.saveTree();
test2.saveTree();*/ test2.saveTree();*/
Tree firstTree("firstTree");
firstTree.addPerson("Адам,", {0, 1, 6}, true);
firstTree.addPerson("Ева", {0, 1, 6}, false);
firstTree.addRelation(0, Husband, 1);
firstTree.addPerson("Кайн", {}, true, 0, 1);
firstTree.addPerson("Авел", {}, true, 0, 1);
firstTree.addPerson("Сит", 230, true, 0, 1);
firstTree.addRelation(2, Brother, 3);
firstTree.addRelation(2, Brother, 4);
firstTree.print();
firstTree.saveTree();
Array<Tree> trees; Array<Tree> trees;
bool quit=0; bool quit = false;
char input[128]; char input[128];
short i; //Number of the entered command short i; //Number of the entered command
const short numCom = 23; const short numCom = 24;
const char* const commandList[] = const char* const commandList[] =
{ {
"quit", //0 "quit", //0
"rename", //1 "rename", //1
"load", //2 "load", //2
"save", //3 "save", //3
"addPerson", //4 "addPerson", //4
"addPersonWP", //5 Adds a person and connects him to his parents, by their number "addPersonWP", //5 Adds a person and connects him to his parents, by their number
"addRelation", //6 Adds a relation between two people input by name "addRelation", //6 Adds a relation between two people input by name
"addRelationID", //7 -||- by number "addRelationID", //7 -||- by number
"findID", //8 "findID", //8
"equate", //9 Enter the number of two trees, the second becomes equal to the first "equate", //9 Enter the number of two trees, the second becomes equal to the first
"combine", //10 "combine", //10
"subtract", //11 "subtract", //11
"removePerson", //12 "removePerson", //12
"removePersonID", //13 "removePersonID", //13
"removeRelation", //14 "removeRelation", //14
"removeRelationID", //15 "removeRelationID", //15
"addTree", //16 "addTree", //16
"prtRelatives", //17 "prtRelatives", //17
"prtMember", //18 "prtMember", //18
"prtAncestors", //19 "prtAncestors", //19
"chooseTree", //20 "chooseTree", //20
"prtCommonAncestor",//21 "prtCommonAncestor", //21
"prtOldestAncestors"//22 "prtOldestAncestors",//22
"prtTree" //23
}; };
unsigned curTree = 0, //Currently selected tree ID unsigned curTree = 0, //Currently selected tree ID
id, secondId; //Indexes id, secondId; //Indexes
Tree *newTree; Tree *newTree;
char name[128], secondName[128]; char name[128], secondName[128];
unsigned char day, month; U8 day, month; //TODO add h m
short year; U16 year;
bool sex; bool sex;
unsigned father, mother; unsigned father, mother;
do do
{ {
std::cout << "Enter a command\n\n"; std::cout << "Enter a command\n";
std::cin >> input; std::cin >> input;
for (i = 0; i < numCom; ++i) for (i = 0; i < numCom; ++i)
{ {
@@ -99,7 +117,9 @@ int main()
trees[curTree].rename(name); trees[curTree].rename(name);
break; break;
case 2: //load case 2: //load
if (!trees[curTree].loadTree()) cin >> input;
trees.push(Tree(input));
if (!trees[trees.gNum() - 1].loadTree())
std::cout << "File doesnt exist or is empty.\n\n"; std::cout << "File doesnt exist or is empty.\n\n";
break; break;
case 3: //save case 3: //save
@@ -107,11 +127,11 @@ int main()
break; break;
case 4: //addPerson case 4: //addPerson
std::cin >> name >> day >> month >> year >> sex; std::cin >> name >> day >> month >> year >> sex;
trees[curTree].addPerson(name, year, month, day, sex); trees[curTree].addPerson(name, BirthTime(year, month, day) , sex);
break; break;
case 5: //addPersonWP case 5: //addPersonWP
std::cin >> name >> day >> month >> year >> sex >> father >> mother; std::cin >> name >> day >> month >> year >> sex >> father >> mother;
trees[curTree].addPerson(name, year, month, day, sex, father, mother); trees[curTree].addPerson(name, BirthTime(year, month, day), sex, father, mother);
break; break;
case 6: //addRelation case 6: //addRelation
std::cin >> name >> input >> secondName; std::cin >> name >> input >> secondName;
@@ -230,6 +250,9 @@ int main()
else else
std::cout << "No such member\n\n"; std::cout << "No such member\n\n";
break; break;
case 23:
trees[curTree].print();
break;
} }
} while (!quit); } while (!quit);
+62 -42
View File
@@ -1,29 +1,54 @@
#include <iostream>
#include <assert.h>
#include"person.h" #include"person.h"
#include"help.h" #include "help.h"
#include<iostream>
/*Person::Person(): using std::cout;
name(nullptr),
numRel(0),
day(0),
month(0),
year(0),
isMale(true)
{}*/
Person::Person(const char* Name, unsigned char Day, unsigned char Month, short Year, bool IsMale) : BirthTime::BirthTime(U16 Year, U8 Month, U8 Day, U8 Hour, U8 Minute)
numRel(0), : year(Year)
day(Day), , month(Month)
month(Month), , day(Day)
year(Year), , hour(Hour)
isMale(IsMale) , minute(Minute)
{ {
name = new char[strLen(Name) + 1]; assert(month <= 12 && day <= 31 && hour <= 23 && minute <= 59 && "Invalid BirthTime data");
strCopy(name, Name); }
void BirthTime::print() const
{
cout << "Birth: ";
if (day != UNKNOWN)
cout << (I32)day;
else
cout << "??";
cout << '.';
if (month != UNKNOWN)
cout << (I32)month;
else
cout << "??";
cout << '.';
if (year != UNKNOWN)
cout << (I32)year;
else
cout << "????";
cout << '\n';
} }
Person& Person::operator=(const Person &other) Person::Person(const char* Name, BirthTime Birth, bool IsMale)
: name(Name)
, numRel(0)
, birth(Birth)
, isMale(IsMale)
{
}
/*Person& Person::operator=(const Person &other)
{ {
if (&other!=this) if (&other!=this)
{ {
@@ -35,58 +60,53 @@ Person& Person::operator=(const Person &other)
year = other.year; year = other.year;
} }
return *this; return *this;
} }*/
Person::~Person()
{
delete[] name;
}
bool Person::operator==(const Person &other)const bool Person::operator==(const Person &other)const
{ {
return strComp(name, other.name) && isMale == other.isMale && (day == other.day || !day || !other.day) && (month == other.month || !month || !other.month) && (year == other.year || !year || !other.year); return name == other.name && isMale == other.isMale; //TODO && day == other.day || !day || !other.day) && (month == other.month || !month || !other.month) && (year == other.year || !year || !other.year);
} }
void Person::save(std::ofstream &file)const void Person::save(std::ofstream &file)const
{ {
// //
char nameLen = strLen(name); char nameLen = name.size();
file.write(reinterpret_cast<char*>(&nameLen), sizeof(nameLen)); file.write(reinterpret_cast<char*>(&nameLen), sizeof(nameLen));
file.write(name, nameLen * sizeof(*name)); file.write(name.data(), nameLen * sizeof(name[0]));
file.write(reinterpret_cast<const char*>(&numRel), sizeof(numRel)); file.write(reinterpret_cast<const char*>(&numRel), sizeof(numRel));
file.write(reinterpret_cast<const char*>(&isMale), sizeof(isMale)); file.write(reinterpret_cast<const char*>(&isMale), sizeof(isMale));
file.write(reinterpret_cast<const char*>(&day), sizeof(day)); //file.write(reinterpret_cast<const char*>(&day), sizeof(day)); TODO
file.write(reinterpret_cast<const char*>(&month), sizeof(month)); //file.write(reinterpret_cast<const char*>(&month), sizeof(month));
file.write(reinterpret_cast<const char*>(&year), sizeof(year)); //file.write(reinterpret_cast<const char*>(&year), sizeof(year));
} }
void Person::load(std::ifstream &file) void Person::load(std::ifstream &file)
{ {
char nameLen; char nameLen;
file.read((char*)&nameLen, sizeof(nameLen)); file.read((char*)&nameLen, sizeof(nameLen)); //Check len
name = new char[nameLen + 1]; C8 nameBuf[128];
file.read(name, nameLen * sizeof(*name)); file.read(nameBuf, nameLen * sizeof(*nameBuf));
name[nameLen] = '\0'; nameBuf[nameLen] = '\0';
name = nameBuf;
file.read(reinterpret_cast<char*>(&numRel), sizeof(numRel)); file.read(reinterpret_cast<char*>(&numRel), sizeof(numRel));
file.read(reinterpret_cast<char*>(&isMale), sizeof(isMale)); file.read(reinterpret_cast<char*>(&isMale), sizeof(isMale));
file.read(reinterpret_cast<char*>(&day), sizeof(day)); //file.read(reinterpret_cast<char*>(&day), sizeof(day)); TODO
file.read(reinterpret_cast<char*>(&month), sizeof(month)); //file.read(reinterpret_cast<char*>(&month), sizeof(month));
file.read(reinterpret_cast<char*>(&year), sizeof(year)); //file.read(reinterpret_cast<char*>(&year), sizeof(year));
} }
void Person::rename(const char* newName) void Person::rename(const char* newName)
{ {
delete[] name; name = newName;
name = new char[strLen(newName) + 1];
strCopy(name, newName);
} }
void Person::print()const void Person::print()const
{ {
std::cout << name << "\nBirthday: " << (int)day << "." << (int)month << "." << year << "\nSex: "; std::cout << name << '\n';
birth.print();
std::cout << (isMale ? "Male\n\n" : "Female\n\n"); std::cout << (isMale ? "Male\n\n" : "Female\n\n");
} }
+15 -7
View File
@@ -1,16 +1,25 @@
#pragma once #pragma once
#include <string>
#include <fstream> #include <fstream>
#include "common/basicTypes.h" #include "common/basicTypes.h"
struct BirthTime
{
static const U16 UNKNOWN = 0;
/*explicit*/ BirthTime(U16 Year=UNKNOWN, U8 Month=UNKNOWN, U8 Day=UNKNOWN, U8 Hour=UNKNOWN, U8 Minute=UNKNOWN);
void print() const;
U16 year;
U8 month, day, hour, minute;
};
class Person class Person
{ {
public: public:
Person() = default; Person() = default;
Person(const char* Name, unsigned char Day, unsigned char Monthay, short Year, bool Sex); Person(const char* Name, BirthTime Birth, bool Sex);
//
Person& operator=(const Person &other);
~Person();
bool operator==(const Person &other)const; bool operator==(const Person &other)const;
@@ -22,9 +31,8 @@ public:
friend class Tree; friend class Tree;
private: private:
char *name; std::string name;
unsigned numRel; //Number of close relatives - mother, father, brother, sister, wife/husband, child, ex-wife/husband unsigned numRel; //Number of close relatives - mother, father, brother, sister, wife/husband, child, ex-wife/husband
unsigned char day, month; //Birth BirthTime birth;
short year;
bool isMale; bool isMale;
}; };
+31 -73
View File
@@ -1,56 +1,20 @@
#include <iostream>
#include<fstream>
#include"tree.h" #include"tree.h"
#include"person.h" #include"person.h"
#include"help.h" #include"help.h"
#include<fstream>
using std::cout;
Tree::Tree() :
numPeople(0)
{
treeName = new char[strLen("Unnamed") + 1];
strCopy(treeName, "Unnamed");
}
Tree::Tree(const char *Name):
numPeople(0)
{
treeName = new char[strLen(Name) + 1];
strCopy(treeName, Name);
}
Tree::Tree(const Tree& other) :
numPeople(other.numPeople)
{
treeName = new char[strLen(other.treeName) + 1];
strCopy(treeName, other.treeName);
people = other.people;
relatives = other.relatives;
relations = other.relations;
}
Tree& Tree::operator= (const Tree& other)
{
if (this != &other)
{
rename(other.treeName);
numPeople = other.numPeople;
people = other.people;
relatives = other.relatives;
relations = other.relations;
}
return *this;
}
Tree::~Tree()
{
delete[] treeName;
}
Tree::Tree()
: treeName("Unnamed")
, numPeople(0)
{}
Tree Tree::operator+ (const Tree& other)// Tree Tree::operator+ (const Tree& other)//
{ {
Tree result(mergeStr(treeName, other.treeName)); //The tree resulting from the addition 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 unsigned *newId = new unsigned[other.numPeople]; //The indexes members of the II tree will have in result
unsigned idCounter = numPeople; unsigned idCounter = numPeople;
@@ -191,17 +155,16 @@ Tree& Tree::operator-= (const Tree& other)
void Tree::rename(const char* newName) void Tree::rename(const char* newName)
{ {
delete[] treeName; treeName = newName;
treeName = new char[strLen(newName) + 1];
strCopy(treeName, newName);
} }
unsigned Tree::findId(const char* name, const short year, const unsigned char month, const unsigned char day)const unsigned Tree::findId(const char* name, const short year, const unsigned char month, const unsigned char day)const
{ {
//TODO
//Person sought(name, day, month, year,) //Person sought(name, day, month, year,)
for (unsigned i = 0; i < numPeople; ++i) for (unsigned i = 0; i < numPeople; ++i)
{ {
if (strComp(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)) 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; return i;
} }
return Nobody; return Nobody;
@@ -226,35 +189,29 @@ unsigned Tree::findCommonAncestor(const unsigned firstId, const unsigned secondI
commonAncestorRec(secondId, visited); commonAncestorRec(secondId, visited);
unsigned oldestId = Nobody; unsigned oldestId = Nobody;
short oldestBday = SHRT_MAX; U16 oldestBday = SHRT_MAX;
for (unsigned i = 0; i < numPeople; ++i) for (unsigned i = 0; i < numPeople; ++i)
{ {
if (visited[i] == 2 && people[i].year<oldestBday) if (visited[i] == 2 && people[i].birth.year<oldestBday)
{ {
oldestBday = people[i].year; oldestBday = people[i].birth.year;
oldestId = i; oldestId = i;
} }
} }
return oldestId; return oldestId;
} }
void Tree::saveTree()const void Tree::saveTree() const
{ {
char* fileName = mergeStr(treeName, ".people"); std::ofstream peopleFile(treeName+ ".people", std::ios::binary);
std::ofstream peopleFile(fileName, std::ios::binary);
delete[] fileName;
peopleFile.write(reinterpret_cast<const char*>(&numPeople), sizeof(numPeople)); peopleFile.write(reinterpret_cast<const char*>(&numPeople), sizeof(numPeople));
for (unsigned i = 0; i < numPeople; ++i) for (unsigned i = 0; i < numPeople; ++i)
people[i].save(peopleFile); people[i].save(peopleFile);
peopleFile.close(); peopleFile.close();
fileName = mergeStr(treeName, ".relatives"); std::ofstream relativeFile(treeName + ".relatives", std::ios::binary);
std::ofstream relativeFile(fileName, std::ios::binary); std::ofstream relationFile(treeName + ".relations", std::ios::binary);
delete[] fileName;
fileName = mergeStr(treeName, ".relations");
std::ofstream relationFile(fileName, std::ios::binary);
delete[] fileName;
/*relativeFile.write((char*)&numPeople, sizeof(numPeople)); /*relativeFile.write((char*)&numPeople, sizeof(numPeople));
relationFile.write((char*)&numPeople, sizeof(numPeople));*/ relationFile.write((char*)&numPeople, sizeof(numPeople));*/
@@ -274,9 +231,7 @@ void Tree::saveTree()const
bool Tree::loadTree() bool Tree::loadTree()
{ {
char* fileName = mergeStr(treeName, ".people");//c std::ifstream peopleFile(treeName + ".people", std::ios::binary);
std::ifstream peopleFile(fileName, std::ios::binary);
delete[] fileName;
if (peopleFile.peek() == std::char_traits<char>::eof()) if (peopleFile.peek() == std::char_traits<char>::eof())
{ {
peopleFile.close(); peopleFile.close();
@@ -290,12 +245,8 @@ bool Tree::loadTree()
people.sNum(numPeople); people.sNum(numPeople);
peopleFile.close(); peopleFile.close();
fileName = mergeStr(treeName, ".relatives"); std::ifstream relativeFile(treeName + ".relatives", std::ios::binary);
std::ifstream relativeFile(fileName, std::ios::binary); std::ifstream relationFile(treeName + ".relations", std::ios::binary);
delete[] fileName;
fileName = mergeStr(treeName, ".relations");
std::ifstream relationFile(fileName, std::ios::binary);
delete[] fileName;
relatives.resize(numPeople); relatives.resize(numPeople);
relations.resize(numPeople); relations.resize(numPeople);
@@ -318,9 +269,9 @@ bool Tree::loadTree()
return 1; return 1;
} }
void Tree::addPerson(const char *name, short year, unsigned char month, unsigned char day, bool isMale, unsigned father, unsigned mother) void Tree::addPerson(const char *name, BirthTime birth, bool isMale, unsigned father, unsigned mother)
{ {
Person newPerson(name, day, month, year, isMale); Person newPerson(name, birth, isMale);
people.push(newPerson); people.push(newPerson);
Array<unsigned> newRelative; Array<unsigned> newRelative;
relatives.push(newRelative); relatives.push(newRelative);
@@ -490,6 +441,13 @@ void Tree::removeRelation(const unsigned firstId, const unsigned secondId)
} }
void Tree::print() const
{
//for(const auto& member: people)
// member.print();
for(int i=0; i<numPeople;++i)
people[i].print();
}
void Tree::printRel(const unsigned id)const void Tree::printRel(const unsigned id)const
{ {
+16 -15
View File
@@ -1,11 +1,10 @@
#pragma once #pragma once
#include <iostream>
#include <climits> #include <climits>
#include"array.h" #include "array.h"
#include "person.h"
class Person; enum Relation : U8
enum Relation : char
{ {
Invalid = 0, Invalid = 0,
Father, Father,
@@ -26,18 +25,13 @@ const unsigned Nobody = UINT_MAX; //Òîçè íîìåð ùå áúäå çàïàç
class Tree class Tree
{ {
private:
char *treeName;
unsigned numPeople;
Array<Person> people; //The data for each member
Array<Array<unsigned>> relatives; //The relatives of each member
Array<Array<Relation>> relations; //The type of relation each member has with his relatives
public: public:
Tree(); Tree();
Tree(const char *Name); template <class Str>
Tree(const Tree&); Tree(Str&& Name) : treeName(std::forward<Str>(Name)), numPeople(0) {}
/*Tree(const Tree&);
Tree& operator= (const Tree& other); Tree& operator= (const Tree& other);
~Tree(); ~Tree();*/
Tree operator+ (const Tree& other); Tree operator+ (const Tree& other);
Tree operator- (const Tree& other); Tree operator- (const Tree& other);
@@ -50,7 +44,7 @@ public:
unsigned findCommonAncestor(const unsigned firstId, const unsigned secondId)const; //oldest common ancestor ID unsigned findCommonAncestor(const unsigned firstId, const unsigned secondId)const; //oldest common ancestor ID
void saveTree()const;// void saveTree()const;//
bool loadTree(); bool loadTree();
void addPerson(const char *, short year, unsigned char month, unsigned char day, bool sex, unsigned father = Nobody, unsigned mother = Nobody); void addPerson(const char *name, BirthTime birth, bool isMale, unsigned father = Nobody, unsigned mother = Nobody);
bool addRelation(const char* firstName, const Relation, const char* secondName); //Adds a new relation or edits an old one. 0 - failure 1 - success bool addRelation(const char* firstName, const Relation, const char* secondName); //Adds a new relation or edits an old one. 0 - failure 1 - success
bool addRelation(const unsigned firstId, const Relation, const unsigned secondId, bool opposite=0); //0 - failure 1 - success bool addRelation(const unsigned firstId, const Relation, const unsigned secondId, bool opposite=0); //0 - failure 1 - success
void removePerson(const unsigned id); //Removes a member and the last one takes his ID void removePerson(const unsigned id); //Removes a member and the last one takes his ID
@@ -58,6 +52,7 @@ public:
void removeRelation(const unsigned firstId, const unsigned secondId); void removeRelation(const unsigned firstId, const unsigned secondId);
void removeRelation(const char* firstName, const char* secondName); void removeRelation(const char* firstName, const char* secondName);
void print()const;
void printRel(const unsigned id)const; //Prints out close relatives void printRel(const unsigned id)const; //Prints out close relatives
void printMember(const unsigned id)const; void printMember(const unsigned id)const;
void printOldestAncestors(const unsigned id)const;// void printOldestAncestors(const unsigned id)const;//
@@ -67,5 +62,11 @@ public:
private: private:
void commonAncestorRec(const unsigned &id, const Array<char> &visited)const; void commonAncestorRec(const unsigned &id, const Array<char> &visited)const;
std::string treeName;
unsigned numPeople;
Array<Person> people; //The data for each member
Array<Array<unsigned>> relatives; //The relatives of each member
Array<Array<Relation>> relations; //The type of relation each member has with his relatives
//Search, ect. //Search, ect.
}; };