From 2a02291537a326947328683f18c142797e3f00ba Mon Sep 17 00:00:00 2001 From: Max Horn Date: Mon, 12 Apr 2004 01:19:26 +0000 Subject: simple double linked list template class (completely untested) svn-id: r13555 --- common/list.h | 169 +++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 114 insertions(+), 55 deletions(-) (limited to 'common') diff --git a/common/list.h b/common/list.h index eabf8a4701..7afc97b014 100644 --- a/common/list.h +++ b/common/list.h @@ -26,95 +26,157 @@ namespace Common { -/* -TODO: Add a true list class, based on a linked list data structure - +/** + * Simple double linked list, modelled after the list template of the standard + * C++ library. + * Warning: as of now, this code is 100% untested. + */ template class List { protected: - template - class Node { - Node *_prev; - Node *_next; - T _data; - } - - template - class Iterator { - friend class List; - private: - Node *_node; + struct NodeBase { + NodeBase *_prev; + NodeBase *_next; + }; - public: - Node &operator++() { + template + struct Node : public NodeBase { + T2 _data; + + Node(const T2 &x) : _data(x) {} + }; + + template + struct Iterator { + NodeBase *_node; + + Iterator(NodeBase *node) : _node(node) {} + + // Prefix inc + Iterator &operator++() { _node = _node->_next; + return *this; + } + // Postfix inc + Iterator operator++(int) { + Iterator tmp = *this; + _node = _node->_next; + return tmp; + } + // Prefix dec + Iterator &operator--() { + _node = _node->_prev; + return *this; + } + // Postfix dec + Iterator operator--(int) { + Iterator tmp = *this; + _node = _node->_prev; + return tmp; } - T& operator*() const { - return _node->_data; + return static_cast*>(_node)->_data; } T* operator->() const { - return &(_node->_data); + return &(operator*()); + } + + bool operator==(const Iterator& x) const { + return _node == x._node; + } + + bool operator!=(const Iterator& x) const { + return _node != x._node; } }; - Iterator *_anchor; + NodeBase *_anchor; public: - typedef Node *iterator; - typedef const Node *const_iterator; + typedef Iterator iterator; + typedef const Iterator const_iterator; public: - List() : _anchor(...) {} - List(const List& list) : _anchor(...) { - ... copy list ... + List() { + _anchor = new NodeBase; + _anchor->_prev = _anchor; + _anchor->_next = _anchor; + } + List(const List& list) { + _anchor = new NodeBase; + _anchor->_prev = _anchor; + _anchor->_next = _anchor; + + insert(begin(), list.begin(), list.end()); } ~List() { - if (_data) - delete [] _data; + clear(); + delete _anchor; } - void push_back(const T& element) { - ... + void push_front(const T& element) { + insert(begin(), element); } - void push_back(const List& list) { - ... + void push_back(const T& element) { + insert(end(), element); } void insert(iterator pos, const T& element) { - ... + NodeBase *newNode = new Node(element); + + newNode->_next = pos._node; + newNode->_prev = pos._node->_prev; + newNode->_prev->_next = newNode; + newNode->_next->_prev = newNode; } - void insert(iterator pos, iterator beg, Iterator end) { - ... + template + void insert(iterator pos, iterator2 first, iterator2 last) { + for (; first != last; ++first) + insert(pos, *first); } - void erase(iterator beg, Iterator end) { - ... + iterator erase(iterator pos) { + assert(pos != end()); + + NodeBase *next = pos._node->_next; + NodeBase *prev = pos._node->_prev; + Node *node = static_cast *>(pos._node); + prev->_next = next; + next->_prev = prev; + delete node; + return next; } - void remove(const T &val) { + iterator erase(iterator first, iterator last) { + while (first != last) + erase(first++); + return last; } +// void remove(const T &val) { +// ... +// } + List& operator =(const List& list) { - // Careful here: handle self-assignment properly! I.e. situations like - // List x; - // ... - // x = x; - // In particular, we can't just do this: - // clear(); - // insert(_first, list.begin(), list.end()); - ... + if (this != &list) { + // TODO: This could (and should) be optimized, by reusing + // the existing nodes... + clear(); + insert(begin(), list.begin(), list.end()); + } + + return *this; } uint size() const { - int size = 0; + int n = 0; for (const_iterator i = begin(); i != end(); ++i) - size++; - return size; + ++n; + return n; } void clear() { @@ -122,13 +184,12 @@ public: } bool isEmpty() const { - return (_anchor._node == _anchor._node._next); + return (_anchor == _anchor->_next); } iterator begin() { - Iterator iter = _anchor; - return ++iter; + return _anchor->_next; } iterator end() { @@ -136,15 +197,13 @@ public: } const_iterator begin() const { - Iterator iter = _anchor; - return ++iter; + return _anchor->_next; } const_iterator end() const { return _anchor; } }; -*/ } // End of namespace Common -- cgit v1.2.3