[Scummvm-cvs-logs] SF.net SVN: scummvm:[40164] scummvm/trunk

fingolfin at users.sourceforge.net fingolfin at users.sourceforge.net
Mon Apr 27 16:25:16 CEST 2009


Revision: 40164
          http://scummvm.svn.sourceforge.net/scummvm/?rev=40164&view=rev
Author:   fingolfin
Date:     2009-04-27 14:25:16 +0000 (Mon, 27 Apr 2009)

Log Message:
-----------
COMMON: Improved efficiency of some Common::List methods; added more unit tests and some doxygen comments for Common::List and Common::Array

Modified Paths:
--------------
    scummvm/trunk/common/array.h
    scummvm/trunk/common/list.h
    scummvm/trunk/common/list_intern.h
    scummvm/trunk/test/common/list.h

Modified: scummvm/trunk/common/array.h
===================================================================
--- scummvm/trunk/common/array.h	2009-04-27 14:23:20 UTC (rev 40163)
+++ scummvm/trunk/common/array.h	2009-04-27 14:25:16 UTC (rev 40164)
@@ -65,6 +65,7 @@
 		delete[] _storage;
 	}
 
+	/** Appends element to the end of the array. */
 	void push_back(const T &element) {
 		ensureCapacity(_size + 1);
 		_storage[_size++] = element;
@@ -76,26 +77,31 @@
 		_size += array._size;
 	}
 
+	/** Removes the last element of the array. */
 	void pop_back() {
 		assert(_size > 0);
 		_size--;
 	}
 
+	/** Returns a reference to the first element of the array. */
 	T &front() {
 		assert(_size > 0);
 		return _storage[0];
 	}
 
+	/** Returns a reference to the first element of the array. */
 	const T &front() const {
 		assert(_size > 0);
 		return _storage[0];
 	}
 
+	/** Returns a reference to the last element of the array. */
 	T &back() {
 		assert(_size > 0);
 		return _storage[_size-1];
 	}
 
+	/** Returns a reference to the last element of the array. */
 	const T &back() const {
 		assert(_size > 0);
 		return _storage[_size-1];

Modified: scummvm/trunk/common/list.h
===================================================================
--- scummvm/trunk/common/list.h	2009-04-27 14:23:20 UTC (rev 40163)
+++ scummvm/trunk/common/list.h	2009-04-27 14:25:16 UTC (rev 40164)
@@ -63,94 +63,103 @@
 		clear();
 	}
 
+	/**
+	 * Inserts element before pos.
+	 */
 	void insert(iterator pos, const t_T &element) {
-		ListInternal::NodeBase *newNode = new Node(element);
-
-		newNode->_next = pos._node;
-		newNode->_prev = pos._node->_prev;
-		newNode->_prev->_next = newNode;
-		newNode->_next->_prev = newNode;
+		insert(pos._node, element);
 	}
 
+	/**
+	 * Inserts the elements from first to last before pos.
+	 */
 	template<typename iterator2>
 	void insert(iterator pos, iterator2 first, iterator2 last) {
 		for (; first != last; ++first)
 			insert(pos, *first);
 	}
 
+	/**
+	 * Deletes the element at location pos and returns an iterator pointing
+	 * to the element after the one which was deleted.
+	 */
 	iterator erase(iterator pos) {
 		assert(pos != end());
-
-		NodeBase *next = pos._node->_next;
-		NodeBase *prev = pos._node->_prev;
-		Node *node = static_cast<Node *>(pos._node);
-		prev->_next = next;
-		next->_prev = prev;
-		delete node;
-		return iterator(next);
+		return iterator(erase(pos._node)._next);
 	}
 
+	/**
+	 * Deletes the element at location pos and returns an iterator pointing
+	 * to the element before the one which was deleted.
+	 */
 	iterator reverse_erase(iterator pos) {
 		assert(pos != end());
-
-		NodeBase *next = pos._node->_next;
-		NodeBase *prev = pos._node->_prev;
-		Node *node = static_cast<Node *>(pos._node);
-		prev->_next = next;
-		next->_prev = prev;
-		delete node;
-		return iterator(prev);
+		return iterator(erase(pos._node)._prev);
 	}
 
+	/**
+	 * Deletes the elements between first and last (including first but not
+	 * last) and returns an iterator pointing to the element after the one
+	 * which was deleted (i.e., last).
+	 */
 	iterator erase(iterator first, iterator last) {
-		while (first != last)
-			erase(first++);
-
+		NodeBase *f = first._node;
+		NodeBase *l = last._node;
+		while (f != l)
+			f = erase(f)._next;
 		return last;
 	}
 
+	/**
+	 * Removes all elements that are equal to val from the list.
+	 */
 	void remove(const t_T &val) {
-		iterator i = begin();
-		const iterator e = end();
-		while (i != e)
-			if (val == *i)
-				i = erase(i);
+		NodeBase *i = _anchor._next;
+		while (i != &_anchor)
+			if (val == static_cast<Node *>(i)->_data)
+				i = erase(i)._next;
 			else
-				++i;
+				i = i->_next;
 	}
 
+	/** Inserts element at the start of the list. */
 	void push_front(const t_T &element) {
-		// TODO: Bypass iterators here for improved efficency
-		insert(begin(), element);
+		insert(_anchor._next, element);
 	}
 
+	/** Appends element to the end of the list. */
 	void push_back(const t_T &element) {
-		// TODO: Bypass iterators here for improved efficency
-		insert(end(), element);
+		insert(&_anchor, element);
 	}
 
+	/** Removes the first element of the list. */
 	void pop_front() {
-		// TODO: Bypass iterators here for improved efficency
-		erase(begin());
+		assert(!empty());
+		erase(_anchor._next);
 	}
 
+	/** Removes the last element of the list. */
 	void pop_back() {
-		// TODO: Bypass iterators here for improved efficency
-		erase(reverse_begin());
+		assert(!empty());
+		erase(_anchor._prev);
 	}
 
+	/** Returns a reference to the first element of the list. */
 	t_T &front() {
 		return static_cast<Node *>(_anchor._next)->_data;
 	}
 
+	/** Returns a reference to the first element of the list. */
 	const t_T &front() const {
 		return static_cast<Node *>(_anchor._next)->_data;
 	}
 
+	/** Returns a reference to the last element of the list. */
 	t_T &back() {
 		return static_cast<Node *>(_anchor._prev)->_data;
 	}
 
+	/** Returns a reference to the last element of the list. */
 	const t_T &back() const {
 		return static_cast<Node *>(_anchor._prev)->_data;
 	}
@@ -214,6 +223,28 @@
 	const_iterator	end() const {
 		return const_iterator(const_cast<NodeBase*>(&_anchor));
 	}
+
+protected:
+	NodeBase erase(NodeBase *pos) {
+		NodeBase n = *pos;
+		Node *node = static_cast<Node *>(pos);
+		n._prev->_next = n._next;
+		n._next->_prev = n._prev;
+		delete node;
+		return n;
+	}
+
+	/**
+	 * Inserts element before pos.
+	 */
+	void insert(NodeBase *pos, const t_T &element) {
+		ListInternal::NodeBase *newNode = new Node(element);
+
+		newNode->_next = pos;
+		newNode->_prev = pos->_prev;
+		newNode->_prev->_next = newNode;
+		newNode->_next->_prev = newNode;
+	}
 };
 
 } // End of namespace Common

Modified: scummvm/trunk/common/list_intern.h
===================================================================
--- scummvm/trunk/common/list_intern.h	2009-04-27 14:23:20 UTC (rev 40163)
+++ scummvm/trunk/common/list_intern.h	2009-04-27 14:25:16 UTC (rev 40164)
@@ -57,7 +57,7 @@
 		NodeBase *_node;
 
 		Iterator() : _node(0) {}
-		Iterator(NodeBase *node) : _node(node) {}
+		explicit Iterator(NodeBase *node) : _node(node) {}
 
 		// Prefix inc
 		Self &operator++() {
@@ -110,7 +110,7 @@
 		const NodeBase *_node;
 
 		ConstIterator() : _node(0) {}
-		ConstIterator(const NodeBase *node) : _node(node) {}
+		explicit ConstIterator(const NodeBase *node) : _node(node) {}
 		ConstIterator(const Iterator<T> &x) : _node(x._node) {}
 
 		// Prefix inc

Modified: scummvm/trunk/test/common/list.h
===================================================================
--- scummvm/trunk/test/common/list.h	2009-04-27 14:23:20 UTC (rev 40163)
+++ scummvm/trunk/test/common/list.h	2009-04-27 14:25:16 UTC (rev 40164)
@@ -104,6 +104,7 @@
 		container.insert(iter, 42);
 		container.insert(iter, 43);
 
+		// Verify contents are correct
 		iter = container.begin();
 
 		TS_ASSERT_EQUALS( *iter, 17 );
@@ -127,6 +128,82 @@
 		TS_ASSERT( iter == container.end() );
 	}
 
+	void test_erase() {
+		Common::List<int> container;
+		Common::List<int>::iterator first, last;
+
+		// Fill the container with some random data
+		container.push_back(17);
+		container.push_back(33);
+		container.push_back(-11);
+		container.push_back(42);
+		container.push_back(43);
+
+		// Iterate to after the second element
+		first = container.begin();
+		++first;
+		++first;
+
+		// Iterate to after the fourth element
+		last = first;
+		++last;
+		++last;
+
+		// Now erase that range
+		container.erase(first, last);
+
+		// Verify contents are correct
+		Common::List<int>::iterator iter = container.begin();
+
+		TS_ASSERT_EQUALS( *iter, 17 );
+		++iter;
+		TS_ASSERT( iter != container.end() );
+
+		TS_ASSERT_EQUALS( *iter, 33 );
+		++iter;
+		TS_ASSERT( iter != container.end() );
+
+		TS_ASSERT_EQUALS( *iter, 43 );
+		++iter;
+		TS_ASSERT( iter == container.end() );
+	}
+
+	void test_remove() {
+		Common::List<int> container;
+		Common::List<int>::iterator first, last;
+
+		// Fill the container with some random data
+		container.push_back(-11);
+		container.push_back(17);
+		container.push_back(33);
+		container.push_back(42);
+		container.push_back(-11);
+		container.push_back(42);
+		container.push_back(43);
+
+		// Remove some stuff
+		container.remove(42);
+		container.remove(-11);
+
+		// Now erase that range
+		container.erase(first, last);
+
+		// Verify contents are correct
+		Common::List<int>::iterator iter = container.begin();
+
+		TS_ASSERT_EQUALS( *iter, 17 );
+		++iter;
+		TS_ASSERT( iter != container.end() );
+
+		TS_ASSERT_EQUALS( *iter, 33 );
+		++iter;
+		TS_ASSERT( iter != container.end() );
+
+		TS_ASSERT_EQUALS( *iter, 43 );
+		++iter;
+		TS_ASSERT( iter == container.end() );
+	}
+
 	void test_reverse() {
 		Common::List<int> container;
 		Common::List<int>::iterator iter;
@@ -186,5 +263,13 @@
 		container.pop_front();
 		TS_ASSERT_EQUALS(container.front(), 163);
 		TS_ASSERT_EQUALS(container.back(),  163);
+
+		container.push_front(99);
+		TS_ASSERT_EQUALS(container.front(), 99);
+		TS_ASSERT_EQUALS(container.back(),  163);
+
+		container.pop_back();
+		TS_ASSERT_EQUALS(container.front(), 99);
+		TS_ASSERT_EQUALS(container.back(),  99);
 	}
 };


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list