From 9311cd345d5cbe95830002b57697d6cd533b713a Mon Sep 17 00:00:00 2001 From: Alessandro Ferro <49845537+xfarrow@users.noreply.github.com> Date: Fri, 9 Apr 2021 10:31:22 +0200 Subject: [PATCH] Library1 --- librerie/exercise1/container/container.cpp | 1 + librerie/exercise1/container/container.hpp | 77 +-- librerie/exercise1/list/list.cpp | 355 ++++++----- librerie/exercise1/list/list.hpp | 42 +- librerie/exercise1/main | Bin 0 -> 255240 bytes librerie/exercise1/main.cpp | 11 +- librerie/exercise1/vector/vector.cpp | 309 +++++----- librerie/exercise1/vector/vector.hpp | 35 +- librerie/exercise1/zmytest/test.cpp | 570 +++++++++++++++++- librerie/exercise1/zmytest/test.hpp | 81 ++- .../{exercise1 => exercise1old}/Exercise1.pdf | Bin librerie/exercise1old/build.sh | 7 + librerie/exercise1old/container/container.cpp | 17 + librerie/exercise1old/container/container.hpp | 304 ++++++++++ librerie/exercise1old/list/list.cpp | 264 ++++++++ librerie/exercise1old/list/list.hpp | 164 +++++ librerie/exercise1old/main.cpp | 18 + librerie/exercise1old/vector/vector.cpp | 181 ++++++ librerie/exercise1old/vector/vector.hpp | 105 ++++ .../zlasdtest/container/container.cpp | 49 ++ .../zlasdtest/container/container.hpp | 301 +++++++++ .../zlasdtest/exercise1/fulltest.cpp | 3 + .../zlasdtest/exercise1/simpletest.cpp | 447 ++++++++++++++ .../exercise1old/zlasdtest/exercise1/test.hpp | 13 + librerie/exercise1old/zlasdtest/list/list.hpp | 92 +++ librerie/exercise1old/zlasdtest/test.cpp | 17 + librerie/exercise1old/zlasdtest/test.hpp | 11 + .../exercise1old/zlasdtest/vector/vector.hpp | 37 ++ librerie/exercise1old/zmytest/test.cpp | 70 +++ librerie/exercise1old/zmytest/test.hpp | 37 ++ 30 files changed, 3178 insertions(+), 440 deletions(-) create mode 100755 librerie/exercise1/main rename librerie/{exercise1 => exercise1old}/Exercise1.pdf (100%) create mode 100755 librerie/exercise1old/build.sh create mode 100644 librerie/exercise1old/container/container.cpp create mode 100644 librerie/exercise1old/container/container.hpp create mode 100644 librerie/exercise1old/list/list.cpp create mode 100644 librerie/exercise1old/list/list.hpp create mode 100644 librerie/exercise1old/main.cpp create mode 100644 librerie/exercise1old/vector/vector.cpp create mode 100644 librerie/exercise1old/vector/vector.hpp create mode 100644 librerie/exercise1old/zlasdtest/container/container.cpp create mode 100644 librerie/exercise1old/zlasdtest/container/container.hpp create mode 100644 librerie/exercise1old/zlasdtest/exercise1/fulltest.cpp create mode 100644 librerie/exercise1old/zlasdtest/exercise1/simpletest.cpp create mode 100644 librerie/exercise1old/zlasdtest/exercise1/test.hpp create mode 100644 librerie/exercise1old/zlasdtest/list/list.hpp create mode 100644 librerie/exercise1old/zlasdtest/test.cpp create mode 100644 librerie/exercise1old/zlasdtest/test.hpp create mode 100644 librerie/exercise1old/zlasdtest/vector/vector.hpp create mode 100644 librerie/exercise1old/zmytest/test.cpp create mode 100644 librerie/exercise1old/zmytest/test.hpp diff --git a/librerie/exercise1/container/container.cpp b/librerie/exercise1/container/container.cpp index 6a22d84..6bbe4bf 100644 --- a/librerie/exercise1/container/container.cpp +++ b/librerie/exercise1/container/container.cpp @@ -14,4 +14,5 @@ bool FoldableContainer::Exists(const Data& dat) const noexcept{ FoldPreOrder(&AuxFoldExists, &dat, &exists); return exists; } + } diff --git a/librerie/exercise1/container/container.hpp b/librerie/exercise1/container/container.hpp index bd42995..c1aeca4 100644 --- a/librerie/exercise1/container/container.hpp +++ b/librerie/exercise1/container/container.hpp @@ -2,17 +2,11 @@ #ifndef CONTAINER_HPP #define CONTAINER_HPP -/* ************************************************************************** */ - #include #include -/* ************************************************************************** */ - namespace lasd { -/* ************************************************************************** */ - class Container { private: @@ -26,40 +20,35 @@ public: // Destructor virtual ~Container() = default; - /* ************************************************************************ */ - // Copy assignment - Container& operator=(const Container&) = delete; // Copy assignment of abstract types should not be possible. + Container& operator=(const Container&) = delete; // Copy assignment of abstract types should not be possible. // Move assignment - Container& operator=(Container&&) noexcept = delete; // Move assignment of abstract types should not be possible. - - /* ************************************************************************ */ + Container& operator=(Container&&) noexcept = delete;; // Move assignment of abstract types should not be possible. // Comparison operators - 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. - - /* ************************************************************************ */ + 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 - virtual bool Empty() const noexcept { // (concrete function should not throw exceptions) - return (size==0); - }; + virtual bool Empty() const noexcept { + return (size == 0); + } // (concrete function should not throw exceptions) - virtual ulong Size() const noexcept{ - return size; - } // (concrete function should not throw exceptions) - - virtual void Clear() = 0; + virtual ulong Size() const noexcept { + return size; + } // (concrete function should not throw exceptions) + virtual void Clear() = 0; }; /* ************************************************************************** */ + + template -class LinearContainer : virtual public Container { // Must extend Container +class LinearContainer : virtual public Container{ // Must extend Container private: @@ -70,15 +59,11 @@ public: // Destructor virtual ~LinearContainer() = default; - /* ************************************************************************ */ - // Copy assignment LinearContainer& operator=(const LinearContainer&) = delete; // Copy assignment of abstract types should not be possible. // Move assignment - LinearContainer& operator=(LinearContainer&&) = delete; // Move assignment of abstract types should not be possible. - - /* ************************************************************************ */ + LinearContainer& operator=(LinearContainer&&) noexcept = delete; // Move assignment of abstract types should not be possible. // Comparison operators bool operator==(const LinearContainer&) const noexcept = delete; // Comparison of abstract types might not be possible. @@ -95,10 +80,8 @@ public: }; -/* ************************************************************************** */ - template -class TestableContainer : public Container { // Must extend Container +class TestableContainer : virtual public Container{ // Must extend Container private: @@ -109,16 +92,12 @@ public: // Destructor virtual ~TestableContainer() = default; - /* ************************************************************************ */ - // Copy assignment TestableContainer& operator=(const TestableContainer&) = delete; // Copy assignment of abstract types should not be possible. // Move assignment TestableContainer& operator=(TestableContainer&&) noexcept = delete; // Move assignment of abstract types should not be possible. - /* ************************************************************************ */ - // Comparison operators bool operator==(const TestableContainer&) const noexcept = delete; // Comparison of abstract types might not be possible. bool operator!=(const TestableContainer&) const noexcept = delete; // Comparison of abstract types might not be possible. @@ -131,8 +110,6 @@ public: }; -/* ************************************************************************** */ - template class MappableContainer : virtual public Container { // Must extend Container @@ -145,22 +122,16 @@ public: // Destructor virtual ~MappableContainer() = default; - /* ************************************************************************ */ - // Copy assignment - MappableContainer& operator=(const MappableContainer&) = delete; // Copy assignment of abstract types should not be possible. + MappableContainer& operator=(const MappableContainer&) = delete; // Copy assignment of abstract types should not be possible. // Move assignment MappableContainer& operator=(MappableContainer&&) noexcept = delete; // Move assignment of abstract types should not be possible. - /* ************************************************************************ */ - // Comparison operators bool operator==(const MappableContainer&) const noexcept = delete; // Comparison of abstract types might not be possible. bool operator!=(const MappableContainer&) const noexcept = delete; // Comparison of abstract types might not be possible. - /* ************************************************************************ */ - // Specific member functions typedef std::function MapFunctor; @@ -170,8 +141,6 @@ public: }; -/* ************************************************************************** */ - template class FoldableContainer : virtual public TestableContainer{ // Must extend TestableContainer @@ -184,25 +153,19 @@ public: // Destructor virtual ~FoldableContainer() = default; - /* ************************************************************************ */ - // Copy assignment FoldableContainer& operator=(const FoldableContainer&) = delete; // Copy assignment of abstract types should not be possible. // Move assignment FoldableContainer& operator=(FoldableContainer&&) noexcept = delete; // Move assignment of abstract types should not be possible. - /* ************************************************************************ */ - // Comparison operators - bool operator==(const FoldableContainer&) const noexcept = delete; // Comparison of abstract types might not be possible. - bool operator!=(const FoldableContainer&) const noexcept = delete; // Comparison of abstract types might not be possible. - - /* ************************************************************************ */ + bool operator==(FoldableContainer&) const noexcept = delete; // Comparison of abstract types might not be possible. + bool operator!=(FoldableContainer&) const noexcept = delete; // Comparison of abstract types might not be possible. // Specific member functions - typedef std::function FoldFunctor; + typedef std::function FoldFunctor; virtual void FoldPreOrder(const FoldFunctor, const void*, void*) const = 0; virtual void FoldPostOrder(const FoldFunctor, const void*, void*) const = 0; diff --git a/librerie/exercise1/list/list.cpp b/librerie/exercise1/list/list.cpp index 0786682..14e8c61 100644 --- a/librerie/exercise1/list/list.cpp +++ b/librerie/exercise1/list/list.cpp @@ -1,141 +1,149 @@ + namespace lasd { - // Specific constructor - template - List::Node::Node(Data newValue){ - value = newValue; - next = nullptr; - } - // Copy constructor - template - List::Node::Node(const Node& copyFrom){ - value = copyFrom.value; - } - template - List::Node::Node(const Data& copyFrom){ - value = copyFrom; - } +/* ************************************************************************** */ - // Move constructor - template - List::Node::Node(Node&& moveFrom){ - std::move(value, moveFrom.value); - std::move(next, moveFrom.next); - } - template - List::Node::Node(Data&& moveFrom){ - std::move(value, moveFrom); - } +// Specific constructors +template +List::Node::Node(Data newValue){ + value = newValue; + next = nullptr; +} - // Comparison operator - template - bool List::Node::operator==(const Node& node) const noexcept{ - if(node.value == value) return true; - else return false; - // TODO: deve confrontare anche il puntatore? - } - template - bool List::Node::operator!=(const Node& node) const noexcept{ - if(node.value != value) return true; - else return false; - // TODO: deve confrontare anche il puntatore? - // return !(this==node) - } +// Copy constructor +template +List::Node::Node(const Node& copyFrom){ + value = copyFrom.value; +} - template - List::List(const LinearContainer& con){ - for(ulong i=0 ; i +List::Node::Node(Node&& moveFrom){ + std::move(value, moveFrom.value); + std::move(next, moveFrom.next); +} + +template +List::Node::Node(Data&& moveFrom){ + std::move(value, moveFrom); +} + + +// Comparison operator +template +bool List::Node::operator==(const Node& node)const noexcept{ + return (node.value == value); +} + +template +bool List::Node::operator!=(const Node& node)const noexcept{ + return !(*this == node); +} + + +// Specific constructor +template +List::List(const LinearContainer& con){ + for(ulong i = 0; i - List::List(const List& copyFrom){ - for(ulong i=0 ; i +List::List(const List& copyFrom){ + for(ulong i = 0; i - List::List(List&& moveFrom){ - std::swap(size, moveFrom.size); - std::swap(head, moveFrom.head); - std::swap(tail, moveFrom.tail); - } +// Move constructor +template +List::List(List&& moveFrom){ + std::swap(size, moveFrom.size); + std::swap(head, moveFrom.head); + std::swap(tail, moveFrom.tail); +} - // Destructor - template - List::~List(){ - Clear(); - } +template +List::~List(){ + Clear(); +} - // Copy assignment - template - List& List::operator=(const List& copyFrom){ - if(*this != copyFrom){ - Clear(); - for(ulong i=0 ; i + List& List::operator=(const List& copyFrom){ + if(*this != copyFrom){ + Clear(); + for(ulong i = 0; i - List& List::operator=(List&& moveFrom){ - if(*this != moveFrom){ - Clear(); - std::swap(size, moveFrom.size); - std::swap(head, moveFrom.head); - std::swap(tail, moveFrom.tail); - } - return *this; + //Move assignment + template + List& List::operator=(List&& moveFrom)noexcept{ + if(*this != moveFrom){ + //Clear(); + std::swap(size, moveFrom.size); + std::swap(head, moveFrom.head); + std::swap(tail, moveFrom.tail); } + return *this; + } - // Comparison operators - template - bool List::operator==(const List& list) const noexcept{ - if(this->size != list.Size()) return false; - for(ulong i=0 ; i<(this->size) ; ++i){ - if(*this[i] != list[i]) return false; - } - return true; - } + //Comparison operators + template + bool List::operator==(const List& list) const noexcept{ + if(this->size != list.Size()) return false; + for(ulong i = 0; i < (this->size); ++i){ + if((*this)[i] != list[i]) return false; + } + return true; + } - template - bool List::operator!=(const List& list) const noexcept{ - return !(*this == list); - } +template +bool List::operator!=(const List& list) const noexcept{ + return !(*this==list); +} - // Specific member functions - template - void List::InsertAtFront(const Data& data){ - struct Node* tmp = new Node(data); - tmp->next = head; - head = tmp; - size++; - if(size==1){ +// Specific member functions + + template + void List::InsertAtFront(const Data& data){ + struct Node* tmp = new Node(data); + tmp->next = head; + head =tmp; + size++; + + if(size == 1){ tail = head; } - } + } + template void List::InsertAtFront(Data&& data){ struct Node* tmp = new Node(data); tmp->next = head; - head = tmp; + head =tmp; size++; - if(size==1){ - tail = head; - } + + if(size == 1){ + tail = head; + } } template void List::RemoveFromFront(){ - if(head==nullptr){ + if(head == nullptr){ throw std::length_error("List is empty!"); - }else{ + } + else{ struct Node* tmp = head; head = head->next; delete tmp; @@ -145,9 +153,10 @@ namespace lasd { template Data List::FrontNRemove(){ - if(head==nullptr){ + if(head == nullptr){ throw std::length_error("List is empty!"); - }else{ + } + else{ Data value = head->value; RemoveFromFront(); return value; @@ -156,9 +165,10 @@ namespace lasd { template void List::InsertAtBack(const Data& data){ - if(size==0){ + if(size == 0){ InsertAtFront(data); - }else{ + } + else{ struct Node* last = new Node(data); tail->next = last; tail = last; @@ -168,9 +178,10 @@ namespace lasd { template void List::InsertAtBack(Data&& data){ - if(size==0){ + if(size == 0){ InsertAtFront(data); - }else{ + } + else{ struct Node* last = new Node(data); tail->next = last; tail = last; @@ -180,14 +191,14 @@ namespace lasd { template void List::Clear(){ - while(head!=nullptr){ + while(head != nullptr){ RemoveFromFront(); } } template Data& List::Front() const{ - if(size==0){ + if(size == 0){ throw std::length_error("List is empty!"); }else{ return head->value; @@ -196,7 +207,7 @@ namespace lasd { template Data& List::Back() const{ - if(size==0){ + if(size == 0){ throw std::length_error("List is empty!"); }else{ return tail->value; @@ -204,67 +215,77 @@ namespace lasd { } template - Data& List::operator[](const ulong index) const{ - if(index>=size || index<0){ - throw std::out_of_range("Out of range!"); - }else{ + Data& List::operator[](const ulong idx) const{ + if(idx >= size || idx < 0){ + throw std::out_of_range("Out of Range!"); + }else + { struct Node* tmp = head; - for(ulong i=0 ; inext; } return tmp->value; } } - template - void List::MapPreOrder(const MapFunctor fun, void* par){ - MapPreOrder(fun, par, head); - } template - void List::MapPreOrder(MapFunctor function, void* par, struct Node* node){ - if(node == nullptr) - return; - function(node->value, par); - MapPreOrder(function, par, node->next); - } + void List::MapPreOrder(MapFunctor function, void* par){ + MapPreOrder(function, par, head); + } - template - void List::MapPostOrder(MapFunctor function, void* par){ - MapPostOrder(function, par, head); - } + template + void List::MapPostOrder(MapFunctor function, void* par){ + MapPostOrder(function, par, head); + } - template - void List::MapPostOrder(MapFunctor function, void* par, struct Node* node){ - if(node == nullptr) - return; - MapPostOrder(function, par, node->next); - function(node->value, par); - } + template + void List::FoldPreOrder(FoldFunctor function, const void* constPar, void* par) const{ + FoldPreOrder(function, constPar, par, head); + } - template - void List::FoldPreOrder(FoldFunctor function, const void* constPar, void* par) const{ - FoldPreOrder(function, constPar, par, head); - } + template + void List::FoldPostOrder(FoldFunctor function, const void* constPar, void* par) const{ + FoldPostOrder(function, constPar, par, head); + } - template - void List::FoldPreOrder(FoldFunctor function, const void* constPar, void* par, struct Node* node) const{ - if(node == nullptr) - return; - function(node->value, constPar, par); - FoldPreOrder(function, constPar, par, node->next); - } + //OVERLOAD Accessory Function - template - void List::FoldPostOrder(FoldFunctor function, const void* constPar, void* par) const{ - FoldPostOrder(function, constPar, par, head); -} - - template - void List::FoldPostOrder(FoldFunctor function, const void* constPar, void* par, struct Node* node) const{ - if(node == nullptr) - return; - FoldPostOrder(function, constPar, par, node->next); - function(node->value, constPar, par); - } + template + void List::MapPreOrder(MapFunctor function, void* par, struct Node* node){ + if(node == nullptr) + return; + + function(node->value, par); + MapPreOrder(function, par, node->next); + } + + template + void List::MapPostOrder(MapFunctor function, void* par, struct Node* node){ + if(node == nullptr) + return; + + MapPostOrder(function, par, node->next); + function(node->value, par); + } + + template + void List::FoldPreOrder(FoldFunctor function, const void* constPar, void* par, struct Node* node) const{ + + if(node == nullptr) + return; + + function(node->value, constPar, par); + FoldPreOrder(function, constPar, par, node->next); + } + + template + void List::FoldPostOrder(FoldFunctor function, const void* constPar, void* par, struct Node* node) const{ + if(node == nullptr) + return; + + FoldPostOrder(function, constPar, par, node->next); + function(node->value, constPar, par); + } +/* ************************************************************************** */ } diff --git a/librerie/exercise1/list/list.hpp b/librerie/exercise1/list/list.hpp index c0ce133..debbf72 100644 --- a/librerie/exercise1/list/list.hpp +++ b/librerie/exercise1/list/list.hpp @@ -13,31 +13,30 @@ namespace lasd { /* ************************************************************************** */ template -class List : virtual public LinearContainer, - virtual public MappableContainer, - virtual public FoldableContainer { // Must extend LinearContainer, MappableContainer, and FoldableContainer +class List : virtual public LinearContainer, + virtual public MappableContainer, + virtual public FoldableContainer{ // Must extend LinearContainer, MappableContainer, and FoldableContainer private: protected: - using LinearContainer::size; + using LinearContainer:: size; struct Node { Data value; - Node* next = nullptr; + Node* next = nullptr; /* ********************************************************************** */ // Specific constructors - Node(Data); + Node(Data); /* ********************************************************************** */ // Copy constructor Node(const Node&); - Node(const Data&); // Move constructor Node(Node&&); @@ -53,6 +52,11 @@ protected: // Comparison operators bool operator==(const Node&) const noexcept; bool operator!=(const Node&) const noexcept; + + /* ********************************************************************** */ + + // Specific member functions + }; struct Node* head = nullptr; @@ -66,14 +70,14 @@ public: /* ************************************************************************ */ // Specific constructor - List(const LinearContainer&); // A list obtained from a LinearContainer + List(const LinearContainer&); // A list obtained from a LinearContainer /* ************************************************************************ */ // Copy constructor List(const List&); - //Move constructor + // Move constructor List(List&&); /* ************************************************************************ */ @@ -84,16 +88,16 @@ public: /* ************************************************************************ */ // Copy assignment - List& operator=(const List&); + List& operator=(const List&); // Move assignment - List& operator=(List&&) noexcept; + List& operator=(List&&) noexcept; /* ************************************************************************ */ // Comparison operators - bool operator==(const List&) const noexcept; - bool operator!=(const List&) const noexcept; + bool operator==(const List&) const noexcept; + bool operator!=(const List&) const noexcept; /* ************************************************************************ */ @@ -111,14 +115,14 @@ public: // 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() override const; // Override LinearContainer member (must throw std::length_error when empty) - Data& Back() override const; // 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& operator[](const ulong) const override; // Override LinearContainer member (must throw std::out_of_range when out of range) @@ -144,15 +148,15 @@ protected: // Auxiliary member functions (for MappableContainer) - void MapPreOrder(const MapFunctor, void*, struct Node*); // Accessory function executing from one point of the list onwards - void MapPostOrder(const MapFunctor, void*, struct Node*); // Accessory function executing from one point of the list onwards + void MapPreOrder(const MapFunctor, void* , struct Node*); // Accessory function executing from one point of the list onwards + void MapPostOrder(const MapFunctor, void* , struct Node*); // Accessory function executing from one point of the list onwards /* ************************************************************************ */ // Auxiliary member functions (for FoldableContainer) void FoldPreOrder(const FoldFunctor, const void*, void*, struct Node*) const; // Accessory function executing from one point of the list onwards - void FoldPostOrder(const FoldFunctor, const void*, void*, struct Node*) const; // Accessory function executing from one point of the list onwards + void FoldPostOrder(const FoldFunctor, const void*, void*, struct Node*) const;; // Accessory function executing from one point of the list onwards }; diff --git a/librerie/exercise1/main b/librerie/exercise1/main new file mode 100755 index 0000000000000000000000000000000000000000..d4c3fa9f35c2366b6215b5b5b6525b28820e2213 GIT binary patch literal 255240 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

V%Tr&JNyp$K8 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 literal 0 HcmV?d00001 diff --git a/librerie/exercise1/main.cpp b/librerie/exercise1/main.cpp index 16c4875..40f1274 100644 --- a/librerie/exercise1/main.cpp +++ b/librerie/exercise1/main.cpp @@ -1,8 +1,10 @@ - -// #include "zlasdtest/test.hpp" -// -// #include "zmytest/test.hpp" #include "container/container.hpp" +#include "vector/vector.hpp" +#include "list/list.hpp" +#include "zlasdtest/test.hpp" + +#include "zmytest/test.hpp" + /* ************************************************************************** */ #include @@ -11,6 +13,7 @@ int main() { std::cout << "Lasd Libraries 2020" << std::endl; + menu(); //lasdtest(); // To call in the menu of your library test! return 0; } diff --git a/librerie/exercise1/vector/vector.cpp b/librerie/exercise1/vector/vector.cpp index 1c72e0a..2ebef36 100644 --- a/librerie/exercise1/vector/vector.cpp +++ b/librerie/exercise1/vector/vector.cpp @@ -1,180 +1,169 @@ + namespace lasd { - // Specific constructor - template typename - Vector::Vector(const ulong dimension){ - Elements = new Data[dimenion] {}; - size = dimenion; - } - // Specific constructor - template typename - Vector::Vector(const LinearContainer& con){ - size = con.Size(); - Elements = new Data[size] {}; - for(ulong i ; i +Vector::Vector(const ulong newsize){ + Elements = new Data[newsize]{}; + size = newsize; +} - // Copy constructor - template typename - Vector::Vector(const Vector& vec){ - size = vec.size; - Elements = new Data[size] {}; - for(ulong i=0 ; i +Vector::Vector(const LinearContainer& con){ + size = con.Size(); + Elements = new Data[size]{}; + for(ulong i=0; i - Vector::Vector(Vector&& vec) noexcept{ - std::swap(Elements, vec.Elements); - std::swap(size, vec.size); +// Copy constructor +template +Vector::Vector(const Vector& vec){ + size = vec.size; + Elements = new Data[size]{}; + for(ulong i=0; i +// Move constructor +template + Vector::Vector(Vector&& vec)noexcept{ + std::swap(Elements, vec.Elements); + std::swap(size, vec.size); + } + + // Destructor + template Vector::~Vector(){ - delete[] Elements; + Clear(); } // Copy assignment - template typename - Vector& Vector::operator=(const Vector& vec){ - Vector* tmpvec = new Vector(vec); - std::swap(*tmpvec,*this); - delete tmpvec; - return *this; - } + template + Vector& Vector::operator=(const Vector& vec){ + Vector* tmpvec = new Vector(vec); + std::swap(*tmpvec, *this); + delete tmpvec; + return *this; + } - // Move assignment - template typename - Vector& Vector::operator=(Vector&& vec) noexcept{ - std::swap(Elements, vec.Elements); - std::swap(size, vec.size); - return *this; - } + // Move assignment + template + Vector& Vector::operator=(Vector&& vec)noexcept{ + std::swap(Elements,vec.Elements); + std::swap(size, vec.size); + return *this; + } - // Comparison operators - template typename - bool Vector::operator==(const Vector& vec) const noexcept{ - if(size!=vec.size) return false; - for(ulong i=0 ; i + bool Vector::operator==(const Vector& vec) const noexcept{ + if(size == vec.size){ + for(ulong i=0; i + bool Vector::operator!=(const Vector& vec)const noexcept{ + return !(*this == vec); + } + + template + void Vector::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 + void Vector::Clear(){ + delete[] Elements; + Elements = nullptr; + size = 0; + } + + template + Data& Vector::Front() const { + if(size != 0) + { + return Elements[0]; + }else{ + throw std::length_error("Access to an empty vector!"); + } + } + + template + Data& Vector::Back() const { + if(size != 0) + { + return Elements[size - 1]; + }else{ + throw std::length_error("Access to an empty vector!"); + } + } + + + template + Data& Vector::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)); } } - return true; - } - template typename - bool Vector::operator!=(const Vector& vec) const noexcept{ - return !(*this == vec); - } - // Specific member function - // template typename - // void Vector::Resize(const ulong newsize){ - // if(newsize == 0){ - // Clear(); - // } - // else{ - // size = newsize; - // if(newsize < size){ - // Data* tmpvec = new Data[newsize] {}; - // for(ulong i=0;i size){ - // Data* tmpvec = new Data[newsize] {}; - // for(ulong i=0;i - void Vector::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 + void Vector::MapPreOrder(const MapFunctor fun, void* par){ + for(ulong i=0; i + void Vector::MapPostOrder(const MapFunctor fun, void* par){ + ulong idx = size; + while(idx > 0) + { + fun(Elements[--idx], par); + } + } + + + template + void Vector::FoldPreOrder(const FoldFunctor fun, const void* par, void* acc) const{ + for(ulong i=0; i + void Vector::FoldPostOrder(const FoldFunctor fun, const void* par, void* acc) const{ + ulong idx = size; + while(idx > 0){ + fun(Elements[--idx], par, acc); + } } } - -template typename -void Vector::Clear(){ - delete[] Elements; - Elements = nullptr; - size = 0; -} - -template typename -Data& Vector::Front() const{ - if(size!=0){ - return Elements[0]; - }else{ - return std::length_error("Access to an empty vector"); - } -} - -template typename -Data& Vector::Back() const{ - if(size!=0){ - return Elements[size-1]; - }else{ - return std::length_error("Access to an empty vector"); - } -} - -template typename -Data& Vector::operator[](const ulong index) const{ - if(index < size){ - return Elements[index]; - }else{ - throw std::out_of_range("Access at index " + std::to_string(index) + " invalid because the vector size is" + std::to_string(size)); - } -} - -template typename -void Vector::MapPreOrder(const MapFunctor fun, void* par){ - for(ulong i = 0 ; i -void Vector::MapPostOrder(const MapFunctor fun, void* par){ - ulong i = size; - while(i>0){ - fun(Elements[--i], par); - } -} - -template typename -void Vector::FoldPreOrder(const FoldFunctor fun, const void* par, void* acc) const{ - for(ulong i = 0 ; i -void Vector::FoldPostOrder(const FoldFunctor fun, const void* par, void* acc) const{ - ulong i = size; - while(i>0){ - fun(Elements[--i], par, acc); - } -} diff --git a/librerie/exercise1/vector/vector.hpp b/librerie/exercise1/vector/vector.hpp index 8fedf96..b5fcbe5 100644 --- a/librerie/exercise1/vector/vector.hpp +++ b/librerie/exercise1/vector/vector.hpp @@ -2,10 +2,16 @@ #ifndef VECTOR_HPP #define VECTOR_HPP +/* ************************************************************************** */ + #include "../container/container.hpp" +/* ************************************************************************** */ + namespace lasd { +/* ************************************************************************** */ + template class Vector : virtual public LinearContainer, virtual public MappableContainer, @@ -13,14 +19,20 @@ class Vector : virtual public LinearContainer, private: + protected: using LinearContainer::size; Data* Elements = nullptr; + + // ... + public: // Default constructor - Vector() = default; + // Vector() specifiers; + Vector() = default; + /* ************************************************************************ */ @@ -31,20 +43,20 @@ public: /* ************************************************************************ */ // Copy constructor - Vector(const Vector&); + Vector(const Vector&); // Move constructor - Vector(Vector&&) noexcept; + Vector(Vector&&)noexcept; /* ************************************************************************ */ // Destructor - ~Vector(); + ~Vector(); /* ************************************************************************ */ // Copy assignment - Vector& operator=(const Vector&); + Vector& operator=(const Vector&); // Move assignment Vector& operator=(Vector&&) noexcept; @@ -52,8 +64,8 @@ public: /* ************************************************************************ */ // 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; /* ************************************************************************ */ @@ -80,20 +92,19 @@ public: // Specific member functions (inherited from MappableContainer) - using typename MappableContainer::MapFunctor; + using typename MappableContainer::MapFunctor; - void MapPreOrder(const MapFunctor, void*) override; // Override MappableContainer member - void MapPostOrder(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 /* ************************************************************************ */ // Specific member functions (inherited from FoldableContainer) - using typename FoldableContainer::FoldFunctor; + using typename FoldableContainer::FoldFunctor; void FoldPreOrder(const FoldFunctor, const void*, void*) const override; // Override FoldableContainer member void FoldPostOrder(const FoldFunctor, const void*, void*) const override; // Override FoldableContainer member - }; /* ************************************************************************** */ diff --git a/librerie/exercise1/zmytest/test.cpp b/librerie/exercise1/zmytest/test.cpp index c3981ba..f7d28f3 100644 --- a/librerie/exercise1/zmytest/test.cpp +++ b/librerie/exercise1/zmytest/test.cpp @@ -1,3 +1,7 @@ +#include"test.hpp" +#include +#include + void menu(){ unsigned short int choice; DataStructure chosenDataStructure; @@ -11,7 +15,7 @@ void menu(){ switch(choice){ case 1: - lasdtest(); + //lasd::lasdtest(); break; case 2: chosenDataStructure = ChooseDataStructure(); @@ -23,10 +27,10 @@ void menu(){ } UseChosenType(chosenDataStructure,chosenDataType); } - DataStructure ChooseDataStructure(){ unsigned short int choice; do{ + std::cout<<"Choose a data structure:"<>std::ws; @@ -37,12 +41,12 @@ DataStructure ChooseDataStructure(){ else if(choice == 2) return DataStructure::list; } - DataType ChooseDataType(){ unsigned short int choice; do{ + std::cout<<"Choose a data type:"<>std::ws; std::cin>>choice; @@ -50,21 +54,553 @@ DataType ChooseDataType(){ if(choice==1) return DataType::integer; else if(choice==2) - return DataType::double; + return DataType::ffloat; else if(choice==3) - return DataType::string; + return DataType::sstring; } void UseChosenType(DataStructure chosenDataStructure, DataType chosenDataType){ - std::cout<<"\tTest on "; - if(chosenDataStructure == DataStructure::vector) - std::cout<<"vector of "; - else if(chosenDataStructure == DataStructure::list) - std::cout<<"list of "; - if(chosenDataType == DataType::integer) - std::cout<<" integers"< myvec; + myvec = generateVectorOfIntegers(); + VectorIntegerFunctions(myvec); + }else if(chosenDataType == DataType::ffloat){ + lasd::Vector myvec; + myvec = generateVectorOfFloat(); + VectorFloatFunctions(myvec); + }else if(chosenDataType == DataType::sstring){ + lasd::Vector myvec; + myvec = generateVectorOfStrings(); + VectorStringFunctions(myvec); + } + }else if(chosenDataStructure == DataStructure::list){ + if(chosenDataType == DataType::integer){ + lasd::List mylist; + mylist = generateListOfIntegers(); + ListIntegerFunctions(mylist); + }else if(chosenDataType == DataType::ffloat){ + lasd::List mylist; + mylist = generateListOfFloat(); + ListFloatFunctions(mylist); + }else if(chosenDataType == DataType::sstring){ + lasd::List mylist; + mylist = generateListOfStrings(); + ListStringFunctions(mylist); + } + } +} + +/* +********** VECTOR FUNCTIONS ********** +*/ +void VectorIntegerFunctions(lasd::Vector myvec){ + unsigned short int choice; + do{ + std::cout<<"Choose one of the following options:"<>std::ws; + std::cin>>choice; + + switch(choice){ + case 1: + ShowFirstElement(myvec); + break; + case 2: + ShowLastElement(myvec); + break; + case 3: + ShowElementWithASpecificIndex(myvec); + break; + case 4: + ShowAllElements(myvec); + break; + case 5: + CheckElementExists(myvec); + break; + case 6: + SumLessThan(myvec); + break; + case 7: + DoubleIntegers(myvec); + break; + } + }while(choice!=8); +} +void VectorFloatFunctions(lasd::Vector myvec){ + unsigned short int choice; + do{ + std::cout<<"Choose one of the following options:"<>std::ws; + std::cin>>choice; + switch(choice){ + case 1: + ShowFirstElement(myvec); + break; + case 2: + ShowLastElement(myvec); + break; + case 3: + ShowElementWithASpecificIndex(myvec); + break; + case 4: + ShowAllElements(myvec); + break; + case 5: + CheckElementExists(myvec); + break; + case 6: + ProductMoreThan(myvec); + break; + case 7: + SquareFloats(myvec); + break; + } + }while(choice!=8); +} +void VectorStringFunctions(lasd::Vector myvec){ + unsigned short int choice; + do{ + std::cout<<"Choose one of the following options:"<>std::ws; + std::cin>>choice; + switch(choice){ + case 1: + ShowFirstElement(myvec); + break; + case 2: + ShowLastElement(myvec); + break; + case 3: + ShowElementWithASpecificIndex(myvec); + break; + case 4: + ShowAllElements(myvec); + break; + case 5: + CheckElementExists(myvec); + break; + case 6: + ConcatLessThan(myvec); + break; + case 7: + Uppercase(myvec); + break; + } + }while(choice!=8); +} +template +void ShowFirstElement(lasd::Vector& vec){ + std::cout< +void ShowLastElement(lasd::Vector& vec){ + std::cout< +void ShowElementWithASpecificIndex(lasd::Vector& vec){ + ulong index; + std::cout<<"Insert the index: "; + std::cin>>std::ws; + std::cin>>index; + try{ + std::cout< +void ShowAllElements(lasd::Vector& vec){ + void (*AuxMapPreOrder) (Data&, void*) = PrintSingleElement; + std::cout<<"The vector contains:"< +void PrintSingleElement(Data& data, void* _){ + std::cout << data << " "; +} +template +void CheckElementExists(lasd::Vector& vec){ + Data element; + std::cout<<"What element do you wanna check its exsistence on? "; + std::cin>>std::ws; + std::cin>>element; + if(vec.Exists(element)) + std::cout<<"The element exists"<& vec){ + int pivot; + ulong acc=0; + void (*func)(const int&, const void*, void*) = AccumulateSum; + std::cout<<"Which element do you choose to performa a sum under it? "; + std::cin>>std::ws; + std::cin>>pivot; + vec.FoldPreOrder(func, (void*)&pivot, (void*)&acc); + std::cout<<"The result of the sum is "<& vec){ + void (*fun)(int&, void*) = DoubleAnInteger; + vec.MapPreOrder(fun, nullptr); + std::cout<<"The doubled elements of the vector are: "; + for (ulong i=0 ; i < vec.Size(); ++i){ + std::cout<& vec){ + float pivot, acc=1; + void (*func)(const float&, const void*, void*) = AccumulateProduct; + std::cout<<"Which element do you choose to performa a product above it? "; + std::cin>>std::ws; + std::cin>>pivot; + vec.FoldPreOrder(func, (void*)&pivot, (void*)&acc); + std::cout<<"The result of the product is "< (*(float*)par)){ + *(float*)acc *= data; + } +} +void SquareFloats(lasd::Vector& vec){ + void (*fun)(float&, void*) = SquareAFloat; + vec.MapPreOrder(fun, nullptr); + std::cout<<"The squared elements of the vector are: "; + for (ulong i=0 ; i < vec.Size(); ++i){ + std::cout<& vec){ + ulong pivot; + std::string acc = ""; + void (*func)(const std::string&, const void*, void*) = ConcatAux; + std::cout<<"Concat elements whose length is less than: "; + std::cin>>std::ws; + std::cin>>pivot; + vec.FoldPreOrder(func, (void*)&pivot, (void*)&acc); + std::cout<<"The concatenated string is "<& vec){ + void (*fun)(std::string&, void*) = UppercaseAString; + vec.MapPreOrder(fun, nullptr); + std::cout<<"The uppercased strings are: "< mylist){ + unsigned short int choice; + do{ + std::cout<<"Choose one of the following options:"<>std::ws; + std::cin>>choice; + + switch(choice){ + case 1: + ShowFirstElement(mylist); + break; + case 2: + ShowLastElement(mylist); + break; + case 3: + ShowElementWithASpecificIndex(mylist); + break; + case 4: + //ShowAllElements(mylist); + break; + case 5: + //CheckElementExists(mylist); + break; + case 6: + //SumLessThan(mylist); + break; + case 7: + //DoubleIntegers(mylist); + break; + } + }while(choice!=8); +} +void ListFloatFunctions(lasd::List mylist){ + unsigned short int choice; + do{ + std::cout<<"Choose one of the following options:"<>std::ws; + std::cin>>choice; + switch(choice){ + case 1: + ShowFirstElement(mylist); + break; + case 2: + ShowLastElement(mylist); + break; + case 3: + ShowElementWithASpecificIndex(mylist); + break; + case 4: + //ShowAllElements(myvec); + break; + case 5: + //CheckElementExists(myvec); + break; + case 6: + //ProductMoreThan(myvec); + break; + case 7: + //SquareFloats(myvec); + break; + } + }while(choice!=8); +} +void ListStringFunctions(lasd::List mylist){ + unsigned short int choice; + do{ + std::cout<<"Choose one of the following options:"<>std::ws; + std::cin>>choice; + switch(choice){ + case 1: + ShowFirstElement(mylist); + break; + case 2: + ShowLastElement(mylist); + break; + case 3: + ShowElementWithASpecificIndex(mylist); + break; + case 4: + //ShowAllElements(myvec); + break; + case 5: + // CheckElementExists(myvec); + break; + case 6: + //ConcatLessThan(myvec); + break; + case 7: + //Uppercase(myvec); + break; + } + }while(choice!=8); +} + +template +void ShowFirstElement(lasd::List& list){ + std::cout< +void ShowLastElement(lasd::List& list){ + std::cout< +void ShowElementWithASpecificIndex(lasd::List& list){ + ulong index; + std::cout<<"Insert the index: "; + std::cin>>std::ws; + std::cin>>index; + try{ + std::cout< generateListOfStrings(){ + ulong dim = getDimension(); + lasd::List mylist = lasd::List(); + + std::default_random_engine gen(std::random_device{}()); + std::uniform_int_distribution dist(1,5); + + for(unsigned long i = 0; i < dim; ++i){ + mylist.InsertAtFront(generateRandomString(dist(gen))); + } + std::cout<<"Elements of the list:"< generateListOfFloat(){ + ulong dim = getDimension(); + lasd::List mylist = lasd::List(); + + std::default_random_engine gen(std::random_device{}()); + std::uniform_real_distribution distr(0,5); + for(unsigned long i = 0; i < dim; ++i){ + mylist.InsertAtFront((round(distr(gen)*10000))/100); + } + std::cout<<"Elements of the list:"< generateListOfIntegers(){ + ulong dim = getDimension(); + lasd::List mylist = lasd::List(); + std::default_random_engine gen(std::random_device{}()); + std::uniform_int_distribution dist(0,1000); + for(ulong i=0 ; i generateVectorOfIntegers(){ + ulong dim = getDimension(); + lasd::Vector myvec = lasd::Vector(dim); + + std::default_random_engine gen(std::random_device{}()); + std::uniform_int_distribution dist(0,1000); + + for(ulong i = 0 ; i generateVectorOfFloat(){ + ulong dim = getDimension(); + lasd::Vector myvec = lasd::Vector(dim); + + std::default_random_engine gen(std::random_device{}()); + std::uniform_real_distribution distr(0,5); + for(unsigned long i = 0; i < dim; ++i){ + myvec[i] = (round(distr(gen)*10000))/100; + } + std::cout<<"Elements of the vector:"< generateVectorOfStrings(){ + ulong dim = getDimension(); + lasd::Vector myvec = lasd::Vector(dim); + + std::default_random_engine gen(std::random_device{}()); + std::uniform_int_distribution dist(1,5); + + for(unsigned long i = 0; i < dim; ++i){ + myvec[i] = generateRandomString(dist(gen)); + } + std::cout<<"Elements of the vector:"< character('a','z'); + char newString[dim+1]; + for(int i=0;i>dimension; + return dimension; } diff --git a/librerie/exercise1/zmytest/test.hpp b/librerie/exercise1/zmytest/test.hpp index bdd88c4..6cf26d7 100644 --- a/librerie/exercise1/zmytest/test.hpp +++ b/librerie/exercise1/zmytest/test.hpp @@ -1,12 +1,85 @@ #ifndef MYTEST_HPP #define MYTEST_HPP - +#include +#include"../vector/vector.hpp" +#include"../list/list.hpp" enum class DataStructure{vector,list}; -enum class DataType{integer,double,string}; +enum class DataType{integer,ffloat,sstring}; void menu(); -DataType ChooseDataType(); -void UseChosenType(DataStructure, DataType); +DataType ChooseDataType(); //choose data type DataStructure ChooseDataStructure(); +void UseChosenType(DataStructure, DataType); +lasd::Vector generateVectorOfIntegers(); +lasd::Vector generateVectorOfFloat(); +lasd::Vector generateVectorOfStrings(); +lasd::List generateListOfStrings(); +lasd::List generateListOfFloat(); +lasd::List generateListOfIntegers(); +std::string generateRandomString(ulong dim); + +void VectorIntegerFunctions(lasd::Vector); +void VectorFloatFunctions(lasd::Vector); +void VectorStringFunctions(lasd::Vector); +template +void ShowFirstElement(lasd::Vector&); +template +void ShowLastElement(lasd::Vector&); +template +void ShowElementWithASpecificIndex(lasd::Vector&); +template +void ShowAllElements(lasd::Vector&); +template +void PrintSingleElement(Data&, void*); +template +void CheckElementExists(lasd::Vector&); +void SumLessThan(lasd::Vector&); +void AccumulateSum(const int&, const void*, void*); +void DoubleIntegers(lasd::Vector&); +void DoubleAnInteger(int&, void*); +void AccumulateProduct(const float&, const void*, void*); +void ProductMoreThan(lasd::Vector&); +void SquareAFloat(float&, void*); +void SquareFloats(lasd::Vector&); +void ConcatLessThan(lasd::Vector&); +void ConcatAux(const std::string&, const void*, void*); +void Uppercase(lasd::Vector&); +void UppercaseAString(std::string&, void*); +void ListIntegerFunctions(lasd::List); +void ListFloatFunctions(lasd::List); +void ListStringFunctions(lasd::List); +template +void ShowFirstElement(lasd::List&); +template +void ShowLastElement(lasd::List&); +template +void ShowElementWithASpecificIndex(lasd::List&); +ulong getDimension(); +/* +void ChooseDimension(ulong&); +LinearContainer GenerateRandomStructure(const ulong&); +void ViewElement(const LinearContainer&); +void PrintAllElements(const LinearContainer&); +void PrintElement(Data&, void*); // funzione richiamata dalla map +void CheckExists(const LinearContainer&); +void ChooseFoldFunction(const LinearContainer&); +void SumLessThan(const LinearContainer&, const ulong&); +void SumLessThanFold(int&, const void*, void*); +void ProductMoreThan(const LinearContainer&, const ulong&); +void ProductMoreThanFold(float&, const void*, void*); +void ConcatStringLessThan(const LinearContainer&, const ulong&); +void ConcatStringLessThanFold(string&, const void*, void*); + +//7 +void ChooseMapFunction(const LinearContainer); +void DoubleN(const LinearContainer&, const ulong&); +void DoubleNMap(int&, void*); + +void SquareN(const LinearContainer&, const ulong&); +void SquareNMap(float&, void*); + +void Uppercase(const LinearContainer&, const ulong&); +void UppercaseMap(string&, void*); +*/ #endif diff --git a/librerie/exercise1/Exercise1.pdf b/librerie/exercise1old/Exercise1.pdf similarity index 100% rename from librerie/exercise1/Exercise1.pdf rename to librerie/exercise1old/Exercise1.pdf diff --git a/librerie/exercise1old/build.sh b/librerie/exercise1old/build.sh new file mode 100755 index 0000000..bbee40e --- /dev/null +++ b/librerie/exercise1old/build.sh @@ -0,0 +1,7 @@ + +#! /bin/bash + +g++ -O3 -o main \ + zlasdtest/exercise1/simpletest.cpp zlasdtest/exercise1/fulltest.cpp \ + zlasdtest/container/container.cpp \ + zlasdtest/test.cpp zmytest/test.cpp main.cpp diff --git a/librerie/exercise1old/container/container.cpp b/librerie/exercise1old/container/container.cpp new file mode 100644 index 0000000..6a22d84 --- /dev/null +++ b/librerie/exercise1old/container/container.cpp @@ -0,0 +1,17 @@ + +namespace lasd { + +template +void AuxFoldExists(const Data& dat, const void* val, void* exists){ + if(dat == *((Data*)val)){ + *((bool*)exists) = true; + } +} + +template +bool FoldableContainer::Exists(const Data& dat) const noexcept{ + bool exists = false; + FoldPreOrder(&AuxFoldExists, &dat, &exists); + return exists; +} +} diff --git a/librerie/exercise1old/container/container.hpp b/librerie/exercise1old/container/container.hpp new file mode 100644 index 0000000..021fcc0 --- /dev/null +++ b/librerie/exercise1old/container/container.hpp @@ -0,0 +1,304 @@ + +#ifndef CONTAINER_HPP +#define CONTAINER_HPP + +/* ************************************************************************** */ + +#include +#include + +/* ************************************************************************** */ + +namespace lasd { + +/* ************************************************************************** */ + +class Container { + +private: + +protected: + + ulong size = 0; + +public: + + // Destructor + virtual ~Container() = default; + + /* ************************************************************************ */ + + // Copy assignment + Container& operator=(const Container&) = delete; // Copy assignment of abstract types should not be possible. + + // Move assignment + Container& operator=(Container&&) noexcept = delete; // Move assignment of abstract types should not be possible. + + /* ************************************************************************ */ + + // Comparison operators + 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 + + virtual bool Empty() const noexcept { // (concrete function should not throw exceptions) + return (size == 0); + } + + virtual ulong Size() const noexcept{ + return size; + } + + virtual void Clear() = 0; + +}; + +/* ************************************************************************** */ + +template +class LinearContainer : virtual public Container { // Must extend Container + +private: + +protected: + +public: + + // Destructor + virtual ~LinearContainer() = default; + + /* ************************************************************************ */ + + // Copy assignment + LinearContainer& operator=(const LinearContainer&) = delete; // Copy assignment of abstract types should not be possible. + + // Move assignment + LinearContainer& operator=(LinearContainer&&) = delete; // Move assignment of abstract types should not be possible. + + /* ************************************************************************ */ + + // Comparison operators + bool operator==(const LinearContainer&) const noexcept = delete; // Comparison of abstract types might not be possible. + bool operator!=(const LinearContainer&) const noexcept = delete; // Comparison of abstract types might not be possible. + + /* ************************************************************************ */ + + // Specific member functions + + 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& operator[](const ulong) const = 0; // (concrete function must throw std::out_of_range when out of range) + +}; + +/* ************************************************************************** */ + +template +class TestableContainer : virtual public Container { // Must extend Container + +private: + +protected: + +public: + + // Destructor + virtual ~TestableContainer() = default; + + /* ************************************************************************ */ + + // Copy assignment + TestableContainer& operator=(const TestableContainer&) = delete; // Copy assignment of abstract types should not be possible. + + // Move assignment + TestableContainer& operator=(TestableContainer&&) noexcept = delete; // Move assignment of abstract types should not be possible. + + /* ************************************************************************ */ + + // Comparison operators + bool operator==(const TestableContainer&) const noexcept = delete; // Comparison of abstract types might not be possible. + bool operator!=(const TestableContainer&) const noexcept = delete; // Comparison of abstract types might not be possible. + + /* ************************************************************************ */ + + // Specific member functions + + virtual bool Exists(const Data&) const noexcept = 0; // (concrete function should not throw exceptions) + +}; + +/* ************************************************************************** */ + +template +class MappableContainer : virtual public Container { // Must extend Container + +private: + +protected: + +public: + + // Destructor + virtual ~MappableContainer() = default; + + /* ************************************************************************ */ + + // Copy assignment + MappableContainer& operator=(const MappableContainer&) = delete; // Copy assignment of abstract types should not be possible. + + // Move assignment + MappableContainer& operator=(MappableContainer&&) noexcept = delete; // Move assignment of abstract types should not be possible. + + /* ************************************************************************ */ + + // Comparison operators + bool operator==(const MappableContainer&) const noexcept = delete; // Comparison of abstract types might not be possible. + bool operator!=(const MappableContainer&) const noexcept = delete; // Comparison of abstract types might not be possible. + + /* ************************************************************************ */ + + // Specific member functions + + typedef std::function MapFunctor; + + virtual void MapPreOrder(const MapFunctor, void*) = 0; + virtual void MapPostOrder(const MapFunctor, void*) = 0; + +}; + +/* ************************************************************************** */ + +template +class FoldableContainer : virtual public TestableContainer{ // Must extend TestableContainer + +private: + +protected: + +public: + + // Destructor + virtual ~FoldableContainer() = default; + + /* ************************************************************************ */ + + // Copy assignment + FoldableContainer& operator=(const FoldableContainer&) = delete; // Copy assignment of abstract types should not be possible. + + // Move assignment + FoldableContainer& operator=(FoldableContainer&&) noexcept = delete; // Move assignment of abstract types should not be possible. + + /* ************************************************************************ */ + + // Comparison operators + bool operator==(const FoldableContainer&) const noexcept = delete; // Comparison of abstract types might not be possible. + bool operator!=(const FoldableContainer&) const noexcept = delete; // Comparison of abstract types might not be possible. + + /* ************************************************************************ */ + + // Specific member functions + + typedef std::function FoldFunctor; + + virtual void FoldPreOrder(const FoldFunctor, const void*, void*) const = 0; + virtual void FoldPostOrder(const FoldFunctor, const void*, void*) const = 0; + + virtual bool Exists(const Data&) const noexcept override; // Override TestableContainer member + +}; + +/* ************************************************************************** */ + +template +class BreadthMappableContainer { // Must extend MappableContainer + +private: + + // ... + +protected: + + // ... + +public: + + // Destructor + // ~BreadthMappableContainer() specifiers + + /* ************************************************************************ */ + + // Copy assignment + // type operator=(argument); // Copy assignment of abstract types should not be possible. + + // Move assignment + // type operator=(argument); // Move assignment of abstract types should not be possible. + + /* ************************************************************************ */ + + // Comparison operators + // type operator==(argument) specifiers; // Comparison of abstract types might not be possible. + // type operator!=(argument) specifiers; // Comparison of abstract types might not be possible. + + /* ************************************************************************ */ + + // Specific member functions + + // using typename MappableContainer::MapFunctor; + + // type MapBreadth(arguments) specifiers; + +}; + +/* ************************************************************************** */ + +template +class BreadthFoldableContainer { // Must extend FoldableContainer + +private: + + // ... + +protected: + + // ... + +public: + + // Destructor + // ~BreadthFoldableContainer() specifiers + + /* ************************************************************************ */ + + // Copy assignment + // type operator=(argument); // Copy assignment of abstract types should not be possible. + + // Move assignment + // type operator=(argument); // Move assignment of abstract types should not be possible. + + /* ************************************************************************ */ + + // Comparison operators + // type operator==(argument) specifiers; // Comparison of abstract types might not be possible. + // type operator!=(argument) specifiers; // Comparison of abstract types might not be possible. + + /* ************************************************************************ */ + + // Specific member functions + + // using typename FoldableContainer::FoldFunctor; + + // type FoldBreadth(arguments) specifiers; + +}; + +/* ************************************************************************** */ + +} + +#include "container.cpp" + +#endif diff --git a/librerie/exercise1old/list/list.cpp b/librerie/exercise1old/list/list.cpp new file mode 100644 index 0000000..ce55016 --- /dev/null +++ b/librerie/exercise1old/list/list.cpp @@ -0,0 +1,264 @@ +namespace lasd { + // Specific constructor + template + List::Node::Node(Data newValue){ + value = newValue; + next = nullptr; + } + + // Copy constructor + template + List::Node::Node(const Node& copyFrom){ + value = copyFrom.value; + } + + // Move constructor + template + List::Node::Node(Node&& moveFrom){ + std::move(value, moveFrom.value); + std::move(next, moveFrom.next); + } + template + List::Node::Node(Data&& moveFrom){ + std::move(value, moveFrom); + } + + // Comparison operator + template + bool List::Node::operator==(const Node& node) const noexcept{ + if(node.value == value) return true; + else return false; + } + + template + bool List::Node::operator!=(const Node& node) const noexcept{ + if(node.value != value) return true; + else return false; + } + + template + List::List(const LinearContainer& con){ + for(ulong i=0 ; i + List::List(const List& copyFrom){ + for(ulong i=0 ; i + List::List(List&& moveFrom){ + std::swap(size, moveFrom.size); + std::swap(head, moveFrom.head); + std::swap(tail, moveFrom.tail); + } + + // Destructor + template + List::~List(){ + Clear(); + } + + // Copy assignment + template + List& List::operator=(const List& copyFrom){ + if(*this != copyFrom){ + Clear(); + for(ulong i=0 ; i + List& List::operator=(List&& moveFrom) noexcept{ + if(*this != moveFrom){ + Clear(); + std::swap(size, moveFrom.size); + std::swap(head, moveFrom.head); + std::swap(tail, moveFrom.tail); + } + return *this; + } + + // Comparison operators + template + bool List::operator==(const List& list) const noexcept{ + if(this->size != list.Size()) return false; + for(ulong i=0 ; i<(this->size) ; ++i){ + if((*this)[i] != list[i]) return false; + } + return true; + } + + template + bool List::operator!=(const List& list) const noexcept{ + return !(*this == list); + } + + // Specific member functions + template + void List::InsertAtFront(const Data& data){ + struct Node* tmp = new Node(data); + tmp->next = head; + head = tmp; + size++; + if(size==1){ + tail = head; + } + } + + template + void List::InsertAtFront(Data&& data){ + struct Node* tmp = new Node(data); + tmp->next = head; + head = tmp; + size++; + if(size==1){ + tail = head; + } + } + + template + void List::RemoveFromFront(){ + if(head==nullptr){ + throw std::length_error("List is empty!"); + }else{ + struct Node* tmp = head; + head = head->next; + delete tmp; + size--; + } + } + + template + Data List::FrontNRemove(){ + if(head==nullptr){ + throw std::length_error("List is empty!"); + }else{ + Data value = head->value; + RemoveFromFront(); + return value; + } + } + + template + void List::InsertAtBack(const Data& data){ + if(size==0){ + InsertAtFront(data); + }else{ + struct Node* last = new Node(data); + tail->next = last; + tail = last; + size++; + } + } + + template + void List::InsertAtBack(Data&& data){ + if(size==0){ + InsertAtFront(data); + }else{ + struct Node* last = new Node(data); + tail->next = last; + tail = last; + size++; + } + } + + template + void List::Clear(){ + while(head!=nullptr){ + RemoveFromFront(); + } + } + + template + Data& List::Front() const{ + if(size==0){ + throw std::length_error("List is empty!"); + }else{ + return head->value; + } + } + + template + Data& List::Back() const{ + if(size==0){ + throw std::length_error("List is empty!"); + }else{ + return tail->value; + } + } + + template + Data& List::operator[](const ulong index) const{ + if(index>=size || index<0){ + throw std::out_of_range("Out of range!"); + }else{ + struct Node* tmp = head; + for(ulong i=0 ; inext; + } + return tmp->value; + } + } + + template + void List::MapPreOrder(const MapFunctor fun, void* par){ + MapPreOrder(fun, par, head); + } + + template + void List::MapPreOrder(MapFunctor function, void* par, struct Node* node){ + if(node == nullptr) + return; + function(node->value, par); + MapPreOrder(function, par, node->next); + } + + template + void List::MapPostOrder(MapFunctor function, void* par){ + MapPostOrder(function, par, head); + } + + template + void List::MapPostOrder(MapFunctor function, void* par, struct Node* node){ + if(node == nullptr) + return; + MapPostOrder(function, par, node->next); + function(node->value, par); + } + + template + void List::FoldPreOrder(FoldFunctor function, const void* constPar, void* par) const{ + FoldPreOrder(function, constPar, par, head); + } + + template + void List::FoldPreOrder(FoldFunctor function, const void* constPar, void* par, struct Node* node) const{ + if(node == nullptr) + return; + function(node->value, constPar, par); + FoldPreOrder(function, constPar, par, node->next); + } + + template + void List::FoldPostOrder(FoldFunctor function, const void* constPar, void* par) const{ + FoldPostOrder(function, constPar, par, head); +} + + template + void List::FoldPostOrder(FoldFunctor function, const void* constPar, void* par, struct Node* node) const{ + if(node == nullptr) + return; + FoldPostOrder(function, constPar, par, node->next); + function(node->value, constPar, par); + } +} diff --git a/librerie/exercise1old/list/list.hpp b/librerie/exercise1old/list/list.hpp new file mode 100644 index 0000000..99bf595 --- /dev/null +++ b/librerie/exercise1old/list/list.hpp @@ -0,0 +1,164 @@ + +#ifndef LIST_HPP +#define LIST_HPP + +/* ************************************************************************** */ + +#include "../container/container.hpp" + +/* ************************************************************************** */ + +namespace lasd { + +/* ************************************************************************** */ + +template +class List : virtual public LinearContainer, + virtual public MappableContainer, + virtual public FoldableContainer { // Must extend LinearContainer, MappableContainer, and FoldableContainer + +private: + +protected: + + using LinearContainer:: size; + + struct Node + { + Data value; + Node* next = nullptr; + + /* ********************************************************************** */ + + // Specific constructors + Node(Data); + + /* ********************************************************************** */ + + // Copy constructor + Node(const Node&); + + // Move constructor + Node(Node&&); + Node(Data&&); + + /* ********************************************************************** */ + + // Destructor + ~Node() = default; + + /* ********************************************************************** */ + + // Comparison operators + bool operator==(const Node&) const noexcept; + bool operator!=(const Node&) const noexcept; + }; + + struct Node* head = nullptr; + struct Node* tail = nullptr; + +public: + + // Default constructor + List() = default; + + /* ************************************************************************ */ + + // Specific constructor + List(const LinearContainer&); // A list obtained from a LinearContainer + + /* ************************************************************************ */ + + // Copy constructor + List(const List&); + + //Move constructor + List(List&&); + + /* ************************************************************************ */ + + // Destructor + ~List(); + + /* ************************************************************************ */ + + // Copy assignment + List& operator=(const List&); + + // Move assignment + List& operator=(List&&) noexcept; + + /* ************************************************************************ */ + + // Comparison operators + bool operator==(const List&) const noexcept; + bool operator!=(const List&) const noexcept; + + /* ************************************************************************ */ + + // Specific member functions + + void InsertAtFront(const Data&); // Copy of the value + void InsertAtFront(Data&&); // Move of the value + void RemoveFromFront(); // (must throw std::length_error when empty) + Data FrontNRemove(); // (must throw std::length_error when empty) + + void InsertAtBack(const Data&); // Copy of the value + void InsertAtBack(Data&&); // Move of the value + + /* ************************************************************************ */ + + // Specific member functions (inherited from Container) + + 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& 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) + + /* ************************************************************************ */ + + // Specific member functions (inherited from MappableContainer) + + using typename MappableContainer::MapFunctor; + + 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::FoldFunctor; + + void FoldPreOrder(const FoldFunctor, const void*, void*) const override; // Override FoldableContainer member + void FoldPostOrder(const FoldFunctor, const void*, void*) const override; // Override FoldableContainer member + +protected: + + // Auxiliary member functions (for MappableContainer) + + void MapPreOrder(const MapFunctor, void*, struct Node*); // Accessory function executing from one point of the list onwards + void MapPostOrder(const MapFunctor, void*, struct Node*); // Accessory function executing from one point of the list onwards + + /* ************************************************************************ */ + + // Auxiliary member functions (for FoldableContainer) + + void FoldPreOrder(const FoldFunctor, const void*, void*, struct Node*) const; // Accessory function executing from one point of the list onwards + void FoldPostOrder(const FoldFunctor, const void*, void*, struct Node*) const; // Accessory function executing from one point of the list onwards + +}; + +/* ************************************************************************** */ + +} + +#include "list.cpp" + +#endif diff --git a/librerie/exercise1old/main.cpp b/librerie/exercise1old/main.cpp new file mode 100644 index 0000000..9c587bb --- /dev/null +++ b/librerie/exercise1old/main.cpp @@ -0,0 +1,18 @@ +#include "container/container.hpp" +#include "vector/vector.hpp" +#include "list/list.hpp" +#include "zlasdtest/test.hpp" + +#include "zmytest/test.hpp" + +/* ************************************************************************** */ + +#include + +/* ************************************************************************** */ + +int main() { + std::cout << "Lasd Libraries 2020" << std::endl; + lasdtest(); // To call in the menu of your library test! + return 0; +} diff --git a/librerie/exercise1old/vector/vector.cpp b/librerie/exercise1old/vector/vector.cpp new file mode 100644 index 0000000..7b7d8ef --- /dev/null +++ b/librerie/exercise1old/vector/vector.cpp @@ -0,0 +1,181 @@ +namespace lasd { + + // Specific constructor + template + Vector::Vector(const ulong dimension){ + Elements = new Data[dimension] {}; + size = dimension; + } + + // Specific constructor + template + Vector::Vector(const LinearContainer& con){ + size = con.Size(); + Elements = new Data[size] {}; + for(ulong i ; i + Vector::Vector(const Vector& vec){ + size = vec.size; + Elements = new Data[size] {}; + for(ulong i=0 ; i + Vector::Vector(Vector&& vec) noexcept{ + std::swap(Elements, vec.Elements); + std::swap(size, vec.size); + } + + // Destructor + template + Vector::~Vector(){ + delete[] Elements; + } + + // Copy assignment + template + Vector& Vector::operator=(const Vector& vec){ + Vector* tmpvec = new Vector(vec); + std::swap(*tmpvec,*this); + delete tmpvec; + return *this; + } + + // Move assignment + template + Vector& Vector::operator=(Vector&& vec) noexcept{ + std::swap(Elements, vec.Elements); + std::swap(size, vec.size); + return *this; + } + + // Comparison operators + template + bool Vector::operator==(const Vector& vec) const noexcept{ + if(size!=vec.size) return false; + for(ulong i=0 ; i + bool Vector::operator!=(const Vector& vec) const noexcept{ + return !(*this == vec); + } + + // Specific member function + // template typename + // void Vector::Resize(const ulong newsize){ + // if(newsize == 0){ + // Clear(); + // } + // else{ + // size = newsize; + // if(newsize < size){ + // Data* tmpvec = new Data[newsize] {}; + // for(ulong i=0;i size){ + // Data* tmpvec = new Data[newsize] {}; + // for(ulong i=0;i + void Vector::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 + void Vector::Clear(){ + delete[] Elements; + Elements = nullptr; + size = 0; + } + + template + Data& Vector::Front() const{ + if(size!=0){ + return Elements[0]; + }else{ + return std::length_error("Access to an empty vector"); + } + } + + template + Data& Vector::Back() const{ + if(size!=0){ + return Elements[size-1]; + }else{ + return std::length_error("Access to an empty vector"); + } + } + + template + Data& Vector::operator[](const ulong index) const{ + if(index < size){ + return Elements[index]; + }else{ + throw std::out_of_range("Access at index " + std::to_string(index) + " invalid because the vector size is" + std::to_string(size)); + } + } + + template + void Vector::MapPreOrder(const MapFunctor fun, void* par){ + for(ulong i = 0 ; i + void Vector::MapPostOrder(const MapFunctor fun, void* par){ + ulong i = size; + while(i>0){ + fun(Elements[--i], par); + } + } + + template + void Vector::FoldPreOrder(const FoldFunctor fun, const void* par, void* acc) const{ + for(ulong i = 0 ; i + void Vector::FoldPostOrder(const FoldFunctor fun, const void* par, void* acc) const{ + ulong i = size; + while(i>0){ + fun(Elements[--i], par, acc); + } + } diff --git a/librerie/exercise1old/vector/vector.hpp b/librerie/exercise1old/vector/vector.hpp new file mode 100644 index 0000000..3c25b30 --- /dev/null +++ b/librerie/exercise1old/vector/vector.hpp @@ -0,0 +1,105 @@ + +#ifndef VECTOR_HPP +#define VECTOR_HPP + +#include "../container/container.hpp" + +namespace lasd { + +template +class Vector : virtual public LinearContainer, + virtual public MappableContainer, + virtual public FoldableContainer{ // Must extend LinearContainer, MappableContainer, and FoldableContainer + +private: + +protected: + + using LinearContainer::size; + Data* Elements = nullptr; +public: + + // Default constructor + Vector() = default; + + /* ************************************************************************ */ + + // Specific constructors + Vector(const ulong); // A vector with a given initial dimension + Vector(const LinearContainer&); // A vector obtained from a LinearContainer + + /* ************************************************************************ */ + + // Copy constructor + Vector(const Vector&); + + // Move constructor + Vector(Vector&&) noexcept; + + /* ************************************************************************ */ + + // Destructor + ~Vector(); + + /* ************************************************************************ */ + + // Copy assignment + Vector& operator=(const Vector&); + + // Move assignment + Vector& operator=(Vector&&) noexcept; + + /* ************************************************************************ */ + + // Comparison operators + 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 + + /* ************************************************************************ */ + + // Specific member functions (inherited from Container) + + 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& 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) + + /* ************************************************************************ */ + + // Specific member functions (inherited from MappableContainer) + + using typename MappableContainer::MapFunctor; + + 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::FoldFunctor; + + void FoldPreOrder(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" + +#endif diff --git a/librerie/exercise1old/zlasdtest/container/container.cpp b/librerie/exercise1old/zlasdtest/container/container.cpp new file mode 100644 index 0000000..0f37c81 --- /dev/null +++ b/librerie/exercise1old/zlasdtest/container/container.cpp @@ -0,0 +1,49 @@ + +#include + +/* ************************************************************************** */ + +#include "../../container/container.hpp" + +/* ************************************************************************** */ + +// Container member functions! + +void Empty(uint& testnum, uint& testerr, const lasd::Container& con, bool chk) { + bool tst; + testnum++; + std::cout << " " << testnum << " The container is " << ((tst = con.Empty()) ? "" : "not ") << "empty: "; + std::cout << ((tst = (tst == chk)) ? "Correct" : "Error") << "!" << std::endl; + testerr += (1 - (uint) tst); +} + +void Size(uint& testnum, uint& testerr, const lasd::Container& con, bool chk, ulong siz) { + bool tst; + testnum++; + std::cout << " " << testnum << " The container has size " << con.Size() << ": "; + std::cout << ((tst = ((con.Size() == siz) == chk)) ? "Correct" : "Error") << "!" << std::endl; + testerr += (1 - (uint) tst); +} + +/* ************************************************************************** */ + +// Auxiliary functions for MappableContainer! + +void MapStringAppend(std::string& dat, void* par) { + dat.append(*((std::string*) par)); +} + +/* ************************************************************************** */ + +// Auxiliary functions for FoldableContainer! + +void FoldParity(const int& dat, const void* _, void* acc) { + *((int*) acc) += dat; + *((int*) acc) %= 2; +} + +void FoldStringConcatenate(const std::string& dat, const void* _, void* acc) { + ((std::string*) acc)->append(dat); +} + +/* ************************************************************************** */ diff --git a/librerie/exercise1old/zlasdtest/container/container.hpp b/librerie/exercise1old/zlasdtest/container/container.hpp new file mode 100644 index 0000000..7b12b44 --- /dev/null +++ b/librerie/exercise1old/zlasdtest/container/container.hpp @@ -0,0 +1,301 @@ + +#ifndef CONTAINERTEST_HPP +#define CONTAINERTEST_HPP + +#include "../../container/container.hpp" + +/* ************************************************************************** */ + +// Container member functions! + +void Empty(uint&, uint&, const lasd::Container&, bool); + +void Size(uint&, uint&, const lasd::Container&, bool, ulong); + +/* ************************************************************************** */ + +// LinearContainer member functions! + +template +void GetFront(uint& testnum, uint& testerr, const lasd::LinearContainer& con, bool chk, const Data& val) { + bool tst; + testnum++; + try { + std::cout << " " << testnum << " The front of the linear container is \"" << con.Front() << "\": "; + std::cout << ((tst = ((con.Front() == val) == chk)) ? "Correct" : "Error") << "!" << std::endl; + } catch(std::length_error exc) { + std::cout << exc.what() << "\": " << ((tst = !chk) ? "Correct" : "Error") << "!" << std::endl; + } catch(std::exception exc) { + tst = true; + std::cout << std::endl << "Wrong std::exception: " << exc.what() << "!" << std::endl; + } + testerr += (1 - (uint) tst); +} + +template +void SetFront(uint& testnum, uint& testerr, const lasd::LinearContainer& con, bool chk, const Data& val) { + bool tst; + testnum++; + try { + std::cout << " " << testnum << " Setting the front of the linear container to \"" << val << "\": "; + con.Front() = val; + std::cout << ((tst = chk) ? "Correct" : "Error") << "!" << std::endl; + } catch(std::length_error exc) { + std::cout << exc.what() << "\": " << ((tst = !chk) ? "Correct" : "Error") << "!" << std::endl; + } catch(std::exception exc) { + tst = true; + std::cout << std::endl << "Wrong std::exception: " << exc.what() << "!" << std::endl; + } + testerr += (1 - (uint) tst); +} + +template +void GetBack(uint& testnum, uint& testerr, const lasd::LinearContainer& con, bool chk, const Data& val) { + bool tst; + testnum++; + try { + std::cout << " " << testnum << " The back of the linear container is \"" << con.Back() << "\": "; + std::cout << ((tst = ((con.Back() == val) == chk)) ? "Correct" : "Error") << "!" << std::endl; + } catch(std::length_error exc) { + std::cout << exc.what() << "\": " << ((tst = !chk) ? "Correct" : "Error") << "!" << std::endl; + } catch(std::exception exc) { + tst = true; + std::cout << std::endl << "Wrong std::exception: " << exc.what() << "!" << std::endl; + } + testerr += (1 - (uint) tst); +} + +template +void SetBack(uint& testnum, uint& testerr, const lasd::LinearContainer& con, bool chk, const Data& val) { + bool tst; + testnum++; + try { + std::cout << " " << testnum << " Setting the back of the linear container to \"" << val << "\": "; + con.Back() = val; + std::cout << ((tst = chk) ? "Correct" : "Error") << "!" << std::endl; + } catch(std::length_error exc) { + std::cout << exc.what() << "\": " << ((tst = !chk) ? "Correct" : "Error") << "!" << std::endl; + } catch(std::exception exc) { + tst = true; + std::cout << std::endl << "Wrong std::exception: " << exc.what() << "!" << std::endl; + } + testerr += (1 - (uint) tst); +} + +template +void SetAt(uint& testnum, uint& testerr, lasd::LinearContainer& con, bool chk, const ulong& ind, const Data& val) { + bool tst; + testnum++; + try { + std::cout << " " << testnum << " Set of the linear container at index \"" << ind << "\" with value \"" << val << "\": "; + con[ind] = val; + std::cout << ((tst = chk) ? "Correct" : "Error") << "!" << std::endl; + } catch(std::out_of_range exc) { + std::cout << "\"" << exc.what() << "\": " << ((tst = !chk) ? "Correct" : "Error") << "!" << std::endl; + } catch(std::exception exc) { + tst = true; + std::cout << std::endl << "Wrong std::exception: " << exc.what() << "!" << std::endl; + } + testerr += (1 - (uint) tst); +} + +template +void GetAt(uint& testnum, uint& testerr, lasd::LinearContainer& con, bool chk, const ulong& ind, const Data& val) { + bool tst; + testnum++; + try { + std::cout << " " << testnum << " Get of the linear container at index \"" << ind << "\" with value \"" << con[ind] << "\": "; + std::cout << ((tst = ((con[ind] == val) == chk)) ? "Correct" : "Error") << "!" << std::endl; + } catch(std::out_of_range exc) { + std::cout << exc.what() << "\": " << ((tst = !chk) ? "Correct" : "Error") << "!" << std::endl; + } catch(std::exception exc) { + tst = true; + std::cout << std::endl << "Wrong std::exception: " << exc.what() << "!" << std::endl; + } + testerr += (1 - (uint) tst); +} + +/* ************************************************************************** */ + +// TestableContainer member functions! + +template +void Exists(uint& testnum, uint& testerr, const lasd::TestableContainer& con, bool chk, const Data& val) { + bool tst; + testnum++; + std::cout << " " << testnum << " Data \"" << val << "\" " << ((tst = con.Exists(val)) ? "does" : "does not") << " exist: "; + std::cout << ((tst = (tst == chk)) ? "Correct" : "Error") << "!" << std::endl; + testerr += (1 - (uint) tst); +} + +/* ************************************************************************** */ + +// MappableContainer member functions! + +template +void MapPreOrder(uint& testnum, uint& testerr, lasd::MappableContainer& con, bool chk, typename lasd::MappableContainer::MapFunctor fun, const Parameter& inipar) { + bool tst = true; + testnum++; + Parameter par = {inipar}; + try { + std::cout << " " << testnum << " Executing map in pre order - "; + con.MapPreOrder(fun, &par); + std::cout << ": " << ((tst = chk) ? "Correct" : "Error") << "!" << std::endl; + } catch(std::exception exc) { + std::cout << "\"" << exc.what() << "\": " << ((tst = !chk) ? "Correct" : "Error") << "!" << std::endl; + } + testerr += (1 - (uint) tst); +} + +template +void MapPostOrder(uint& testnum, uint& testerr, lasd::MappableContainer& con, bool chk, typename lasd::MappableContainer::MapFunctor fun, const Parameter& inipar) { + bool tst = true; + testnum++; + Parameter par = {inipar}; + try { + std::cout << " " << testnum << " Executing map in post order - "; + con.MapPostOrder(fun, &par); + std::cout << ": " << ((tst = chk) ? "Correct" : "Error") << "!" << std::endl; + } catch(std::exception exc) { + std::cout << "\"" << exc.what() << "\": " << ((tst = !chk) ? "Correct" : "Error") << "!" << std::endl; + } + testerr += (1 - (uint) tst); +} + +template +void MapPrint(const Data& dat, void* _) { + std::cout << dat << " "; +} + +template +void MapIncrement(Data& dat, void* _) { + dat++; +} + +template +void MapIncrementNPrint(Data& dat, void* _) { + std::cout << dat++ << "->" << dat << "; "; +} + +template +void MapDouble(Data& dat, void* _) { + dat *= 2; +} + +template +void MapDoubleNPrint(Data& dat, void* _) { + std::cout << dat << "->" << (dat *= 2) << "; "; +} + +template +void MapInvert(Data& dat, void* _) { + dat = -dat; +} + +template +void MapInvertNPrint(Data& dat, void* _) { + std::cout << dat << "->" << (dat = -dat) << "; "; +} + +template +void MapParityInvert(Data& dat, void* _) { + if (dat % 2 != 0) { dat = -dat; } +} + +void MapStringAppend(std::string&, void*); + +/* ************************************************************************** */ + +// FoldableContainer member functions! + +template +void FoldPreOrder(uint& testnum, uint& testerr, const lasd::FoldableContainer& con, bool chk, typename lasd::FoldableContainer::FoldFunctor fun, const Parameter& inipar, const Value& inival, const Value& finval) { + bool tst; + testnum++; + Parameter par = {inipar}; + Value val = inival; + try { + std::cout << " " << testnum << " Executing fold in pre order - "; + con.FoldPreOrder(fun, &par, &val); + std::cout << "obtained value is \"" << val << "\": "; + std::cout << ((tst = ((val == finval) == chk)) ? "Correct" : "Error") << "!" << std::endl; + } catch(std::exception exc) { + std::cout << "\"" << exc.what() << "\": " << ((tst = !chk) ? "Correct" : "Error") << "!" << std::endl; + } + testerr += (1 - (uint) tst); +} + +template +void FoldPostOrder(uint& testnum, uint& testerr, const lasd::FoldableContainer& con, bool chk, typename lasd::FoldableContainer::FoldFunctor fun, const Parameter& inipar, const Value& inival, const Value& finval) { + bool tst; + testnum++; + Parameter par = {inipar}; + Value val = inival; + try { + std::cout << " " << testnum << " Executing fold in post order - "; + con.FoldPostOrder(fun, &par, &val); + std::cout << "obtained value is \"" << val << "\": "; + std::cout << ((tst = ((val == finval) == chk)) ? "Correct" : "Error") << "!" << std::endl; + } catch(std::exception exc) { + std::cout << "\"" << exc.what() << "\": " << ((tst = !chk) ? "Correct" : "Error") << "!" << std::endl; + } + testerr += (1 - (uint) tst); +} + +template +void FoldAdd(const Data& dat, const void* _, void* acc) { + *((Data*) acc) += dat; +} + +template +void FoldMultiply(const Data& dat, const void* _, void* acc) { + *((Data*) acc) *= dat; +} + +void FoldParity(const int&, const void*, void*); + +void FoldStringConcatenate(const std::string&, const void*, void*); + +/* ************************************************************************** */ + +// BreadthMappableContainer member functions! + +template +void MapBreadth(uint& testnum, uint& testerr, lasd::BreadthMappableContainer& con, bool chk, typename lasd::BreadthMappableContainer::MapFunctor fun, const Parameter& inipar) { + bool tst = true; + testnum++; + Parameter par = {inipar}; + try { + std::cout << " " << testnum << " Executing map in pre order - "; + con.MapBreadth(fun, &par); + std::cout << ": " << ((tst = chk) ? "Correct" : "Error") << "!" << std::endl; + } catch(std::exception exc) { + std::cout << "\"" << exc.what() << "\": " << ((tst = !chk) ? "Correct" : "Error") << "!" << std::endl; + } + testerr += (1 - (uint) tst); +} + +/* ************************************************************************** */ + +// BreadthFoldableContainer member functions! + +template +void FoldBreadth(uint& testnum, uint& testerr, const lasd::BreadthFoldableContainer& con, bool chk, typename lasd::BreadthFoldableContainer::FoldFunctor fun, const Parameter& inipar, const Value& inival, const Value& finval) { + bool tst; + testnum++; + Parameter par = {inipar}; + Value val = inival; + try { + std::cout << " " << testnum << " Executing fold in post order - "; + con.FoldBreadth(fun, &par, &val); + std::cout << "obtained value is \"" << val << "\": "; + std::cout << ((tst = ((val == finval) == chk)) ? "Correct" : "Error") << "!" << std::endl; + } catch(std::exception exc) { + std::cout << "\"" << exc.what() << "\": " << ((tst = !chk) ? "Correct" : "Error") << "!" << std::endl; + } + testerr += (1 - (uint) tst); +} + +/* ************************************************************************** */ + +#endif diff --git a/librerie/exercise1old/zlasdtest/exercise1/fulltest.cpp b/librerie/exercise1old/zlasdtest/exercise1/fulltest.cpp new file mode 100644 index 0000000..27f84be --- /dev/null +++ b/librerie/exercise1old/zlasdtest/exercise1/fulltest.cpp @@ -0,0 +1,3 @@ + +void testFullExercise1() { +} diff --git a/librerie/exercise1old/zlasdtest/exercise1/simpletest.cpp b/librerie/exercise1old/zlasdtest/exercise1/simpletest.cpp new file mode 100644 index 0000000..8fbc655 --- /dev/null +++ b/librerie/exercise1old/zlasdtest/exercise1/simpletest.cpp @@ -0,0 +1,447 @@ + +#include + +/* ************************************************************************** */ + +#include "../container/container.hpp" + +#include "../vector/vector.hpp" + +#include "../list/list.hpp" + +/* ************************************************************************** */ + +using namespace std; + +/* ************************************************************************** */ + +void stestVectorInt(uint& testnum, uint& testerr) { + uint loctestnum = 0, loctesterr = 0; + cout << endl << "Begin of Vector Test:" << endl; + try { + { + lasd::Vector vec; + Empty(loctestnum, loctesterr, vec, true); + + GetFront(loctestnum, loctesterr, vec, false, 0); + GetBack(loctestnum, loctesterr, vec, false, 0); + SetAt(loctestnum, loctesterr, vec, false, 1, 0); + GetAt(loctestnum, loctesterr, vec, false, 2, 0); + + Exists(loctestnum, loctesterr, vec, false, 0); + + MapPreOrder(loctestnum, loctesterr, vec, true, &MapPrint, 0); + MapPostOrder(loctestnum, loctesterr, vec, true, &MapPrint, 0); + + FoldPreOrder(loctestnum, loctesterr, vec, true, &FoldAdd, 0, 0, 0); + FoldPostOrder(loctestnum, loctesterr, vec, true, &FoldAdd, 0, 0, 0); + } + { + lasd::Vector vec(3); + Empty(loctestnum, loctesterr, vec, false); + Size(loctestnum, loctesterr, vec, true, 3); + + SetAt(loctestnum, loctesterr, vec, true, 0, 4); + SetAt(loctestnum, loctesterr, vec, true, 1, 3); + SetAt(loctestnum, loctesterr, vec, true, 2, 1); + + GetFront(loctestnum, loctesterr, vec, true, 4); + GetBack(loctestnum, loctesterr, vec, true, 1); + + SetFront(loctestnum, loctesterr, vec, true, 5); + SetBack(loctestnum, loctesterr, vec, true, 4); + + Exists(loctestnum, loctesterr, vec, true, 4); + + MapPreOrder(loctestnum, loctesterr, vec, true, &MapPrint, 0); + MapPostOrder(loctestnum, loctesterr, vec, true, &MapPrint, 0); + FoldPreOrder(loctestnum, loctesterr, vec, true, &FoldAdd, 0, 0, 12); + FoldPostOrder(loctestnum, loctesterr, vec, true, &FoldMultiply, 0, 1, 60); + + vec.Resize(2); + FoldPostOrder(loctestnum, loctesterr, vec, true, &FoldMultiply, 0, 1, 15); + } + } catch(...) { + loctestnum++; loctesterr++; + cout << endl << "Unmanaged error! " << endl; + } + cout << "End of Vector Test! (Errors/Tests: " << loctesterr << "/" << loctestnum << ")" << endl; + testnum += loctestnum; + testerr += loctesterr; +} + +void stestVectorDouble(uint& testnum, uint& testerr) { + uint loctestnum = 0, loctesterr = 0; + cout << endl << "Begin of Vector Test:" << endl; + try { + lasd::Vector vec(3); + Empty(loctestnum, loctesterr, vec, false); + Size(loctestnum, loctesterr, vec, true, 3); + + SetAt(loctestnum, loctesterr, vec, true, 0, 5.5); + SetAt(loctestnum, loctesterr, vec, true, 1, 3.3); + SetAt(loctestnum, loctesterr, vec, true, 2, 1.1); + + GetFront(loctestnum, loctesterr, vec, true, 5.5); + GetBack(loctestnum, loctesterr, vec, true, 1.1); + + Exists(loctestnum, loctesterr, vec, true, 3.3); + + FoldPreOrder(loctestnum, loctesterr, vec, true, &FoldAdd, 0.0, 0.0, 9.9); + FoldPostOrder(loctestnum, loctesterr, vec, true, &FoldMultiply, 0.0, 1.0, 19.965); + } catch(...) { + loctestnum++; loctesterr++; + cout << endl << "Unmanaged error! " << endl; + } + cout << "End of Vector Test! (Errors/Tests: " << loctesterr << "/" << loctestnum << ")" << endl; + testnum += loctestnum; + testerr += loctesterr; +} + +void stestVectorString(uint& testnum, uint& testerr) { + uint loctestnum = 0, loctesterr = 0; + cout << endl << "Begin of Vector Test:" << endl; + try { + lasd::Vector vec(2); + Empty(loctestnum, loctesterr, vec, false); + Size(loctestnum, loctesterr, vec, true, 2); + + SetAt(loctestnum, loctesterr, vec, true, 0, string("A")); + SetAt(loctestnum, loctesterr, vec, true, 1, string("B")); + + GetFront(loctestnum, loctesterr, vec, true, string("A")); + GetBack(loctestnum, loctesterr, vec, true, string("B")); + + Exists(loctestnum, loctesterr, vec, true, string("A")); + + MapPreOrder(loctestnum, loctesterr, vec, true, &MapStringAppend, string(" ")); + MapPreOrder(loctestnum, loctesterr, vec, true, &MapPrint, 0); + FoldPreOrder(loctestnum, loctesterr, vec, true, &FoldStringConcatenate, string(""), string("X"), string("XA B ")); + FoldPostOrder(loctestnum, loctesterr, vec, true, &FoldStringConcatenate, string(""), string("X"), string("XB A ")); + + Exists(loctestnum, loctesterr, vec, false, string("A")); + + lasd::Vector copvec(vec); + EqualVector(loctestnum, loctesterr, vec, copvec, true); + MapPreOrder(loctestnum, loctesterr, vec, true, &MapStringAppend, string("!")); + NonEqualVector(loctestnum, loctesterr, vec, copvec, true); + + copvec = std::move(vec); + FoldPreOrder(loctestnum, loctesterr, copvec, true, &FoldStringConcatenate, string(""), string("?"), string("?A !B !")); + + lasd::Vector movvec(std::move(vec)); + FoldPreOrder(loctestnum, loctesterr, movvec, true, &FoldStringConcatenate, string(""), string("?"), string("?A B ")); + SetAt(loctestnum, loctesterr, vec, false, 1, string("")); + vec.Resize(1); + SetAt(loctestnum, loctesterr, vec, true, 0, string("X")); + + movvec.Clear(); + Empty(loctestnum, loctesterr, movvec, true); + } catch(...) { + loctestnum++; loctesterr++; + cout << endl << "Unmanaged error! " << endl; + } + cout << "End of Vector Test! (Errors/Tests: " << loctesterr << "/" << loctestnum << ")" << endl; + testnum += loctestnum; + testerr += loctesterr; +} + +void stestVector(uint& testnum, uint& testerr) { + uint loctestnum = 0, loctesterr = 0; + stestVectorInt(loctestnum, loctesterr); + stestVectorDouble(loctestnum, loctesterr); + stestVectorString(loctestnum, loctesterr); + testnum += loctestnum; + testerr += loctesterr; + cout << endl << "Exercise 1 - Vector (Errors/Tests: " << loctesterr << "/" << loctestnum << ")" << endl; +} + +/* ************************************************************************** */ + +void stestListInt(uint& testnum, uint& testerr) { + uint loctestnum = 0, loctesterr = 0; + cout << endl << "Begin of List Test:" << endl; + try { + lasd::List lst; + Empty(loctestnum, loctesterr, lst, true); + Size(loctestnum, loctesterr, lst, true, 0); + + GetFront(loctestnum, loctesterr, lst, false, 0); + GetBack(loctestnum, loctesterr, lst, false, 0); + + Exists(loctestnum, loctesterr, lst, false, 0); + + MapPreOrder(loctestnum, loctesterr, lst, true, &MapPrint, 0); + MapPostOrder(loctestnum, loctesterr, lst, true, &MapPrint, 0); + FoldPreOrder(loctestnum, loctesterr, lst, true, &FoldAdd, 0, 0, 0); + FoldPostOrder(loctestnum, loctesterr, lst, true, &FoldAdd, 0, 0, 0); + + RemoveFromFront(loctestnum, loctesterr, lst, false); + FrontNRemove(loctestnum, loctesterr, lst, false, 0); + + InsertAtBack(loctestnum, loctesterr, lst, true, 4); + InsertAtFront(loctestnum, loctesterr, lst, true, 5); + InsertAtFront(loctestnum, loctesterr, lst, true, 9); + InsertAtBack(loctestnum, loctesterr, lst, true, 2); + InsertAtFront(loctestnum, loctesterr, lst, true, 1); + + GetFront(loctestnum, loctesterr, lst, true, 1); + GetBack(loctestnum, loctesterr, lst, true, 2); + SetFront(loctestnum, loctesterr, lst, true, 2); + SetBack(loctestnum, loctesterr, lst, true, 6); + + GetAt(loctestnum, loctesterr, lst, true, 3, 4); + SetAt(loctestnum, loctesterr, lst, true, 3, 3); + + Exists(loctestnum, loctesterr, lst, false, 4); + + MapPreOrder(loctestnum, loctesterr, lst, true, &MapPrint, 0); + MapPostOrder(loctestnum, loctesterr, lst, true, &MapPrint, 0); + FoldPreOrder(loctestnum, loctesterr, lst, true, &FoldAdd, 0, 0, 25); + FoldPostOrder(loctestnum, loctesterr, lst, true, &FoldMultiply, 0, 1, 1620); + + RemoveFromFront(loctestnum, loctesterr, lst, true); + FrontNRemove(loctestnum, loctesterr, lst, true, 9); + FoldPostOrder(loctestnum, loctesterr, lst, true, &FoldMultiply, 0, 1, 90); + + lasd::List coplst(lst); + EqualList(loctestnum, loctesterr, lst, coplst, true); + MapPreOrder(loctestnum, loctesterr, lst, true, &MapIncrement, 0); + NonEqualList(loctestnum, loctesterr, lst, coplst, true); + + InsertAtFront(loctestnum, loctesterr, lst, true, 0); + InsertAtBack(loctestnum, loctesterr, lst, true, 0); + NonEqualList(loctestnum, loctesterr, lst, coplst, true); + coplst = lst; + EqualList(loctestnum, loctesterr, lst, coplst, true); + + RemoveFromFront(loctestnum, loctesterr, coplst, true); + FrontNRemove(loctestnum, loctesterr, coplst, true, 6); + coplst = std::move(lst); + FoldPreOrder(loctestnum, loctesterr, lst, true, &FoldAdd, 0, 0, 11); + FoldPreOrder(loctestnum, loctesterr, coplst, true, &FoldAdd, 0, 0, 17); + + lasd::List movlst(std::move(lst)); + MapPreOrder(loctestnum, loctesterr, movlst, true, &MapIncrement, 0); + FoldPreOrder(loctestnum, loctesterr, movlst, true, &FoldAdd, 0, 0, 14); + + movlst.Clear(); + Empty(loctestnum, loctesterr, movlst, true); + Size(loctestnum, loctesterr, movlst, true, 0); + } catch(...) { + loctestnum++; loctesterr++; + cout << endl << "Unmanaged error! " << endl; + } + cout << "End of List Test! (Errors/Tests: " << loctesterr << "/" << loctestnum << ")" << endl; + testnum += loctestnum; + testerr += loctesterr; +} + +void stestListDouble(uint& testnum, uint& testerr) { + uint loctestnum = 0, loctesterr = 0; + cout << endl << "Begin of List Test:" << endl; + try { + lasd::List lst; + Empty(loctestnum, loctesterr, lst, true); + Size(loctestnum, loctesterr, lst, true, 0); + + InsertAtBack(loctestnum, loctesterr, lst, true, -2.5); + InsertAtBack(loctestnum, loctesterr, lst, true, 2.5); + + lst.Clear(); + + InsertAtBack(loctestnum, loctesterr, lst, true, 0.5); + InsertAtFront(loctestnum, loctesterr, lst, true, 3.3); + InsertAtFront(loctestnum, loctesterr, lst, true, 5.5); + InsertAtBack(loctestnum, loctesterr, lst, true, 1.1); + + GetFront(loctestnum, loctesterr, lst, true, 5.5); + GetBack(loctestnum, loctesterr, lst, true, 1.1); + + Exists(loctestnum, loctesterr, lst, false, 0.0); + + MapPreOrder(loctestnum, loctesterr, lst, true, &MapPrint, 0); + MapPostOrder(loctestnum, loctesterr, lst, true, &MapPrint, 0); + FoldPreOrder(loctestnum, loctesterr, lst, true, &FoldAdd, 0.0, 0.0, 10.4); + FoldPostOrder(loctestnum, loctesterr, lst, true, &FoldMultiply, 0.0, 1.0, 9.9825); + } catch(...) { + loctestnum++; loctesterr++; + cout << endl << "Unmanaged error! " << endl; + } + cout << "End of List Test! (Errors/Tests: " << loctesterr << "/" << loctestnum << ")" << endl; + testnum += loctestnum; + testerr += loctesterr; +} + +void stestListString(uint& testnum, uint& testerr) { + uint loctestnum = 0, loctesterr = 0; + cout << endl << "Begin of List Test:" << endl; + try { + lasd::List lst; + Empty(loctestnum, loctesterr, lst, true); + Size(loctestnum, loctesterr, lst, true, 0); + + InsertAtFront(loctestnum, loctesterr, lst, true, string("A")); + InsertAtBack(loctestnum, loctesterr, lst, true, string("B")); + + GetFront(loctestnum, loctesterr, lst, true, string("A")); + GetBack(loctestnum, loctesterr, lst, true, string("B")); + + Exists(loctestnum, loctesterr, lst, true, string("B")); + + MapPreOrder(loctestnum, loctesterr, lst, true, &MapStringAppend, string(" ")); + MapPreOrder(loctestnum, loctesterr, lst, true, &MapPrint, 0); + FoldPreOrder(loctestnum, loctesterr, lst, true, &FoldStringConcatenate, string(""), string("X"), string("XA B ")); + FoldPostOrder(loctestnum, loctesterr, lst, true, &FoldStringConcatenate, string(""), string("X"), string("XB A ")); + + Exists(loctestnum, loctesterr, lst, false, string("B")); + + lasd::List coplst(lst); + EqualList(loctestnum, loctesterr, lst, coplst, true); + RemoveFromFront(loctestnum, loctesterr, coplst, true); + NonEqualList(loctestnum, loctesterr, lst, coplst, true); + + lst = coplst; + EqualList(loctestnum, loctesterr, lst, coplst, true); + InsertAtBack(loctestnum, loctesterr, lst, true, string("A")); + InsertAtFront(loctestnum, loctesterr, lst, true, string("C")); + NonEqualList(loctestnum, loctesterr, lst, coplst, true); + + coplst = std::move(lst); + FoldPreOrder(loctestnum, loctesterr, coplst, true, &FoldStringConcatenate, string(""), string("?"), string("?CB A")); + } catch(...) { + loctestnum++; loctesterr++; + cout << endl << "Unmanaged error! " << endl; + } + cout << "End of List Test! (Errors/Tests: " << loctesterr << "/" << loctestnum << ")" << endl; + testnum += loctestnum; + testerr += loctesterr; +} + +void stestList(uint& testnum, uint& testerr) { + uint loctestnum = 0, loctesterr = 0; + stestListInt(loctestnum, loctesterr); + stestListDouble(loctestnum, loctesterr); + stestListString(loctestnum, loctesterr); + testnum += loctestnum; + testerr += loctesterr; + cout << endl << "Exercise 1 - List (Errors/Tests: " << loctesterr << "/" << loctestnum << ")" << endl; +} + +/* ************************************************************************** */ + +void stestVectorListInt(uint& testnum, uint& testerr) { + uint loctestnum = 0, loctesterr = 0; + cout << endl << "Begin of Vector/List Test:" << endl; + try { + lasd::Vector vec(3); + SetAt(loctestnum, loctesterr, vec, true, 0, -1); + SetAt(loctestnum, loctesterr, vec, true, 1, 0); + SetAt(loctestnum, loctesterr, vec, true, 2, 1); + + lasd::List lst; + InsertAtFront(loctestnum, loctesterr, lst, true, 1); + InsertAtFront(loctestnum, loctesterr, lst, true, 0); + InsertAtFront(loctestnum, loctesterr, lst, true, -1); + + lasd::Vector copvec(lst); + EqualVector(loctestnum, loctesterr, vec, copvec, true); + lasd::Vector copvecx(vec); + EqualVector(loctestnum, loctesterr, copvecx, copvec, true); + + lasd::List coplst(vec); + EqualList(loctestnum, loctesterr, lst, coplst, true); + lasd::List coplstx(lst); + EqualList(loctestnum, loctesterr, coplstx, coplst, true); + } catch(...) { + loctestnum++; loctesterr++; + cout << endl << "Unmanaged error! " << endl; + } + cout << "End of Vector/List Test! (Errors/Tests: " << loctesterr << "/" << loctestnum << ")" << endl; + testnum += loctestnum; + testerr += loctesterr; +} + +void stestVectorListDouble(uint& testnum, uint& testerr) { + uint loctestnum = 0, loctesterr = 0; + cout << endl << "Begin of Vector/List Test:" << endl; + try { + lasd::Vector vec(3); + SetAt(loctestnum, loctesterr, vec, true, 0, -0.5); + SetAt(loctestnum, loctesterr, vec, true, 1, 0.0); + SetAt(loctestnum, loctesterr, vec, true, 2, 0.5); + + lasd::List lst; + InsertAtBack(loctestnum, loctesterr, lst, true, -0.5); + InsertAtBack(loctestnum, loctesterr, lst, true, 0.0); + InsertAtBack(loctestnum, loctesterr, lst, true, 0.5); + + lasd::Vector copvec(lst); + EqualVector(loctestnum, loctesterr, vec, copvec, true); + lasd::Vector copvecx(vec); + EqualVector(loctestnum, loctesterr, copvecx, copvec, true); + + lasd::List coplst(vec); + EqualList(loctestnum, loctesterr, lst, coplst, true); + lasd::List coplstx(lst); + EqualList(loctestnum, loctesterr, coplstx, coplst, true); + } catch(...) { + loctestnum++; loctesterr++; + cout << endl << "Unmanaged error! " << endl; + } + cout << "End of Vector/List Test! (Errors/Tests: " << loctesterr << "/" << loctestnum << ")" << endl; + testnum += loctestnum; + testerr += loctesterr; +} + +void stestVectorListString(uint& testnum, uint& testerr) { + uint loctestnum = 0, loctesterr = 0; + cout << endl << "Begin of Vector/List Test:" << endl; + try { + lasd::Vector vec(3); + SetAt(loctestnum, loctesterr, vec, true, 0, string("A")); + SetAt(loctestnum, loctesterr, vec, true, 1, string("B")); + SetAt(loctestnum, loctesterr, vec, true, 2, string("C")); + + lasd::List lst; + InsertAtFront(loctestnum, loctesterr, lst, true, string("B")); + InsertAtBack(loctestnum, loctesterr, lst, true, string("C")); + InsertAtFront(loctestnum, loctesterr, lst, true, string("A")); + + lasd::Vector copvec(lst); + EqualVector(loctestnum, loctesterr, vec, copvec, true); + lasd::Vector copvecx(vec); + EqualVector(loctestnum, loctesterr, copvecx, copvec, true); + + lasd::List coplst(vec); + EqualList(loctestnum, loctesterr, lst, coplst, true); + lasd::List coplstx(lst); + EqualList(loctestnum, loctesterr, coplstx, coplst, true); + } catch(...) { + loctestnum++; loctesterr++; + cout << endl << "Unmanaged error! " << endl; + } + cout << "End of Vector/List Test! (Errors/Tests: " << loctesterr << "/" << loctestnum << ")" << endl; + testnum += loctestnum; + testerr += loctesterr; +} + +void stestVectorList(uint& testnum, uint& testerr) { + uint loctestnum = 0, loctesterr = 0; + stestVectorListInt(loctestnum, loctesterr); + stestVectorListDouble(loctestnum, loctesterr); + stestVectorListString(loctestnum, loctesterr); + testnum += loctestnum; + testerr += loctesterr; + cout << endl << "Exercise 1 - Vector/List (Errors/Tests: " << loctesterr << "/" << loctestnum << ")" << endl; +} + +/* ************************************************************************** */ + +void testSimpleExercise1() { + uint testnum = 0, testerr = 0; + stestVector(testnum, testerr); + stestList(testnum, testerr); + stestVectorList(testnum, testerr); + cout << endl << "Exercise 1 (Simple Test) (Errors/Tests: " << testerr << "/" << testnum << ")" << endl; +} diff --git a/librerie/exercise1old/zlasdtest/exercise1/test.hpp b/librerie/exercise1old/zlasdtest/exercise1/test.hpp new file mode 100644 index 0000000..c151dcf --- /dev/null +++ b/librerie/exercise1old/zlasdtest/exercise1/test.hpp @@ -0,0 +1,13 @@ + +#ifndef EX1TEST_HPP +#define EX1TEST_HPP + +/* ************************************************************************** */ + +void testSimpleExercise1(); + +void testFullExercise1(); + +/* ************************************************************************** */ + +#endif diff --git a/librerie/exercise1old/zlasdtest/list/list.hpp b/librerie/exercise1old/zlasdtest/list/list.hpp new file mode 100644 index 0000000..94fbe48 --- /dev/null +++ b/librerie/exercise1old/zlasdtest/list/list.hpp @@ -0,0 +1,92 @@ + +#ifndef LISTTEST_HPP +#define LISTTEST_HPP + +#include "../../list/list.hpp" + +/* ************************************************************************** */ + +template +void InsertAtFront(uint& testnum, uint& testerr, lasd::List& lst, bool chk, const Data& val) { + bool tst; + testnum++; + try { + std::cout << " " << testnum << " Insert at the front of the list the value \"" << val << "\": "; + lst.InsertAtFront(val); + std::cout << ((tst = chk) ? "Correct" : "Error") << "!" << std::endl; + } catch(std::exception exc) { + std::cout << "\"" << exc.what() << "\": " << ((tst = !chk) ? "Correct" : "Error") << "!" << std::endl; + } + testerr += (1 - (uint) tst); +} + +template +void RemoveFromFront(uint& testnum, uint& testerr, lasd::List& lst, bool chk) { + bool tst; + testnum++; + try { + std::cout << " " << testnum << " Remove from the list of \"" << lst.Front() << "\": "; + lst.RemoveFromFront(); + std::cout << ((tst = chk) ? "Correct" : "Error") << "!" << std::endl; + } catch(std::length_error exc) { + std::cout << exc.what() << "\": " << ((tst = !chk) ? "Correct" : "Error") << "!" << std::endl; + } + testerr += (1 - (uint) tst); +} + +template +void FrontNRemove(uint& testnum, uint& testerr, lasd::List& lst, bool chk, const Data& val) { + bool tst; + testnum++; + try { + std::cout << " " << testnum << " FrontNRemove from the list of \"" << lst.Front() << "\": "; + std::cout << ((tst = ((lst.FrontNRemove() == val) == chk)) ? "Correct" : "Error") << "!" << std::endl; + } catch(std::length_error exc) { + std::cout << exc.what() << "\": " << ((tst = !chk) ? "Correct" : "Error") << "!" << std::endl; + } + testerr += (1 - (uint) tst); +} + +template +void InsertAtBack(uint& testnum, uint& testerr, lasd::List& lst, bool chk, const Data& val) { + bool tst; + testnum++; + try { + std::cout << " " << testnum << " Insert at the back of the list the value \"" << val << "\": "; + lst.InsertAtBack(val); + std::cout << ((tst = chk) ? "Correct" : "Error") << "!" << std::endl; + } catch(std::exception exc) { + std::cout << "\"" << exc.what() << "\": " << ((tst = !chk) ? "Correct" : "Error") << "!" << std::endl; + } + testerr += (1 - (uint) tst); +} + +template +void EqualList(uint& testnum, uint& testerr, const lasd::List& lst1, const lasd::List& lst2, bool chk) { + bool tst; + testnum++; + try { + std::cout << " " << testnum << " The two lists are " << ((tst = (lst1 == lst2)) ? "" : "not ") << "equal: "; + std::cout << ((tst = (tst == chk)) ? "Correct" : "Error") << "!" << std::endl; + } catch(std::exception exc) { + std::cout << "\"" << exc.what() << "\": " << ((tst = !chk) ? "Correct" : "Error") << "!" << std::endl; + } + testerr += (1 - (uint) tst); +} + +template +void NonEqualList(uint& testnum, uint& testerr, const lasd::List& lst1, const lasd::List& lst2, bool chk) { + bool tst; + testnum++; + try { + std::cout << " " << testnum << " The two lists are " << ((tst = (lst1 != lst2)) ? "not " : "") << "equal: "; + std::cout << ((tst = (tst == chk)) ? "Correct" : "Error") << "!" << std::endl; + } catch(std::exception exc) { + std::cout << "\"" << exc.what() << "\": " << ((tst = !chk) ? "Correct" : "Error") << "!" << std::endl; + } + testerr += (1 - (uint) tst); +} + +/* ************************************************************************** */ + +#endif diff --git a/librerie/exercise1old/zlasdtest/test.cpp b/librerie/exercise1old/zlasdtest/test.cpp new file mode 100644 index 0000000..faa5bf0 --- /dev/null +++ b/librerie/exercise1old/zlasdtest/test.cpp @@ -0,0 +1,17 @@ + +#include "./exercise1/test.hpp" + +/* ************************************************************************** */ + +#include + +using namespace std; + +/* ************************************************************************** */ + +void lasdtest() { + cout << endl << "~*~#~*~ Welcome to the LASD Test Suite ~*~#~*~ " << endl; + testSimpleExercise1(); + testFullExercise1(); + cout << endl << "Goodbye!" << endl; +} diff --git a/librerie/exercise1old/zlasdtest/test.hpp b/librerie/exercise1old/zlasdtest/test.hpp new file mode 100644 index 0000000..a2fca61 --- /dev/null +++ b/librerie/exercise1old/zlasdtest/test.hpp @@ -0,0 +1,11 @@ + +#ifndef LASDTEST_HPP +#define LASDTEST_HPP + +/* ************************************************************************** */ + +void lasdtest(); + +/* ************************************************************************** */ + +#endif diff --git a/librerie/exercise1old/zlasdtest/vector/vector.hpp b/librerie/exercise1old/zlasdtest/vector/vector.hpp new file mode 100644 index 0000000..bb0ccf6 --- /dev/null +++ b/librerie/exercise1old/zlasdtest/vector/vector.hpp @@ -0,0 +1,37 @@ + +#ifndef VECTORTEST_HPP +#define VECTORTEST_HPP + +#include "../../vector/vector.hpp" + +/* ************************************************************************** */ + +template +void EqualVector(uint& testnum, uint& testerr, const lasd::Vector& vec1, const lasd::Vector& vec2, bool chk) { + bool tst; + testnum++; + try { + std::cout << " " << testnum << " The two vectors are " << ((tst = (vec1 == vec2)) ? "" : "not ") << "equal: "; + std::cout << ((tst = (tst == chk)) ? "Correct" : "Error") << "!" << std::endl; + } catch(std::exception exc) { + std::cout << "\"" << exc.what() << "\": " << ((tst = !chk) ? "Correct" : "Error") << "!" << std::endl; + } + testerr += (1 - (uint) tst); +} + +template +void NonEqualVector(uint& testnum, uint& testerr, const lasd::Vector& vec1, const lasd::Vector& vec2, bool chk) { + bool tst; + testnum++; + try { + std::cout << " " << testnum << " The two vectors are " << ((tst = (vec1 != vec2)) ? "not " : "") << "equal: "; + std::cout << ((tst = (tst == chk)) ? "Correct" : "Error") << "!" << std::endl; + } catch(std::exception exc) { + std::cout << "\"" << exc.what() << "\": " << ((tst = !chk) ? "Correct" : "Error") << "!" << std::endl; + } + testerr += (1 - (uint) tst); +} + +/* ************************************************************************** */ + +#endif diff --git a/librerie/exercise1old/zmytest/test.cpp b/librerie/exercise1old/zmytest/test.cpp new file mode 100644 index 0000000..ae73e4d --- /dev/null +++ b/librerie/exercise1old/zmytest/test.cpp @@ -0,0 +1,70 @@ +void menu(){ + unsigned short int choice; + DataStructure chosenDataStructure; + DataType chosenDataType; + do{ + std::cout<<"1. Use your tests (to be used by the professor)"<>std::ws; + std::cin>>choice; + }while(choice!=1 && choice!=2); + + switch(choice){ + case 1: + lasdtest(); + break; + case 2: + chosenDataStructure = ChooseDataStructure(); + chosenDataType = ChooseDataType(); + break; + default: + std::cout<<"An error has occurred"<>std::ws; + std::cin>>choice; + }while(choice!=1 && choice!=2); + if(choice == 1) + return DataStructure::vector; + else if(choice == 2) + return DataStructure::list; +} + +DataType ChooseDataType(){ + unsigned short int choice; + do{ + std::cout<<"1. Integer"<>std::ws; + std::cin>>choice; + }while(!(choice>0 && choice<4)); + if(choice==1) + return DataType::integer; + else if(choice==2) + return DataType::ddouble; + else if(choice==3) + return DataType::sstring; +} +void UseChosenType(DataStructure chosenDataStructure, DataType chosenDataType){ + std::cout<<"\tTest on "; + if(chosenDataStructure == DataStructure::vector) + std::cout<<"vector of "; + else if(chosenDataStructure == DataStructure::list) + std::cout<<"list of "; + + if(chosenDataType == DataType::integer) + std::cout<<" integers"< GenerateRandomStructure(const ulong&); +void ViewElement(const LinearContainer&); +void PrintAllElements(const LinearContainer&); +void PrintElement(Data&, void*); // funzione richiamata dalla map +void CheckExists(const LinearContainer&); +void ChooseFoldFunction(const LinearContainer&); +void SumLessThan(const LinearContainer&, const ulong&); +void SumLessThanFold(int&, const void*, void*); +void ProductMoreThan(const LinearContainer&, const ulong&); +void ProductMoreThanFold(float&, const void*, void*); +void ConcatStringLessThan(const LinearContainer&, const ulong&); +void ConcatStringLessThanFold(string&, const void*, void*); + +//7 +void ChooseMapFunction(const LinearContainer); +void DoubleN(const LinearContainer&, const ulong&); +void DoubleNMap(int&, void*); + +void SquareN(const LinearContainer&, const ulong&); +void SquareNMap(float&, void*); + +void Uppercase(const LinearContainer&, const ulong&); +void UppercaseMap(string&, void*); + + +#endif