diff --git a/EOOP/Various/LICENSE b/EOOP/Various/LICENSE new file mode 100644 index 00000000..37b2665c --- /dev/null +++ b/EOOP/Various/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 Krzysztof Rudnicki + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/EOOP/Various/currency/currency.cpp b/EOOP/Various/currency/currency.cpp new file mode 100755 index 00000000..e81d6f02 --- /dev/null +++ b/EOOP/Various/currency/currency.cpp @@ -0,0 +1,94 @@ +/** + Unit tests for 2nd EOOP assignment. + + Currency - aggregate 2 doubles (monetary value, exchange rate to dollars) + CurrencyView - view the given currency with different exchange rate + (e.g. view PLN value in GBP), store the reference to the Currency. + + Note that this is in a big part "code reading" exercise. + Based on this file you should implement two classes mentioned above, + with proper interface, and in the right header file. + + Make sure that you use proper method composition in your code. + + Please make sure that you compile your solution with warnings enabled and that there are no warnings during compilation. You can do this via the following command: + g++ -Wall -Wextra -Werror -pedantic lab_2.cpp currency.hpp + */ + +#include "currency2.hpp" +#include + +int main() { + double monetary_value = 8; + double usd_exchange_rate = 0.23; + + Currency pln(monetary_value, usd_exchange_rate); + + if (pln.getValue() != 8) { + std::cerr << "Error in getValue()" << std::endl; + } + if (pln.getUSDExchangeRate() != 0.23) { + std::cerr << pln.getUSDExchangeRate() << std::endl; + std::cerr << "Error in getUSDExchangeRate()" << std::endl; + } + + pln.setValue(42); + pln.setUSDExchangeRate(0.24); + if (pln.getValue() != 42) { + std::cerr << "Error in setValue()" << std::endl; + } + if (pln.getUSDExchangeRate() != 0.24) { + std::cerr << "Error in setUSDExchangeRate()" << std::endl; + } + + Currency gbp(1336, 1.2); + Currency usd(78, 1); + + if (gbp.toDollars() != 1603.2) { + std::cerr << "Error in toDollars() 1" << std::endl; + } + if (usd.toDollars() != 78) { + std::cerr << "Error in toDollars() 2" << std::endl; + } + + gbp.setValueFromDollars(1800); + usd.setValueFromDollars(120); + pln.setValueFromDollars(180); + if (gbp.getValue() != 1500) { + std::cerr << "Error in setValueFromDollars() 1" << std::endl; + } + if (usd.getValue() != 120) { + std::cerr << "Error in setValueFromDollars() 2" << std::endl; + } + if (pln.getValue() != 750) { + std::cerr << "Error in setValueFromDollars() 3" << std::endl; + } + + + usd.addValue(gbp); + if (usd.getValue() != 1920) { + std::cerr << "Error in addValue() 1" << std::endl; + } + gbp.addValue(pln); + if (gbp.getValue() != 1650) { + std::cerr << "Error in addValue() 2" << std::endl; + } + pln.addValue(usd); + if (pln.getValue() != 8750) { + std::cerr << "Error in addValue() 3" << std::endl; + } + + + CurrencyView in_gbp(pln, 1.2); + if (in_gbp.getValue() != 1750) { + std::cerr << "Error in CurrencyView::getValue() 1" << std::endl; + } + pln.setValue(100); + if (in_gbp.getValue() != 20) { + std::cerr << "Error in CurrencyView::getValue() 2" << std::endl; + } + + + std::cerr << "End of tests." << std::endl; + return 0; +} diff --git a/EOOP/Various/currency/currency.hpp b/EOOP/Various/currency/currency.hpp new file mode 100755 index 00000000..9d802a8f --- /dev/null +++ b/EOOP/Various/currency/currency.hpp @@ -0,0 +1,72 @@ +#include + + +class Currency +{ + private: + double monetary_value; + double usd_exchange_rate; + public: + Currency() + { + monetary_value = 0; + usd_exchange_rate = 1; + } + + Currency(double value, double rate) + { + monetary_value = value; + usd_exchange_rate = rate; + } + + double getValue() const { return monetary_value; }; + + double getUSDExchangeRate() const { return usd_exchange_rate; }; + + void setValue(double value) + { + monetary_value = value; + return; + }; + + void setUSDExchangeRate(double rate) + { + usd_exchange_rate = rate; + return; + }; + + double toDollars() const { return monetary_value * usd_exchange_rate; }; + + void setValueFromDollars(double dollarsValue) + { + monetary_value = dollarsValue / usd_exchange_rate; + return; + } + + void addValue(Currency whichWeAdd) + { + monetary_value = (toDollars() + whichWeAdd.toDollars()) / usd_exchange_rate; + } +}; + +class CurrencyView +{ + private: + Currency& original; + double exchangeRate; + public: + CurrencyView(Currency& og, double rate); + + double getValue() const; +}; + +CurrencyView::CurrencyView(Currency& reference, double rate) : original(reference) +{ + exchangeRate = rate; +} + +double CurrencyView::getValue() const +{ + return original.toDollars() / exchangeRate; +} + diff --git a/EOOP/Various/node/node.cpp b/EOOP/Various/node/node.cpp new file mode 100755 index 00000000..7d225465 --- /dev/null +++ b/EOOP/Various/node/node.cpp @@ -0,0 +1,282 @@ +#include + +struct list_node +{ + int value; + list_node *next; + + list_node(int v, list_node* nxt = nullptr) + { + value = v; + next = nxt; + } +}; + +class list +{ + list_node *head; + int listSize; +public: + list() + { + head = nullptr; + listSize = 0; + } + bool is_empty() const; + int size() const; + void push_front(int val); + void pop_front(); + void clear(); + // removes first occurence of `val` in the list + // returns true if removal occured + bool remove(int val); + list_node *get_head(); + void printValues() const; +}; + +bool list::is_empty() const +{ + return head == nullptr; +} + +int list::size() const +{ + return listSize; +} + +void list::push_front(int val) +{ + list_node *pNewNode = new list_node(val); + pNewNode -> next = head; + head = pNewNode; + listSize++; + return; +} + +void list::pop_front() +{ + if(is_empty()) + { + std::cout << "There are no elements to be popped!" << std::endl; + return; + } + + list_node *pTemp = head; + pTemp = pTemp -> next; + delete head; + head = pTemp; + listSize--; + return; +} + +void list::printValues() const +{ + if(head == nullptr) + { + std::cout << "There are no values to be printed!" << std::endl; + return; + } + list_node *pNodes = head; + int i = 1; + while(pNodes) + { + std::cout << i << " value is: " << pNodes -> value << std::endl; + pNodes = pNodes -> next; + i++; + } + return; +} + +void list::clear() +{ + if(head == nullptr) + { + std::cout << "The list is already empty! " << std::endl; + return; + } + while(head) pop_front(); + listSize = 0; + return; +} + +bool list::remove(int val) +{ + list_node *current = head; + list_node *previous = nullptr; + bool valueFound = 0; + while (current != nullptr) + { + if(current -> value == val) + { + valueFound = 1; + break; + } + + previous = current; + current = current -> next; + } + + if(!valueFound) return false; + if(previous == nullptr) head = head -> next; // THIS ELEMENT IS FIRST ELEMENT + else previous -> next = current -> next; + delete current; + listSize--; + return true; +} + +list_node *list::get_head() +{ + return head; +} + +void printIsEmptyValue(list printedList) +{ + std::cout << "is_empty() method value: " << printedList.is_empty() << std::endl; + return; +} + +void isEmptyTest() +{ + std::cout << "TESTING is_empty() METHOD" << std::endl; + list testIsEmpty; + std::cout << "Testing for 0 elements" << std::endl; + printIsEmptyValue(testIsEmpty); + std::cout << "Testing for 1 element" << std::endl; + testIsEmpty.push_front(1); + printIsEmptyValue(testIsEmpty); + std::cout <<"Testing after deleting 1 element" << std::endl; + testIsEmpty.pop_front(); + printIsEmptyValue(testIsEmpty); + return; +} + +void printSize(list printList) +{ + std::cout << "Size of this list is: " << printList.size() << std::endl; + return; +} + +void sizeTest() +{ + std::cout << "TESTING size() METHOD" << std::endl; + list testSize; + std::cout << "Testing for empty list: " << std::endl; + printSize(testSize); + std::cout << "Testing for 1 element list: " << std::endl; + testSize.push_front(1); + printSize(testSize); + std::cout << "Testing after removing one element from 1 element list: " << std::endl; + testSize.pop_front(); + printSize(testSize); + std::cout << "Testing for 5 elements list: " << std::endl; + for(int i = 0; i < 5; i++) testSize.push_front(i); + printSize(testSize); + return; +} + +void pop_frontTest() +{ + std::cout << "TESTING pop_front() METHOD" << std::endl; + list testPopFront; + std::cout << "Trying to pop empty list" << std::endl; + testPopFront.pop_front(); + printIsEmptyValue(testPopFront); + printSize(testPopFront); + testPopFront.push_front(2137); + std::cout << "Poping one element list" << std::endl; + testPopFront.pop_front(); + printIsEmptyValue(testPopFront); + printSize(testPopFront); + std::cout << "Poping two element list" << std::endl; + testPopFront.push_front(1); + testPopFront.push_front(2); + testPopFront.pop_front(); + printIsEmptyValue(testPopFront); + printSize(testPopFront); + testPopFront.printValues(); + return; +} + + void clearTest() + { + std::cout << "TESTING clear() METHOD" << std::endl; + list testClear; + std::cout << "Trying to clear empty list: " << std::endl; + testClear.clear(); + printIsEmptyValue(testClear); + printSize(testClear); + testClear.printValues(); + std::cout << "Clearing one element list: " << std::endl; + testClear.push_front(1); + testClear.clear(); + printIsEmptyValue(testClear); + printSize(testClear); + testClear.printValues(); + std::cout << "Clearing two element list: " << std::endl; + testClear.push_front(1); + testClear.push_front(2); + testClear.clear(); + printIsEmptyValue(testClear); + printSize(testClear); + testClear.printValues(); + std::cout << "Clearing five element list: " << std::endl; + for(int i = 0; i < 5; i++) testClear.push_front(i); + testClear.clear(); + printIsEmptyValue(testClear); + printSize(testClear); + testClear.printValues(); + return; + } + + void printRemoveResult(list fromWhichRemove, int value) + { + if(fromWhichRemove.remove(value)) std::cout << "Removal of value: " << value << " Successful!" << std::endl; + else std::cout << "Removal of value: " << value << " Failed! " << std::endl; + } + + void removeTest() + { + std::cout << "TESTING remove() METHOD " << std::endl; + list testRemove; + std::cout << "Trying to remove element from empty list: " << std::endl; + printRemoveResult(testRemove, 0); + + std::cout << "Trying to remove wrong element from 1 element list: " << std::endl; + testRemove.push_front(1); + printRemoveResult(testRemove, 2); + std::cout << "Trying to remove right element from 1 element list: " << std::endl; + testRemove.push_front(1); + printRemoveResult(testRemove, 1); + + return; + + } + +void getHeadTest() +{ + list testHead; + std::cout << "Testing getHead for empty list: " << std::endl; + std::cout << "getHead value: " << testHead.get_head() << std::endl; + testHead.push_front(5); + std::cout << "Testing getHead for non empty list: " << std::endl; + std::cout << "getHead value: " << testHead.get_head() << std::endl; + return; +} + + +void runTests() +{ + isEmptyTest(); + sizeTest(); + pop_frontTest(); + clearTest(); + removeTest(); + getHeadTest(); + return; +} + +int main() +{ + runTests(); + return 0; +} diff --git a/EOOP/Various/ringBuffer/ring_buffer.cpp b/EOOP/Various/ringBuffer/ring_buffer.cpp new file mode 100755 index 00000000..075d45d8 --- /dev/null +++ b/EOOP/Various/ringBuffer/ring_buffer.cpp @@ -0,0 +1,161 @@ + + +#include "ring_buffer.hpp" +#include +#include +#include + +void error_message(const std::string& message, int value, int expected) { + std::cerr << "Error - " << message << ", got: " << value << " expected " << expected << std::endl; +} + +void error_message(const std::string& message) { + std::cerr << "Error - " << message << "!" << std::endl; +} + +void check_buffer(const RingBuffer& buffer, unsigned int expected_size, unsigned int expected_capacity) { + bool is_empty = buffer.isEmpty(); + bool is_full = buffer.isFull(); + if (expected_size == 0) { + if (!is_empty) { + error_message("buffer should be empty"); + } + if (is_full) { + error_message("buffer shouldn't be full"); + } + } else { + if (is_empty) { + error_message("buffer shouldn't be empty"); + } + if ((expected_size == expected_capacity) && !is_full) { + error_message("buffer should be full"); + } + } + unsigned int size = buffer.size(); + if (size != expected_size) { + error_message("wrong buffer size", static_cast(size), static_cast(expected_size)); + } + unsigned int capacity = buffer.capacity(); + if (capacity != expected_capacity) { + error_message("wrong buffer capacity", static_cast(capacity), static_cast(expected_capacity)); + } +} + +void check_empty_buffer() { + unsigned int capacity = 4; + RingBuffer buffer(capacity); + check_buffer(buffer, 0, capacity); +} + +void check_write_without_overwriting() { + unsigned int capacity = 6; + RingBuffer buffer(capacity); + buffer.write(7); + check_buffer(buffer, 1, capacity); + + buffer.write(42); + check_buffer(buffer, 2, capacity); +} + +void check_read_without_overwriting() { + RingBuffer buffer(3); + + buffer.write(7); + buffer.write(42); + + int read_number = buffer.read(); + if (read_number != 7) { + error_message("read", read_number, 7); + } + read_number = buffer.read(); + if (read_number != 42) { + error_message("read", read_number, 42); + } + check_buffer(buffer, 0, 3); +} + +void _check_reading_after_overwrite(RingBuffer& buffer, unsigned int capacity) { + for ( unsigned int i = 2; i <= capacity + 1; ++i ) { + int read_number = buffer.read(); + if (read_number != static_cast(i)) { + error_message("read with overwrite", read_number, static_cast(i)); + } + } + + check_buffer(buffer, 0, capacity); +} + +void check_overwriting() { + unsigned int capacity = 4; + RingBuffer buffer(capacity); + + for (unsigned int i = 0; i <= capacity + 1; ++i) { + buffer.write(static_cast(i)); + } + check_buffer(buffer, capacity, capacity); + + _check_reading_after_overwrite(buffer, capacity); +} + +void check_copy_constructor() { + unsigned int capacity = 5; + RingBuffer buffer(capacity); + + for (unsigned int i = 0; i <= capacity + 1; ++i) { + buffer.write(static_cast(i)); + } + check_buffer(buffer, capacity, capacity); + + RingBuffer copied(buffer); + + check_buffer(copied, capacity, capacity); + + _check_reading_after_overwrite(buffer, capacity); + _check_reading_after_overwrite(copied, capacity); +} + +void check_assignment_operator() { + unsigned int capacity = 5; + RingBuffer buffer(capacity); + RingBuffer other(capacity); + + for (unsigned int i = 0; i <= capacity + 1; ++i) { + buffer.write(static_cast(i)); + } + check_buffer(buffer, capacity, capacity); + check_buffer(other, 0, capacity); + + other = buffer; + check_buffer(other, capacity, capacity); + + _check_reading_after_overwrite(buffer, capacity); + _check_reading_after_overwrite(other, capacity); +} + +void check_exceptions() { + unsigned int capacity = 5; + RingBuffer buffer(capacity); + RingBuffer other(capacity - 1); + + try { + buffer.read(); + error_message("missing exception while reading from empty buffer"); + } catch(std::exception& e) { } + + try { + buffer = other; + error_message("missing exception in copy constructor"); + } catch(std::exception& e) { } +} + +int main() { + check_empty_buffer(); + check_write_without_overwriting(); + check_read_without_overwriting(); + check_overwriting(); + check_copy_constructor(); + check_assignment_operator(); + check_exceptions(); + std::cout << "End of tests." << std::endl; + return 0; +} diff --git a/EOOP/Various/ringBuffer/ring_buffer.hpp b/EOOP/Various/ringBuffer/ring_buffer.hpp new file mode 100755 index 00000000..8e7a4101 --- /dev/null +++ b/EOOP/Various/ringBuffer/ring_buffer.hpp @@ -0,0 +1,113 @@ +#ifndef RINGBUFFER_HPP +#define RINGBUFFER_HPP +#include +#include + +class RingBuffer { + public: + explicit RingBuffer(unsigned int capacity): capacity_ (capacity) + { + head_ = 0; + tail_ = 0; + size_ = 0; + overwritten = 0; + data_ = (int *)malloc(capacity_); + } + RingBuffer(const RingBuffer& other); + + RingBuffer& operator=(const RingBuffer& other) + { + if(capacity_ != other.capacity_) throw std::exception(); + head_ = other.head_; + tail_ = other.tail_; + size_ = other.size_; + overwritten = other.overwritten; + data_ = (int *)malloc(capacity_); + for(unsigned int i = 0; i < other.size_; i++) + { + data_[head_] = other.data_[head_]; + if(overwritten) + { + tail_ = (tail_ + 1) % capacity_; + size_ = capacity_ - 1; + } + head_ = (head_ + 1) % capacity_; + overwritten = (head_ == tail_); + size_++; + } + } + ~RingBuffer(); + + unsigned int size() const { return size_; } + unsigned int capacity() const { return capacity_; } + bool isEmpty() const { return size_ == 0; } + bool isFull() const { return size_ == capacity_; } + + int& read(); + + void write(int value); + + private: + const unsigned int capacity_; + unsigned int size_; + unsigned int head_; + unsigned int tail_; + int* data_; + bool overwritten; +}; + +RingBuffer::~RingBuffer() +{ + if(data_) + { + delete data_; + data_ = nullptr; + } +} + +void RingBuffer::write(int value) +{ + data_[head_] = value; + if(overwritten) + { + tail_ = (tail_ + 1) % capacity_; + size_ = capacity_ - 1; + } + head_ = (head_ + 1) % capacity_; + overwritten = (head_ == tail_); + size_++; +} + +int& RingBuffer::read() +{ + if(size_ == 0) throw std::exception(); + + int& answer = data_[tail_]; + overwritten = false; + tail_ = (tail_ + 1) % capacity_; + size_--; + return answer; +} + +RingBuffer::RingBuffer(const RingBuffer& other): capacity_ (other.capacity_) +{ + head_ = other.head_; + tail_ = other.tail_; + size_ = other.size_; + overwritten = other.overwritten; + data_ = (int *)malloc(capacity_); + for(unsigned int i = 0; i < other.size_; i++) + { + data_[head_] = other.data_[head_]; + if(overwritten) + { + tail_ = (tail_ + 1) % capacity_; + size_ = capacity_ - 1; + } + head_ = (head_ + 1) % capacity_; + overwritten = (head_ == tail_); + size_++; + } +} + +#endif // RINGBUFFER_HPP diff --git a/EOOP/Various/ringBuffer2/ringbuffer2.cpp b/EOOP/Various/ringBuffer2/ringbuffer2.cpp new file mode 100755 index 00000000..4c5a3455 --- /dev/null +++ b/EOOP/Various/ringBuffer2/ringbuffer2.cpp @@ -0,0 +1,359 @@ +// 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; + +} \ No newline at end of file diff --git a/EOOP/Various/ringBuffer2/ringbuffer3.cpp b/EOOP/Various/ringBuffer2/ringbuffer3.cpp new file mode 100755 index 00000000..2aa74c44 --- /dev/null +++ b/EOOP/Various/ringBuffer2/ringbuffer3.cpp @@ -0,0 +1,406 @@ +#include + +using namespace std; + +template +class Ring +{ +private: + struct Node + { + Key key; + Info info; + Node *prev; + Node *next; + }; + Node *head; + +public: + class Iterator + { + private: + Node *ptr; + Node *headPtr; + Iterator(Node*); + friend class Ring; + public: + Iterator(); + Iterator(Ring); + Info getInfo(); + Key getKey(); + void printData(int); + Info operator*(); + Iterator& operator++();//prefix + Iterator operator++(int);//postfix + Iterator& operator--();//prefix + Iterator operator--(int);//postfix + bool operator==(const Iterator&); + bool operator!=(const Iterator&); + bool isFirst(); + bool isLast(); + }; + + Ring(); + ~Ring(); + void insertAtBeginning(const Key& k, const Info& inf); + void insertAtEnd(const Key& k, const Info& inf); + void removeAtBeginning(); + void removeAtEnd(); + void clear(); + + void printContent(); + void printContentReverse(); + + Iterator begin(); + Iterator end(); +}; + +//main function +int main() +{ + //test 1 - printing + + Ring ring; + + ring.insertAtEnd('a', "letter 1"); + ring.insertAtEnd('b', "letter 2"); + ring.insertAtEnd('c', "letter 3"); + ring.insertAtEnd('d', "letter 4"); + ring.insertAtEnd('e', "letter 5"); + + cout << "Normal print:" << endl; + ring.printContent(); + + Ring::Iterator *ringIt = new Ring::Iterator(ring); + + cout << endl << "Iterator print:" << endl; + int number = 0; + while (ringIt->isLast() == false) + { + ringIt->printData(number); + + number++; + ++ringIt; + } + + + return 0; +} + +//------------------------------Ring functions + +template +Ring::Ring() +{ + head = nullptr; +} + +template +Ring::~Ring() +{ + clear(); +} + +template +void Ring::insertAtBeginning(const Key& k, const Info& inf) +{ + if (head == nullptr) + { + Node *newNode = new Node(); + newNode->key = k; + newNode->info = inf; + newNode->next = newNode; + newNode->prev = newNode; + + head = newNode; + + return; + } + + Node *last = head->prev; + + Node *newNode = new Node(); + newNode->key = k; + newNode->info = inf; + newNode->prev = last; + last->next = newNode; + + newNode->next = head; + head->prev = newNode; + + head = newNode; +} + +template +void Ring::insertAtEnd(const Key& k, const Info& inf) +{ + if (head == nullptr) + { + Node *newNode = new Node(); + newNode->key = k; + newNode->info = inf; + newNode->next = newNode; + newNode->prev = newNode; + + head = newNode; + + return; + } + + Node *last = head->prev; + + Node *newNode = new Node(); + newNode->key = k; + newNode->info = inf; + + newNode->prev = last; + last->next = newNode; + + newNode->next = head; + head->prev = newNode; +} + +template +void Ring::removeAtBeginning() +{ + if (head == nullptr) + return; + + if (head->next == head) + { + delete head; + head = nullptr; + + return; + } + + Node *prev = head->prev; + Node *next = head->next; + + prev->next = next; + next->prev = prev; + + delete head; + head = next; +} + +template +void Ring::removeAtEnd() +{ + if (head == nullptr) + return; + + if (head->next == head) + { + delete head; + head = nullptr; + + return; + } + + Node *prev = head->prev->prev; + //Node *next = head; + + delete head->prev; + + prev->next = head; + head->prev = prev; +} + +template +void Ring::clear() +{ + while (head != nullptr) + removeAtEnd(); +} + +template +void Ring::printContent() +{ + if (head == nullptr) + return; + + Node *current = head; + int number = 0; + + do + { + cout << number << "# - Key: " << current->key << ", Info: " << current->info << endl; + + number++; + current = current->next; + } while (current != head); +} + +template +void Ring::printContentReverse() +{ + if (head == nullptr) + return; + + + if (head->next == head) + { + cout << "0# - Key: " << head->key << ", Info: " << head->info << endl; + } + + Node *current = head->prev; + int number = 0; + + do + { + cout << number << "# - Key: " << current->key << ", Info: " << current->info << endl; + + number++; + current = current->prev; + } while (current != head); +} + +template +typename Ring::Iterator Ring::begin() +{ + Ring::Iterator tempIter = new Ring::Iterator(head); + + return tempIter; +} + +template +typename Ring::Iterator Ring::end() +{ + Ring::Iterator tempIter = new Ring::Iterator(head->prev); + + return tempIter; +} + +//------------------------------Ring Iterator functions + +template +Ring::Iterator::Iterator() +{ + ptr = nullptr; + headPtr = nullptr; +} + +template +Ring::Iterator::Iterator(Node* nodePtr) +{ + ptr = nodePtr; + headPtr = nodePtr; +} + +template +Ring::Iterator::Iterator(Ring ring) +{ + ptr = ring.head; + headPtr = ring.head; +} + +template +Info Ring::Iterator::getInfo() +{ + if (ptr != nullptr) + return ptr->info; + else + throw "Iterator was nullptr"; +} + +template +Key Ring::Iterator::getKey() +{ + if (ptr != nullptr) + return ptr->key; + else + throw "Iterator was nullptr"; +} + +template +void Ring::Iterator::printData(int number) +{ + if (ptr != nullptr) + cout << number << "# - Key: " << ptr->key << ", Info: " << ptr->info << endl; + else + cout << "Tried to print an empty iterator" << endl; +} + +template +Info Ring::Iterator::operator*() +{ + if (ptr != nullptr) + return ptr->info; + else + throw "Iterator was nullptr"; +} + +template +typename Ring::Iterator& Ring::Iterator::operator++() +{ + if (ptr != nullptr && headPtr != nullptr && ptr->next != headPtr) + ptr = ptr->next; + + return *this; +} + +template +typename Ring::Iterator Ring::Iterator::operator++(int) +{ + Ring::Iterator incremented = *this; + + ++(*this); + return incremented; +} + +template +typename Ring::Iterator& Ring::Iterator::operator--() +{ + if (ptr != nullptr && headPtr != nullptr && ptr != headPtr) + ptr = ptr->prev; + + return *this; +} + +template +typename Ring::Iterator Ring::Iterator::operator--(int) +{ + Ring::Iterator decremented = *this; + + --(*this); + return decremented; +} + +template +bool Ring::Iterator::operator==(const Ring::Iterator& iter) +{ + if (ptr == iter->ptr) + return true; + else + return false; +} + +template +bool Ring::Iterator::operator!=(const Ring::Iterator& iter) +{ + if (operator==(this)) + return false; + else + return true; +} + + +template +bool Ring::Iterator::isLast() +{ + cout << (ptr != nullptr) << " " << (headPtr != nullptr) << " " << (ptr->next == headPtr) << endl; + if (ptr != nullptr && headPtr != nullptr && ptr->next == headPtr) + return true; + else + return false; +} + +template +bool Ring::Iterator::isFirst() +{ + if (ptr != nullptr && headPtr != nullptr && ptr == headPtr) + return true; + else + return false; +}