commit a0c986a5c03ceef781a27ed89f2c05c9499e5271 parent b7cffe29333bd24fc72193978d002ace21dd2981 Author: Christos Margiolis <christos@margiolis.net> Date: Thu, 7 May 2020 10:37:43 +0300 changed template specializations to std::is_same Diffstat:
17 files changed, 390 insertions(+), 386 deletions(-)
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/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/src/appsystem.cpp b/assignment-2.4-inheritance/src/appsystem.cpp @@ -4,17 +4,8 @@ AppSystem::AppSystem() {} AppSystem::~AppSystem() { - for (auto& app : apps) - if (app != nullptr) - delete app; - if (!apps.empty()) - apps.clear(); - - for (auto& manf : manfs) - if (manf != nullptr) - delete manf; - if (!manfs.empty()) - manfs.clear(); + dealloc<App>(apps); + dealloc<Manufacturer>(manfs); } AppSystem& AppSystem::operator+= (App *app) @@ -29,174 +20,6 @@ AppSystem& AppSystem::operator+= (Manufacturer *man) return *this; } -template<> -bool AppSystem::parse<Manufacturer>(std::ifstream& f) -{ - try - { - 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)); - } - catch (const std::ifstream::failure& e) - { - std::cerr << "Error reading manufacturer data." << std::endl << - e.what() << std::endl; - return false; - } - return true; -} - -template<> -bool AppSystem::import_data<Manufacturer>(const char *fpath) -{ - std::ifstream f; - f.exceptions(std::ifstream::badbit); - try - { - std::string strpath(fpath); - if (!valid_path(strpath)) throw strpath; - - f.open(fpath); - if (f.is_open()) - { - std::string skip; - std::getline(f, skip); - while (f.good()) - if (!parse<Manufacturer>(f)) break; - } - f.close(); - } - catch (const std::string& strpath) - { - throw std::runtime_error(err_csv(strpath)); - } - catch (const std::ifstream::failure& e) - { - std::cerr << err_read(fpath) << std::endl << e.what() << std::endl; - return false; - } - return true; -} - -template<> -bool AppSystem::parse<Office>(std::ifstream& f) -{ - try - { - 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, ','); - std::vector<std::string> exts = parse_office_exts(f); - - if (!manfs.empty()) - { - for (auto& man : manfs) - { - if (man->get_name() == manf) - { - apps.push_back(new Office(sn.c_str(), name, os, - man, std::stoi(price), exts)); - break; - } - } - } - } - catch (const std::ifstream::failure& e) - { - std::cerr << "Error reading office data." << std::endl << - e.what() << std::endl; - return false; - } - return true; -} - -template<> -bool AppSystem::parse<Game>(std::ifstream& f) -{ - try - { - 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); - bool onl = online == "Yes"; - - if (!manfs.empty()) - { - for (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) - { - std::cerr << "Error reading game data." << std::endl << - e.what() << std::endl; - return false; - } - return true; -} - -template<> -bool AppSystem::import_data<App>(const char *fpath) -{ - std::ifstream f; - f.exceptions(std::ifstream::badbit); - try - { - std::string strpath(fpath); - if (!valid_path(strpath)) throw strpath; - - f.open(fpath); - if (f.is_open()) - { - std::string skip; - std::getline(f, skip); - while (f.good()) - { - std::string type; - std::getline(f, type, ','); - if (type == "Game") - if (!parse<Game>(f)) break; - if (type == "Office") - if (!parse<Office>(f)) break; - } - } - f.close(); - } - catch (const std::string& strpath) - { - throw std::runtime_error(err_csv(strpath)); - } - catch (const std::ifstream::failure& e) - { - std::cerr << err_read(fpath) << std::endl << e.what() << std::endl; - return false; - } - return true; -} - const std::vector<std::string> AppSystem::parse_office_exts(std::ifstream& f) { std::vector<std::string> exts; @@ -207,145 +30,6 @@ const std::vector<std::string> AppSystem::parse_office_exts(std::ifstream& f) return exts; } -template<> -bool AppSystem::import_data<Review>(const char *fpath) -{ - std::ifstream f; - try - { - std::string strpath(fpath); - if (!valid_path(strpath)) throw strpath; - f.open(fpath); - std::string skip; - std::getline(f, skip); - while (f.good()) - { - std::string appname, stars, username, comment; - std::getline(f, appname, ','); - std::getline(f, stars, ','); - std::getline(f, username, ','); - std::getline(f, comment); - for (auto& app : apps) - if (appname == app->get_name()) - app->addrev(new Review(std::stoi(stars), username, comment)); - } - } - catch (const std::string& strpath) - { - throw std::runtime_error(err_csv(strpath)); - } - catch (const std::ifstream::failure& e) - { - std::cerr << "Error reading reviews." << std::endl << e.what() << std::endl; - return false; - } - return true; -} - -template<> -bool AppSystem::export_data<Manufacturer>(const char *fpath) -{ - std::ofstream f; - f.exceptions(std::ofstream::failbit | std::ofstream::badbit); - try - { - f.open(fpath); - f << "SN,Name,Email\n"; - for (auto& manf : manfs) - f << manf->get_serialnum() << ',' << - manf->get_name() << ',' << - manf->get_email() << std::endl; - f.close(); - } - catch (const std::ofstream::failure& e) - { - std::cerr << err_read(fpath) << std::endl << e.what() << std::endl; - return false; - } - return true; -} - -template<> -bool AppSystem::export_data<App>(const char *fpath) -{ - std::ofstream f; - f.exceptions(std::ofstream::failbit | std::ofstream::badbit); - try - { - std::string strpath(fpath); - if (!valid_path(strpath)) throw strpath; - f.open(fpath); - f << "Type,SN,Name,OS,Manf,Price,Genre,Online,Extensions\n"; - for (auto& app : apps) - { - Manufacturer manf = app->get_manf(); - Game *o = dynamic_cast<Game *>(app); - f << (o ? "Game" : "Office") << ','; - f << app->get_serialnum() << ',' << - app->get_name() << ',' << - app->get_os() << ',' << - manf.get_name() << ',' << - app->get_price() << ',' << - (o ? o->get_genre() :"N/A") << ',' << - (o ? (o->get_online() ? "Yes" : "No") : "N/A") << ','; - if (o) f << "N/A" << std::endl; - else - { - Office *of = dynamic_cast<Office *>(app); - write_office_exts(of, f); - f << std::endl; - } - } - f.close(); - } - catch (const std::string& strpath) - { - throw std::runtime_error(err_csv(strpath)); - } - catch (const std::ofstream::failure& e) - { - std::cerr << err_write(fpath) << e.what() << std::endl; - return false; - } - return true; -} - -template<> -bool AppSystem::export_data<Review>(const char *fpath) -{ - std::ofstream f; - f.exceptions(std::ofstream::failbit | std::ofstream::badbit); - try - { - std::string strpath(fpath); - if (!valid_path(strpath)) throw strpath; - f.open(fpath); - f << "AppName,Stars,Username,Comment\n"; - for (auto& app : apps) - { - const std::vector<Review *> revs = app->get_revs(); - if (!revs.empty()) - for (auto& rev : revs) - f << - app->get_name() << ',' << - rev->get_stars() << ',' << - rev->get_username() << ',' << - rev->get_comment() << std::endl; - } - f.close(); - } - catch (const std::string& strpath) - { - throw std::runtime_error(err_csv(strpath)); - } - catch (const std::ofstream::failure& e) - { - std::cerr << err_write(fpath) << e.what() << std::endl; - return false; - } - return true; -} - void AppSystem::write_office_exts(Office *of, std::ofstream& f) { std::vector<std::string> exts = of->get_exts(); diff --git a/assignment-2.4-inheritance/src/appsystem.h b/assignment-2.4-inheritance/src/appsystem.h @@ -51,6 +51,225 @@ class AppSystem const std::string err_csv(const std::string& fpath); const std::string err_read(const char *fpath); const std::string err_write(const char *fpath); + template<typename T> void dealloc(std::vector<T *>& vec); }; +template<typename T> +bool AppSystem::parse(std::ifstream& f) +{ + try + { + if (std::is_same<T, Manufacturer>::value) + { + 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 (std::is_same<T, Office>::value) + { + 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 (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 (std::is_same<T, Game>::value) + { + 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 (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) + { + std::cerr << "Error parsing data." << std::endl << + e.what() << std::endl; + return false; + } + return true; +} + +template<typename T> +bool AppSystem::import_data(const char *fpath) +{ + std::ifstream f; + f.exceptions(std::ifstream::badbit); + try + { + std::string strpath(fpath); + if (!valid_path(strpath)) throw strpath; + + f.open(fpath); + if (f.is_open()) + { + std::string skip; + std::getline(f, skip); + while (f.good()) + { + if (std::is_same<T, Manufacturer>::value) + { + if (!parse<Manufacturer>(f)) break; + } + else if (std::is_same<T, App>::value) + { + std::string type; + std::getline(f, type, ','); + if (type == "Game") + if (!parse<Game>(f)) break; + if (type == "Office") + if (!parse<Office>(f)) break; + } + else if (std::is_same<T, Review>::value) + { + 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 true; + for (auto& app : apps) + if (appname == app->get_name()) + app->addrev(new Review(std::stoi(stars), username, comment)); + } + } + } + f.close(); + } + catch (const std::string& strpath) + { + throw std::runtime_error(err_csv(strpath)); + } + catch (const std::ifstream::failure& e) + { + std::cerr << err_read(fpath) << std::endl << e.what() << std::endl; + return false; + } + return true; +} + +template<typename T> +bool AppSystem::export_data(const char *fpath) +{ + std::ofstream f; + f.exceptions(std::ofstream::failbit | std::ofstream::badbit); + try + { + std::string strpath(fpath); + if (!valid_path(strpath)) throw strpath; + f.open(fpath); + + if (std::is_same<T, Manufacturer>::value) + { + f << "SN,Name,Email\n"; + for (auto& manf : manfs) + f << manf->get_serialnum() << ',' << + manf->get_name() << ',' << + manf->get_email() << std::endl; + } + else if (std::is_same<T, App>::value) + { + f << "Type,SN,Name,OS,Manf,Price,Genre,Online,Extensions\n"; + for (auto& app : apps) + { + Manufacturer manf = app->get_manf(); + Game *o = dynamic_cast<Game *>(app); + f << (o ? "Game" : "Office") << ','; + f << app->get_serialnum() << ',' << + app->get_name() << ',' << + app->get_os() << ',' << + manf.get_name() << ',' << + app->get_price() << ',' << + (o ? o->get_genre() :"N/A") << ',' << + (o ? (o->get_online() ? "Yes" : "No") : "N/A") << ','; + if (o) f << "N/A" << std::endl; + else + { + Office *of = dynamic_cast<Office *>(app); + write_office_exts(of, f); + f << std::endl; + } + } + } + else if (std::is_same<T, Review>::value) + { + f << "AppName,Stars,Username,Comment\n"; + for (auto& app : apps) + { + const std::vector<Review *> revs = app->get_revs(); + if (!revs.empty()) + for (auto& rev : revs) + f << + app->get_name() << ',' << + rev->get_stars() << ',' << + rev->get_username() << ',' << + rev->get_comment() << std::endl; + } + } + f.close(); + } + catch (const std::string& strpath) + { + throw std::runtime_error(err_csv(strpath)); + } + catch (const std::ofstream::failure& e) + { + std::cerr << err_read(fpath) << std::endl << e.what() << std::endl; + return false; + } + return true; +} + +template<typename T> +void AppSystem::dealloc(std::vector<T *>& vec) +{ + for (auto& v : vec) + if (v != nullptr) + delete v; + if (!vec.empty()) + vec.clear(); +} + #endif /* APPSYSTEM_H */ diff --git a/assignment-2.5-spreadsheets/bin/spreadsheets b/assignment-2.5-spreadsheets/bin/spreadsheets Binary files differ. diff --git a/assignment-2.5-spreadsheets/obj/course.o b/assignment-2.5-spreadsheets/obj/course.o Binary files differ. diff --git a/assignment-2.5-spreadsheets/obj/grades.o b/assignment-2.5-spreadsheets/obj/grades.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/student.o b/assignment-2.5-spreadsheets/obj/student.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. diff --git a/assignment-2.5-spreadsheets/src/app.cpp b/assignment-2.5-spreadsheets/src/app.cpp @@ -0,0 +1,42 @@ +#include "app.h" + +App::App() {} + +App::~App() +{ + dealloc<Course>(courses); + dealloc<Grades>(grades); + dealloc<Student>(studs); +} + +bool App::import_matchings(const char *fpath) +{ + std::ifstream f; + f.open(fpath); + // exceptions + while (f.good()) + { + lab::xstring newcurr, oldcurr; + lab::getline(f, newcurr, ';'); + lab::getline(f, oldcurr); + if (f.eof()) break; + matchings.emplace_back(newcurr, oldcurr); + } + f.close(); + return true; +} + +const std::vector<Course *>& App::get_courses() const +{ + return courses; +} + +const std::vector<Grades *>& App::get_grades() const +{ + return grades; +} + +const std::vector<Student *>& App::get_studs() const +{ + return studs; +} diff --git a/assignment-2.5-spreadsheets/src/app.h b/assignment-2.5-spreadsheets/src/app.h @@ -0,0 +1,89 @@ +#ifndef APP_H +#define APP_H + +#include <iostream> +#include <fstream> +#include <unordered_map> +#include <vector> + +#include "course.h" +#include "grades.h" +#include "student.h" +#include "xstring.h" + +class App +{ + private: + std::vector<Course *> courses; + std::vector<Grades *> grades; + std::vector<Student *> studs; + std::vector<std::pair<lab::xstring, lab::xstring>> matchings; + + public: + App(); + ~App(); + + template<typename T> bool import_data(const char *fpath); + bool import_matchings(const char *fpath); + + const std::vector<Course *>& get_courses() const; + const std::vector<Grades *>& get_grades() const; + const std::vector<Student *>& get_studs() const; + + private: + template<typename T> void dealloc(std::vector<T *>& vec); +}; + +template<typename T> +bool App::import_data(const char *fpath) +{ + std::ifstream f; + f.exceptions(std::ifstream::badbit); + f.open(fpath); + lab::xstring skip; + lab::getline(f, skip); + while (f.good()) + { + if (std::is_same<T, Course>::value) + { + lab::xstring code, name; + lab::getline(f, code, ';'); + lab::getline(f, name); + if (f.eof()) break; + courses.push_back(new Course(code, name)); + } + else if (std::is_same<T, Grades>::value) + { + lab::xstring AM, code, grade; + lab::getline(f, AM, ';'); + lab::getline(f, code, ';'); + lab::getline(f, grade); + if (f.eof()) break; + grades.push_back(new Grades(AM, code, std::atof(grade.cstr()))); + + } + else if (std::is_same<T, Student>::value) + { + lab::xstring AM, lname, fname; + lab::getline(f, AM, ';'); + lab::getline(f, lname, ';'); + lab::getline(f, fname); + if (f.eof()) break; + studs.push_back(new Student(AM, lname, fname)); + } + + } + f.close(); + return true; +} + +template<typename T> +void App::dealloc(std::vector<T *>& vec) +{ + for (auto& v : vec) + if (v != nullptr) + delete v; + vec.clear(); +} + +#endif /* APP_H */ diff --git a/assignment-2.5-spreadsheets/src/main.cpp b/assignment-2.5-spreadsheets/src/main.cpp @@ -1,20 +1,20 @@ -#include <fstream> -#include <vector> -#include "xstring.h" +#include "app.h" + +std::ostream& operator<< (std::ostream& stream, const App& app); int main(int argc, char **argv) { - std::ifstream f("res/grades.csv"); - while (f.good()) - { - lab::xstring a, b, c; - lab::getline(f, a, ';'); - lab::getline(f, b, ';'); - lab::getline(f, c); - if (f.eof()) break; - std::cout << a << " " << b << " " << std::atof(c.cstr()) << std::endl; - } - f.close(); + App app; + if (!app.import_data<Course>("res/courses.csv")) return -1; + if (!app.import_data<Grades>("res/grades.csv")) return -1; + if (!app.import_data<Student>("res/students.csv")) return -1; + if (!app.import_matchings("res/matchings.csv")) return -1; + //std::cout << app << std::endl; return 0; } + +std::ostream& operator<< (std::ostream& stream, const App& app) +{ + return stream; +} diff --git a/assignment-2.5-spreadsheets/src/student.h b/assignment-2.5-spreadsheets/src/student.h @@ -15,7 +15,7 @@ class Student const lab::xstring& lname, const lab::xstring& fname); - const lab::xstring& get_AM() const; + const lab::xstring& get_AM() const; const lab::xstring& get_lname() const; const lab::xstring& get_fname() const; }; diff --git a/assignment-2.5-spreadsheets/src/xstring.cpp b/assignment-2.5-spreadsheets/src/xstring.cpp @@ -160,10 +160,9 @@ xstring& xstring::append(const xstring& s) { if (!s.empty()) { - resize(s.str); + resize(s.len); strcat(str, s.str); } - else str = conv(s.str); len = length(); return *this; } @@ -192,10 +191,9 @@ xstring& xstring::append(const char *s) { if (!strempty(s)) { - resize(s); + resize(strlen(s)); strcat(str, s); } - else str = conv(s); len = length(); return *this; } @@ -228,13 +226,9 @@ xstring& xstring::append(char c) void xstring::push_back(char c) { - if (!this->empty()) - { - resize(1); - str[len] = c; - str[len+1] = '\0'; - } - else str = conv(c); + resize(1); + str[len] = c; + str[len+1] = '\0'; len = length(); } @@ -279,10 +273,9 @@ char& xstring::back() const else return str[0]; } -std::size_t xstring::length() +std::size_t xstring::length() const { - len = strlen(str); - return len; + return strlen(str); } bool xstring::empty() const @@ -290,11 +283,6 @@ bool xstring::empty() const return len == 0; } -bool xstring::strempty(const char *s) const -{ - return strlen(s) == 0; -} - void xstring::clear() { if (!this->empty()) delete[] str; @@ -303,35 +291,6 @@ void xstring::clear() len = 0; } -char *xstring::conv(const char *s) -{ - std::size_t l = strlen(s); - char *tmp = new char[l + 1]; - std::copy(s, s + l+1, tmp); - return tmp; -} - -char *xstring::conv(char c) -{ - char *tmp = new char[2]; - tmp[0] = c; - tmp[1] = '\0'; - return tmp; -} - -void xstring::resize(const char *s) -{ - if (!this->empty()) - { - std::size_t l = len + strlen(s); - char *tmp = new char[l + 1]; - std::copy(str, str + len+1, tmp); - delete[] str; - str = tmp; - len = length(); - } -} - void xstring::resize(std::size_t n) { if (!this->empty()) @@ -345,6 +304,19 @@ void xstring::resize(std::size_t n) } } +char *xstring::conv(const char *s) const +{ + std::size_t l = strlen(s); + char *tmp = new char[l + 1]; + std::copy(s, s + l+1, tmp); + return tmp; +} + +bool xstring::strempty(const char *s) const +{ + return strlen(s) == 0; +} + std::istream& getline(std::istream& stream, xstring& s, char delim) { char c; @@ -352,7 +324,7 @@ std::istream& getline(std::istream& stream, xstring& s, char delim) while (stream.get(c) && c != '\n') { if (c == delim) break; - else s.append(c); + else s.push_back(c); } return stream; } diff --git a/assignment-2.5-spreadsheets/src/xstring.h b/assignment-2.5-spreadsheets/src/xstring.h @@ -54,15 +54,13 @@ class xstring char *cstr() const; char& front() const; char& back() const; - std::size_t length(); + std::size_t length() const; bool empty() const; void clear(); private: - char *conv(const char *s); - char *conv(char c); - void resize(const char *s); void resize(std::size_t n); + char *conv(const char *s) const; bool strempty(const char *s) const; };