mirror of
https://github.com/kuhyx/WUT_Computer_Science.git
synced 2026-11-11 20:33:55 +01:00
Merge remote-tracking branch 'EOOPVarious/branch' into main
This commit is contained in:
commit
e1e4737c7f
21
EOOP/Various/LICENSE
Normal file
21
EOOP/Various/LICENSE
Normal file
@ -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.
|
||||||
94
EOOP/Various/currency/currency.cpp
Executable file
94
EOOP/Various/currency/currency.cpp
Executable file
@ -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 <iostream>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
72
EOOP/Various/currency/currency.hpp
Executable file
72
EOOP/Various/currency/currency.hpp
Executable file
@ -0,0 +1,72 @@
|
|||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
282
EOOP/Various/node/node.cpp
Executable file
282
EOOP/Various/node/node.cpp
Executable file
@ -0,0 +1,282 @@
|
|||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
161
EOOP/Various/ringBuffer/ring_buffer.cpp
Executable file
161
EOOP/Various/ringBuffer/ring_buffer.cpp
Executable file
@ -0,0 +1,161 @@
|
|||||||
|
|
||||||
|
|
||||||
|
#include "ring_buffer.hpp"
|
||||||
|
#include <array>
|
||||||
|
#include <iostream>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
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<int>(size), static_cast<int>(expected_size));
|
||||||
|
}
|
||||||
|
unsigned int capacity = buffer.capacity();
|
||||||
|
if (capacity != expected_capacity) {
|
||||||
|
error_message("wrong buffer capacity", static_cast<int>(capacity), static_cast<int>(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<int>(i)) {
|
||||||
|
error_message("read with overwrite", read_number, static_cast<int>(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<int>(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<int>(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<int>(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;
|
||||||
|
}
|
||||||
113
EOOP/Various/ringBuffer/ring_buffer.hpp
Executable file
113
EOOP/Various/ringBuffer/ring_buffer.hpp
Executable file
@ -0,0 +1,113 @@
|
|||||||
|
#ifndef RINGBUFFER_HPP
|
||||||
|
#define RINGBUFFER_HPP
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
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
|
||||||
359
EOOP/Various/ringBuffer2/ringbuffer2.cpp
Executable file
359
EOOP/Various/ringBuffer2/ringbuffer2.cpp
Executable file
@ -0,0 +1,359 @@
|
|||||||
|
// Krzysztof Rudnicki, 307585, EADS 2
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
void print(const std::string s)
|
||||||
|
{
|
||||||
|
std::cout << s << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Key, typename Info>
|
||||||
|
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<typename Key, typename Info>
|
||||||
|
Ring<Key, Info>::Ring()
|
||||||
|
{
|
||||||
|
any = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Key, typename Info>
|
||||||
|
void Ring<Key, Info>::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<typename Key, typename Info>
|
||||||
|
Ring<Key, Info>::~Ring()
|
||||||
|
{
|
||||||
|
this -> clearRing();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Key, typename Info>
|
||||||
|
void Ring<Key, Info>::print() const
|
||||||
|
{
|
||||||
|
Node* curr = any;
|
||||||
|
do{
|
||||||
|
std::cout << curr -> key << "; " << curr->info << std::endl;
|
||||||
|
curr = curr->next;
|
||||||
|
}while (curr != any);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Key, typename Info>
|
||||||
|
void Ring<Key, Info>::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<typename Key, typename Info>
|
||||||
|
int Ring<Key, Info>::size() const
|
||||||
|
{
|
||||||
|
Node* curr = any;
|
||||||
|
int size = 0;
|
||||||
|
do{
|
||||||
|
size++;
|
||||||
|
curr = curr -> next;
|
||||||
|
}while (curr != any);
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Key, typename Info>
|
||||||
|
void printPair(const Key key, const Info info)
|
||||||
|
{
|
||||||
|
std::cout << "Key: " << key << "; Info: " << info << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool testForEmpty()
|
||||||
|
{
|
||||||
|
Ring<int, int> marcel;
|
||||||
|
Ring<int, int>::Iterator it = marcel.begin();
|
||||||
|
if(it != nullptr)
|
||||||
|
{
|
||||||
|
print("testForEmpty");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool testOneElement()
|
||||||
|
{
|
||||||
|
Ring<int, int> marcel;
|
||||||
|
marcel.addAtEnd(1, 1);
|
||||||
|
Ring<int, int>::Iterator it = marcel.begin();
|
||||||
|
if(it -> key != 1 || it -> info != 1)
|
||||||
|
{
|
||||||
|
print("testForwardIncrementingOneElement");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool testForwardIncrementing()
|
||||||
|
{
|
||||||
|
Ring<int, int> 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<int, int>::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<int, int> 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<int, int>::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<int, int> marcel;
|
||||||
|
marcel.addAtEnd(1, 1);
|
||||||
|
marcel.addAtEnd(2, 2);
|
||||||
|
marcel.addAtEnd(3, 3);
|
||||||
|
marcel.addAtEnd(4, 4);
|
||||||
|
marcel.addAtEnd(5, 5);
|
||||||
|
Ring<int, int>::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<int, int> marcel;
|
||||||
|
marcel.addAtEnd(1, 1);
|
||||||
|
marcel.addAtEnd(2, 2);
|
||||||
|
marcel.addAtEnd(3, 3);
|
||||||
|
marcel.addAtEnd(4, 4);
|
||||||
|
marcel.addAtEnd(5, 5);
|
||||||
|
Ring<int, int>::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<int, int> marcel;
|
||||||
|
marcel.addAtEnd(1, 1);
|
||||||
|
marcel.addAtEnd(2, 2);
|
||||||
|
marcel.addAtEnd(3, 3);
|
||||||
|
marcel.addAtEnd(4, 4);
|
||||||
|
marcel.addAtEnd(5, 5);
|
||||||
|
Ring<int, int>::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;
|
||||||
|
|
||||||
|
}
|
||||||
406
EOOP/Various/ringBuffer2/ringbuffer3.cpp
Executable file
406
EOOP/Various/ringBuffer2/ringbuffer3.cpp
Executable file
@ -0,0 +1,406 @@
|
|||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
template <typename Key, typename Info>
|
||||||
|
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<Key, Info>;
|
||||||
|
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<char, string> 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<char, string>::Iterator *ringIt = new Ring<char, string>::Iterator(ring);
|
||||||
|
|
||||||
|
cout << endl << "Iterator print:" << endl;
|
||||||
|
int number = 0;
|
||||||
|
while (ringIt->isLast() == false)
|
||||||
|
{
|
||||||
|
ringIt->printData(number);
|
||||||
|
|
||||||
|
number++;
|
||||||
|
++ringIt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------Ring functions
|
||||||
|
|
||||||
|
template <typename Key, typename Info>
|
||||||
|
Ring<Key, Info>::Ring()
|
||||||
|
{
|
||||||
|
head = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Key, typename Info>
|
||||||
|
Ring<Key, Info>::~Ring()
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Key, typename Info>
|
||||||
|
void Ring<Key, Info>::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 <typename Key, typename Info>
|
||||||
|
void Ring<Key, Info>::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 <typename Key, typename Info>
|
||||||
|
void Ring<Key, Info>::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 <typename Key, typename Info>
|
||||||
|
void Ring<Key, Info>::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 <typename Key, typename Info>
|
||||||
|
void Ring<Key, Info>::clear()
|
||||||
|
{
|
||||||
|
while (head != nullptr)
|
||||||
|
removeAtEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Key, typename Info>
|
||||||
|
void Ring<Key, Info>::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 <typename Key, typename Info>
|
||||||
|
void Ring<Key, Info>::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 Key, typename Info>
|
||||||
|
typename Ring<Key, Info>::Iterator Ring<Key, Info>::begin()
|
||||||
|
{
|
||||||
|
Ring<Key, Info>::Iterator tempIter = new Ring<Key, Info>::Iterator(head);
|
||||||
|
|
||||||
|
return tempIter;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Key, typename Info>
|
||||||
|
typename Ring<Key, Info>::Iterator Ring<Key, Info>::end()
|
||||||
|
{
|
||||||
|
Ring<Key, Info>::Iterator tempIter = new Ring<Key, Info>::Iterator(head->prev);
|
||||||
|
|
||||||
|
return tempIter;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------Ring Iterator functions
|
||||||
|
|
||||||
|
template <typename Key, typename Info>
|
||||||
|
Ring<Key, Info>::Iterator::Iterator()
|
||||||
|
{
|
||||||
|
ptr = nullptr;
|
||||||
|
headPtr = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Key, typename Info>
|
||||||
|
Ring<Key, Info>::Iterator::Iterator(Node* nodePtr)
|
||||||
|
{
|
||||||
|
ptr = nodePtr;
|
||||||
|
headPtr = nodePtr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Key, typename Info>
|
||||||
|
Ring<Key, Info>::Iterator::Iterator(Ring<Key, Info> ring)
|
||||||
|
{
|
||||||
|
ptr = ring.head;
|
||||||
|
headPtr = ring.head;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Key, typename Info>
|
||||||
|
Info Ring<Key, Info>::Iterator::getInfo()
|
||||||
|
{
|
||||||
|
if (ptr != nullptr)
|
||||||
|
return ptr->info;
|
||||||
|
else
|
||||||
|
throw "Iterator was nullptr";
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Key, typename Info>
|
||||||
|
Key Ring<Key, Info>::Iterator::getKey()
|
||||||
|
{
|
||||||
|
if (ptr != nullptr)
|
||||||
|
return ptr->key;
|
||||||
|
else
|
||||||
|
throw "Iterator was nullptr";
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Key, typename Info>
|
||||||
|
void Ring<Key, Info>::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 <typename Key, typename Info>
|
||||||
|
Info Ring<Key, Info>::Iterator::operator*()
|
||||||
|
{
|
||||||
|
if (ptr != nullptr)
|
||||||
|
return ptr->info;
|
||||||
|
else
|
||||||
|
throw "Iterator was nullptr";
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Key, typename Info>
|
||||||
|
typename Ring<Key, Info>::Iterator& Ring<Key, Info>::Iterator::operator++()
|
||||||
|
{
|
||||||
|
if (ptr != nullptr && headPtr != nullptr && ptr->next != headPtr)
|
||||||
|
ptr = ptr->next;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Key, typename Info>
|
||||||
|
typename Ring<Key, Info>::Iterator Ring<Key, Info>::Iterator::operator++(int)
|
||||||
|
{
|
||||||
|
Ring<Key, Info>::Iterator incremented = *this;
|
||||||
|
|
||||||
|
++(*this);
|
||||||
|
return incremented;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Key, typename Info>
|
||||||
|
typename Ring<Key, Info>::Iterator& Ring<Key, Info>::Iterator::operator--()
|
||||||
|
{
|
||||||
|
if (ptr != nullptr && headPtr != nullptr && ptr != headPtr)
|
||||||
|
ptr = ptr->prev;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Key, typename Info>
|
||||||
|
typename Ring<Key, Info>::Iterator Ring<Key, Info>::Iterator::operator--(int)
|
||||||
|
{
|
||||||
|
Ring<Key, Info>::Iterator decremented = *this;
|
||||||
|
|
||||||
|
--(*this);
|
||||||
|
return decremented;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Key, typename Info>
|
||||||
|
bool Ring<Key, Info>::Iterator::operator==(const Ring<Key, Info>::Iterator& iter)
|
||||||
|
{
|
||||||
|
if (ptr == iter->ptr)
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Key, typename Info>
|
||||||
|
bool Ring<Key, Info>::Iterator::operator!=(const Ring<Key, Info>::Iterator& iter)
|
||||||
|
{
|
||||||
|
if (operator==(this))
|
||||||
|
return false;
|
||||||
|
else
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename Key, typename Info>
|
||||||
|
bool Ring<Key, Info>::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 <typename Key, typename Info>
|
||||||
|
bool Ring<Key, Info>::Iterator::isFirst()
|
||||||
|
{
|
||||||
|
if (ptr != nullptr && headPtr != nullptr && ptr == headPtr)
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user