#ifndef SIMPLESEARCH_TLINKEDLIST_H #define SIMPLESEARCH_TLINKEDLIST_H #include "TBankAccount.h" #include "FCompareAccount.h" #include "SearchSummary.h" // Using singly linked list since we gain very little in terms of functionality when going for doubly or circular // and singly is a lot leaner when it comes to space complexity template struct Node { T value; Node* next = nullptr; explicit Node(T v) : value(v), next(nullptr) {} }; template class TLinkedList { private: Node* head = nullptr; Node* tail = nullptr; bool ownsData = false; std::size_t listSize = 0; public: explicit TLinkedList(bool owns) : ownsData(owns) {} ~TLinkedList() { Node* current = head; while (current) { Node* next = current->next; if (ownsData) delete current->value; delete current; current = next; } } [[nodiscard]] size_t Size() const; [[nodiscard]] bool Empty() const; void PushBack(T v); template T FindIf(Pred p) const { for (auto* n = head; n; n = n->next) if (p(n->value)) return n->value; return nullptr; } template bool RemoveIf(Pred p) { Node* prev = nullptr; Node* current = head; while (current) { if (p(current->value)) { if (prev) prev->next = current->next; else head = current->next; if (ownsData) delete current->value; delete current; --listSize; return true; } prev = current; current = current->next; } return false; } TBankAccount* Find(FCompareAccount onCompare, void* searchKey, SearchSummary* summary) const; TLinkedList* Every(FCompareAccount onCompare, void* searchKey, SearchSummary* summary) const; }; #endif //SIMPLESEARCH_TLINKEDLIST_H #include template TBankAccount *TLinkedList::Find(FCompareAccount onCompare, void *searchKey, SearchSummary *summary) const { using clock = std::chrono::steady_clock; auto start = clock::now(); if (!onCompare) return nullptr; for (auto* n = head; n; n = n->next) { ++summary->comparisons; if (onCompare(n->value, searchKey)) { auto elapsed = clock::now() - start; summary->timeSpentMs = std::chrono::duration(elapsed).count(); return n->value; } } auto elapsed = clock::now() - start; summary->timeSpentMs = std::chrono::duration(elapsed).count(); return nullptr; } template TLinkedList *TLinkedList::Every(FCompareAccount onCompare, void *searchKey, SearchSummary *summary) const { using clock = std::chrono::steady_clock; auto start = clock::now(); auto* result = new TLinkedList(false); if (!onCompare) { auto elapsed = clock::now() - start; summary->timeSpentMs = std::chrono::duration(elapsed).count(); return result; } for (auto* n = head; n; n = n->next) { ++summary->comparisons; if (onCompare(n->value, searchKey)) { result->PushBack(n->value); } } auto elapsed = clock::now() - start; summary->timeSpentMs = std::chrono::duration(elapsed).count(); return result; } template size_t TLinkedList::Size() const { return listSize; } template bool TLinkedList::Empty() const { return listSize == 0; } template void TLinkedList::PushBack(T v) { auto* n = new Node(v); if (!tail) head = tail = n; else { tail->next = n; tail = n; } listSize++; }