namespace lasd { /* ************************************************************************** */ // Specific constructors template List::Node::Node(const Data& newValue){ value = newValue; next = nullptr; } // Copy constructor template List::Node::Node(const Node& copyFrom){ value = copyFrom.value; next = nullptr; } // Move constructor template List::Node::Node(Node&& moveFrom){ std::swap(value, moveFrom.value); std::swap(next, moveFrom.next); } template List::Node::Node(Data&& moveFrom){ std::swap(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(List&& moveFrom){ std::swap(size, moveFrom.size); std::swap(head, moveFrom.head); std::swap(tail, moveFrom.tail); } 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){ 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; tmp->next = nullptr; delete tmp; size--; if(head==nullptr){ tail=nullptr; } } } 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 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(MapFunctor function, void* par){ MapPreOrder(function, par, head); } template void List::MapPostOrder(MapFunctor function, void* par){ MapPostOrder(function, 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); } //OVERLOAD Accessory Function 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); } /* ************************************************************************** */ }