diff options
Diffstat (limited to 'raul/List.hpp')
-rw-r--r-- | raul/List.hpp | 416 |
1 files changed, 20 insertions, 396 deletions
diff --git a/raul/List.hpp b/raul/List.hpp index a090251..f695421 100644 --- a/raul/List.hpp +++ b/raul/List.hpp @@ -49,28 +49,36 @@ public: public: Node(T elem) : _elem(elem) {} virtual ~Node() {} + + template <typename Y> + Node(const typename List<Y>::Node& copy) + : _elem(copy._elem), _prev(copy._prev), _next(copy._next) + {} - Node* next() const { return _next.get(); } - void next(Node* ln) { _next = ln; } - Node* prev() const { return _prev.get(); } + Node* prev() const { return _prev.get(); } void prev(Node* ln) { _prev = ln; } - T& elem() { return _elem;} - const T& elem() const { return _elem; } + Node* next() const { return _next.get(); } + void next(Node* ln) { _next = ln; } + + T& elem() { return _elem;} + const T& elem() const { return _elem; } private: - T _elem; - AtomicPtr<Node> _next; + T _elem; AtomicPtr<Node> _prev; + AtomicPtr<Node> _next; }; // List - List() : _size(0), _end_iter(this), _const_end_iter(this) + List() + : _size(0), _end_iter(this), _const_end_iter(this) { _end_iter._listnode = NULL; _const_end_iter._listnode = NULL; } + ~List(); void push_back(Node* elem); // realtime safe @@ -97,6 +105,7 @@ public: : _list(i._list), _listnode(i._listnode) {} inline const T& operator*(); + inline const T* operator->(); inline const_iterator& operator++(); inline bool operator!=(const const_iterator& iter) const; inline bool operator!=(const iterator& iter) const; @@ -118,6 +127,7 @@ public: iterator(List<T>* const list); inline T& operator*(); + inline T* operator->(); inline iterator& operator++(); inline bool operator!=(const iterator& iter) const; inline bool operator!=(const const_iterator& iter) const; @@ -152,394 +162,8 @@ private: }; - - -template <typename T> -List<T>::~List<T>() -{ - clear(); -} - - -/** Clear the list, deleting all Nodes contained (but NOT their contents!) - * - * Not realtime safe. - */ -template <typename T> -void -List<T>::clear() -{ - Node* node = _head.get(); - Node* next = NULL; - - while (node) { - next = node->next(); - delete node; - node = next; - } - - _head = 0; - _tail = 0; - _size = 0; -} - - -/** Add an element to the list. - * - * Thread safe (may be called while another thread is reading the list). - * Realtime safe. - */ -template <typename T> -void -List<T>::push_back(Node* const ln) -{ - assert(ln); - - ln->next(NULL); - - if ( ! _head.get()) { // empty - ln->prev(NULL); - _tail = ln; - _head = ln; - } else { - ln->prev(_tail.get()); - _tail.get()->next(ln); - _tail = ln; - } - ++_size; -} - - -/** Add an element to the list. - * - * Thread safe (may be called while another thread is reading the list). - * NOT realtime safe (a Node is allocated). - */ -template <typename T> -void -List<T>::push_back(T& elem) -{ - Node* const ln = new Node(elem); - - assert(ln); - - ln->next(NULL); - - if ( ! _head.get()) { // empty - ln->prev(NULL); - _tail = ln; - _head = ln; - } else { - ln->prev(_tail.get()); - _tail.get()->next(ln); - _tail = ln; - } - ++_size; -} - - -/** Append a list to this list. - * - * This operation is fast ( O(1) ). - * The appended list is not safe to use concurrently with this call. - * - * The appended list will be empty after this call. - * - * Thread safe (may be called while another thread is reading the list). - * Realtime safe. - */ -template <typename T> -void -List<T>::append(List<T>& list) -{ - Node* const my_head = _head.get(); - Node* const my_tail = _tail.get(); - Node* const other_head = list._head.get(); - Node* const other_tail = list._tail.get(); - - // Appending to an empty list - if (my_head == NULL && my_tail == NULL) { - _head = other_head; - _tail = other_tail; - _size = list._size; - } else if (other_head != NULL && other_tail != NULL) { - - other_head->prev(my_tail); - - // FIXME: atomicity an issue? _size < true size is probably fine... - // no gurantee an iteration runs exactly size times though. verify/document this. - // assuming comment above that says tail is writer only, this is fine - my_tail->next(other_head); - _tail = other_tail; - _size += list.size(); - } - - list._head = NULL; - list._tail = NULL; - list._size = 0; -} - - -/** Remove all elements equal to @val from the list. - * - * This function is realtime safe - it is the caller's responsibility to - * delete the returned ListNode, or there will be a leak. - */ -#if 0 -template <typename T> -ListNode<T>* -List<T>::remove(const T val) -{ - // FIXME: atomicity? - ListNode<T>* n = _head; - while (n) { - if (n->elem() == elem) - break; - n = n->next(); - } - if (n) { - if (n == _head) _head = _head->next(); - if (n == _tail) _tail = _tail->prev(); - if (n->prev()) - n->prev()->next(n->next()); - if (n->next()) - n->next()->prev(n->prev()); - --_size; - - if (_size == 0) - _head = _tail = NULL; // FIXME: Shouldn't be necessary - - return n; - } - return NULL; -} -#endif - - -/** Find an element in the list. - * - * This will only return the first element found. If there are duplicated, - * another call to find() will return the next, etc. - */ -template <typename T> -typename List<T>::iterator -List<T>::find(const T& val) -{ - for (iterator i = begin(); i != end(); ++i) - if (*i == val) - return i; - - return end(); -} - - -/** Remove an element from the list using an iterator. - * - * This function is realtime safe - it is the caller's responsibility to - * delete the returned Node, or there will be a leak. - * Thread safe (safe to call while another thread reads the list). - * @a iter is invalid immediately following this call. - */ -template <typename T> -typename List<T>::Node* -List<T>::erase(const iterator iter) -{ - Node* const n = iter._listnode; - - if (n) { - - Node* const prev = n->prev(); - Node* const next = n->next(); - - // Removing the head (or the only element) - if (n == _head.get()) - _head = next; - - // Removing the tail (or the only element) - if (n == _tail.get()) - _tail = _tail.get()->prev(); - - if (prev) - n->prev()->next(next); - - if (next) - n->next()->prev(prev); - - --_size; - } - - return n; -} - - -//// Iterator stuff //// - -template <typename T> -List<T>::iterator::iterator(List<T>* list) -: _list(list), - _listnode(NULL) -{ -} - - -template <typename T> -T& -List<T>::iterator::operator*() -{ - assert(_listnode); - return _listnode->elem(); -} - - -template <typename T> -inline typename List<T>::iterator& -List<T>::iterator::operator++() -{ - assert(_listnode); - _listnode = _listnode->next(); - - return *this; -} - - -template <typename T> -inline bool -List<T>::iterator::operator!=(const iterator& iter) const -{ - return (_listnode != iter._listnode); -} - - -template <typename T> -inline bool -List<T>::iterator::operator!=(const const_iterator& iter) const -{ - return (_listnode != iter._listnode); -} - - -template <typename T> -inline bool -List<T>::iterator::operator==(const iterator& iter) const -{ - return (_listnode == iter._listnode); -} - - -template <typename T> -inline bool -List<T>::iterator::operator==(const const_iterator& iter) const -{ - return (_listnode == iter._listnode); -} - - -template <typename T> -inline typename List<T>::iterator -List<T>::begin() -{ - typename List<T>::iterator iter(this); - - iter._listnode = _head.get(); - - return iter; -} - - -template <typename T> -inline const typename List<T>::iterator -List<T>::end() const -{ - return _end_iter; -} - - - -/// const_iterator stuff /// - - -template <typename T> -List<T>::const_iterator::const_iterator(const List<T>* const list) -: _list(list), - _listnode(NULL) -{ -} - - -template <typename T> -const T& -List<T>::const_iterator::operator*() -{ - assert(_listnode); - return _listnode->elem(); -} - - -template <typename T> -inline typename List<T>::const_iterator& -List<T>::const_iterator::operator++() -{ - assert(_listnode); - _listnode = _listnode->next(); - - return *this; -} - - -template <typename T> -inline bool -List<T>::const_iterator::operator!=(const const_iterator& iter) const -{ - return (_listnode != iter._listnode); -} - - -template <typename T> -inline bool -List<T>::const_iterator::operator!=(const iterator& iter) const -{ - return (_listnode != iter._listnode); -} - - -template <typename T> -inline bool -List<T>::const_iterator::operator==(const const_iterator& iter) const -{ - return (_listnode == iter._listnode); -} - - -template <typename T> -inline bool -List<T>::const_iterator::operator==(const iterator& iter) const -{ - return (_listnode == iter._listnode); -} - -template <typename T> -inline typename List<T>::const_iterator -List<T>::begin() const -{ - typename List<T>::const_iterator iter(this); - iter._listnode = _head.get(); - return iter; -} - -#if 0 -template <typename T> -inline typename List<T>::const_iterator -List<T>::end() const -{ - /*typename List<T>::const_iterator iter(this); - iter._listnode = NULL; - iter._next = NULL; - return iter;*/ - return _const_end_iter; -} -#endif - - } // namespace Raul +#include "ListImpl.hpp" + #endif // RAUL_LIST_HPP |