/* ScummVM - Scumm Interpreter * Copyright (C) 2002-2004 The ScummVM project * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * $Header$ */ #ifndef COMMON_LIST_H #define COMMON_LIST_H #include "common/scummsys.h" #include namespace Common { /** * 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: struct NodeBase { NodeBase *_prev; NodeBase *_next; }; template struct Node : public NodeBase { T2 _data; Node(const T2 &x) : _data(x) {} }; template struct Iterator { NodeBase *_node; Iterator() : _node(0) {} Iterator(NodeBase *node) : _node(node) {} // Prefix inc Iterator &operator++() { if (_node) _node = _node->_next; return *this; } // Postfix inc Iterator operator++(int) { Iterator tmp = *this; if (_node) _node = _node->_next; return tmp; } // Prefix dec Iterator &operator--() { if (_node) _node = _node->_prev; return *this; } // Postfix dec Iterator operator--(int) { Iterator tmp = *this; if (_node) _node = _node->_prev; return tmp; } T2& operator*() const { assert(_node); return static_cast*>(_node)->_data; } T2* operator->() const { return &(operator*()); } bool operator==(const Iterator& x) const { return _node == x._node; } bool operator!=(const Iterator& x) const { return _node != x._node; } }; NodeBase *_anchor; public: typedef Iterator iterator; typedef Iterator const_iterator; public: 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() { clear(); delete _anchor; } void push_front(const T& element) { insert(begin(), element); } 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; } template void insert(iterator pos, iterator2 first, iterator2 last) { for (; first != last; ++first) insert(pos, *first); } 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; } iterator erase(iterator first, iterator last) { while (first != last) erase(first++); return last; } // void remove(const T &val) { // ... // } List& operator =(const List& list) { 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 n = 0; for (const_iterator i = begin(); i != end(); ++i) ++n; return n; } void clear() { erase(begin(), end()); } bool isEmpty() const { return (_anchor == _anchor->_next); } iterator begin() { return _anchor->_next; } iterator end() { return _anchor; } const_iterator begin() const { return _anchor->_next; } const_iterator end() const { return _anchor; } }; } // End of namespace Common #endif