/////////////////////////////////////////////////////////////////////// // MT4Q1.cpp - TypeTable // // // // Jim Fawcett, CSE687 - Object Oriented Design, Midterm Spring 2016 // /////////////////////////////////////////////////////////////////////// #include #include #include #include #include "../Utilities/Utilities.h" /* * The record class below could be simplified to a simple struct with * all public fields, assuming that our Table class doesn't need to * expose that to client code. * * I chose to put most of the user interface into this record class, * so I do need the encapsulation used here. */ class TypeTableRecord { public: using Namespace = std::string; using Name = std::string; using Type = std::string; using FileName = std::string; using iterator = std::vector::iterator; Name& name() { return _name; } Type& type() { return _type; } FileName& fileName() { return _whereDefined; } void addNameSpace(const Namespace& ns) { if (find(_namespaces.begin(), _namespaces.end(), ns) == _namespaces.end()) _namespaces.push_back(ns); } size_t numberOfNameSpaces() { return _namespaces.size(); } iterator begin() { return _namespaces.begin(); } iterator end() { return _namespaces.end(); } Namespace operator[](size_t n) const { if (n < 0 || n >= _namespaces.size()) throw(std::exception("index out of range")); return _namespaces[n]; } private: Name _name; Type _type; FileName _whereDefined; std::vector _namespaces; }; ///////////////////////////////////////////////////////////////////// // beginning of solution // - needs a few words about the record structure // - With a Record class that holds required information the // Table only needs to add records, store them, and provide access. template class TypeTable { public: using iterator = typename std::vector::iterator; void addRecord(const TableRecord& record) { _records.push_back(record); } TableRecord& operator[](size_t n) { if (n < 0 || n >= _records.size()) throw(std::exception("index out of range")); return _records[n]; } TableRecord operator[](size_t n) const { if (n < 0 || n >= _records.size()) throw(std::exception("index out of range")); return _records[n]; } iterator begin() { return _records.begin(); } iterator end() { return _records.end(); } private: std::vector _records; }; // end of solution ///////////////////////////////////////////////////////////////////// template void showRecord(TableRecord& record) { std::cout << "\n "; std::cout << std::setw(16) << record.fileName(); std::cout << std::setw(8) << record.name(); std::cout << std::setw(12) << record.type(); for (auto ns : record) std::cout << std::setw(16) << ns; } void showRecordHeader() { std::cout << std::left << "\n "; std::cout << std::setw(16) << "Filename"; std::cout << std::setw(8) << "Name"; std::cout << std::setw(12) << "Type"; std::cout << std::setw(16) << "Namespaces" << "\n"; std::cout << " " << std::setw(16) << std::string(14, '-'); std::cout << std::setw(8) << std::string(6, '-'); std::cout << std::setw(12) << std::string(10, '-'); std::cout << std::setw(16) < void showTypeTable(TypeTable& table) { showRecordHeader(); for (auto record : table) showRecord(record); } using namespace Utilities; using Utils = StringHelper; void main() { Utils::Title("MT4Q1 - TypeTable"); putline(); TypeTable table; TypeTableRecord record; record.name() = "X"; record.type() = "class"; record.fileName() = "X.h"; record.addNameSpace("TypeAnalysis"); record.addNameSpace("MT4"); table.addRecord(record); record.name() = "fun"; record.type() = "method"; record.fileName() = "X.h"; record.addNameSpace("TypeAnalysis"); record.addNameSpace("MT4"); table.addRecord(record); showTypeTable(table); std::cout << "\n\n"; }