Added a generic List class

This commit is contained in:
anschrammh 2019-05-08 23:06:13 +02:00
parent 359160fa6d
commit 01303f97bf

318
src/app/List.h Normal file
View File

@ -0,0 +1,318 @@
#ifndef LIST_H
#define LIST_H
template <typename T>
class List
{
public:
List():_next(NULL), _head(this), _value(NULL)
{
}
~List()
{
if(_head == this)
dispose();
}
boolean addFirst(T value)
{
List *listNode = new List(new T(value));
return addNewNodeAtTheStart(listNode);
}
boolean addFirst(T *value)
{
List *listNode = new List(value);
return addNewNodeAtTheStart(listNode);
}
boolean addLast(T value)
{
List *listNode = new List(new T(value));
return addNewNodeAtTheEnd(listNode);
}
boolean addLast(T *value)
{
List *listNode = new List(value);
return addNewNodeAtTheEnd(listNode);
}
T* getRef(unsigned int index)
{
unsigned int position(0);
if(_head->_next == NULL) return NULL;
List *cursor = _head;
while(!isListEmpty(cursor->_next))
{
if(position++ == index)
{
return cursor->_next->_value;
}
cursor = cursor->_next;
}
return NULL;
}
T get(unsigned int index)
{
T* p = getRef(index);
if(p == NULL)
{
T value;
return value;
}else
{
T value(*p);
return value;
}
}
T* getFirstRef()
{
if(_head->_next == NULL) return NULL;
return _head->_next->_value;
}
T getFirst()
{
T* p = getFirstRef();
if(p == NULL)
{
T value;
return value;
}else
{
T value(*p);
return value;
}
}
T* getLastRef()
{
if(_head->_next == NULL) return NULL;
List *cursor = _head;
while(!isListEmpty(cursor->_next))
{
cursor = cursor->_next;
}
return cursor->_value;
}
T getLast()
{
T* p = getLastRef();
if(p == NULL)
{
T value;
return value;
}else
{
T value(*p);
return value;
}
}
T* removeRef(unsigned int index)
{
unsigned int position(0);
if(_head->_next == NULL) return NULL;
List *cursor = _head, *toRemove(NULL);
while(!isListEmpty(cursor->_next))
{
if(position++ == index || position == _head->count())
{
toRemove = cursor->_next;
cursor->_next = cursor->_next->_next;
T *toReturn = toRemove->_value;
delete toRemove;
return toReturn;
}
cursor = cursor->_next;
}
return NULL;
}
T remove(unsigned int index)
{
T *ref = removeRef(index);
if(ref != NULL)
{
T value(*ref);
delete ref;
return value;
}else
{
T value;
return value;
}
}
T* removeFirstRef()
{
if(isListEmpty(_head->_next))return NULL;
T *refToReturn = _head->_next->_value;
List *toDelete(_head->_next);
_head->_next = _head->_next->_next;
delete toDelete;
return refToReturn;
}
T removeFirst()
{
T *ref = removeFirstRef();
if(ref != NULL)
{
T value(*ref);
delete ref;
return value;
}else
{
T value;
return value;
}
}
T* removeLastRef()
{
unsigned int position(0);
if(_head->_next == NULL) return NULL;
List *cursor = _head, *toRemove(NULL);
while(!isListEmpty(cursor->_next->_next))
{
cursor = cursor->_next;
}
toRemove = cursor->_next;
cursor->_next = cursor->_next->_next;
T *toReturn = toRemove->_value;
delete toRemove;
return toReturn;
}
T removeLast()
{
T *ref = removeLastRef();
if(ref != NULL)
{
T value(*ref);
delete ref;
return value;
}else
{
T value;
return value;
}
}
int contains(T *value)
{
unsigned int position(-1);
if(_head->_next == NULL) return NULL;
List *cursor = _head;
while(!isListEmpty(cursor->_next))
{
position++;
if(*(cursor->_next->_value) == *value)
return position;
cursor = cursor->_next;
}
return -1;
}
int contains(T value)
{
return contains(new T(value));
}
unsigned int count()
{
unsigned int counter(0);
if(isListEmpty(_head->_next))return counter;
List *cursor = _head->_next;
while(!isListEmpty(cursor))
{
counter++;
cursor = cursor->_next;
}
return counter;
}
void clear(){_head->dispose();}
void dispose()
{
if(isListEmpty(_head->_next))return;
List *cursor = _head->_next, *toDelete(NULL);
while(!isListEmpty(cursor))
{
toDelete = cursor;
cursor = cursor->_next;
delete toDelete->_value;
delete toDelete;
}
_head = this;
_next = NULL;
}
protected:
List(T *value):List()
{
_value = value;
}
boolean isListEmpty(List *node){return node == NULL;}
boolean addNewNodeAtTheEnd(List *node)
{
if(node == NULL) return false;
node->_head = _head;
if(_next == NULL)
{
_next = node;
return true;
}
// /!\ We have to work with the _next reference in the loop, if we don't it won't work as expected
List *cursor = _head;
while(!isListEmpty(cursor->_next))
{
cursor = cursor->_next;
}
cursor->_next = node;
return true;
}
boolean addNewNodeAtTheStart(List *node)
{
if(node == NULL) return false;
node->_head = _head;
if(_next == NULL)
{
_next = node;
return true;
}
List *temp = _next;
_next = node;
node->_next = temp;
return true;
}
List *_next;
List *_head;
T* _value;
private:
};
#endif //LIST_H