diff options
author | Clyne Sullivan <tullivan99@gmail.com> | 2016-11-11 15:02:17 -0500 |
---|---|---|
committer | Clyne Sullivan <tullivan99@gmail.com> | 2016-11-11 15:02:17 -0500 |
commit | 7772ea4579a45bcf63ebd5e68be66ba1a9c72dfa (patch) | |
tree | 9e1ce52ea97102d3513e519a77d999eac228820b /include/estd/IntrusiveList.hpp | |
parent | 02b3ff42cccf32617c88c0ca65436b8c9d4f61eb (diff) |
chibios!
Diffstat (limited to 'include/estd/IntrusiveList.hpp')
-rw-r--r-- | include/estd/IntrusiveList.hpp | 1208 |
1 files changed, 0 insertions, 1208 deletions
diff --git a/include/estd/IntrusiveList.hpp b/include/estd/IntrusiveList.hpp deleted file mode 100644 index 82597f4..0000000 --- a/include/estd/IntrusiveList.hpp +++ /dev/null @@ -1,1208 +0,0 @@ -/** - * \file - * \brief IntrusiveList template class header - * - * \author Copyright (C) 2015 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info - * - * \par License - * 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 ESTD_INTRUSIVELIST_HPP_ -#define ESTD_INTRUSIVELIST_HPP_ - -#include <iterator> - -#include <cstddef> - -namespace estd -{ - -namespace internal -{ - -class IntrusiveListBase; - -} - -/** - * \brief IntrusiveListNode class is the node that is needed for the object to be linked in IntrusiveList - * - * To some extent, this class can be considered to be a limited (raw) iterator. - * - * The object that wants to be linked in IntrusiveList must contain a variable of this type - one for each intrusive - * list that will be used with object. - */ - -class IntrusiveListNode -{ -public: - - /// LinkAccessKey class is used to limit access to IntrusiveListNode::link() function - only - /// internal::IntrusiveListBase can link nodes to the list - class LinkAccessKey - { - friend class internal::IntrusiveListBase; - - /** - * \brief LinkAccessKey's constructor - */ - - constexpr LinkAccessKey() - { - - } - - LinkAccessKey(const LinkAccessKey&) = delete; - LinkAccessKey(LinkAccessKey&&) = delete; - const LinkAccessKey& operator=(const LinkAccessKey&) = delete; - LinkAccessKey& operator=(LinkAccessKey&&) = delete; - }; - - /** - * \brief IntrusiveListNode's constructor - */ - - constexpr IntrusiveListNode() : - nextNode_{this}, - previousNode_{this} - { - - } - - /** - * \brief IntrusiveListNode's move constructor - * - * \param [in] other is a rvalue reference to IntrusiveListNode used as source of move construction - */ - - IntrusiveListNode(IntrusiveListNode&& other) - { - if (other.isLinked() == false) - { - reset(); - return; - } - - nextNode_ = other.nextNode_; - previousNode_ = other.previousNode_; - nextNode_->previousNode_ = previousNode_->nextNode_ = this; - other.reset(); - } - - /** - * \brief IntrusiveListNode's destructor - * - * Unlinks the node from the list. - */ - - ~IntrusiveListNode() - { - unlink(); - } - - /** - * \return reference to next node on the list - */ - - IntrusiveListNode& getNextNode() const - { - return *nextNode_; - } - - /** - * \return reference to previous node on the list - */ - - IntrusiveListNode& getPreviousNode() const - { - return *previousNode_; - } - - /** - * \return true if the node is linked in some list, false otherwise - */ - - bool isLinked() const - { - return nextNode_ != this; - } - - /** - * \brief Links the node in the list before \a position. - * - * \note Access to this function is restricted only to functions from internal::IntrusiveListBase class - * - * \param [in] position is a reference to node before which this node will be linked - * \param [in] linkAccessKey is used to limit access to this function - */ - - void link(IntrusiveListNode& position, LinkAccessKey) - { - unlink(); - - nextNode_ = &position; - previousNode_ = position.previousNode_; - position.previousNode_->nextNode_ = this; - position.previousNode_ = this; - } - - /** - * \brief Swaps contents with another node. - * - * \param [in] other is a reference to IntrusiveListNode with which contents of this node will be swapped - */ - - void swap(IntrusiveListNode& other) - { - const auto thisWasLinked = isLinked(); - const auto otherWasLinked = other.isLinked(); - - if (thisWasLinked == true || otherWasLinked == true) - { - using std::swap; - swap(nextNode_, other.nextNode_); - swap(previousNode_, other.previousNode_); - - if (thisWasLinked == true) - other.nextNode_->previousNode_ = other.previousNode_->nextNode_ = &other; - else - other.reset(); - - if (otherWasLinked == true) - nextNode_->previousNode_ = previousNode_->nextNode_ = this; - else - reset(); - } - } - - /** - * \brief Unlinks the node from the list. - */ - - void unlink() - { - previousNode_->nextNode_ = nextNode_; - nextNode_->previousNode_ = previousNode_; - - reset(); - } - - IntrusiveListNode(const IntrusiveListNode&) = delete; - const IntrusiveListNode& operator=(const IntrusiveListNode&) = delete; - IntrusiveListNode& operator=(IntrusiveListNode&&) = delete; - -private: - - /** - * \brief Resets the node to the same state as right after construction. - */ - - void reset() - { - nextNode_ = this; - previousNode_ = this; - } - - /// reference to next node on the list - IntrusiveListNode* nextNode_; - - /// reference to previous node on the list - IntrusiveListNode* previousNode_; -}; - -namespace internal -{ - -/** - * \brief IntrusiveListBase class provides base functionalities for IntrusiveList class, but without any knowledge about - * types - * - * This class tries to provide an interface similar to std::list. - */ - -class IntrusiveListBase -{ -public: - - /** - * \brief IntrusiveListBase's constructor - */ - - constexpr IntrusiveListBase() : - rootNode_{} - { - - } - - /** - * \brief IntrusiveListBase's destructor - * - * Unlinks all nodes from the list. - */ - - ~IntrusiveListBase() - { - clear(); - } - - /** - * \return reference to first node on the list - */ - - IntrusiveListNode& begin() - { - return rootNode_.getNextNode(); - } - - /** - * \return const reference to first node on the list - */ - - const IntrusiveListNode& begin() const - { - return rootNode_.getNextNode(); - } - - /** - * \return const reference to first node on the list - */ - - const IntrusiveListNode& cbegin() const - { - return begin(); - } - - /** - * \return const reference to "one past the last" node on the list - */ - - const IntrusiveListNode& cend() const - { - return end(); - } - - /** - * \brief Unlinks all nodes from the list. - */ - - void clear() - { - while (empty() == false) - pop_front(); - } - - /** - * \return true is the list is empty, false otherwise - */ - - bool empty() const - { - return &begin() == &end(); - } - - /** - * \return reference to "one past the last" node on the list - */ - - IntrusiveListNode& end() - { - return rootNode_; - } - - /** - * \return const reference to "one past the last" node on the list - */ - - const IntrusiveListNode& end() const - { - return rootNode_; - } - - /** - * \brief Unlinks the last node from the list. - */ - - void pop_back() - { - erase(end().getPreviousNode()); - } - - /** - * \brief Unlinks the first node from the list. - */ - - void pop_front() - { - erase(begin()); - } - - /** - * \brief Links the node at the end of the list. - * - * \param [in] newNode is a reference to node that will be linked in the list - */ - - void push_back(IntrusiveListNode& newNode) - { - insert(end(), newNode); - } - - /** - * \brief Links the node at the beginning of the list. - * - * \param [in] newNode is a reference to node that will be linked in the list - */ - - void push_front(IntrusiveListNode& newNode) - { - insert(begin(), newNode); - } - - /** - * \brief Swaps contents with another list. - * - * \param [in] other is a reference to IntrusiveListBase with which contents of this list will be swapped - */ - - void swap(IntrusiveListBase& other) - { - rootNode_.swap(other.rootNode_); - } - - /** - * \brief Unlinks the node at \a position from the list. - * - * \note No instance of the list is needed for this operation. - * - * \param [in] position is a reference to the node that will be unlinked from the list - * - * \return reference to the node that was following the node which was unlinked - */ - - static IntrusiveListNode& erase(IntrusiveListNode& position) - { - auto& next = position.getNextNode(); - position.unlink(); - return next; - } - - /** - * \brief Links the node in the list before \a position. - * - * \note No instance of the list is needed for this operation. - * - * \param [in] position is a reference to node before which \a newNode will be linked - * \param [in] newNode is a reference to node that will be linked in the list - */ - - static void insert(IntrusiveListNode& position, IntrusiveListNode& newNode) - { - newNode.link(position, {}); - } - - /** - * \brief Transfers the node from one list to another list before \a position. - * - * \note No instance of any list is needed for this operation. - * - * \param [in] position is a reference to node before which \a splicedNode will be linked - * \param [in] splicedNode is a reference to node that will be spliced from one list to another - */ - - static void splice(IntrusiveListNode& position, IntrusiveListNode& splicedNode) - { - insert(position, splicedNode); - } - - IntrusiveListBase(const IntrusiveListBase&) = delete; - IntrusiveListBase(IntrusiveListBase&&) = default; - const IntrusiveListBase& operator=(const IntrusiveListBase&) = delete; - IntrusiveListBase& operator=(IntrusiveListBase&&) = delete; - -private: - - /// root node of the intrusive list - IntrusiveListNode rootNode_; -}; - -/** - * \brief Swaps contents of two lists. - * - * \param [in] left is a reference to IntrusiveListBase with which contents of \a right will be swapped - * \param [in] right is a reference to IntrusiveListBase with which contents of \a left will be swapped - */ - -inline void swap(IntrusiveListBase& left, IntrusiveListBase& right) -{ - left.swap(right); -} - -} // namespace internal - -/** - * \brief IntrusiveListIterator class is an iterator of elements on IntrusiveList. - * - * This class provides an interface similar to std::list::iterator. - * - * \tparam T is the type that has the IntrusiveListNode variable - * \tparam NodePointer is a pointer-to-member to IntrusiveListNode variable in \a T - * \tparam U is the type that will be stored on the list; it can be different from \a T, but must be implicitly - * convertible to \a T (so usually a type derived from \a T); default - \a T; - */ - -template<typename T, IntrusiveListNode T::* NodePointer, typename U = T> -class IntrusiveListIterator -{ -public: - - /// difference type - using difference_type = ptrdiff_t; - - /// category of the iterator - using iterator_category = std::bidirectional_iterator_tag; - - /// pointer to object "pointed to" by the iterator - using pointer = U*; - - /// reference to object "pointed to" by the iterator - using reference = U&; - - /// value "pointed to" by the iterator - using value_type = U; - - /** - * \brief IntrusiveListIterator's constructor - */ - - constexpr IntrusiveListIterator() : - node_{} - { - - } - - /** - * \brief IntrusiveListIterator's constructor - * - * \param [in] node is a pointer to IntrusiveListNode of element that will be "pointed to" by the iterator - */ - - constexpr explicit IntrusiveListIterator(IntrusiveListNode* const node) : - node_{node} - { - - } - - /** - * \brief IntrusiveListIterator's constructor - * - * \param [in] element is a reference to element that will be "pointed to" by the iterator - */ - - constexpr explicit IntrusiveListIterator(reference element) : - node_{&(element.*NodePointer)} - { - static_assert(std::is_convertible<U, T>::value == true, "U must be implicitly convertible to T!"); - } - - /** - * \brief IntrusiveListIterator's binary infix pointer member access operator - * - * \return pointer to object "pointed to" by the iterator - */ - - pointer operator->() const - { - return getPointer(); - } - - /** - * \brief IntrusiveListIterator's unary prefix dereference operator - * - * \return reference to object "pointed to" by the iterator - */ - - reference operator*() const - { - return *getPointer(); - } - - /** - * \brief IntrusiveListIterator's unary prefix increment operator - * - * \return reference to "this" iterator - */ - - IntrusiveListIterator& operator++() - { - node_ = &node_->getNextNode(); - return *this; - } - - /** - * \brief IntrusiveListIterator's unary postfix increment operator - * - * \return copy of "this" iterator before increment - */ - - IntrusiveListIterator operator++(int) - { - const auto temporary = *this; - node_ = &node_->getNextNode(); - return temporary; - } - - /** - * \brief IntrusiveListIterator's unary prefix decrement operator - * - * \return reference to "this" iterator - */ - - IntrusiveListIterator& operator--() - { - node_ = &node_->getPreviousNode(); - return *this; - } - - /** - * \brief IntrusiveListIterator's unary postfix decrement operator - * - * \return copy of "this" iterator before decrement - */ - - IntrusiveListIterator operator--(int) - { - const auto temporary = *this; - node_ = &node_->getPreviousNode(); - return temporary; - } - - /** - * \brief IntrusiveListIterator's "equal to" comparison operator - * - * \param [in] other is a const reference to IntrusiveListIterator on right-hand side of comparison operator - * - * \return true if both iterators are equal, false otherwise - */ - - bool operator==(const IntrusiveListIterator& other) const - { - return node_ == other.node_; - } - -private: - - /** - * \brief Converts contained pointer to IntrusiveListNode to pointer to object that contains this node. - * - * \return pointer to object "pointed to" by the iterator - */ - - pointer getPointer() const - { - static_assert(std::is_convertible<U, T>::value == true, "U must be implicitly convertible to T!"); - - const auto offset = reinterpret_cast<size_t>(&(static_cast<pointer>(nullptr)->*NodePointer)); - return reinterpret_cast<pointer>(reinterpret_cast<size_t>(node_) - offset); - } - - /// pointer to IntrusiveListNode of the object "pointed to" by the iterator - IntrusiveListNode* node_; -}; - -/** - * \brief IntrusiveListIterator's "not equal to" comparison operator - * - * \tparam T is the type that has the IntrusiveListNode variable - * \tparam NodePointer is a pointer-to-member to IntrusiveListNode variable in \a T - * \tparam U is the type that will be stored on the list; it can be different from \a T, but must be implicitly - * convertible to \a T (so usually a type derived from \a T); default - \a T; - * - * \param [in] left is a const reference to IntrusiveListIterator on left-hand side of comparison operator - * \param [in] right is a const reference to IntrusiveListIterator on right-hand side of comparison operator - * - * \return true if iterators are not equal, false otherwise - */ - -template<typename T, IntrusiveListNode T::* NodePointer, typename U = T> -inline bool operator!=(const IntrusiveListIterator<T, NodePointer, U>& left, - const IntrusiveListIterator<T, NodePointer, U>& right) -{ - return (left == right) == false; -} - -/** - * \brief IntrusiveListConstIterator class is a const iterator of elements on IntrusiveList. - * - * This class provides an interface similar to std::list::const_iterator. - * - * \tparam T is the type that has the IntrusiveListNode variable - * \tparam NodePointer is a const pointer-to-member to IntrusiveListNode variable in \a T - * \tparam U is the type that will be stored on the list; it can be different from \a T, but must be implicitly - * convertible to \a T (so usually a type derived from \a T); default - \a T; - */ - -template<typename T, const IntrusiveListNode T::* NodePointer, typename U = T> -class IntrusiveListConstIterator -{ -public: - - /// difference type - using difference_type = ptrdiff_t; - - /// category of the iterator - using iterator_category = std::bidirectional_iterator_tag; - - /// pointer to object "pointed to" by the iterator - using pointer = const U*; - - /// reference to object "pointed to" by the iterator - using reference = const U&; - - /// value "pointed to" by the iterator - using value_type = U; - - /** - * \brief IntrusiveListConstIterator's constructor - */ - - constexpr IntrusiveListConstIterator() : - node_{} - { - - } - - /** - * \brief IntrusiveListConstIterator's constructor - * - * \param [in] node is a pointer to const IntrusiveListNode of element that will be "pointed to" by the iterator - */ - - constexpr explicit IntrusiveListConstIterator(const IntrusiveListNode* const node) : - node_{node} - { - - } - - /** - * \brief IntrusiveListConstIterator's constructor - * - * \param [in] element is a const reference to element that will be "pointed to" by the iterator - */ - - constexpr explicit IntrusiveListConstIterator(reference element) : - node_{&(element.*NodePointer)} - { - static_assert(std::is_convertible<U, T>::value == true, "U must be implicitly convertible to T!"); - } - - /** - * \brief IntrusiveListConstIterator's constructor - * - * Converts non-const iterator (IntrusiveListIterator) to const iterator (IntrusiveListConstIterator). - * - * \tparam NonConstNodePointer is a non-const version of \a NodePointer - * - * \param [in] iterator is a const reference to non-const iterator (IntrusiveListIterator) - */ - - template<IntrusiveListNode T::* NonConstNodePointer> - constexpr IntrusiveListConstIterator(const IntrusiveListIterator<T, NonConstNodePointer, U>& iterator) : - IntrusiveListConstIterator{*iterator} - { - - } - - /** - * \brief IntrusiveListConstIterator's binary infix pointer member access operator - * - * \return pointer to object "pointed to" by the iterator - */ - - pointer operator->() const - { - return getPointer(); - } - - /** - * \brief IntrusiveListConstIterator's unary prefix dereference operator - * - * \return reference to object "pointed to" by the iterator - */ - - reference operator*() const - { - return *getPointer(); - } - - /** - * \brief IntrusiveListConstIterator's unary prefix increment operator - * - * \return reference to "this" iterator - */ - - IntrusiveListConstIterator& operator++() - { - node_ = &node_->getNextNode(); - return *this; - } - - /** - * \brief IntrusiveListConstIterator's unary postfix increment operator - * - * \return copy of "this" iterator before increment - */ - - IntrusiveListConstIterator operator++(int) - { - const auto temporary = *this; - node_ = &node_->getNextNode(); - return temporary; - } - - /** - * \brief IntrusiveListConstIterator's unary prefix decrement operator - * - * \return reference to "this" iterator - */ - - IntrusiveListConstIterator& operator--() - { - node_ = &node_->getPreviousNode(); - return *this; - } - - /** - * \brief IntrusiveListConstIterator's unary postfix decrement operator - * - * \return copy of "this" iterator before decrement - */ - - IntrusiveListConstIterator operator--(int) - { - const auto temporary = *this; - node_ = &node_->getPreviousNode(); - return temporary; - } - - /** - * \brief IntrusiveListConstIterator's "equal to" comparison operator - * - * \param [in] other is a const reference to IntrusiveListConstIterator on right-hand side of comparison operator - * - * \return true if both iterators are equal, false otherwise - */ - - bool operator==(const IntrusiveListConstIterator& other) const - { - return node_ == other.node_; - } - -private: - - /** - * \brief Converts contained pointer to IntrusiveListNode to pointer to object that contains this node. - * - * \return pointer to object "pointed to" by the iterator - */ - - pointer getPointer() const - { - static_assert(std::is_convertible<U, T>::value == true, "U must be implicitly convertible to T!"); - - const auto offset = reinterpret_cast<size_t>(&(static_cast<pointer>(nullptr)->*NodePointer)); - return reinterpret_cast<pointer>(reinterpret_cast<size_t>(node_) - offset); - } - - /// pointer to const IntrusiveListNode of the object "pointed to" by the iterator - const IntrusiveListNode* node_; -}; - -/** - * \brief IntrusiveListConstIterator's "not equal to" comparison operator - * - * \tparam T is the type that has the IntrusiveListNode variable - * \tparam NodePointer is a const pointer-to-member to IntrusiveListNode variable in \a T - * \tparam U is the type that will be stored on the list; it can be different from \a T, but must be implicitly - * convertible to \a T (so usually a type derived from \a T); default - \a T; - * - * \param [in] left is a const reference to IntrusiveListConstIterator on left-hand side of comparison operator - * \param [in] right is a const reference to IntrusiveListConstIterator on right-hand side of comparison operator - * - * \return true if iterators are not equal, false otherwise - */ - -template<typename T, const IntrusiveListNode T::* NodePointer, typename U = T> -inline bool operator!=(const IntrusiveListConstIterator<T, NodePointer, U>& left, - const IntrusiveListConstIterator<T, NodePointer, U>& right) -{ - return (left == right) == false; -} - -/** - * \brief "Equal to" comparison operator for IntrusiveListIterator and IntrusiveListConstIterator - * - * \tparam T is the type that has the IntrusiveListNode variable - * \tparam NodePointer is a pointer-to-member to IntrusiveListNode variable in \a T - * \tparam ConstNodePointer is a const pointer-to-member to IntrusiveListNode variable in \a T - * \tparam U is the type that will be stored on the list; it can be different from \a T, but must be implicitly - * convertible to \a T (so usually a type derived from \a T); default - \a T; - * - * \param [in] left is a const reference to IntrusiveListIterator on left-hand side of comparison operator - * \param [in] right is a const reference to IntrusiveListConstIterator on right-hand side of comparison operator - * - * \return true if both iterators are equal, false otherwise - */ - -template<typename T, IntrusiveListNode T::* NodePointer, const IntrusiveListNode T::* ConstNodePointer, typename U = T> -inline bool operator==(const IntrusiveListIterator<T, NodePointer, U>& left, - const IntrusiveListConstIterator<T, ConstNodePointer, U>& right) -{ - return decltype(right){left} == right; -} - -/** - * \brief "Not equal to" comparison operator for IntrusiveListIterator and IntrusiveListConstIterator - * - * \tparam T is the type that has the IntrusiveListNode variable - * \tparam NodePointer is a pointer-to-member to IntrusiveListNode variable in \a T - * \tparam ConstNodePointer is a const pointer-to-member to IntrusiveListNode variable in \a T - * \tparam U is the type that will be stored on the list; it can be different from \a T, but must be implicitly - * convertible to \a T (so usually a type derived from \a T); default - \a T; - * - * \param [in] left is a const reference to IntrusiveListIterator on left-hand side of comparison operator - * \param [in] right is a const reference to IntrusiveListConstIterator on right-hand side of comparison operator - * - * \return true if iterators are not equal, false otherwise - */ - -template<typename T, IntrusiveListNode T::* NodePointer, const IntrusiveListNode T::* ConstNodePointer, typename U = T> -inline bool operator!=(const IntrusiveListIterator<T, NodePointer, U>& left, - const IntrusiveListConstIterator<T, ConstNodePointer, U>& right) -{ - return (left == right) == false; -} - -/** - * \brief "Not equal to" comparison operator for IntrusiveListConstIterator and IntrusiveListIterator - * - * \tparam T is the type that has the IntrusiveListNode variable - * \tparam NodePointer is a pointer-to-member to IntrusiveListNode variable in \a T - * \tparam ConstNodePointer is a const pointer-to-member to IntrusiveListNode variable in \a T - * \tparam U is the type that will be stored on the list; it can be different from \a T, but must be implicitly - * convertible to \a T (so usually a type derived from \a T); default - \a T; - * - * \param [in] left is a const reference to IntrusiveListConstIterator on left-hand side of comparison operator - * \param [in] right is a const reference to IntrusiveListIterator on right-hand side of comparison operator - * - * \return true if iterators are not equal, false otherwise - */ - -template<typename T, IntrusiveListNode T::* NodePointer, const IntrusiveListNode T::* ConstNodePointer, typename U = T> -inline bool operator!=(const IntrusiveListConstIterator<T, ConstNodePointer, U>& left, - const IntrusiveListIterator<T, NodePointer, U>& right) -{ - return right != left; -} - -/** - * \brief IntrusiveList class is an intrusive circular doubly linked list. - * - * This class tries to provide an interface similar to std::list. - * - * \tparam T is the type that has the IntrusiveListNode variable - * \tparam NodePointer is a pointer-to-member to IntrusiveListNode variable in \a T - * \tparam U is the type that will be stored on the list; it can be different from \a T, but must be implicitly - * convertible to \a T (so usually a type derived from \a T); default - \a T; using different type than \a T can be used - * to break circular dependencies, because \a T must be fully defined to instantiate this class, but it is enough to - * forward declare \a U - it only needs to be fully defined to use member functions - */ - -template<typename T, IntrusiveListNode T::* NodePointer, typename U = T> -class IntrusiveList -{ -public: - - /// const iterator of elements on the list - using const_iterator = IntrusiveListConstIterator<T, NodePointer, U>; - - /// const reverse iterator of elements on the list - using const_reverse_iterator = std::reverse_iterator<const_iterator>; - - /// const pointer to value linked in the list - using const_pointer = const U*; - - /// const reference to value linked in the list - using const_reference = const U&; - - /// iterator of elements on the list - using iterator = IntrusiveListIterator<T, NodePointer, U>; - - /// reverse iterator of elements on the list - using reverse_iterator = std::reverse_iterator<iterator>; - - /// pointer to value linked in the list - using pointer = U*; - - /// reference to value linked in the list - using reference = U&; - - /// value linked in the list - using value_type = U; - - /** - * \brief IntrusiveList's constructor - */ - - constexpr IntrusiveList() : - intrusiveListBase_{} - { - - } - - /** - * \return reference to last element on the list - */ - - reference back() - { - return *--end(); - } - - /** - * \return const reference to last element on the list - */ - - const_reference back() const - { - return *--end(); - } - - /** - * \return iterator of first element on the list - */ - - iterator begin() - { - return iterator{&intrusiveListBase_.begin()}; - } - - /** - * \return const iterator of first element on the list - */ - - const_iterator begin() const - { - return const_iterator{&intrusiveListBase_.begin()}; - } - - /** - * \return const iterator of first element on the list - */ - - const_iterator cbegin() const - { - return begin(); - } - - /** - * \return const iterator of "one past the last" element on the list - */ - - const_iterator cend() const - { - return end(); - } - - /** - * \brief Unlinks all elements from the list. - */ - - void clear() - { - intrusiveListBase_.clear(); - } - - /** - * \return true is the list is empty, false otherwise - */ - - bool empty() const - { - return intrusiveListBase_.empty(); - } - - /** - * \return iterator of "one past the last" element on the list - */ - - iterator end() - { - return iterator{&intrusiveListBase_.end()}; - } - - /** - * \return const iterator of "one past the last" element on the list - */ - - const_iterator end() const - { - return const_iterator{&intrusiveListBase_.end()}; - } - - /** - * \return reference to first element on the list - */ - - reference front() - { - return *begin(); - } - - /** - * \return const reference to first element on the list - */ - - const_reference front() const - { - return *begin(); - } - - /** - * \brief Unlinks the last element from the list. - */ - - void pop_back() - { - erase(--end()); - } - - /** - * \brief Unlinks the first element from the list. - */ - - void pop_front() - { - erase(begin()); - } - - /** - * \brief Links the element at the end of the list. - * - * \param [in] newElement is a reference to the element that will be linked in the list - */ - - void push_back(reference newElement) - { - insert(end(), newElement); - } - - /** - * \brief Links the element at the beginning of the list. - * - * \param [in] newElement is a reference to the element that will be linked in the list - */ - - void push_front(reference newElement) - { - insert(begin(), newElement); - } - - /** - * \brief Swaps contents with another list. - * - * \param [in] other is a reference to IntrusiveList with which contents of this list will be swapped - */ - - void swap(IntrusiveList& other) - { - intrusiveListBase_.swap(other.intrusiveListBase_); - } - - /** - * \brief Unlinks the element at \a position from the list. - * - * \note No instance of the list is needed for this operation. - * - * \param [in] position is an iterator of the element that will be unlinked from the list - * - * \return iterator of the element that was following the element which was unlinked - */ - - static iterator erase(const iterator position) - { - auto& positionNode = (*position).*NodePointer; - auto& nextNode = internal::IntrusiveListBase::erase(positionNode); - return iterator{&nextNode}; - } - - /** - * \brief Links the element in the list before \a position. - * - * \note No instance of the list is needed for this operation. - * - * \param [in] position is an iterator of the element before which \a newNode will be linked - * \param [in] newElement is a reference to the element that will be linked in the list - * - * \return iterator of \a newElement - */ - - static iterator insert(const iterator position, reference newElement) - { - static_assert(std::is_convertible<U, T>::value == true, "U must be implicitly convertible to T!"); - - auto& positionNode = (*position).*NodePointer; - auto& newElementNode = newElement.*NodePointer; - internal::IntrusiveListBase::insert(positionNode, newElementNode); - return iterator{&newElementNode}; - } - - /** - * \brief Transfers the element from one list to another list before \a position. - * - * \note No instance of any list is needed for this operation. - * - * \param [in] position is an iterator of the element before which \a splicedElement will be linked - * \param [in] splicedElement is an iterator of the element that will be spliced from one list to another - */ - - static void splice(const iterator position, const iterator splicedElement) - { - auto& positionNode = (*position).*NodePointer; - auto& splicedElementNode = (*splicedElement).*NodePointer; - internal::IntrusiveListBase::splice(positionNode, splicedElementNode); - } - - IntrusiveList(const IntrusiveList&) = delete; - IntrusiveList(IntrusiveList&&) = default; - const IntrusiveList& operator=(const IntrusiveList&) = delete; - IntrusiveList& operator=(IntrusiveList&&) = delete; - -private: - - /// internal IntrusiveListBase object - internal::IntrusiveListBase intrusiveListBase_; -}; - -/** - * \brief Swaps contents of two lists. - * - * \tparam T is the type that has the IntrusiveListNode variable - * \tparam NodePointer is a pointer-to-member to IntrusiveListNode variable in \a T - * \tparam U is the type that will be stored on the list; it can be different from \a T, but must be implicitly - * convertible to \a T (so usually a type derived from \a T); default - \a T; - * - * \param [in] left is a reference to IntrusiveList with which contents of \a right will be swapped - * \param [in] right is a reference to IntrusiveList with which contents of \a left will be swapped - */ - -template<typename T, IntrusiveListNode T::* NodePointer, typename U = T> -inline void swap(IntrusiveList<T, NodePointer, U>& left, IntrusiveList<T, NodePointer, U>& right) -{ - left.swap(right); -} - -} // namespace estd - -#endif // ESTD_INTRUSIVELIST_HPP_ |