commit 25833cc23feb2b216114abd719e6487d6a8172ba parent 293fe340904dd4684393253518cb43ceb935b8ab Author: Christos Margiolis <christos@margiolis.net> Date: Mon, 8 Jun 2020 01:04:42 +0300 added comments Diffstat:
35 files changed, 203 insertions(+), 107 deletions(-)
diff --git a/assignment-1.5-arrays-pointers-files/minecurses/obj/audio.o b/assignment-1.5-arrays-pointers-files/minecurses/obj/audio.o Binary files differ. diff --git a/assignment-1.5-arrays-pointers-files/minecurses/obj/gameplay.o b/assignment-1.5-arrays-pointers-files/minecurses/obj/gameplay.o Binary files differ. diff --git a/assignment-1.5-arrays-pointers-files/minecurses/obj/main.o b/assignment-1.5-arrays-pointers-files/minecurses/obj/main.o Binary files differ. diff --git a/assignment-1.5-arrays-pointers-files/minecurses/obj/minesweeper.o b/assignment-1.5-arrays-pointers-files/minecurses/obj/minesweeper.o Binary files differ. diff --git a/assignment-1.5-arrays-pointers-files/minecurses/obj/navigation.o b/assignment-1.5-arrays-pointers-files/minecurses/obj/navigation.o Binary files differ. diff --git a/assignment-1.5-arrays-pointers-files/minecurses/obj/outputs.o b/assignment-1.5-arrays-pointers-files/minecurses/obj/outputs.o Binary files differ. diff --git a/assignment-1.5-arrays-pointers-files/minecurses/obj/settings.o b/assignment-1.5-arrays-pointers-files/minecurses/obj/settings.o Binary files differ. diff --git a/assignment-1.5-arrays-pointers-files/minecurses/obj/wins.o b/assignment-1.5-arrays-pointers-files/minecurses/obj/wins.o Binary files differ. diff --git a/assignment-2.2-classes/classes.cpp b/assignment-2.2-classes/classes.cpp @@ -81,6 +81,10 @@ Student::get_name() const return this->name; } +/* + * The function below are marked as constexpr just so they + * can be computed at compile time since everything is hardcoded. + */ constexpr const char * Student::get_id() const { @@ -179,6 +183,11 @@ Student::avg() const else return 0.0f; } +/* + * Makes a copy of a given array of type T and returns a temporary array + * which is meant to be stored in a member variable. + * If the array is empty it returns nullptr. + */ template<typename T> T * Student::conv(const T *arr, std::size_t len) const { @@ -214,6 +223,11 @@ static void detprint (const Student& s3); static void setters(Student& s3); static void addgrd(Student& s3); +/* + * main uses smart pointers since there are quite a few dynamically + * allocated objects and so it looks cleaner to let them handle the + * deletions. + */ int main(int argc, char **argv) { diff --git a/assignment-2.3-operoverloading/obj/course.o b/assignment-2.3-operoverloading/obj/course.o Binary files differ. diff --git a/assignment-2.3-operoverloading/obj/main.o b/assignment-2.3-operoverloading/obj/main.o Binary files differ. diff --git a/assignment-2.3-operoverloading/obj/student.o b/assignment-2.3-operoverloading/obj/student.o Binary files differ. diff --git a/assignment-2.3-operoverloading/src/main.cpp b/assignment-2.3-operoverloading/src/main.cpp @@ -18,6 +18,11 @@ static void plusequals_overload(Student& s3, Course *c); static void getters(const Course& s3); static void setters(Course& c); +/* + * main uses smart pointers since there are quite a few dynamically + * allocated objects and so it looks cleaner to let them handle the + * deletions. + */ int main(int argc, char **argv) { diff --git a/assignment-2.3-operoverloading/src/student.hpp b/assignment-2.3-operoverloading/src/student.hpp @@ -32,6 +32,10 @@ class Student void operator+= (Course *c); Student operator= (const Student& s); + /* + * The function below are marked as constexpr just so they + * can be computed at compile time since everything is hardcoded. + */ constexpr bool operator== (const Student& s) const {return this->semester == s.semester;} constexpr bool operator!= (const Student& s) const {return this->semester != s.semester;} constexpr bool operator< (const Student& s) const {return this->semester < s.semester;} @@ -66,6 +70,11 @@ class Student float avg() const; }; +/* + * Makes a copy of a given array of type T and returns a temporary array + * which is meant to be stored in a member variable. + * If the array is empty it returns nullptr. + */ template<typename T> T * Student::conv(const T *arr, std::size_t len) const { diff --git a/assignment-2.4-inheritance/bin/inheritance b/assignment-2.4-inheritance/bin/inheritance Binary files differ. diff --git a/assignment-2.4-inheritance/obj/app.o b/assignment-2.4-inheritance/obj/app.o Binary files differ. diff --git a/assignment-2.4-inheritance/obj/appsystem.o b/assignment-2.4-inheritance/obj/appsystem.o Binary files differ. diff --git a/assignment-2.4-inheritance/obj/main.o b/assignment-2.4-inheritance/obj/main.o Binary files differ. diff --git a/assignment-2.4-inheritance/obj/review.o b/assignment-2.4-inheritance/obj/review.o Binary files differ. diff --git a/assignment-2.4-inheritance/res/errlog.txt b/assignment-2.4-inheritance/res/errlog.txt diff --git a/assignment-2.4-inheritance/src/app.cpp b/assignment-2.4-inheritance/src/app.cpp @@ -18,7 +18,7 @@ App::App(const char *serialnum, const std::string& name, } App::App(const App& app) - :serialnum(app.serialnum), name(app.name), os(app.os), manf(app.manf), + :serialnum(convsn(app.serialnum)), name(app.name), os(app.os), manf(app.manf), price(app.price) {} App::~App() @@ -33,6 +33,11 @@ App::~App() } } +/* + * Makes a copy of a const char array and returns + * a temporary array which is meant to be stored in + * a member variable. + */ char * App::convsn(const char *serialnum) { diff --git a/assignment-2.4-inheritance/src/appsystem.cpp b/assignment-2.4-inheritance/src/appsystem.cpp @@ -8,6 +8,10 @@ AppSystem::~AppSystem() dealloc<Manufacturer>(manfs); } +/* + * Adds a new App object to the apps vector in case it doesn't already exist. + * If it exists, an error is written to the error log. + */ AppSystem& AppSystem::operator+= (App *app) { @@ -17,6 +21,7 @@ AppSystem::operator+= (App *app) return *this; } +/* Same as above, but for a Manufacturer object */ AppSystem& AppSystem::operator+= (Manufacturer *manf) { @@ -26,6 +31,13 @@ AppSystem::operator+= (Manufacturer *manf) return *this; } +/* + * Parses a given file containing file extensions for an Office object + * which are formatted as: .ext1|.ext2|. + * Using STL's sstream we can extract each extension as a substring + * by setting the delimeter to | and then push them back to + * a vector which contains each extension. + */ const std::vector<std::string> AppSystem::parse_office_exts(std::ifstream& f) { @@ -37,6 +49,7 @@ AppSystem::parse_office_exts(std::ifstream& f) return exts; } +/* Writes file extensions to a file with the above format */ void AppSystem::write_office_exts(const Office *of, std::ofstream& f) { @@ -45,32 +58,46 @@ AppSystem::write_office_exts(const Office *of, std::ofstream& f) f << ext << '|'; } +/* + * Searches through the apps vector to see if a given Manufacturer + * object exists. If it does, it deletes every single app related + * to that manufacturer. + */ void AppSystem::removebad(const Manufacturer *manf) { auto lambda = [&](App *app) -> bool { Manufacturer m = app->get_manf(); - if (!std::strcmp(m.get_name(), manf->get_name())) + if (!std::strcmp(m.get_serialnum(), manf->get_serialnum())) delete app; - return !std::strcmp(m.get_name(), manf->get_name()); + return !std::strcmp(m.get_serialnum(), manf->get_serialnum()); }; apps.erase(std::remove_if(apps.begin(), apps.end(), lambda), apps.end()); } +/* + * Same as above but this time we only pass the + * manufacturer's serial number + */ void -AppSystem::removebad(const char *manfname) +AppSystem::removebad(const char *manfsn) { auto lambda = [&](App *app) -> bool { Manufacturer m = app->get_manf(); - if (!std::strcmp(m.get_name(), manfname)) + if (!std::strcmp(m.get_serialnum(), manfsn)) delete app; - return !std::strcmp(m.get_name(), manfname); + return !std::strcmp(m.get_serialnum(), manfsn); }; apps.erase(std::remove_if(apps.begin(), apps.end(), lambda), apps.end()); } +/* + * Returns a vector of Office objects whose prices are 0 (free). + * dynamic_cast is required in order to only take Office objects + * into account (the vector contains App objects). + */ const std::vector<Office *> AppSystem::get_freeapps() const { @@ -82,6 +109,11 @@ AppSystem::get_freeapps() const return fapps; } +/* + * Returns a vector with all the Game objects that have an + * average rating bigger than 4. dynamic_cast is required + * for the same reason as above. + */ const std::vector<Game *> AppSystem::get_goodgames() const { diff --git a/assignment-2.4-inheritance/src/appsystem.hpp b/assignment-2.4-inheritance/src/appsystem.hpp @@ -35,7 +35,7 @@ class AppSystem const T element, void (U::*setter)(T)); void removebad(const Manufacturer *manf); - void removebad(const char *manfname); + void removebad(const char *manfsn); constexpr const std::vector<App *>& get_apps() const {return apps;} constexpr const std::vector<Manufacturer *>& get_manfs() const {return manfs;} @@ -44,7 +44,7 @@ class AppSystem private: template<typename T> bool exists(const std::vector<T *>& vec, const T *element); - template<typename T> bool parse(std::ifstream& f); + template<typename T> void parse(std::ifstream& f); const std::vector<std::string> parse_office_exts(std::ifstream& f); const std::vector<Review *> parse_reviews(const std::string& appname, const char *rpath); @@ -54,83 +54,96 @@ class AppSystem template<typename T> void dealloc(std::vector<T *>& vec); }; -template<typename T> bool +/* + * Parses .csv fields for each type T + * The function is templated just for the sake + * of not having overloads, although this one is + * not any more practical either. + */ +template<typename T> void AppSystem::parse(std::ifstream& f) { - try - { - if constexpr (std::is_same_v<T, Manufacturer>) - { - std::string sn, name, email; - std::getline(f, sn, ','); - std::getline(f, name, ','); - std::getline(f, email); - if (f.eof()) return true; - manfs.push_back(new Manufacturer(sn.c_str(), name.c_str(), email)); - } - else if constexpr (std::is_same_v<T, Office>) - { - std::string sn, name, os, manf, price, skip1, skip2; - std::getline(f, sn, ','); - std::getline(f, name, ','); - std::getline(f, os, ','); - std::getline(f, manf, ','); - std::getline(f, price, ','); - std::getline(f, skip1, ','); - std::getline(f, skip2, ','); - if (f.eof()) return true; - std::vector<std::string> exts = parse_office_exts(f); - - if (!manfs.empty()) - { - for (const auto& man : manfs) - { - if (man->get_name() == manf) - { - apps.push_back(new Office(sn.c_str(), name, os, - man, std::stoi(price), exts)); - break; - } - } - } - } - else if constexpr (std::is_same_v<T, Game>) - { - std::string sn, name, os, manf, price, genre, online; - std::string skip; - std::getline(f, sn, ','); - std::getline(f, name, ','); - std::getline(f, os, ','); - std::getline(f, manf, ','); - std::getline(f, price, ','); - std::getline(f, genre, ','); - std::getline(f, online, ','); - std::getline(f, skip); - if (f.eof()) return true; - bool onl = online == "Yes"; - - if (!manfs.empty()) - { - for (const auto& man : manfs) - { - if (man->get_name() == manf) - { - apps.push_back(new Game(sn.c_str(), name, os, - man, std::stoi(price), genre, onl)); - break; - } - } - } - } - } - catch (const std::ifstream::failure& e) - { - errlog.write("Error parsing data"); - return false; - } - return true; + if constexpr (std::is_same_v<T, Manufacturer>) + { + std::string sn, name, email; + std::getline(f, sn, ','); + std::getline(f, name, ','); + std::getline(f, email); + if (f.eof()) return; + manfs.push_back(new Manufacturer(sn.c_str(), name.c_str(), email)); + } + else if constexpr (std::is_same_v<T, Office>) + { + std::string sn, name, os, manf, price, skip1, skip2; + std::getline(f, sn, ','); + std::getline(f, name, ','); + std::getline(f, os, ','); + std::getline(f, manf, ','); + std::getline(f, price, ','); + std::getline(f, skip1, ','); + std::getline(f, skip2, ','); + if (f.eof()) return; + std::vector<std::string> exts = parse_office_exts(f); + + if (!manfs.empty()) + { + for (const auto& man : manfs) + { + if (man->get_name() == manf) + { + apps.push_back(new Office(sn.c_str(), name, os, + man, std::stoi(price), exts)); + break; + } + } + } + } + else if constexpr (std::is_same_v<T, Game>) + { + std::string sn, name, os, manf, price, genre, online; + std::string skip; + std::getline(f, sn, ','); + std::getline(f, name, ','); + std::getline(f, os, ','); + std::getline(f, manf, ','); + std::getline(f, price, ','); + std::getline(f, genre, ','); + std::getline(f, online, ','); + std::getline(f, skip); + if (f.eof()) return; + bool onl = online == "Yes"; + + if (!manfs.empty()) + { + for (const auto& man : manfs) + { + if (man->get_name() == manf) + { + apps.push_back(new Game(sn.c_str(), name, os, + man, std::stoi(price), genre, onl)); + break; + } + } + } + } + else if constexpr (std::is_same_v<T, Review>) + { + std::string appname, stars, username, comment; + std::getline(f, appname, ','); + std::getline(f, stars, ','); + std::getline(f, username, ','); + std::getline(f, comment); + if (f.eof()) return; + for (auto&& app : apps) + if (appname == app->get_name()) + app->addrev(new Review(std::stoi(stars), username, comment)); + } } +/* + * Imports data from a given path and handles a possible + * std::ifstream::badbit exception + */ template<typename T> void AppSystem::import_data(const char *fpath) { @@ -148,30 +161,16 @@ AppSystem::import_data(const char *fpath) while (f.good()) { if constexpr (std::is_same_v<T, Manufacturer>) - { - if (!parse<Manufacturer>(f)) break; - } + parse<Manufacturer>(f); else if constexpr (std::is_same_v<T, App>) { std::string type; std::getline(f, type, ','); - if (type == "Game") - if (!parse<Game>(f)) break; - if (type == "Office") - if (!parse<Office>(f)) break; + if (type == "Game") parse<Game>(f); + if (type == "Office") parse<Office>(f); } else if constexpr (std::is_same_v<T, Review>) - { - std::string appname, stars, username, comment; - std::getline(f, appname, ','); - std::getline(f, stars, ','); - std::getline(f, username, ','); - std::getline(f, comment); - if (f.eof()) break; - for (auto&& app : apps) - if (appname == app->get_name()) - app->addrev(new Review(std::stoi(stars), username, comment)); - } + parse<Review>(f); } } f.close(); @@ -182,6 +181,11 @@ AppSystem::import_data(const char *fpath) } } +/* + * Exports data to a given path for each type T. + * This function is also templated just for the sake + * of not having overloads. It also handles exceptions. + */ template<typename T> void AppSystem::export_data(const char *fpath) { @@ -248,12 +252,23 @@ AppSystem::export_data(const char *fpath) } } +/* + * Searches a vector of any type T and returns true if the + * element is found. I made it just so I don't have to write + * all this every time. + */ template<typename T> bool AppSystem::exists(const std::vector<T *>& vec, const T *element) { return std::find(vec.begin(), vec.end(), element) != vec.end(); } +/* + * Searches through the apps array and in case the app is found + * it calls a given App setter through a function pointer. + * "element" must be of the same type as the setter's parameter. + * It's ugly. + */ template<typename T> void AppSystem::call(const std::string& appname, const T element, void (App::*setter)(T)) { @@ -262,6 +277,11 @@ AppSystem::call(const std::string& appname, const T element, void (App::*setter) (app->*setter)(element); } +/* + * Same as above but this one is used for the derived classes + * "Game" and "Office". I could use this one in all cases but + * dynamic casting everytime would be pointless. + */ template<typename T, class U> void AppSystem::cast_call(const std::string& appname, const T element, void (U::*setter)(T)) { @@ -271,6 +291,10 @@ AppSystem::cast_call(const std::string& appname, const T element, void (U::*sett (o->*setter)(element); } +/* + * Frees every pointer object in every vector. + * This function is called only by the destructor. + */ template<typename T> void AppSystem::dealloc(std::vector<T *>& vec) { diff --git a/assignment-2.4-inheritance/src/errlog.cpp b/assignment-2.4-inheritance/src/errlog.cpp diff --git a/assignment-2.4-inheritance/src/errlog.hpp b/assignment-2.4-inheritance/src/errlog.hpp diff --git a/assignment-2.4-inheritance/src/main.cpp b/assignment-2.4-inheritance/src/main.cpp @@ -8,6 +8,11 @@ static void edit(AppSystem& sys); static void remove(AppSystem& sys); static void getapps(const AppSystem& sys); +/* + * main uses smart pointers just so I don't have to delete + * them manually. There's obviously no good reason to do it + * as there's only one object, but it looks cool. + */ int main(int argc, char **argv) { @@ -109,7 +114,7 @@ edit(AppSystem& sys) void remove(AppSystem& sys) { - sys.removebad("GNU"); + sys.removebad("0003"); } void diff --git a/assignment-2.4-inheritance/src/manufacturer.cpp b/assignment-2.4-inheritance/src/manufacturer.cpp @@ -26,6 +26,11 @@ Manufacturer::~Manufacturer() if (name != nullptr) delete[] name; } +/* + * Makes a copy of a const char array and returns + * a temporary array which is meant to be stored in + * a member variable. + */ char * Manufacturer::convstr(const char *str) { diff --git a/assignment-2.4-inheritance/src/office.cpp b/assignment-2.4-inheritance/src/office.cpp @@ -7,8 +7,8 @@ Office::Office(const char *serialnum, const std::string& name, const int price, const std::vector<std::string>& ext) :App(serialnum, name, os, manf, price), extensions(ext) {} -Office::Office(const Office& o) - :App(o.serialnum, o.name, o.os, o.manf, o.price) {} +Office::Office(const Office& of) + :App(of.serialnum, of.name, of.os, of.manf, of.price) {} Office::~Office() { diff --git a/assignment-2.4-inheritance/src/office.hpp b/assignment-2.4-inheritance/src/office.hpp @@ -13,7 +13,7 @@ class Office final: public App Office(const char *serialnum, const std::string& name, const std::string& os, Manufacturer *manf, const int price, const std::vector<std::string>& ext); - Office(const Office& o); + Office(const Office& of); ~Office(); const std::vector<std::string> get_exts() const {return extensions;} diff --git a/assignment-2.4-inheritance/src/review.cpp b/assignment-2.4-inheritance/src/review.cpp @@ -10,6 +10,3 @@ Review::Review(const int stars, const std::string& username, if (stars < 0 || stars > 5) errlog.write("Review from: " + username + ": Star value out of bounds"); } - -Review::Review(const Review& rev) - :stars(rev.stars), username(rev.username), comment(rev.comment) {} diff --git a/assignment-2.4-inheritance/src/review.hpp b/assignment-2.4-inheritance/src/review.hpp @@ -18,7 +18,7 @@ class Review Review(); Review(const int stars, const std::string& username, const std::string& comment); - Review(const Review& rev); + Review(const Review& rev) = default; const std::string& get_username() const {return username;} const std::string& get_comment() const {return comment;} diff --git a/assignment-2.5-spreadsheets/obj/datahandler.o b/assignment-2.5-spreadsheets/obj/datahandler.o Binary files differ. diff --git a/assignment-2.5-spreadsheets/obj/errlog.o b/assignment-2.5-spreadsheets/obj/errlog.o Binary files differ. diff --git a/assignment-2.5-spreadsheets/obj/main.o b/assignment-2.5-spreadsheets/obj/main.o Binary files differ. diff --git a/assignment-2.5-spreadsheets/obj/xstring.o b/assignment-2.5-spreadsheets/obj/xstring.o Binary files differ.