From 08dfb0e1db1059d14bd1794ee072128ea04c43e7 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Mon, 6 Feb 2023 19:01:52 +0200 Subject: [PATCH] BAN: Cleanup LinkedList code --- BAN/include/BAN/LinkedList.h | 265 ++++++++++++++++++++++------------- 1 file changed, 169 insertions(+), 96 deletions(-) diff --git a/BAN/include/BAN/LinkedList.h b/BAN/include/BAN/LinkedList.h index 046c980a..a504ec95 100644 --- a/BAN/include/BAN/LinkedList.h +++ b/BAN/include/BAN/LinkedList.h @@ -7,26 +7,26 @@ namespace BAN { - template + template class LinkedListIterator; - template - class LinkedListConstIterator; template class LinkedList { - BAN_NON_COPYABLE(LinkedList); - BAN_NON_MOVABLE(LinkedList); - public: using size_type = size_t; using value_type = T; - using iterator = LinkedListIterator; - using const_iterator = LinkedListConstIterator; + using iterator = LinkedListIterator; + using const_iterator = LinkedListIterator; public: LinkedList() = default; - ~LinkedList(); + LinkedList(const LinkedList& other) { *this = other; } + LinkedList(LinkedList&& other) { *this = move(other); } + ~LinkedList() { clear(); } + + LinkedList& operator=(const LinkedList&); + LinkedList& operator=(LinkedList&&); [[nodiscard]] ErrorOr push_back(const T&); [[nodiscard]] ErrorOr push_back(T&&); @@ -41,8 +41,8 @@ namespace BAN void remove(const_iterator); void clear(); - iterator begin() { return iterator(m_data, false); } - const_iterator begin() const { return const_iterator(m_data, false); } + iterator begin() { return iterator(m_data, empty()); } + const_iterator begin() const { return const_iterator(m_data, empty()); } iterator end() { return iterator(m_last, true); } const_iterator end() const { return const_iterator(m_last, true); } @@ -68,11 +68,11 @@ namespace BAN Node* m_last = nullptr; size_type m_size = 0; - friend class LinkedListIterator; - friend class LinkedListConstIterator; + friend class LinkedListIterator; + friend class LinkedListIterator; }; - template + template class LinkedListIterator { public: @@ -80,111 +80,77 @@ namespace BAN public: LinkedListIterator() = default; - LinkedListIterator(const LinkedListIterator& other) : m_current(other.m_current), m_past_end(other.m_past_end) {} - LinkedListIterator& operator++() - { - ASSERT(m_current); - ASSERT(m_current->next || !m_past_end); - if (m_current->next) - m_current = m_current->next; - else - m_past_end = true; - return *this; - } - LinkedListIterator& operator--() - { - ASSERT(m_current); - ASSERT(m_current->prev || m_past_end); - if (m_past_end) - m_past_end = false; - else - m_current = m_current->prev; - return *this; - } - LinkedListIterator operator++(int) { auto temp = *this; ++(*this); return temp; } - LinkedListIterator operator--(int) { auto temp = *this; --(*this); return temp; } - T& operator*() { ASSERT(m_current); return m_current->value; } - const T& operator*() const { ASSERT(m_current); return m_current->value; } - bool operator==(const LinkedListIterator& other) const { return m_current && m_current == other.m_current && m_past_end == other.m_past_end; } - bool operator!=(const LinkedListIterator& other) const { return !(*this == other); } - operator bool() const { return m_current; } + template + LinkedListIterator(const LinkedListIterator&, enable_if_t* = 0); + + LinkedListIterator& operator++(); + LinkedListIterator& operator--(); + LinkedListIterator operator++(int); + LinkedListIterator operator--(int); + + template + enable_if_t operator*(); + const T& operator*() const; + + template + enable_if_t operator->(); + const T* operator->() const; + + bool operator==(const LinkedListIterator&) const; + bool operator!=(const LinkedListIterator&) const; + operator bool() const; + private: - LinkedListIterator(typename LinkedList::Node* node, bool past_end) : m_current(node), m_past_end(past_end) { } + LinkedListIterator(typename LinkedList::Node*, bool); + private: typename LinkedList::Node* m_current = nullptr; bool m_past_end = false; friend class LinkedList; - friend class LinkedListConstIterator; + friend class LinkedListIterator; }; - template - class LinkedListConstIterator - { - public: - using value_type = T; - public: - LinkedListConstIterator() = default; - LinkedListConstIterator(const LinkedListIterator& other) : m_current(other.m_current), m_past_end(other.m_past_end) {} - LinkedListConstIterator(const LinkedListConstIterator& other) : m_current(other.m_current), m_past_end(other.m_past_end) {} - LinkedListConstIterator& operator++() - { - ASSERT(m_current); - ASSERT(m_current->next || !m_past_end); - if (m_current->next) - m_current = m_current->next; - else - m_past_end = true; - return *this; - } - LinkedListConstIterator& operator--() - { - ASSERT(m_current); - ASSERT(m_current->prev || m_past_end); - if (m_past_end) - m_past_end = false; - else - m_current = m_current->prev; - return *this; - } - LinkedListConstIterator operator++(int) { auto temp = *this; ++(*this); return temp; } - LinkedListConstIterator operator--(int) { auto temp = *this; --(*this); return temp; } - const T& operator*() const { ASSERT(m_current); return m_current->value; } - bool operator==(const LinkedListConstIterator& other) const { return m_current && m_current == other.m_current && m_past_end == other.m_past_end; } - bool operator!=(const LinkedListConstIterator& other) const { return !(*this == other); } - operator bool() const { return m_current; } - private: - LinkedListConstIterator(typename LinkedList::Node* node, bool past_end) : m_current(node), m_past_end(past_end) {} - private: - typename LinkedList::Node* m_current = nullptr; - bool m_past_end = false; - - friend class LinkedList; - }; template - LinkedList::~LinkedList() + LinkedList& LinkedList::operator=(const LinkedList& other) { clear(); + for (const T& elem : other) + MUST(push_back(elem)); + return *this; + } + + template + LinkedList& LinkedList::operator=(LinkedList&& other) + { + clear(); + m_data = other.m_data; + m_last = other.m_last; + m_size = other.m_size; + other.m_data = nullptr; + other.m_last = nullptr; + other.m_size = 0; + return *this; } template ErrorOr LinkedList::push_back(const T& value) { - return push_back(Move(T(value))); + return push_back(move(T(value))); } template ErrorOr LinkedList::push_back(T&& value) { - return insert(end(), Move(value)); + return insert(end(), move(value)); } template ErrorOr LinkedList::insert(const_iterator iter, const T& value) { - return insert(iter, Move(T(value))); + return insert(iter, move(T(value))); } template @@ -234,7 +200,7 @@ namespace BAN template void LinkedList::remove(const_iterator iter) { - ASSERT(m_size > 0); + ASSERT(!empty() && iter); Node* node = iter.m_current; Node* prev = node->prev; Node* next = node->next; @@ -264,28 +230,28 @@ namespace BAN template const T& LinkedList::back() const { - ASSERT(m_size > 0); + ASSERT(!empty()); return *const_iterator(m_last); } template T& LinkedList::back() { - ASSERT(m_size > 0); + ASSERT(!empty()); return *iterator(m_last); } template const T& LinkedList::front() const { - ASSERT(m_size > 0); + ASSERT(!empty()); return *const_iterator(m_data); } template T& LinkedList::front() { - ASSERT(m_size > 0); + ASSERT(!empty()); return *iterator(m_data); } @@ -310,4 +276,111 @@ namespace BAN return node; } + + + template + template + LinkedListIterator::LinkedListIterator(const LinkedListIterator& other, enable_if_t*) + : m_current(other.m_current) + , m_past_end(other.m_past_end) + { + } + + template + LinkedListIterator::LinkedListIterator(typename LinkedList::Node* node, bool past_end) + : m_current(node), + m_past_end(past_end) + { + } + + template + LinkedListIterator& LinkedListIterator::operator++() + { + ASSERT(m_current); + ASSERT(m_current->next || !m_past_end); + if (m_current->next) + m_current = m_current->next; + else + m_past_end = true; + return *this; + } + + template + LinkedListIterator& LinkedListIterator::operator--() + { + ASSERT(m_current); + ASSERT(m_current->prev || m_past_end); + if (m_past_end) + m_past_end = false; + else + m_current = m_current->prev; + return *this; + } + + template + LinkedListIterator LinkedListIterator::operator++(int) + { + auto temp = *this; + ++(*this); + return temp; + } + + template + LinkedListIterator LinkedListIterator::operator--(int) + { + auto temp = *this; + --(*this); + return temp; + } + + template + template + enable_if_t LinkedListIterator::operator*() + { + ASSERT(m_current); + return m_current->value; + } + + template + const T& LinkedListIterator::operator*() const + { + ASSERT(m_current); + return m_current->value; + } + + template + template + enable_if_t LinkedListIterator::operator->() + { + ASSERT(m_current); + return &m_current->value; + } + + template + const T* LinkedListIterator::operator->() const + { + ASSERT(m_current); + return &m_current->value; + } + + template + bool LinkedListIterator::operator==(const LinkedListIterator& other) const + { + if (m_current != other.m_current) + return false; + return m_past_end == other.m_past_end; + } + + template + bool LinkedListIterator::operator!=(const LinkedListIterator& other) const + { + return !(*this == other); + } + + template + LinkedListIterator::operator bool() const + { + return m_current; + } + } \ No newline at end of file