Library 1

fixed issue #2 and cleaned code
This commit is contained in:
Alessandro Ferro 2021-04-23 21:44:06 +02:00
parent 69489dac81
commit dc0739a4f8
5 changed files with 273 additions and 354 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
**/main

View File

@ -31,7 +31,6 @@ public:
bool operator!=(const Container&&) const noexcept = delete; // Comparison of abstract types might not be possible. bool operator!=(const Container&&) const noexcept = delete; // Comparison of abstract types might not be possible.
// Specific member functions // Specific member functions
virtual bool Empty() const noexcept { virtual bool Empty() const noexcept {
return (size == 0); return (size == 0);
} // (concrete function should not throw exceptions) } // (concrete function should not throw exceptions)
@ -43,10 +42,6 @@ public:
virtual void Clear() = 0; virtual void Clear() = 0;
}; };
/* ************************************************************************** */
template <typename Data> template <typename Data>
class LinearContainer : virtual public Container{ // Must extend Container class LinearContainer : virtual public Container{ // Must extend Container
@ -72,7 +67,6 @@ public:
/* ************************************************************************ */ /* ************************************************************************ */
// Specific member functions // Specific member functions
virtual Data& Front() const = 0; // (concrete function must throw std::length_error when empty) virtual Data& Front() const = 0; // (concrete function must throw std::length_error when empty)
virtual Data& Back() const = 0; // (concrete function must throw std::length_error when empty) virtual Data& Back() const = 0; // (concrete function must throw std::length_error when empty)
@ -105,7 +99,6 @@ public:
/* ************************************************************************ */ /* ************************************************************************ */
// Specific member functions // Specific member functions
virtual bool Exists(const Data&) const noexcept = 0; // (concrete function should not throw exceptions) virtual bool Exists(const Data&) const noexcept = 0; // (concrete function should not throw exceptions)
}; };

View File

@ -29,21 +29,16 @@ List<Data>::Node::Node(Data&& moveFrom){
std::swap(value, moveFrom); std::swap(value, moveFrom);
} }
// Comparison operator
template <typename Data> template <typename Data>
bool List<Data>::Node::operator==(const Node& node)const noexcept{ bool List<Data>::Node::operator==(const Node& node)const noexcept{
return (node.value == value); return (node.value == value);
} }
template <typename Data> template <typename Data>
bool List<Data>::Node::operator!=(const Node& node)const noexcept{ bool List<Data>::Node::operator!=(const Node& node)const noexcept{
return !(*this == node); return !(*this == node);
} }
// Specific constructor
template <typename Data> template <typename Data>
List<Data>::List(const LinearContainer<Data>& con){ List<Data>::List(const LinearContainer<Data>& con){
for(ulong i = 0; i<con.Size(); ++i){ for(ulong i = 0; i<con.Size(); ++i){
@ -51,7 +46,6 @@ List<Data>::List(const LinearContainer<Data>& con){
} }
} }
// Copy constructor
template <typename Data> template <typename Data>
List<Data>::List(const List<Data>& copyFrom){ List<Data>::List(const List<Data>& copyFrom){
for(ulong i = 0; i<copyFrom.Size(); ++i){ for(ulong i = 0; i<copyFrom.Size(); ++i){
@ -59,7 +53,6 @@ List<Data>::List(const List<Data>& copyFrom){
} }
} }
// Move constructor
template <typename Data> template <typename Data>
List<Data>::List(List<Data>&& moveFrom){ List<Data>::List(List<Data>&& moveFrom){
std::swap(size, moveFrom.size); std::swap(size, moveFrom.size);
@ -72,19 +65,17 @@ List<Data>::~List(){
Clear(); Clear();
} }
// Copy assignment
template <typename Data> template <typename Data>
List<Data>& List<Data>::operator=(const List<Data>& copyFrom){ List<Data>& List<Data>::operator=(const List<Data>& copyFrom){
if(*this != copyFrom){ if(*this != copyFrom){
Clear(); Clear();
for(ulong i = 0; i<copyFrom.Size(); ++i){ for(ulong i = 0 ; i<copyFrom.Size() ; ++i){
InsertAtBack(copyFrom[i]); InsertAtBack(copyFrom[i]);
} }
} }
return *this; return *this;
} }
//Move assignment
template <typename Data> template <typename Data>
List<Data>& List<Data>::operator=(List<Data>&& moveFrom)noexcept{ List<Data>& List<Data>::operator=(List<Data>&& moveFrom)noexcept{
if(*this != moveFrom){ if(*this != moveFrom){
@ -95,11 +86,10 @@ template <typename Data>
return *this; return *this;
} }
//Comparison operators
template <typename Data> template <typename Data>
bool List<Data>::operator==(const List<Data>& list) const noexcept{ bool List<Data>::operator==(const List<Data>& list) const noexcept{
if(this->size != list.Size()) return false; if(size != list.Size()) return false;
for(ulong i = 0; i < (this->size); ++i){ for(ulong i = 0 ; i < size ; ++i){
if((*this)[i] != list[i]) return false; if((*this)[i] != list[i]) return false;
} }
return true; return true;
@ -110,34 +100,29 @@ bool List<Data>::operator!=(const List<Data>& list) const noexcept{
return !(*this==list); return !(*this==list);
} }
// Specific member functions template <typename Data>
void List<Data>::InsertAtFront(const Data& data){
template <typename Data>
void List<Data>::InsertAtFront(const Data& data){
struct Node* tmp = new Node(data); struct Node* tmp = new Node(data);
tmp->next = head; tmp->next = head;
head =tmp; head = tmp;
size++; size++;
if(size == 1){ if(size == 1){
tail = head; tail = head;
} }
} }
template <typename Data>
template <typename Data> void List<Data>::InsertAtFront(Data&& data){
void List<Data>::InsertAtFront(Data&& data){ struct Node* tmp = new Node(std::move(data));
struct Node* tmp = new Node(data);
tmp->next = head; tmp->next = head;
head =tmp; head = tmp;
size++; size++;
if(size == 1){ if(size == 1){
tail = head; tail = head;
} }
} }
template <typename Data> template <typename Data>
void List<Data>::RemoveFromFront(){ void List<Data>::RemoveFromFront(){
if(head == nullptr){ if(head == nullptr){
throw std::length_error("List is empty!"); throw std::length_error("List is empty!");
@ -148,15 +133,14 @@ bool List<Data>::operator!=(const List<Data>& list) const noexcept{
tmp->next = nullptr; tmp->next = nullptr;
delete tmp; delete tmp;
size--; size--;
if(head==nullptr){ if(head==nullptr){
tail=nullptr; tail=nullptr;
} }
} }
} }
template <typename Data> template <typename Data>
Data List<Data>::FrontNRemove(){ Data List<Data>::FrontNRemove(){
if(head == nullptr){ if(head == nullptr){
throw std::length_error("List is empty!"); throw std::length_error("List is empty!");
} }
@ -165,10 +149,10 @@ bool List<Data>::operator!=(const List<Data>& list) const noexcept{
RemoveFromFront(); RemoveFromFront();
return value; return value;
} }
} }
template <typename Data> template <typename Data>
void List<Data>::InsertAtBack(const Data& data){ void List<Data>::InsertAtBack(const Data& data){
if(size == 0){ if(size == 0){
InsertAtFront(data); InsertAtFront(data);
} }
@ -178,118 +162,104 @@ bool List<Data>::operator!=(const List<Data>& list) const noexcept{
tail = last; tail = last;
size++; size++;
} }
} }
template <typename Data> template <typename Data>
void List<Data>::InsertAtBack(Data&& data){ void List<Data>::InsertAtBack(Data&& data){
if(size == 0){ if(size == 0){
InsertAtFront(data); InsertAtFront(data);
} }
else{ else{
struct Node* last = new Node(data); struct Node* last = new Node(std::move(data));
tail->next = last; tail->next = last;
tail = last; tail = last;
size++; size++;
} }
} }
template <typename Data> template <typename Data>
void List<Data>::Clear(){ void List<Data>::Clear(){
while(head != nullptr){ while(head != nullptr){
RemoveFromFront(); RemoveFromFront();
} }
} }
template <typename Data> template <typename Data>
Data& List<Data>::Front() const{ Data& List<Data>::Front() const{
if(size == 0){ if(size == 0){
throw std::length_error("List is empty!"); throw std::length_error("List is empty!");
}else{ }else{
return head->value; return head->value;
} }
} }
template <typename Data> template <typename Data>
Data& List<Data>::Back() const{ Data& List<Data>::Back() const{
if(size == 0){ if(size == 0){
throw std::length_error("List is empty!"); throw std::length_error("List is empty!");
}else{ }else{
return tail->value; return tail->value;
} }
} }
template <typename Data> template <typename Data>
Data& List<Data>::operator[](const ulong idx) const{ Data& List<Data>::operator[](const ulong index) const{
if(idx >= size || idx < 0){ if(index >= size || index < 0){
throw std::out_of_range("Out of Range!"); throw std::out_of_range("Out of Range!");
}else }else{
{
struct Node* tmp = head; struct Node* tmp = head;
for(ulong i=0; i<idx; ++i){ for(ulong i=0; i<index; ++i){
tmp = tmp->next; tmp = tmp->next;
} }
return tmp->value; return tmp->value;
} }
} }
template <typename Data>
template <typename Data> void List<Data>::MapPreOrder(MapFunctor function, void* par){
void List<Data>::MapPreOrder(MapFunctor function, void* par){
MapPreOrder(function, par, head); MapPreOrder(function, par, head);
} }
template <typename Data> template <typename Data>
void List<Data>::MapPostOrder(MapFunctor function, void* par){ void List<Data>::MapPostOrder(MapFunctor function, void* par){
MapPostOrder(function, par, head); MapPostOrder(function, par, head);
} }
template <typename Data> template <typename Data>
void List<Data>::FoldPreOrder(FoldFunctor function, const void* constPar, void* par) const{ void List<Data>::FoldPreOrder(FoldFunctor function, const void* constPar, void* par) const{
FoldPreOrder(function, constPar, par, head); FoldPreOrder(function, constPar, par, head);
} }
template <typename Data> template <typename Data>
void List<Data>::FoldPostOrder(FoldFunctor function, const void* constPar, void* par) const{ void List<Data>::FoldPostOrder(FoldFunctor function, const void* constPar, void* par) const{
FoldPostOrder(function, constPar, par, head); FoldPostOrder(function, constPar, par, head);
} }
//OVERLOAD Accessory Function
template <typename Data>
void List<Data>::MapPreOrder(MapFunctor function, void* par, struct Node* node){
if(node == nullptr)
return;
template <typename Data>
void List<Data>::MapPreOrder(MapFunctor function, void* par, struct Node* node){
if(node == nullptr) return;
function(node->value, par); function(node->value, par);
MapPreOrder(function, par, node->next); MapPreOrder(function, par, node->next);
} }
template <typename Data>
void List<Data>::MapPostOrder(MapFunctor function, void* par, struct Node* node){
if(node == nullptr)
return;
template <typename Data>
void List<Data>::MapPostOrder(MapFunctor function, void* par, struct Node* node){
if(node == nullptr) return;
MapPostOrder(function, par, node->next); MapPostOrder(function, par, node->next);
function(node->value, par); function(node->value, par);
} }
template <typename Data>
void List<Data>::FoldPreOrder(FoldFunctor function, const void* constPar, void* par, struct Node* node) const{
if(node == nullptr)
return;
template <typename Data>
void List<Data>::FoldPreOrder(FoldFunctor function, const void* constPar, void* par, struct Node* node) const{
if(node == nullptr) return;
function(node->value, constPar, par); function(node->value, constPar, par);
FoldPreOrder(function, constPar, par, node->next); FoldPreOrder(function, constPar, par, node->next);
} }
template <typename Data>
void List<Data>::FoldPostOrder(FoldFunctor function, const void* constPar, void* par, struct Node* node) const{
if(node == nullptr)
return;
template <typename Data>
void List<Data>::FoldPostOrder(FoldFunctor function, const void* constPar, void* par, struct Node* node) const{
if(node == nullptr) return;
FoldPostOrder(function, constPar, par, node->next); FoldPostOrder(function, constPar, par, node->next);
function(node->value, constPar, par); function(node->value, constPar, par);
} }
/* ************************************************************************** */
} }

View File

@ -34,31 +34,30 @@ template <typename Data>
} }
// Destructor // Destructor
template <typename Data> template <typename Data>
Vector<Data>::~Vector(){ Vector<Data>::~Vector(){
Clear(); Clear();
} }
// Copy assignment // Copy assignment
template <typename Data> template <typename Data>
Vector<Data>& Vector<Data>::operator=(const Vector<Data>& vec){ Vector<Data>& Vector<Data>::operator=(const Vector<Data>& vec){
Vector<Data>* tmpvec = new Vector<Data>(vec); Vector<Data>* tmpvec = new Vector<Data>(vec);
std::swap(*tmpvec, *this); std::swap(*tmpvec, *this);
delete tmpvec; delete tmpvec;
return *this; return *this;
} }
// Move assignment // Move assignment
template <typename Data> template <typename Data>
Vector<Data>& Vector<Data>::operator=(Vector<Data>&& vec)noexcept{ Vector<Data>& Vector<Data>::operator=(Vector<Data>&& vec)noexcept{
std::swap(Elements,vec.Elements); std::swap(Elements,vec.Elements);
std::swap(size, vec.size); std::swap(size, vec.size);
return *this; return *this;
} }
// Comparison operators template <typename Data>
template <typename Data> bool Vector<Data>::operator==(const Vector<Data>& vec) const noexcept{
bool Vector<Data>::operator==(const Vector<Data>& vec) const noexcept{
if(size == vec.size){ if(size == vec.size){
for(ulong i=0; i<size; ++i){ for(ulong i=0; i<size; ++i){
if(Elements[i] != vec.Elements[i]) if(Elements[i] != vec.Elements[i])
@ -68,20 +67,19 @@ template <typename Data>
}else{ }else{
return false; return false;
} }
} }
template <typename Data>
template <typename Data> bool Vector<Data>::operator!=(const Vector<Data>& vec)const noexcept{
bool Vector<Data>::operator!=(const Vector<Data>& vec)const noexcept{
return !(*this == vec); return !(*this == vec);
} }
template <typename Data> template <typename Data>
void Vector<Data>::Resize(const ulong newsize){ void Vector<Data>::Resize(const ulong newsize){
if(newsize == 0){ if(newsize == 0){
Clear(); Clear();
}else if(size != newsize) }
{ else if(size != newsize){
ulong limit = (size < newsize) ? size : newsize; ulong limit = (size < newsize) ? size : newsize;
Data* TmpElements = new Data[newsize]{}; Data* TmpElements = new Data[newsize]{};
for(ulong i=0; i<limit; ++i){ for(ulong i=0; i<limit; ++i){
@ -91,79 +89,72 @@ template <typename Data>
size = newsize; size = newsize;
delete[] TmpElements; delete[] TmpElements;
} }
} }
template <typename Data>
template <typename Data> void Vector<Data>::Clear(){
void Vector<Data>::Clear(){
delete[] Elements; delete[] Elements;
Elements = nullptr; Elements = nullptr;
size = 0; size = 0;
} }
template <typename Data> template <typename Data>
Data& Vector<Data>::Front() const { Data& Vector<Data>::Front() const {
if(size != 0) if(size != 0){
{
return Elements[0]; return Elements[0];
}else{ }
else{
throw std::length_error("Access to an empty vector!"); throw std::length_error("Access to an empty vector!");
} }
} }
template <typename Data> template <typename Data>
Data& Vector<Data>::Back() const { Data& Vector<Data>::Back() const {
if(size != 0) if(size != 0){
{
return Elements[size - 1]; return Elements[size - 1];
}else{ }
else{
throw std::length_error("Access to an empty vector!"); throw std::length_error("Access to an empty vector!");
} }
} }
template <typename Data>
template <typename Data> Data& Vector<Data>::operator[](const ulong index) const{
Data& Vector<Data>::operator[](const ulong idx) const{ if(index < size){
if(idx < size) return Elements[index];
{
return Elements[idx];
}
else
{
throw std::out_of_range("Tried to access index " + std::to_string(idx) + " but the dimension of the vector is " + std::to_string(size));
} }
else{
throw std::out_of_range("Tried to access index " + std::to_string(index) + " but the dimension of the vector is " + std::to_string(size));
} }
}
template <typename Data>
template <typename Data> void Vector<Data>::MapPreOrder(const MapFunctor fun, void* par){
void Vector<Data>::MapPreOrder(const MapFunctor fun, void* par){
for(ulong i=0; i<size; ++i){ for(ulong i=0; i<size; ++i){
fun(Elements[i], par); fun(Elements[i], par);
} }
} }
template <typename Data> template <typename Data>
void Vector<Data>::MapPostOrder(const MapFunctor fun, void* par){ void Vector<Data>::MapPostOrder(const MapFunctor fun, void* par){
ulong idx = size; ulong index = size;
while(idx > 0) while(index > 0){
{ fun(Elements[--index], par);
fun(Elements[--idx], par);
}
} }
}
template <typename Data>
template <typename Data> void Vector<Data>::FoldPreOrder(const FoldFunctor fun, const void* par, void* acc) const{
void Vector<Data>::FoldPreOrder(const FoldFunctor fun, const void* par, void* acc) const{
for(ulong i=0; i<size; ++i){ for(ulong i=0; i<size; ++i){
fun(Elements[i], par, acc); fun(Elements[i], par, acc);
} }
} }
template <typename Data> template <typename Data>
void Vector<Data>::FoldPostOrder(const FoldFunctor fun, const void* par, void* acc) const{ void Vector<Data>::FoldPostOrder(const FoldFunctor fun, const void* par, void* acc) const{
ulong idx = size; ulong idx = size;
while(idx > 0){ while(idx > 0){
fun(Elements[--idx], par, acc); fun(Elements[--idx], par, acc);
} }
} }
} }

View File

@ -25,90 +25,53 @@ protected:
using LinearContainer<Data>::size; using LinearContainer<Data>::size;
Data* Elements = nullptr; Data* Elements = nullptr;
// ...
public: public:
// Default constructor
// Vector() specifiers;
Vector() = default; Vector() = default;
/* ************************************************************************ */
// Specific constructors // Specific constructors
Vector(const ulong); // A vector with a given initial dimension Vector(const ulong); // A vector with a given initial dimension
Vector(const LinearContainer<Data>&); // A vector obtained from a LinearContainer Vector(const LinearContainer<Data>&); // A vector obtained from a LinearContainer
/* ************************************************************************ */
// Copy constructor // Copy constructor
Vector(const Vector&); Vector(const Vector&);
// Move constructor // Move constructor
Vector(Vector&&)noexcept; Vector(Vector&&)noexcept;
/* ************************************************************************ */
// Destructor // Destructor
~Vector(); ~Vector();
/* ************************************************************************ */
// Copy assignment // Copy assignment
Vector& operator=(const Vector&); Vector& operator=(const Vector&);
// Move assignment // Move assignment
Vector& operator=(Vector&&) noexcept; Vector& operator=(Vector&&) noexcept;
/* ************************************************************************ */
// Comparison operators // Comparison operators
bool operator==(const Vector&) const noexcept; bool operator==(const Vector&) const noexcept;
bool operator!=(const Vector&) const noexcept; bool operator!=(const Vector&) const noexcept;
/* ************************************************************************ */
// Specific member functions
void Resize(const ulong); // Resize the vector to a given size void Resize(const ulong); // Resize the vector to a given size
/* ************************************************************************ */
// Specific member functions (inherited from Container)
void Clear() override; // Override Container member void Clear() override; // Override Container member
/* ************************************************************************ */
// Specific member functions (inherited from LinearContainer)
Data& Front() const override; // Override LinearContainer member (must throw std::length_error when empty) Data& Front() const override; // Override LinearContainer member (must throw std::length_error when empty)
Data& Back() const override; // Override LinearContainer member (must throw std::length_error when empty) Data& Back() const override; // Override LinearContainer member (must throw std::length_error when empty)
Data& operator[](const ulong) const override; // Override LinearContainer member (must throw std::out_of_range when out of range) Data& operator[](const ulong) const override; // Override LinearContainer member (must throw std::out_of_range when out of range)
/* ************************************************************************ */
// Specific member functions (inherited from MappableContainer)
using typename MappableContainer<Data>::MapFunctor; using typename MappableContainer<Data>::MapFunctor;
void MapPreOrder(const MapFunctor, void*) override; // Override MappableContainer member void MapPreOrder(const MapFunctor, void*) override; // Override MappableContainer member
void MapPostOrder(const MapFunctor, void*) override; // Override MappableContainer member void MapPostOrder(const MapFunctor, void*) override; // Override MappableContainer member
/* ************************************************************************ */
// Specific member functions (inherited from FoldableContainer)
using typename FoldableContainer<Data>::FoldFunctor; using typename FoldableContainer<Data>::FoldFunctor;
void FoldPreOrder(const FoldFunctor, const void*, void*) const override; // Override FoldableContainer member void FoldPreOrder(const FoldFunctor, const void*, void*) const override; // Override FoldableContainer member
void FoldPostOrder(const FoldFunctor, const void*, void*) const override; // Override FoldableContainer member void FoldPostOrder(const FoldFunctor, const void*, void*) const override; // Override FoldableContainer member
}; };
/* ************************************************************************** */
} }
#include "vector.cpp" #include "vector.cpp"