Ticket #8803: list.patch

File list.patch, 5.1 KB (added by lordhoto, 16 years ago)
  • list.h

     
    261261        }
    262262};
    263263
     264/**
     265 * Simple double linked list, modeled after the list template of the standard
     266 * C++ library.
     267 */
     268template<class t_T>
     269class List<t_T*> {
     270protected:
     271#if defined (_WIN32_WCE) || defined (_MSC_VER)
     272//FIXME evc4 and msvc7 doesn't like it as protected member
     273public:
     274#endif
     275        struct NodeBase {
     276                NodeBase *_prev;
     277                NodeBase *_next;
     278        };
     279
     280        template <class t_T2>
     281        struct Node : public NodeBase {
     282                t_T2 _data;
     283
     284                Node(const t_T2 &x) : _data(x) {}
     285        };
     286
     287        template <class t_T2>
     288        class Iterator {
     289                friend class List<t_T*>;
     290                NodeBase *_node;
     291
     292#if !defined (__WINSCW__)
     293                explicit Iterator(NodeBase *node) : _node(node) {}
     294#else
     295                Iterator(NodeBase *node) : _node(node) {}
     296#endif
     297
     298        public:
     299                Iterator() : _node(0) {}
     300
     301                // Prefix inc
     302                Iterator<t_T2> &operator++() {
     303                        if (_node)
     304                                _node = _node->_next;
     305                        return *this;
     306                }
     307                // Postfix inc
     308                Iterator<t_T2> operator++(int) {
     309                        Iterator tmp(_node);
     310                        ++(*this);
     311                        return tmp;
     312                }
     313                // Prefix dec
     314                Iterator<t_T2> &operator--() {
     315                        if (_node)
     316                                _node = _node->_prev;
     317                        return *this;
     318                }
     319                // Postfix dec
     320                Iterator<t_T2> operator--(int) {
     321                        Iterator tmp(_node);
     322                        --(*this);
     323                        return tmp;
     324                }
     325                t_T2& operator*() const {
     326                        assert(_node);
     327#if (__GNUC__ == 2) && (__GNUC_MINOR__ >= 95)
     328                        return static_cast<List<t_T*>::Node<t_T2> *>(_node)->_data;
     329#else
     330                        return static_cast<Node<t_T2>*>(_node)->_data;
     331#endif
     332                }
     333                t_T2* operator->() const {
     334                        return &(operator*());
     335                }
     336
     337                bool operator==(const Iterator<t_T2>& x) const {
     338                        return _node == x._node;
     339                }
     340
     341                bool operator!=(const Iterator<t_T2>& x) const {
     342                        return _node != x._node;
     343                }
     344        };
     345
     346        NodeBase *_anchor;
     347        bool _autoFree;
     348
     349public:
     350        typedef Iterator<t_T*>                  iterator;
     351        typedef Iterator<t_T* const>    const_iterator;
     352
     353        typedef t_T* value_type;
     354
     355public:
     356        List(bool autoFree = false) : _autoFree(autoFree) {
     357                _anchor = new NodeBase;
     358                _anchor->_prev = _anchor;
     359                _anchor->_next = _anchor;
     360        }
     361        List(const List<t_T*>& list) {
     362                // FIXME: really set _autoFree to false here?
     363                _autoFree = false;
     364                _anchor = new NodeBase;
     365                _anchor->_prev = _anchor;
     366                _anchor->_next = _anchor;
     367
     368                insert(begin(), list.begin(), list.end());
     369        }
     370
     371        ~List() {
     372                clear();
     373                delete _anchor;
     374        }
     375
     376        void push_front(t_T *const &element) {
     377                insert(begin(), element);
     378        }
     379
     380        void push_back(t_T *const &element) {
     381                insert(end(), element);
     382        }
     383
     384        void insert(iterator pos, t_T *const &element) {
     385                NodeBase *newNode = new Node<t_T*>(element);
     386
     387                newNode->_next = pos._node;
     388                newNode->_prev = pos._node->_prev;
     389                newNode->_prev->_next = newNode;
     390                newNode->_next->_prev = newNode;
     391        }
     392
     393    template <typename iterator2>
     394        void insert(iterator pos, iterator2 first, iterator2 last) {
     395                for (; first != last; ++first)
     396                        insert(pos, *first);
     397        }
     398
     399        iterator erase(iterator pos) {
     400                assert(pos != end());
     401
     402                NodeBase *next = pos._node->_next;
     403                NodeBase *prev = pos._node->_prev;
     404                if (_autoFree)
     405                        delete *pos;
     406                Node<t_T*> *node = static_cast<Node<t_T*> *>(pos._node);
     407                prev->_next = next;
     408                next->_prev = prev;
     409                delete node;
     410                return iterator(next);
     411        }
     412
     413        iterator reverse_erase(iterator pos) {
     414                assert(pos != end());
     415
     416                NodeBase *next = pos._node->_next;
     417                NodeBase *prev = pos._node->_prev;
     418                if (_autoFree)
     419                        delete *pos;
     420                Node<t_T*> *node = static_cast<Node<t_T*> *>(pos._node);
     421                prev->_next = next;
     422                next->_prev = prev;
     423                delete node;
     424                return iterator(prev);
     425        }
     426
     427        iterator erase(iterator first, iterator last) {
     428                while (first != last)
     429                        erase(first++);
     430
     431                return last;
     432        }
     433
     434        void remove(t_T *const &val) {
     435                iterator i = begin();
     436                while (i != end())
     437                        if (val == i.operator*())
     438                                i = erase(i);
     439                        else
     440                                ++i;
     441        }
     442
     443
     444        List<t_T*>& operator  =(const List<t_T*>& list) {
     445                if (this != &list) {
     446                        iterator i;
     447                        const_iterator j;
     448
     449                        for (i = begin(), j = list.begin();  (i != end()) && (j != list.end()) ; ++i, ++j) {
     450                                if (_autoFree)
     451                                        delete *i;
     452                                static_cast<Node<t_T*> *>(i._node)->_data = static_cast<Node<t_T*> *>(j._node)->_data;
     453                        }
     454
     455                        if (i == end())
     456                                insert(i, j, list.end());
     457                        else
     458                                erase(i, end());
     459                        // FIXME: really set _autoFree to false here?
     460                        _autoFree = false;
     461                }
     462
     463                return *this;
     464        }
     465
     466        uint size() const {
     467                int n = 0;
     468                for (const_iterator i = begin(); i != end(); ++i)
     469                        ++n;
     470                return n;
     471        }
     472
     473        void clear() {
     474                erase(begin(), end());
     475        }
     476
     477        bool empty() const {
     478                return (_anchor == _anchor->_next);
     479        }
     480
     481
     482        iterator                begin() {
     483                return iterator(_anchor->_next);
     484        }
     485
     486        iterator                reverse_begin() {
     487                return iterator(_anchor->_prev);
     488        }
     489
     490        iterator                end() {
     491                return iterator(_anchor);
     492        }
     493
     494        const_iterator  begin() const {
     495                return const_iterator(_anchor->_next);
     496        }
     497
     498        const_iterator  reverse_begin() const {
     499                return const_iterator(_anchor->_prev);
     500        }
     501
     502        const_iterator  end() const {
     503                return const_iterator(_anchor);
     504        }
     505};
    264506} // End of namespace Common
    265507
    266508#endif