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> struct Node* tmp = new Node(data);
void List<Data>::InsertAtFront(const Data& data){ tmp->next = head;
struct Node* tmp = new Node(data); head = tmp;
tmp->next = head; size++;
head =tmp; if(size == 1){
size++; tail = head;
}
if(size == 1){
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){
tail = head;
if(size == 1){
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,148 +133,133 @@ 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!");
}
else{
Data value = head->value;
RemoveFromFront();
return value;
}
} }
else{
template <typename Data> Data value = head->value;
void List<Data>::InsertAtBack(const Data& data){ RemoveFromFront();
if(size == 0){ return value;
InsertAtFront(data);
}
else{
struct Node* last = new Node(data);
tail->next = last;
tail = last;
size++;
}
} }
}
template <typename Data>
void List<Data>::InsertAtBack(Data&& data){ template <typename Data>
if(size == 0){ void List<Data>::InsertAtBack(const Data& data){
InsertAtFront(data); if(size == 0){
} InsertAtFront(data);
else{ }
struct Node* last = new Node(data); else{
tail->next = last; struct Node* last = new Node(data);
tail = last; tail->next = last;
size++; tail = last;
} size++;
} }
}
template <typename Data>
void List<Data>::Clear(){ template <typename Data>
while(head != nullptr){ void List<Data>::InsertAtBack(Data&& data){
RemoveFromFront(); if(size == 0){
} InsertAtFront(data);
} }
else{
template <typename Data> struct Node* last = new Node(std::move(data));
Data& List<Data>::Front() const{ tail->next = last;
if(size == 0){ tail = last;
throw std::length_error("List is empty!"); size++;
}else{ }
return head->value; }
}
} template <typename Data>
void List<Data>::Clear(){
template <typename Data> while(head != nullptr){
Data& List<Data>::Back() const{ RemoveFromFront();
if(size == 0){ }
throw std::length_error("List is empty!"); }
}else{
return tail->value; template <typename Data>
} Data& List<Data>::Front() const{
} if(size == 0){
throw std::length_error("List is empty!");
template <typename Data> }else{
Data& List<Data>::operator[](const ulong idx) const{ return head->value;
if(idx >= size || idx < 0){ }
throw std::out_of_range("Out of Range!"); }
}else
{ template <typename Data>
struct Node* tmp = head; Data& List<Data>::Back() const{
for(ulong i=0; i<idx; ++i){ if(size == 0){
tmp = tmp->next; throw std::length_error("List is empty!");
} }else{
return tmp->value; return tail->value;
} }
} }
template <typename Data>
template <typename Data> Data& List<Data>::operator[](const ulong index) const{
void List<Data>::MapPreOrder(MapFunctor function, void* par){ if(index >= size || index < 0){
MapPreOrder(function, par, head); throw std::out_of_range("Out of Range!");
} }else{
struct Node* tmp = head;
template <typename Data> for(ulong i=0; i<index; ++i){
void List<Data>::MapPostOrder(MapFunctor function, void* par){ tmp = tmp->next;
MapPostOrder(function, par, head); }
} return tmp->value;
}
template <typename Data> }
void List<Data>::FoldPreOrder(FoldFunctor function, const void* constPar, void* par) const{
FoldPreOrder(function, constPar, par, head); template <typename Data>
} void List<Data>::MapPreOrder(MapFunctor function, void* par){
MapPreOrder(function, par, head);
template <typename Data> }
void List<Data>::FoldPostOrder(FoldFunctor function, const void* constPar, void* par) const{
FoldPostOrder(function, constPar, par, head); template <typename Data>
} void List<Data>::MapPostOrder(MapFunctor function, void* par){
MapPostOrder(function, par, head);
//OVERLOAD Accessory Function }
template <typename Data> template <typename Data>
void List<Data>::MapPreOrder(MapFunctor function, void* par, struct Node* node){ void List<Data>::FoldPreOrder(FoldFunctor function, const void* constPar, void* par) const{
if(node == nullptr) FoldPreOrder(function, constPar, par, head);
return; }
function(node->value, par); template <typename Data>
MapPreOrder(function, par, node->next); void List<Data>::FoldPostOrder(FoldFunctor function, const void* constPar, void* par) const{
} FoldPostOrder(function, constPar, par, head);
}
template <typename Data>
void List<Data>::MapPostOrder(MapFunctor function, void* par, struct Node* node){ template <typename Data>
if(node == nullptr) void List<Data>::MapPreOrder(MapFunctor function, void* par, struct Node* node){
return; if(node == nullptr) return;
function(node->value, par);
MapPostOrder(function, par, node->next); MapPreOrder(function, par, node->next);
function(node->value, par); }
}
template <typename Data>
template <typename Data> void List<Data>::MapPostOrder(MapFunctor function, void* par, struct Node* node){
void List<Data>::FoldPreOrder(FoldFunctor function, const void* constPar, void* par, struct Node* node) const{ if(node == nullptr) return;
MapPostOrder(function, par, node->next);
if(node == nullptr) function(node->value, par);
return; }
function(node->value, constPar, par); template <typename Data>
FoldPreOrder(function, constPar, par, node->next); void List<Data>::FoldPreOrder(FoldFunctor function, const void* constPar, void* par, struct Node* node) const{
} if(node == nullptr) return;
function(node->value, constPar, par);
template <typename Data> FoldPreOrder(function, constPar, par, node->next);
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{
FoldPostOrder(function, constPar, par, node->next); if(node == nullptr) return;
function(node->value, constPar, par); FoldPostOrder(function, constPar, par, node->next);
} function(node->value, constPar, par);
/* ************************************************************************** */ }
} }

View File

@ -34,136 +34,127 @@ template <typename Data>
} }
// Destructor // Destructor
template <typename Data> template <typename Data>
Vector<Data>::~Vector(){ Vector<Data>::~Vector(){
Clear();
}
// Copy assignment
template <typename Data>
Vector<Data>& Vector<Data>::operator=(const Vector<Data>& vec){
Vector<Data>* tmpvec = new Vector<Data>(vec);
std::swap(*tmpvec, *this);
delete tmpvec;
return *this;
}
// Move assignment
template <typename Data>
Vector<Data>& Vector<Data>::operator=(Vector<Data>&& vec)noexcept{
std::swap(Elements,vec.Elements);
std::swap(size, vec.size);
return *this;
}
template <typename Data>
bool Vector<Data>::operator==(const Vector<Data>& vec) const noexcept{
if(size == vec.size){
for(ulong i=0; i<size; ++i){
if(Elements[i] != vec.Elements[i])
return false;
}
return true;
}else{
return false;
}
}
template <typename Data>
bool Vector<Data>::operator!=(const Vector<Data>& vec)const noexcept{
return !(*this == vec);
}
template <typename Data>
void Vector<Data>::Resize(const ulong newsize){
if(newsize == 0){
Clear(); Clear();
} }
else if(size != newsize){
// Copy assignment ulong limit = (size < newsize) ? size : newsize;
template <typename Data> Data* TmpElements = new Data[newsize]{};
Vector<Data>& Vector<Data>::operator=(const Vector<Data>& vec){ for(ulong i=0; i<limit; ++i){
Vector<Data>* tmpvec = new Vector<Data>(vec); std::swap(Elements[i], TmpElements[i]);
std::swap(*tmpvec, *this);
delete tmpvec;
return *this;
}
// Move assignment
template <typename Data>
Vector<Data>& Vector<Data>::operator=(Vector<Data>&& vec)noexcept{
std::swap(Elements,vec.Elements);
std::swap(size, vec.size);
return *this;
}
// Comparison operators
template <typename Data>
bool Vector<Data>::operator==(const Vector<Data>& vec) const noexcept{
if(size == vec.size){
for(ulong i=0; i<size; ++i){
if(Elements[i] != vec.Elements[i])
return false;
}
return true;
}else{
return false;
}
}
template <typename Data>
bool Vector<Data>::operator!=(const Vector<Data>& vec)const noexcept{
return !(*this == vec);
}
template <typename Data>
void Vector<Data>::Resize(const ulong newsize){
if(newsize == 0){
Clear();
}else if(size != newsize)
{
ulong limit = (size < newsize) ? size : newsize;
Data* TmpElements = new Data[newsize]{};
for(ulong i=0; i<limit; ++i){
std::swap(Elements[i], TmpElements[i]);
}
std::swap(Elements, TmpElements);
size = newsize;
delete[] TmpElements;
}
}
template <typename Data>
void Vector<Data>::Clear(){
delete[] Elements;
Elements = nullptr;
size = 0;
}
template <typename Data>
Data& Vector<Data>::Front() const {
if(size != 0)
{
return Elements[0];
}else{
throw std::length_error("Access to an empty vector!");
}
}
template <typename Data>
Data& Vector<Data>::Back() const {
if(size != 0)
{
return Elements[size - 1];
}else{
throw std::length_error("Access to an empty vector!");
}
}
template <typename Data>
Data& Vector<Data>::operator[](const ulong idx) const{
if(idx < size)
{
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));
}
}
template <typename Data>
void Vector<Data>::MapPreOrder(const MapFunctor fun, void* par){
for(ulong i=0; i<size; ++i){
fun(Elements[i], par);
}
}
template <typename Data>
void Vector<Data>::MapPostOrder(const MapFunctor fun, void* par){
ulong idx = size;
while(idx > 0)
{
fun(Elements[--idx], par);
}
}
template <typename Data>
void Vector<Data>::FoldPreOrder(const FoldFunctor fun, const void* par, void* acc) const{
for(ulong i=0; i<size; ++i){
fun(Elements[i], par, acc);
}
}
template <typename Data>
void Vector<Data>::FoldPostOrder(const FoldFunctor fun, const void* par, void* acc) const{
ulong idx = size;
while(idx > 0){
fun(Elements[--idx], par, acc);
}
} }
std::swap(Elements, TmpElements);
size = newsize;
delete[] TmpElements;
}
}
template <typename Data>
void Vector<Data>::Clear(){
delete[] Elements;
Elements = nullptr;
size = 0;
}
template <typename Data>
Data& Vector<Data>::Front() const {
if(size != 0){
return Elements[0];
}
else{
throw std::length_error("Access to an empty vector!");
}
}
template <typename Data>
Data& Vector<Data>::Back() const {
if(size != 0){
return Elements[size - 1];
}
else{
throw std::length_error("Access to an empty vector!");
}
}
template <typename Data>
Data& Vector<Data>::operator[](const ulong index) const{
if(index < size){
return Elements[index];
}
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>
void Vector<Data>::MapPreOrder(const MapFunctor fun, void* par){
for(ulong i=0; i<size; ++i){
fun(Elements[i], par);
}
}
template <typename Data>
void Vector<Data>::MapPostOrder(const MapFunctor fun, void* par){
ulong index = size;
while(index > 0){
fun(Elements[--index], par);
}
}
template <typename Data>
void Vector<Data>::FoldPreOrder(const FoldFunctor fun, const void* par, void* acc) const{
for(ulong i=0; i<size; ++i){
fun(Elements[i], par, acc);
}
}
template <typename Data>
void Vector<Data>::FoldPostOrder(const FoldFunctor fun, const void* par, void* acc) const{
ulong idx = size;
while(idx > 0){
fun(Elements[--idx], par, acc);
}
}
} }

View File

@ -25,35 +25,22 @@ protected:
using LinearContainer<Data>::size; using LinearContainer<Data>::size;
Data* Elements = nullptr; Data* Elements = nullptr;
// ...
public: public:
// Default constructor Vector() = default;
// Vector() specifiers;
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&);
@ -61,54 +48,30 @@ public:
// 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)
/* ************************************************************************ */ using typename MappableContainer<Data>::MapFunctor;
// Specific member functions (inherited from MappableContainer) void MapPreOrder(const MapFunctor, void*) override; // Override MappableContainer member
void MapPostOrder(const MapFunctor, void*) override; // Override MappableContainer member
using typename MappableContainer<Data>::MapFunctor; using typename FoldableContainer<Data>::FoldFunctor;
void MapPreOrder(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;
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"