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); } // 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) } 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){ 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); } }