diff --git a/src/modm/container/doubly_linked_list.hpp b/src/modm/container/doubly_linked_list.hpp index ecd73abb61..a15f67b423 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,100 @@ 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; + using Size = std::size_t; - ~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); + bool + append(const T& value) + { + data_.push_back(value); + return true; + } /// Remove the first entry void - removeFront(); + removeFront() + { + data_.pop_front(); + } void - removeBack(); - - /** - * \return the first node in the list - */ - inline const T& - getFront() const; - - /** - * \return the last node in the list - */ - inline const T& - getBack() const; - - protected: - struct Node + removeBack() { - T value; - - Node *previous; - Node *next; - }; + data_.pop_back(); + } - // 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; + T& + getFront() + { + return data_.front(); + } - public: - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wdeprecated-declarations" /** - * \brief Forward iterator - * - * \todo decrement operator doesn't work correctly + * \return the first node in the list */ - class iterator : public std::iterator + const T& + getFront() const { - 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); + return data_.front(); + } - Node* node; - }; + T& + getBack() + { + return data_.back(); + } /** - * \brief forward const iterator - * - * \todo decrement operator doesn't work correctly + * \return the last node in the list */ - 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 + const T& + getBack() const + { + return data_.back(); + } /** - * 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 +130,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 +141,10 @@ namespace modm * order. */ iterator - end(); + end() + { + return data_.end(); + } /** * Returns a read-only (constant) iterator that points one past @@ -200,7 +152,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 +164,36 @@ namespace modm * Warning: you must not use the iterator after calling erase() */ iterator - erase(iterator position); - - private: - friend class const_iterator; - friend class iterator; + erase(iterator position) + { + if (position != data_.end()) { + return data_.erase(position); + } else { + return data_.end(); + } + } - DoublyLinkedList(const DoublyLinkedList& other); + /** + * Insert data after position iterator. + * + * This behavior is compatible with modm::LinkedList but different + * compared to std::list which inserts before the position iterator + * argument. + */ + bool + insert(iterator position, const T& value) + { + if (position == data_.end()) { + data_.push_back(value); + } else { + data_.insert(std::next(position), value); + } + return true; + } - DoublyLinkedList& - operator = (const DoublyLinkedList& other); + private: + 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; -} diff --git a/src/modm/container/dynamic_array.hpp b/src/modm/container/dynamic_array.hpp index 24b1b1a615..6804e5fa84 100644 --- a/src/modm/container/dynamic_array.hpp +++ b/src/modm/container/dynamic_array.hpp @@ -4,6 +4,7 @@ * Copyright (c) 2013, Martin Rosekeit * Copyright (c) 2014, Daniel Krebs * Copyright (c) 2015, Kevin Läufer + * Copyright (c) 2023, Christopher Durand * * This file is part of the modm project. * @@ -16,10 +17,11 @@ #ifndef MODM_DYNAMIC_ARRAY_HPP #define MODM_DYNAMIC_ARRAY_HPP +#include #include -#include #include #include +#include namespace modm { @@ -44,11 +46,14 @@ namespace modm * \author Fabian Greif * \ingroup modm_container */ - template > + template > class DynamicArray { public: - typedef std::size_t SizeType; + using SizeType = std::size_t; + using const_iterator = std::vector::const_iterator; + using iterator = std::vector::iterator; + public: /** * \brief Default constructor @@ -56,7 +61,9 @@ namespace modm * Constructs an empty dynamic array, with no content and a * size of zero. */ - DynamicArray(const Allocator& allocator = Allocator()); + DynamicArray(const Allocator& allocator = Allocator()) + : data_(allocator) + {} /** * \brief Allocation constructor @@ -64,7 +71,11 @@ namespace modm * Construct a dynamic array of given capacity. The array will still * be empty. */ - DynamicArray(SizeType n, const Allocator& allocator = Allocator()); + DynamicArray(SizeType n, const Allocator& allocator = Allocator()) + : data_(allocator) + { + data_.reserve(n); + } /** * \brief Repetitive sequence constructor @@ -74,7 +85,9 @@ namespace modm * Initializes the dynamic array with its content set to a * repetition, n times, of copies of value. */ - DynamicArray(SizeType n, const T& value, const Allocator& allocator = Allocator()); + DynamicArray(SizeType n, const T& value, const Allocator& allocator = Allocator()) + : data_(n, value, allocator) + {} /** * \brief Initializer List constructor @@ -82,15 +95,9 @@ namespace modm * Construct a dynamic array that holds the values specified in the * initialize list */ - DynamicArray(std::initializer_list init, - const Allocator& allocator = Allocator()); - - DynamicArray(const DynamicArray& other); - - ~DynamicArray(); - - DynamicArray& - operator = (const DynamicArray& other); + DynamicArray(std::initializer_list init, const Allocator& allocator = Allocator()) + : data_(init, allocator) + {} /** * \brief Test whether dynamic array is empty @@ -98,10 +105,10 @@ namespace modm * Returns whether the dynamic array container is empty, i.e. whether * its size is 0. */ - inline bool + bool isEmpty() const { - return (this->size == 0); + return data_.empty(); } /** @@ -109,10 +116,10 @@ namespace modm * * Returns the number of elements in the container. */ - inline SizeType + SizeType getSize() const { - return this->size; + return data_.size(); } /** @@ -129,10 +136,10 @@ namespace modm * * \see getSize() */ - inline SizeType + SizeType getCapacity() const { - return this->capacity; + return data_.capacity(); } /** @@ -149,7 +156,10 @@ namespace modm * \see getCapacity() */ void - reserve(SizeType n); + reserve(SizeType n) + { + data_.reserve(n); + } /** * \brief Remove all elements and set capacity to zero @@ -160,7 +170,11 @@ namespace modm * \warning This will discard all the items in the container */ void - clear(); + clear() + { + data_.clear(); + data_.shrink_to_fit(); + } /** * \brief Remove all elements @@ -168,7 +182,10 @@ namespace modm * Keeps the capacity at its current level. */ void - removeAll(); + removeAll() + { + data_.clear(); + } /** * \brief Access element @@ -184,7 +201,7 @@ namespace modm inline T& operator [](SizeType index) { - return this->values[index]; + return data_[index]; } /** @@ -196,7 +213,7 @@ namespace modm inline const T& operator [](SizeType index) const { - return this->values[index]; + return data_[index]; } /** @@ -213,7 +230,10 @@ namespace modm * iterators, references and pointers. */ void - append(const T& value); + append(const T& value) + { + data_.push_back(value); + } /** * \brief Delete last element @@ -225,7 +245,10 @@ namespace modm * This calls the removed element's destructor. */ void - removeBack(); + removeBack() + { + data_.pop_back(); + } // TODO insert implementation //void @@ -234,106 +257,36 @@ namespace modm inline const T& getFront() const { - return this->values[0]; + return data_.front(); } inline T& getFront() { - return this->values[0]; + return data_.front(); } inline const T& getBack() const { - return this->values[this->size - 1]; + return data_.back(); } inline T& getBack() { - return this->values[this->size - 1]; + return data_.back(); } - public: - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wdeprecated-declarations" - /** - * \brief Forward iterator - */ - class iterator : public std::iterator - { - friend class DynamicArray; - 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; - bool operator < (const iterator& other) const; - bool operator > (const iterator& other) const; - T& operator * (); - T* operator -> (); - - private: - iterator(DynamicArray* parent, SizeType index); - - DynamicArray *parent; - SizeType index; - }; - - /** - * \brief forward const iterator - */ - class const_iterator : public std::iterator - { - friend class DynamicArray; - - 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 DynamicArray* parent, SizeType index); - - const DynamicArray *parent; - SizeType index; - }; - #pragma GCC diagnostic pop - /** * 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 @@ -341,7 +294,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 @@ -349,7 +305,10 @@ namespace modm * order. */ iterator - end(); + end() + { + return data_.end(); + } /** * Returns a read-only (constant) iterator that points one past @@ -357,7 +316,10 @@ namespace modm * element order. */ const_iterator - end() const; + end() const + { + return data_.end(); + } /** * Returns a read/write iterator that points to the first element @@ -365,7 +327,10 @@ namespace modm * last element. */ iterator - find(const T& value); + find(const T& value) + { + return std::find(data_.begin(), data_.end(), value); + } /** * Returns a read-only (constant) iterator that points to the first @@ -373,29 +338,14 @@ namespace modm * the last element. */ const_iterator - find(const T& value) const; - - private: - friend class const_iterator; - friend class iterator; + find(const T& value) const + { + return std::find(data_.begin(), data_.end(), value); + } private: - /* - * Allocate a new buffer of size n and copy the elements from the - * old buffer to the new buffer. - */ - void - relocate(SizeType n); - - Allocator allocator; - - SizeType size; - SizeType capacity; - T* values; + std::vector data_; }; } -#include "dynamic_array_impl.hpp" -#include "dynamic_array_iterator_impl.hpp" - #endif // MODM_DYNAMIC_ARRAY_HPP diff --git a/src/modm/container/dynamic_array_impl.hpp b/src/modm/container/dynamic_array_impl.hpp deleted file mode 100644 index 544764456a..0000000000 --- a/src/modm/container/dynamic_array_impl.hpp +++ /dev/null @@ -1,245 +0,0 @@ -/* - * Copyright (c) 2009-2010, Martin Rosekeit - * Copyright (c) 2009-2011, Fabian Greif - * Copyright (c) 2012, Niklas Hauser - * Copyright (c) 2014, Daniel Krebs - * Copyright (c) 2015, Kevin Läufer - * - * 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_DYNAMIC_ARRAY_HPP - #error "Don't include this file directly, use 'vector.hpp' instead" -#endif - -// ---------------------------------------------------------------------------- -template -modm::DynamicArray::DynamicArray(const Allocator& alloc) : - allocator(alloc), - size(0), capacity(0), values(0) -{ -} - -template -modm::DynamicArray::DynamicArray(SizeType n, const Allocator& alloc) : - allocator(alloc), size(0), capacity(n) -{ - this->values = this->allocator.allocate(n); -} - -template -modm::DynamicArray::DynamicArray(SizeType n, const T& value, const Allocator& alloc) : - allocator(alloc), size(n), capacity(n) -{ - this->values = this->allocator.allocate(n); - for (SizeType i = 0; i < n; ++i) { - allocator.construct(&this->values[i], value); - } -} - -template -modm::DynamicArray::DynamicArray(std::initializer_list init, const Allocator& alloc) : - allocator(alloc), size(init.size()), capacity(init.size()) -{ - this->values = this->allocator.allocate(init.size()); - std::size_t ii = 0; - for (auto value : init) { - allocator.construct(&this->values[ii], value); - ++ii; - } -} - -template -modm::DynamicArray::DynamicArray(const DynamicArray& other) : - allocator(other.allocator), - size(other.size), capacity(other.capacity) -{ - this->values = allocator.allocate(other.capacity); - for (SizeType i = 0; i < this->size; ++i) { - this->allocator.construct(&this->values[i], other.values[i]); - } -} - -template -modm::DynamicArray::~DynamicArray() -{ - for (SizeType i = 0; i < this->size; ++i) { - this->allocator.destroy(&this->values[i]); - } - this->allocator.deallocate(this->values); -} - -template -modm::DynamicArray& -modm::DynamicArray::operator = (const DynamicArray& other) -{ - for (SizeType i = 0; i < this->size; ++i) { - this->allocator.destroy(&this->values[i]); - } - this->allocator.deallocate(this->values); - - this->allocator = other.allocator; - this->size = other.size; - this->capacity = other.capacity; - this->values = this->allocator.allocate(this->capacity); - - for (SizeType i = 0; i < this->size; ++i) { - this->allocator.construct(&this->values[i], other.values[i]); - } - return *this; -} - -// ---------------------------------------------------------------------------- -template -void -modm::DynamicArray::reserve(SizeType n) -{ - if (n <= (this->capacity - this->size)) { - // capacity is already big enough, nothing to do. - return; - } - - // allocate new memory - this->relocate(this->size + n); -} - -// ---------------------------------------------------------------------------- -template -void -modm::DynamicArray::clear() -{ - for (SizeType i = 0; i < this->size; ++i) { - this->allocator.destroy(&this->values[i]); - } - this->allocator.deallocate(this->values); - this->values = 0; - - this->size = 0; - this->capacity = 0; -} - -// ---------------------------------------------------------------------------- -template -void -modm::DynamicArray::removeAll() -{ - for (SizeType i = 0; i < this->size; ++i) { - this->allocator.destroy(&this->values[i]); - } - this->size = 0; -} - -// ---------------------------------------------------------------------------- -template -void -modm::DynamicArray::append(const T& value) -{ - if (this->capacity == this->size) - { - // allocate new memory if no more space is left - SizeType n = this->size + (this->size + 1) / 2; - if (n == 0) { - n = 1; - } - this->relocate(n); - } - - this->allocator.construct(&this->values[this->size], value); - ++this->size; -} - -// ---------------------------------------------------------------------------- -template -void -modm::DynamicArray::removeBack() -{ - --this->size; - - // call destructor - this->allocator.destroy(&this->values[this->size]); -} - -// ---------------------------------------------------------------------------- -template -void -modm::DynamicArray::relocate(SizeType n) -{ - this->capacity = n; - - T* newBuffer = allocator.allocate(n); - for (SizeType i = 0; i < this->size; ++i) { - this->allocator.construct(&newBuffer[i], this->values[i]); - this->allocator.destroy(&this->values[i]); - } - this->allocator.deallocate(this->values); - - this->values = newBuffer; -} - -// ---------------------------------------------------------------------------- -template -typename modm::DynamicArray::iterator -modm::DynamicArray::begin() -{ - return iterator(this, 0); -} - -template -typename modm::DynamicArray::iterator -modm::DynamicArray::end() -{ - return iterator(this, size); -} - -template -typename modm::DynamicArray::iterator -modm::DynamicArray::find(const T& value) -{ - modm::DynamicArray::iterator iter = this->begin(); - - for(; iter != this->end(); ++iter) - { - if((*iter) == value) { - return iter; - } - } - - // return end() if value has not been found - return iter; -} - -template -typename modm::DynamicArray::const_iterator -modm::DynamicArray::begin() const -{ - return const_iterator(this, 0); -} - -template -typename modm::DynamicArray::const_iterator -modm::DynamicArray::end() const -{ - return const_iterator(this, size); -} - -template -typename modm::DynamicArray::const_iterator -modm::DynamicArray::find(const T& value) const -{ - modm::DynamicArray::const_iterator iter = this->begin(); - - for(; iter != this->end(); ++iter) - { - if((*iter) == value) { - return iter; - } - } - - // return end() if value has not been found - return iter; -} diff --git a/src/modm/container/dynamic_array_iterator_impl.hpp b/src/modm/container/dynamic_array_iterator_impl.hpp deleted file mode 100644 index 885ffbd98a..0000000000 --- a/src/modm/container/dynamic_array_iterator_impl.hpp +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright (c) 2010-2011, Fabian Greif - * 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_DYNAMIC_ARRAY_HPP - #error "Don't include this file directly, use 'dynamic_array.hpp' instead" -#endif - -// ---------------------------------------------------------------------------- -// Iterators -// ---------------------------------------------------------------------------- - -// const iterator -template -modm::DynamicArray::const_iterator::const_iterator() : - parent(0), - index(0) -{ -} - -template -modm::DynamicArray::const_iterator::const_iterator( - const DynamicArray* inParent, SizeType inIndex) : - parent(inParent), - index(inIndex) -{ -} - -template -modm::DynamicArray::const_iterator::const_iterator( - const iterator& other) : - parent(other.parent), - index(other.index) -{ -} - -template -modm::DynamicArray::const_iterator::const_iterator( - const const_iterator& other) : - parent(other.parent), - index(other.index) -{ -} - -template -typename modm::DynamicArray::const_iterator& -modm::DynamicArray::const_iterator::operator = ( - const const_iterator& other) -{ - this->parent = other.parent; - this->index = other.index; - return *this; -} - -template -typename modm::DynamicArray::const_iterator& -modm::DynamicArray::const_iterator::operator ++ () -{ - ++this->index; - return *this; -} - -template -typename modm::DynamicArray::const_iterator& -modm::DynamicArray::const_iterator::operator -- () -{ - --this->index; - return *this; -} - -template -bool -modm::DynamicArray::const_iterator::operator == ( - const const_iterator& other) const -{ - return ((parent == other.parent) && - (index == other.index)); -} - -template -bool -modm::DynamicArray::const_iterator::operator != ( - const const_iterator& other) const -{ - return ((parent != other.parent) || - (index != other.index)); -} - -template -const T& -modm::DynamicArray::const_iterator::operator * () const -{ - return parent->values[index]; -} - -template -const T* -modm::DynamicArray::const_iterator::operator -> () const -{ - return &parent->values[index]; -} - -// ---------------------------------------------------------------------------- -// iterator -template -modm::DynamicArray::iterator::iterator() : - parent(0), - index(0) -{ -} - -template -modm::DynamicArray::iterator::iterator( - DynamicArray* inParent, SizeType inIndex) : - parent(inParent), - index(inIndex) -{ -} - -template -modm::DynamicArray::iterator::iterator(const iterator& other) : - parent(other.parent), - index(other.index) -{ -} - -template -typename modm::DynamicArray::iterator& -modm::DynamicArray::iterator::operator = (const iterator& other) -{ - this->parent = other.parent; - this->index = other.index; - return *this; -} - -template -typename modm::DynamicArray::iterator& -modm::DynamicArray::iterator::operator ++ () -{ - ++index; - return *this; -} - -template -typename modm::DynamicArray::iterator& -modm::DynamicArray::iterator::operator -- () -{ - --index; - return *this; -} - -template -bool -modm::DynamicArray::iterator::operator == ( - const iterator& other) const -{ - return ((parent == other.parent) && - (index == other.index)); -} - -template -bool -modm::DynamicArray::iterator::operator != ( - const iterator& other) const -{ - return ((parent != other.parent) || - (index != other.index)); -} - -template -bool -modm::DynamicArray::iterator::operator < ( - const iterator& other) const -{ - return ((parent == other.parent) && - (index < other.index)); -} - -template -bool -modm::DynamicArray::iterator::operator > ( - const iterator& other) const -{ - return ((parent == other.parent) && - (index > other.index)); -} - - -template -T& -modm::DynamicArray::iterator::operator * () -{ - return parent->values[index]; -} - -template -T* -modm::DynamicArray::iterator::operator -> () -{ - return &parent->values[index]; -} diff --git a/src/modm/container/linked_list.hpp b/src/modm/container/linked_list.hpp index 2cb57e0fa9..56fed2548c 100644 --- a/src/modm/container/linked_list.hpp +++ b/src/modm/container/linked_list.hpp @@ -4,6 +4,7 @@ * Copyright (c) 2012, Niklas Hauser * Copyright (c) 2013-2014, Sascha Schade * Copyright (c) 2015, Kevin Läufer + * Copyright (c) 2023, Christopher Durand * * This file is part of the modm project. * @@ -16,9 +17,7 @@ #ifndef MODM_LINKED_LIST_HPP #define MODM_LINKED_LIST_HPP -#include -#include -#include +#include namespace modm { @@ -34,210 +33,31 @@ namespace modm * * \author Fabian Greif * \ingroup modm_container + * + * \todo TODO: implementated as doubly-linked list + * std::forward_list does not save both front and back pointers. + * This would make operations in xpcc very inefficient. */ - template > - class LinkedList + template > + class LinkedList : public DoublyLinkedList { public: - typedef std::size_t Size; - - public: - LinkedList(const Allocator& allocator = Allocator()); - - ~LinkedList(); - - /// check if there are any nodes in the list - inline bool - isEmpty() const; - - /** - * \brief Get number of elements - * - * \warning This method is slow because it has to iterate through - * all elements. - */ - std::size_t - getSize() const; - - /// Insert in front - bool - prepend(const T& value); - - /// Insert at the end of the list - bool - append(const T& value); - - /// Remove the first entry - void - removeFront(); - - /** - * \return the first node in the list - */ - inline const T& - getFront() const; - - inline T& - getFront(); + using DoublyLinkedList::DoublyLinkedList; + using iterator = DoublyLinkedList::iterator; - /** - * \return the last node in the list - */ - inline const T& - getBack() const; - - inline T& - getBack(); - - /** - * \brief Remove all elements form the list - */ - void - removeAll(); - - protected: - struct Node - { - T value; - 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; - - public: - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wdeprecated-declarations" - /** - * \brief Forward iterator - */ - class iterator : public std::iterator + iterator + remove(const iterator& position) { - friend class LinkedList; - friend class const_iterator; - - public: - /// Default constructor - iterator(); - iterator(const iterator& other); + return this->erase(position); + } - iterator& operator = (const iterator& other); - 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 - */ - class const_iterator : public std::iterator + void + removeAll() { - friend class LinkedList; - - public: - /// Default constructor - const_iterator(); - - /** - * \brief Copy construtor - * - * Used to convert a normal iterator to a const iterator. - * The other way is not possible. - */ - const_iterator(const iterator& other); - - /** - * \brief Copy construtor - */ - const_iterator(const const_iterator& other); - - const_iterator& operator = (const const_iterator& other); - 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(Node* node); - // TODO: this should acutally be a node that points to a const - // value, but since all access is const, this does not really make - // a difference - Node* node; - }; - #pragma GCC diagnostic pop - - /** - * Returns a read/write iterator that points to the first element in the - * list. Iteration is done in ordinary element order. - */ - iterator - begin(); - - /** - * Returns a read-only (constant) iterator that points to the - * first element in the list. Iteration is done in ordinary - * element order. - */ - const_iterator - begin() const; - - /** - * Returns a read/write iterator that points one past the last - * element in the list. Iteration is done in ordinary element - * order. - */ - iterator - end(); - - /** - * Returns a read-only (constant) iterator that points one past - * the last element in the list. Iteration is done in ordinary - * element order. - */ - const_iterator - end() const; - - /** - * \brief Erase element - * - * Removes a single element from the list container. - * This effectively reduces the list size by one, calling the element's - * destructor before. - */ - iterator - remove(const iterator& position); - - bool - insert(const_iterator pos, const T& value); - - private: - friend class const_iterator; - friend class iterator; - - LinkedList(const LinkedList& other); - - LinkedList& - operator = (const LinkedList& other); + while (!this->isEmpty()) { + this->removeFront(); + } + } }; } - -#include "linked_list_impl.hpp" -#include "linked_list_iterator_impl.hpp" - #endif // MODM_LINKED_LIST_HPP diff --git a/src/modm/container/linked_list_impl.hpp b/src/modm/container/linked_list_impl.hpp deleted file mode 100644 index 7716879fb4..0000000000 --- a/src/modm/container/linked_list_impl.hpp +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright (c) 2009, Martin Rosekeit - * Copyright (c) 2009, Thorsten Lajewski - * Copyright (c) 2009-2011, Fabian Greif - * Copyright (c) 2012, Niklas Hauser - * Copyright (c) 2013-2014, Sascha Schade - * Copyright (c) 2015, Kevin Läufer - * - * 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_LINKED_LIST_HPP - #error "Don't include this file directly, use 'linked_list.hpp' instead" -#endif - -// ---------------------------------------------------------------------------- -template -modm::LinkedList::LinkedList(const Allocator& allocator) : - nodeAllocator(allocator), front(0), back(0) -{ -} - -template -modm::LinkedList::~LinkedList() -{ - while (this->front != 0) - { - Node *node = this->front; - this->front = this->front->next; - - Allocator::destroy(&node->value); - this->nodeAllocator.deallocate(node); - } -} - -template -bool -modm::LinkedList::isEmpty() const -{ - return (this->front == 0); -} - -template -std::size_t -modm::LinkedList::getSize() const -{ - std::size_t count = 0; - for (const_iterator it = this->begin(); it != this->end(); ++it) { - count++; - } - return count; -} - -// ---------------------------------------------------------------------------- -template -bool -modm::LinkedList::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; - this->front = node; - - if (this->back == 0) { - // first entry in the list - this->back = node; - } - - return true; -} - -template -bool -modm::LinkedList::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; - if (this->front == 0) - { - // first entry in the list - this->front = node; - } - else { - this->back->next = node; - } - this->back = node; - - return true; -} - -template -bool -modm::LinkedList::insert(const_iterator pos, const T& value) -{ - // if pos is the `end` iterator - if(pos.node == nullptr) { - return this->append(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 = pos.node->next; - pos.node->next = node; - if(this->back == pos.node) { - this->back = node; - } - - return true; -} - -// ---------------------------------------------------------------------------- -template -void -modm::LinkedList::removeFront() -{ - // remove node from the list - Node *node = this->front; - if (this->front->next == 0) - { - // last entry in the list - this->back = 0; - this->front = 0; - } - else { - this->front = this->front->next; - } - - // call destructor and free memory - Allocator::destroy(&node->value); - this->nodeAllocator.deallocate(node); -} - -// ---------------------------------------------------------------------------- -template -inline const T& -modm::LinkedList::getFront() const -{ - return this->front->value; -} - -template -inline T& -modm::LinkedList::getFront() -{ - return this->front->value; -} - -template -inline const T& -modm::LinkedList::getBack() const -{ - return this->back->value; -} - -template -inline T& -modm::LinkedList::getBack() -{ - return this->back->value; -} - -// ---------------------------------------------------------------------------- -template -void -modm::LinkedList::removeAll() -{ - while (!this->isEmpty()) { - this->removeFront(); - } -} - -// ---------------------------------------------------------------------------- -template -typename modm::LinkedList::iterator -modm::LinkedList::remove(const iterator& iter) -{ - if (this->isEmpty()) { - return this->begin(); - } - else if (iter.node == this->front) - { - this->removeFront(); - return this->begin(); - } - - Node *node = this->front; - while (node->next != 0) - { - if (node->next == iter.node) - { - if (iter.node == this->back) { - this->back = node; - } - node->next = iter.node->next; - - // call destructor and free memory - Allocator::destroy(&iter.node->value); - this->nodeAllocator.deallocate(iter.node); - - return iterator(node->next); - } - node = node->next; - } - - return iter; -} diff --git a/src/modm/container/linked_list_iterator_impl.hpp b/src/modm/container/linked_list_iterator_impl.hpp deleted file mode 100644 index 840dc1d3b0..0000000000 --- a/src/modm/container/linked_list_iterator_impl.hpp +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (c) 2010, Fabian Greif - * Copyright (c) 2012, Niklas Hauser - * Copyright (c) 2013, Sascha Schade - * Copyright (c) 2015, Kevin Läufer - * - * 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_LINKED_LIST_HPP - #error "Don't include this file directly, use 'linked_list.hpp' instead" -#endif - -// ---------------------------------------------------------------------------- -// Iterators -// ---------------------------------------------------------------------------- - -// const iterator -template -modm::LinkedList::const_iterator::const_iterator() : - node(0) -{ -} - -template -modm::LinkedList::const_iterator::const_iterator( - Node* node) : - node(node) -{ -} - -template -modm::LinkedList::const_iterator::const_iterator( - const iterator& other) : - node(other.node) -{ -} - -template -modm::LinkedList::const_iterator::const_iterator( - const const_iterator& other) : - node(other.node) -{ -} - -template -typename modm::LinkedList::const_iterator& -modm::LinkedList::const_iterator::operator = (const const_iterator& other) -{ - this->node = other.node; - return *this; -} - -template -typename modm::LinkedList::const_iterator& -modm::LinkedList::const_iterator::operator ++ () -{ - this->node = this->node->next; - return *this; -} - -template -bool -modm::LinkedList::const_iterator::operator == ( - const const_iterator& other) const -{ - return (node == other.node); -} - -template -bool -modm::LinkedList::const_iterator::operator != ( - const const_iterator& other) const -{ - return (node != other.node); -} - -template -const T& -modm::LinkedList::const_iterator::operator * () const -{ - return this->node->value; -} - -template -const T* -modm::LinkedList::const_iterator::operator -> () const -{ - return &this->node->value; -} - - -template -typename modm::LinkedList::const_iterator -modm::LinkedList::begin() const -{ - return const_iterator(this->front); -} - -template -typename modm::LinkedList::const_iterator -modm::LinkedList::end() const -{ - return const_iterator(0); -} - -// iterator -template -modm::LinkedList::iterator::iterator() : - node(0) -{ -} - -template -modm::LinkedList::iterator::iterator(Node* node) : - node(node) -{ -} - -template -modm::LinkedList::iterator::iterator( - const iterator& other) : - node(other.node) -{ -} - -template -typename modm::LinkedList::iterator& -modm::LinkedList::iterator::operator = (const iterator& other) -{ - this->node = other.node; - return *this; -} - -template -typename modm::LinkedList::iterator& -modm::LinkedList::iterator::operator ++ () -{ - this->node = this->node->next; - return *this; -} - -template -bool -modm::LinkedList::iterator::operator == ( - const iterator& other) const -{ - return (node == other.node); -} - -template -bool -modm::LinkedList::iterator::operator != ( - const iterator& other) const -{ - return (node != other.node); -} - -template -T& -modm::LinkedList::iterator::operator * () -{ - return this->node->value; -} - -template -T* -modm::LinkedList::iterator::operator -> () -{ - return &this->node->value; -} - - -template -typename modm::LinkedList::iterator -modm::LinkedList::begin() -{ - return iterator(this->front); -} - -template -typename modm::LinkedList::iterator -modm::LinkedList::end() -{ - return iterator(0); -} diff --git a/src/modm/container/pair.hpp b/src/modm/container/pair.hpp index 22784f9188..7b1a31339b 100644 --- a/src/modm/container/pair.hpp +++ b/src/modm/container/pair.hpp @@ -3,6 +3,7 @@ * Copyright (c) 2009-2010, Martin Rosekeit * Copyright (c) 2009-2011, Fabian Greif * Copyright (c) 2012, Niklas Hauser + * Copyright (c) 2023, Christopher Durand * * This file is part of the modm project. * @@ -15,6 +16,8 @@ #ifndef MODM_PAIR_HPP #define MODM_PAIR_HPP +#include + namespace modm { /** @@ -63,49 +66,38 @@ namespace modm * \ingroup modm_container */ template - class Pair + class Pair : public std::pair { public: - typedef T1 FirstType; - typedef T2 SecondType; + using FirstType = T1; + using SecondType = T2; public: - // No non-trivial constructor is allowed, otherwise this class - // won't be POD (plain old data) :-( - // (this behavior changes with C++0x) - /*Pair(const FirstType& first, const SecondType& second) : - first(first), second(second) - { - }*/ + using std::pair::pair; FirstType& getFirst() { - return first; + return this->first; } const FirstType& getFirst() const { - return first; + return this->first; } SecondType& getSecond() { - return second; + return this->second; } const SecondType& getSecond() const { - return second; + return this->second; } - - // ... not allowed either, only public attributes :-( - //private: - FirstType first; - SecondType second; }; }