From 55a003a698536752953cfc6694b3386addbede82 Mon Sep 17 00:00:00 2001 From: Christopher Durand Date: Sun, 14 May 2023 00:20:55 +0200 Subject: [PATCH] [container] Implement DoublyLinkedList as std::list --- src/modm/container/doubly_linked_list.hpp | 196 ++++++--------- .../container/doubly_linked_list_impl.hpp | 224 ------------------ .../doubly_linked_list_iterator_impl.hpp | 178 -------------- 3 files changed, 66 insertions(+), 532 deletions(-) delete mode 100644 src/modm/container/doubly_linked_list_impl.hpp delete mode 100644 src/modm/container/doubly_linked_list_iterator_impl.hpp diff --git a/src/modm/container/doubly_linked_list.hpp b/src/modm/container/doubly_linked_list.hpp index ecd73abb61..7d38df0479 100644 --- a/src/modm/container/doubly_linked_list.hpp +++ b/src/modm/container/doubly_linked_list.hpp @@ -4,6 +4,7 @@ * Copyright (c) 2012, Niklas Hauser * Copyright (c) 2013, Sascha Schade * Copyright (c) 2014, Daniel Krebs + * Copyright (c) 2023, Christopher Durand * * This file is part of the modm project. * @@ -16,9 +17,7 @@ #ifndef MODM_DOUBLY_LINKED_LIST_HPP #define MODM_DOUBLY_LINKED_LIST_HPP -#include -#include -#include +#include namespace modm { @@ -30,153 +29,87 @@ namespace modm * \author Fabian Greif * \ingroup modm_container */ - template > + template > class DoublyLinkedList { public: - DoublyLinkedList(const Allocator& allocator = Allocator()); + using const_iterator = std::list::const_iterator; + using iterator = std::list::iterator; - ~DoublyLinkedList(); + DoublyLinkedList(const Allocator& allocator = Allocator()) + : data_(allocator) + {} /// check if there are any nodes in the list - inline bool - isEmpty() const; + bool + isEmpty() const + { + return data_.empty(); + } - /** - * \brief Get number of items in the list - * - * Very slow for a long list as it needs to iterate through all - * items in the list. - */ + /// Get number of items in the list std::size_t - getSize() const; + getSize() const + { + return data_.size(); + } /// Insert in front bool - prepend(const T& value); + prepend(const T& value) + { + data_.push_front(value); + return true; + } /// Insert at the end of the list void - append(const T& value); + append(const T& value) + { + data_.push_back(value); + } /// Remove the first entry void - removeFront(); + removeFront() + { + data_.pop_front(); + } void - removeBack(); + removeBack() + { + data_.pop_back(); + } /** * \return the first node in the list */ - inline const T& - getFront() const; + const T& + getFront() const + { + return data_.front(); + } /** * \return the last node in the list */ - inline const T& - getBack() const; - - protected: - struct Node + const T& + getBack() const { - T value; - - Node *previous; - Node *next; - }; - - // The stored instance is not actually of type Allocator. Instead we - // rebind the type to Allocator>. Node is not the same - // size as T (it's one pointer larger), and specializations on T may go - // unused because Node is being bound instead. - typedef typename Allocator::template rebind< Node >::other NodeAllocator; - - NodeAllocator nodeAllocator; - - Node *front; - Node *back; + return data_.back(); + } public: - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wdeprecated-declarations" - /** - * \brief Forward iterator - * - * \todo decrement operator doesn't work correctly - */ - class iterator : public std::iterator - { - friend class DoublyLinkedList; - friend class const_iterator; - - public: - /// Default constructor - iterator(); - iterator(const iterator& other); - - iterator& operator = (const iterator& other); - iterator& operator ++ (); - iterator& operator -- (); - bool operator == (const iterator& other) const; - bool operator != (const iterator& other) const; - T& operator * (); - T* operator -> (); - - private: - iterator(Node* node); - - Node* node; - }; - /** - * \brief forward const iterator - * - * \todo decrement operator doesn't work correctly - */ - class const_iterator : public std::iterator - { - friend class DoublyLinkedList; - - public: - /// Default constructor - const_iterator(); - - /** - * \brief Copy constructor - * - * Used to convert a normal iterator to a const iterator. - * The other way is not possible. - */ - const_iterator(const iterator& other); - - /** - * \brief Copy constructor - */ - const_iterator(const const_iterator& other); - - const_iterator& operator = (const const_iterator& other); - const_iterator& operator ++ (); - const_iterator& operator -- (); - bool operator == (const const_iterator& other) const; - bool operator != (const const_iterator& other) const; - const T& operator * () const; - const T* operator -> () const; - - private: - const_iterator(const Node* node); - - const Node* node; - }; - #pragma GCC diagnostic pop - - /** - * Returns a read/write iterator that points to the first element in the + * Returns a read/write iterator that points to the first element in the * list. Iteration is done in ordinary element order. */ iterator - begin(); + begin() + { + return data_.begin(); + } /** * Returns a read-only (constant) iterator that points to the @@ -184,7 +117,10 @@ namespace modm * element order. */ const_iterator - begin() const; + begin() const + { + return data_.begin(); + } /** * Returns a read/write iterator that points one past the last @@ -192,7 +128,10 @@ namespace modm * order. */ iterator - end(); + end() + { + return data_.end(); + } /** * Returns a read-only (constant) iterator that points one past @@ -200,7 +139,10 @@ namespace modm * element order. */ const_iterator - end() const; + end() const + { + return data_.end(); + } /** * Deletes element pointed to by iterator and returns an iterator @@ -209,20 +151,14 @@ namespace modm * Warning: you must not use the iterator after calling erase() */ iterator - erase(iterator position); + erase(iterator position) + { + return data_.erase(position); + } private: - friend class const_iterator; - friend class iterator; - - DoublyLinkedList(const DoublyLinkedList& other); - - DoublyLinkedList& - operator = (const DoublyLinkedList& other); + std::list data_; }; } -#include "doubly_linked_list_impl.hpp" -#include "doubly_linked_list_iterator_impl.hpp" - #endif // MODM_DOUBLY_LINKED_LIST_HPP diff --git a/src/modm/container/doubly_linked_list_impl.hpp b/src/modm/container/doubly_linked_list_impl.hpp deleted file mode 100644 index b386e79393..0000000000 --- a/src/modm/container/doubly_linked_list_impl.hpp +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright (c) 2009, Martin Rosekeit - * Copyright (c) 2009-2011, Fabian Greif - * Copyright (c) 2009, 2011, Thorsten Lajewski - * Copyright (c) 2012, Niklas Hauser - * Copyright (c) 2013, Sascha Schade - * Copyright (c) 2014, Daniel Krebs - * - * This file is part of the modm project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ -// ---------------------------------------------------------------------------- - -#ifndef MODM_DOUBLY_LINKED_LIST_HPP - #error "Don't include this file directly, use 'doubly_linked_list.hpp' instead" -#endif - -// ---------------------------------------------------------------------------- -template -modm::DoublyLinkedList::DoublyLinkedList(const Allocator& allocator) : - nodeAllocator(allocator), front(0), back(0) -{ -} - -template -modm::DoublyLinkedList::~DoublyLinkedList() -{ - while (this->front != 0) - { - Node *node = this->front; - this->front = this->front->next; - - Allocator::destroy(&node->value); - this->nodeAllocator.deallocate(node); - } -} - -template -bool -modm::DoublyLinkedList::isEmpty() const -{ - return (this->front == 0); -} - -template -std::size_t -modm::DoublyLinkedList::getSize() const -{ - std::size_t count = 0; - for (const_iterator it = this->begin(); it != this->end(); ++it) { - count++; - } - return count; -} - -// ---------------------------------------------------------------------------- -template -bool -modm::DoublyLinkedList::prepend(const T& value) -{ - // allocate memory for the new node and copy the value into it - Node *node = this->nodeAllocator.allocate(1); - Allocator::construct(&node->value, value); - - // hook the node into the list - node->next = this->front; - node->previous = 0; - - if (this->front == 0) - { - // node it the first entry - this->back = node; - } - else { - this->front->previous = node; - } - this->front = node; - - return true; -} - -template -void -modm::DoublyLinkedList::append(const T& value) -{ - // allocate memory for the new node and copy the value into it - Node *node = this->nodeAllocator.allocate(1); - Allocator::construct(&node->value, value); - - // hook the node into the list - node->next = 0; - node->previous = this->back; - - if (this->back == 0) - { - // first entry in the list - this->front = node; - } - else { - this->back->next = node; - } - this->back = node; -} - -// ---------------------------------------------------------------------------- -template -void -modm::DoublyLinkedList::removeFront() -{ - // remove node from the list - Node *node = this->front; - - if (this->front->next == 0) - { - // last entry in the list - this->front = 0; - this->back = 0; - } - else { - this->front = this->front->next; - this->front->previous = 0; - } - - // call destructor and free memory - Allocator::destroy(&node->value); - this->nodeAllocator.deallocate(node); -} - -template -void -modm::DoublyLinkedList::removeBack() -{ - // remove node from the list - Node *node = this->back; - - if (this->back->previous == 0) - { - // last entry in the list - this->front = 0; - this->back = 0; - } - else { - this->back = this->back->previous; - this->back->next = 0; - } - - // call destructor and free memory - Allocator::destroy(&node->value); - this->nodeAllocator.deallocate(node); -} - -// ---------------------------------------------------------------------------- -template -inline const T& -modm::DoublyLinkedList::getFront() const -{ - return this->front->value; -} - -template -inline const T& -modm::DoublyLinkedList::getBack() const -{ - return this->back->value; -} - -// ---------------------------------------------------------------------------- -template -typename modm::DoublyLinkedList::iterator -modm::DoublyLinkedList::begin() -{ - return iterator(this->front); -} - -template -typename modm::DoublyLinkedList::iterator -modm::DoublyLinkedList::end() -{ - return iterator(0); -} - -template -typename modm::DoublyLinkedList::const_iterator -modm::DoublyLinkedList::begin() const -{ - return const_iterator(this->front); -} - -template -typename modm::DoublyLinkedList::const_iterator -modm::DoublyLinkedList::end() const -{ - return const_iterator(0); -} - -template -typename modm::DoublyLinkedList::iterator -modm::DoublyLinkedList::erase(iterator position) -{ - - if(position.node->previous == 0) { - this->removeFront(); - return this->begin(); - } - - if(position.node->next == 0) { - this->removeBack(); - return this->end(); - } - - position.node->previous->next = position.node->next; - position.node->next->previous = position.node->previous; - - Node* next = position.node->next; - - Allocator::destroy(&(position.node->value)); - this->nodeAllocator.deallocate(position.node); - - return iterator(next); - -} diff --git a/src/modm/container/doubly_linked_list_iterator_impl.hpp b/src/modm/container/doubly_linked_list_iterator_impl.hpp deleted file mode 100644 index a2cd66b61e..0000000000 --- a/src/modm/container/doubly_linked_list_iterator_impl.hpp +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright (c) 2010, Fabian Greif - * Copyright (c) 2012, Niklas Hauser - * Copyright (c) 2013, Sascha Schade - * - * This file is part of the modm project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ -// ---------------------------------------------------------------------------- - -#ifndef MODM_DOUBLY_LINKED_LIST_HPP - #error "Don't include this file directly, use 'doubly_linked_list.hpp' instead" -#endif - -// ---------------------------------------------------------------------------- -// Iterators -// ---------------------------------------------------------------------------- - -// const iterator -template -modm::DoublyLinkedList::const_iterator::const_iterator() : - node(0) -{ -} - -template -modm::DoublyLinkedList::const_iterator::const_iterator( - const Node* node) : - node(node) -{ -} - -template -modm::DoublyLinkedList::const_iterator::const_iterator( - const iterator& other) : - node(other.node) -{ -} - -template -modm::DoublyLinkedList::const_iterator::const_iterator( - const const_iterator& other) : - node(other.node) -{ -} - -template -typename modm::DoublyLinkedList::const_iterator& -modm::DoublyLinkedList::const_iterator::operator = ( - const const_iterator& other) -{ - this->node = other.node; - return *this; -} - -template -typename modm::DoublyLinkedList::const_iterator& -modm::DoublyLinkedList::const_iterator::operator ++ () -{ - this->node = this->node->next; - return *this; -} - -template -typename modm::DoublyLinkedList::const_iterator& -modm::DoublyLinkedList::const_iterator::operator -- () -{ - this->node = this->node->previous; - return *this; -} - -template -bool -modm::DoublyLinkedList::const_iterator::operator == ( - const const_iterator& other) const -{ - return (node == other.node); -} - -template -bool -modm::DoublyLinkedList::const_iterator::operator != ( - const const_iterator& other) const -{ - return (node != other.node); -} - -template -const T& -modm::DoublyLinkedList::const_iterator::operator * () const -{ - return this->node->value; -} - -template -const T* -modm::DoublyLinkedList::const_iterator::operator -> () const -{ - return &this->node->value; -} - - -// iterator -template -modm::DoublyLinkedList::iterator::iterator() : - node(0) -{ -} - -template -modm::DoublyLinkedList::iterator::iterator(Node* node) : - node(node) -{ -} - -template -modm::DoublyLinkedList::iterator::iterator( - const iterator& other) : - node(other.node) -{ -} - -template -typename modm::DoublyLinkedList::iterator& -modm::DoublyLinkedList::iterator::operator = (const iterator& other) -{ - this->node = other.node; - return *this; -} - -template -typename modm::DoublyLinkedList::iterator& -modm::DoublyLinkedList::iterator::operator ++ () -{ - this->node = this->node->next; - return *this; -} - -template -typename modm::DoublyLinkedList::iterator& -modm::DoublyLinkedList::iterator::operator -- () -{ - this->node = this->node->previous; - return *this; -} - -template -bool -modm::DoublyLinkedList::iterator::operator == ( - const iterator& other) const -{ - return (node == other.node); -} - -template -bool -modm::DoublyLinkedList::iterator::operator != ( - const iterator& other) const -{ - return (node != other.node); -} - -template -T& -modm::DoublyLinkedList::iterator::operator * () -{ - return this->node->value; -} - -template -T* -modm::DoublyLinkedList::iterator::operator -> () -{ - return &this->node->value; -}