#ifndef LIST_H #define LIST_H template 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