// Krzysztof Rudnicki, 307585, EADS 2 #include void print(const std::string s) { std::cout << s << std::endl; } template class Ring{ private: struct Node{ Key key; Info info; Node* next; Node* prev; }; Node* any; public: class Iterator { private: Node* pNode; public: Iterator() { pNode = nullptr; } ~Iterator() { pNode = nullptr; } Iterator(Node* ptr) : pNode(ptr) {} bool operator!=(const Iterator& other) const { return pNode != other.pNode; } Iterator& operator++() { pNode = pNode -> next; return *this; } Iterator operator++(int) { Iterator it = *this; pNode = pNode -> next; return it; } Iterator& operator--() { pNode = pNode -> prev; return *this; } Iterator operator--(int) { Iterator it = *this; pNode = pNode -> prev; return it; } Node& operator[](int index) { Node* indexedNode = pNode; for(int i = 0; i < index; i++) { indexedNode = indexedNode -> next; } return *indexedNode; } Node* operator->() { return pNode; } Node& operator*() { return *pNode; } bool operator==(const Iterator& other) const { return pNode == other.pNode; } }; Ring(); ~Ring(); void clearRing(); void print() const; void addAtEnd(Key newKey, Info newInfo); int size() const; Iterator begin() const // I will treat "any" Node as a "begining" of a ring { return Iterator(any); } Iterator end() const // I will treat a Node just before "any" node as an "end" of a ring { if(any == nullptr) return nullptr; return any -> prev; } }; template Ring::Ring() { any = nullptr; } template void Ring::clearRing() { if(any == nullptr) return; Node* curr = any; Node* temp = any; do{ temp = curr; curr = curr->next; delete temp; }while(curr != any); delete any; } template Ring::~Ring() { this -> clearRing(); } template void Ring::print() const { Node* curr = any; do{ std::cout << curr -> key << "; " << curr->info << std::endl; curr = curr->next; }while (curr != any); } template void Ring::addAtEnd(Key newKey, Info newInfo) { Node* newNode = new Node(); newNode -> key = newKey; newNode -> info = newInfo; if(any == nullptr) { any = newNode; any -> next = any; any -> prev = any; return; } if(any -> next == nullptr) { any -> next = newNode; any -> prev = newNode; newNode -> next = any; newNode -> prev = any; return; } Node* curr = any; while(curr -> next != any) curr = curr -> next; any->prev = newNode; curr->next = newNode; newNode -> prev = curr; newNode -> next = any; } template int Ring::size() const { Node* curr = any; int size = 0; do{ size++; curr = curr -> next; }while (curr != any); return size; } template void printPair(const Key key, const Info info) { std::cout << "Key: " << key << "; Info: " << info << std::endl; } bool testForEmpty() { Ring marcel; Ring::Iterator it = marcel.begin(); if(it != nullptr) { print("testForEmpty"); return false; } return true; } bool testOneElement() { Ring marcel; marcel.addAtEnd(1, 1); Ring::Iterator it = marcel.begin(); if(it -> key != 1 || it -> info != 1) { print("testForwardIncrementingOneElement"); return false; } return true; } bool testForwardIncrementing() { Ring marcel; marcel.addAtEnd(1, 1); marcel.addAtEnd(2, 2); marcel.addAtEnd(3, 3); marcel.addAtEnd(4, 4); marcel.addAtEnd(5, 5); int i = 0; for( Ring::Iterator it = marcel.begin(); it != marcel.end(); it++, i++) { if(it -> key != i + 1 || it -> info != i + 1) { print("testForwardIncrementingNormal"); return false; } } if(marcel.end() -> key != 5 || marcel.end() -> info != 5) { print("testForwardIncrementingNormal"); return false; } return true; } bool testBackwardDecrementing() { Ring marcel; marcel.addAtEnd(1, 1); marcel.addAtEnd(2, 2); marcel.addAtEnd(3, 3); marcel.addAtEnd(4, 4); marcel.addAtEnd(5, 5); int i = 0; for( Ring::Iterator it = marcel.end(); it != marcel.begin(); it++, i++) { if(it -> key != 5 - i || it -> info != 5 - i) { print("testBackwardDecrementing"); return false; } } if(marcel.begin() -> key != 1 || marcel.begin() -> info != 1) { print("testBackwardDecrementing"); return false; } return true; } bool testForwardSquareBracket() { Ring marcel; marcel.addAtEnd(1, 1); marcel.addAtEnd(2, 2); marcel.addAtEnd(3, 3); marcel.addAtEnd(4, 4); marcel.addAtEnd(5, 5); Ring::Iterator it = marcel.begin(); for(int i = 0; i < marcel.size(); i++) { if(it[i].key != i + 1 || it[i].info != i + 1) { print("testForwardSquareBracket"); return false; } } return true; } bool testBackwardSquareBracket() { Ring marcel; marcel.addAtEnd(1, 1); marcel.addAtEnd(2, 2); marcel.addAtEnd(3, 3); marcel.addAtEnd(4, 4); marcel.addAtEnd(5, 5); Ring::Iterator it = marcel.end(); for(int i = marcel.size(); i > 0; i--) { if(it[i].key != i || it[i].info != i) { print("testBackwardSquareBracket"); return false; } } return true; } bool testSquareBracketRandomOverflow() { Ring marcel; marcel.addAtEnd(1, 1); marcel.addAtEnd(2, 2); marcel.addAtEnd(3, 3); marcel.addAtEnd(4, 4); marcel.addAtEnd(5, 5); Ring::Iterator it = marcel.begin(); //Checking for some random places in ring: if(it[2].key != 3) { print("testSquareBracketRandomOverflow"); return false; } if(it[4].key != 5) { print("testSquareBracketRandomOverflow"); return false; } if(it[0].key != 1) { print("testSquareBracketRandomOverflow"); return false; } //Checking for overflow: if(it[10].key != 1) { print("testSquareBracketRandomOverflow"); return false; } return true; } bool tests() { return testForEmpty()&&testOneElement()&&testForwardIncrementing() &&testBackwardDecrementing()&&testForwardSquareBracket()&&testBackwardSquareBracket() &&testSquareBracketRandomOverflow(); } int main() { std::cout << "Result of tests is: " << tests() << std::endl; return 1; }