mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-02-02 01:45:31 +00:00
Various improvements to misc/list.hpp
This commit is contained in:
parent
2e2f8e9725
commit
3df4362b33
1 changed files with 86 additions and 18 deletions
104
misc/list.hpp
104
misc/list.hpp
|
@ -6,27 +6,23 @@
|
|||
namespace Misc{
|
||||
|
||||
/*
|
||||
This is just a suggested data structure for List. You can use
|
||||
anything that has next and prev pointers.
|
||||
*/
|
||||
template <typename X>
|
||||
struct ListElem
|
||||
{
|
||||
X data;
|
||||
ListElem *next;
|
||||
ListElem *prev;
|
||||
};
|
||||
|
||||
/*
|
||||
A generic class that contains a doubly linked list of elements. It
|
||||
does not do any allocation of elements, it just keeps pointers to
|
||||
them.
|
||||
A simple and completely allocation-less doubly linked list. The
|
||||
class only manages pointers to and between elements. It leaving all
|
||||
memory management to the user.
|
||||
*/
|
||||
template <typename Elem>
|
||||
struct List
|
||||
{
|
||||
List() : head(0), tail(0), totalNum(0) {}
|
||||
|
||||
// Empty the list.
|
||||
void reset()
|
||||
{
|
||||
head = 0;
|
||||
tail = 0;
|
||||
totalNum = 0;
|
||||
}
|
||||
|
||||
// Insert an element at the end of the list. The element cannot be
|
||||
// part of any other list when this is called.
|
||||
void insert(Elem *p)
|
||||
|
@ -95,9 +91,81 @@ struct List
|
|||
return res;
|
||||
}
|
||||
|
||||
Elem* getHead() { return head; }
|
||||
Elem* getTail() { return tail; }
|
||||
unsigned int getNum() { return totalNum; }
|
||||
// Swap the contents of this list with another of the same type
|
||||
void swap(List &other)
|
||||
{
|
||||
Elem *tmp;
|
||||
|
||||
tmp = head;
|
||||
head = other.head;
|
||||
other.head = tmp;
|
||||
|
||||
tmp = tail;
|
||||
tail = other.tail;
|
||||
other.tail = tmp;
|
||||
|
||||
unsigned int tmp2 = totalNum;
|
||||
totalNum = other.totalNum;
|
||||
other.totalNum = tmp2;
|
||||
}
|
||||
|
||||
/* Absorb the contents of another list. All the elements from the
|
||||
list are moved to the end of this list, and the other list is
|
||||
cleared.
|
||||
*/
|
||||
void absorb(List &other)
|
||||
{
|
||||
assert(&other != this);
|
||||
if(other.totalNum)
|
||||
{
|
||||
absorb(other.head, other.tail, other.totalNum);
|
||||
other.reset();
|
||||
}
|
||||
assert(other.totalNum == 0);
|
||||
}
|
||||
|
||||
/* Absorb a range of elements, endpoints included. The elements are
|
||||
assumed NOT to belong to any list, but they ARE assumed to be
|
||||
connected with a chain between them.
|
||||
|
||||
The connection MUST run all the way from 'first' to 'last'
|
||||
through the ->next pointers, and vice versa through ->prev
|
||||
pointers.
|
||||
|
||||
The parameter 'num' must give the exact number of elements in the
|
||||
chain.
|
||||
|
||||
Passing first == last, num == 1 is allowed and is equivalent to
|
||||
calling insert().
|
||||
*/
|
||||
void absorb(Elem* first, Elem *last, int num)
|
||||
{
|
||||
assert(first && last && num>=1);
|
||||
if(tail)
|
||||
{
|
||||
// There are existing elements. Insert the first node at the
|
||||
// end of the list.
|
||||
assert(head && totalNum > 0);
|
||||
tail->next = first;
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is the first element
|
||||
assert(head == 0 && totalNum == 0);
|
||||
head = first;
|
||||
}
|
||||
|
||||
// These have to be done in either case
|
||||
first->prev = tail;
|
||||
last->next = 0;
|
||||
tail = last;
|
||||
|
||||
totalNum += num;
|
||||
}
|
||||
|
||||
Elem* getHead() const { return head; }
|
||||
Elem* getTail() const { return tail; }
|
||||
unsigned int getNum() const { return totalNum; }
|
||||
|
||||
private:
|
||||
|
||||
|
|
Loading…
Reference in a new issue