#ifndef CONTACT_LIST_HPP #define CONTACT_LIST_HPP #include "Contact.hpp" namespace MyStructures { template class ContactList { public: ContactList() = default; ContactList(size_t size); ContactList(const C* contacts, const size_t& length); ~ContactList(); ContactList(const ContactList& copy); ContactList& operator=(const ContactList& rhs); ContactList(ContactList&& move); ContactList& operator=(ContactList&& rhs); void PrintList() const; size_t Size() const; void Append(const C& data); void Prepend(const C& data); void RemoveLast(); void RemoveFirst(); void Extract(const C& data); void InsertAfter(const C& data, const C& after); void InsertBefore(const C& data, const C& before); void Clear(); void ContactDeleter(const size_t& size); void DeleteContact(const size_t& choice); C& Last(); C Last() const; C& First(); C First() const; void ContactDoubler(); C& operator[](const int& index); C operator[](const int& index) const; explicit operator bool() const; bool operator==(const ContactList& rhs) const; bool Empty() const; bool Full() const; private: C* contacts_{ nullptr }; size_t length_{ 0 }; size_t size_{ 0 }; C* AllocateContactList(const size_t& length); }; template ContactList::ContactList(size_t size) { contacts_ = AllocateContactList(size); } template ContactList::ContactList(const C* contacts, const size_t& length) { contacts_ = AllocateContactList(length); for (auto i = 0u; i < size_; ++i) { contacts_[i] = contacts[i]; } } template ContactList::~ContactList() { delete[] contacts_; contacts_ = nullptr; } template ContactList::ContactList(const ContactList& copy) { delete[] contacts_; contacts_ = nullptr; auto temp = ContactList{ copy.contacts_, copy.length_ }; *this = std::move(temp); size_ = copy.size_; } template ContactList&ContactList::operator=(const ContactList& rhs) { if (this != &rhs) //asking if they're the same object { delete[] contacts_; contacts_ = nullptr; if (rhs.contacts_ != nullptr) { contacts_ = AllocateContactList(rhs.length_); size_ = rhs.size_; contacts_ = AllocateContactList(length_); for (auto i = 0u; i < length_; ++i) { contacts_[i] = rhs[i]; } } else contacts_ = nullptr; } return *this; } template ContactList::ContactList(ContactList&& move) { *this = std::move(move); } template ContactList& ContactList::operator=(ContactList&& rhs) { if (this != &rhs) { delete[] contacts_; contacts_ = nullptr; contacts_ = rhs.contacts_; length_ = rhs.length_; size_ = rhs.size_; rhs.contacts_ = nullptr; } return *this; } template void ContactList::PrintList() const { for (auto i = 0u; i < size_; ++i) { cout << i + 1 << ": "; contacts_[i].Print(); } } template size_t ContactList::Size() const { return size_t(); } template C* ContactList::AllocateContactList(const size_t& length) { C* storage = nullptr; length_ = length; storage = new C[length]{}; return storage; } template void ContactList::Append(const C& data) { size_t index_locate = 0; if (size_ == 0) { index_locate = 0; } if (size_ > 0 && size_ < length_) { index_locate = size_; } if (Full()) { auto temp = ContactList{ length_ * 2 }; for (auto i = 0; i <= size_; ++i) { temp[i] = contacts_[i]; } temp[size_] = data; delete[] contacts_; contacts_ = nullptr; *this = std::move(temp); size_ += 4; return; } contacts_[index_locate] = data; ++size_; } template void ContactList::Prepend(const C& data) { if (Empty()) { Append(data); size_++; return; } if (!Full()) { for (auto i = 0; i{length_*2}; temp.Append(data); for (auto i = 0; i <= size_; ++i) { temp.Append(contacts_[i]); } delete[] contacts_; contacts_ = nullptr; *this = std::move(temp); } size_++; } template void ContactList::RemoveLast() { if (Empty()) return; ContactDeleter(size_ - 1); size_--; } template void ContactList::RemoveFirst() { if (Empty()) return; ContactDeleter(0); for (auto i = 0u; i < size_; i++) { contacts_[i] = contacts_[i + 1]; } ContactDeleter(size_ - 1); size_--; } template void ContactList::Extract(const C& data) { if (Empty())return; auto tempo = ContactList{ length_ }; for (auto i = 0u; i < size_; i++) { if (contacts_[i] == data) { tempo.Append(data); //the extraction ContactDeleter(i); for (auto j = size_; j > i; j--) { contacts_[j - 1] = contacts_[j]; } } } size_--; } template void ContactList::InsertAfter(const C& data, const C& after) { if (Empty()) Append(data); return; if (Full()) ContactDoubler(); if (after == contacts_[0]) { for (auto i = 1u; i < size_; i++) { contacts_[i + 1] = contacts_[i]; } contacts_[1] = data; size_++; return; } if (after == contacts_[size_ - 1]) { contacts_[size_] = data; size_++; return; } else { for (auto i = size_-1; i>0; i--) { if (contacts_[i] != after) { contacts_[i + 1] = contacts_[i]; } } for (auto j = 0u; j < size_; j++) { if (contacts_[j] == after) { contacts_[j + 1] = data; } }size_++; return; } } template void ContactList::InsertBefore(const C& data, const C& before) { if (Empty()) Append(data); return; bool found = false; for (auto i = 0u; i < size_ ; i++) { found = true; if (contacts_[i] == before) { switch (i) { default: auto temp = ContactList{ length_ }; for (auto j = 0u; j < i; ++j) { temp.Append(contacts_[j]); } temp.Append(data); for (auto k = i; k < size_; ++k) { temp.Append(contacts_[k]); } delete[] contacts_; contacts_ = nullptr; *this = std::move(temp); } } } if (!found) { cout << "Error: Before data not found" << endl; } } template void ContactList::Clear() { size_ = 0; length_ = 0; delete[] contacts_; contacts_ = nullptr; } template void ContactList::ContactDeleter(const size_t& size) { contacts_[size].SetFirstName(nullptr); contacts_[size].SetLastName(nullptr); contacts_[size].SetEmail(nullptr); contacts_[size].SetStreet(nullptr); contacts_[size].SetState(nullptr); contacts_[size].SetCity(nullptr); contacts_[size].SetZip(0); } template void ContactList::DeleteContact(const size_t& choice) { ContactDeleter(choice); for (auto i = choice+1; i C& ContactList::Last() { return contacts_[size_-1]; } template C ContactList::Last() const { return contacts_[size_-1]; } template C& ContactList::First() { return contacts_[0]; } template C ContactList::First() const { return contacts_[0]; } template void ContactList::ContactDoubler() { auto temp = ContactList{ length_ * 2 }; for (auto i = 0u; i <= size_; ++i) { temp.Append(contacts_[i]); } delete[] contacts_; contacts_ = nullptr; *this = std::move(temp); size_--; } template C& ContactList::operator[](const int& index) { if (index < 0 || index >= static_cast(length_)) { Contact EmptyContact; cout << "The index exceeds the array length!!" << endl; return EmptyContact; } return contacts_[index]; } template C ContactList::operator[](const int& index) const { if (index < 0 || index >= static_cast(size_)) { cout << "The index exceeds the array length!!" << endl; return NULL; } return contacts_[index]; } template ContactList::operator bool() const { bool var = contacts_ != nullptr; return (var); } template bool ContactList::operator==(const ContactList& rhs) const { if (&contacts_ == &rhs.contacts_) return true; if (&size_ != &rhs.size_) return false; if (&length_ != &rhs.length_) return false; for (auto i = 0u; i < size_; ++i) { if (contacts_[i] != rhs.contacts_[i]) return false; } return true; } template bool ContactList::Empty() const { return size_ == 0; } template bool ContactList::Full() const { if (size_ < length_) return false; return true; } }; #endif