#include "CObjectList.h"
#include <iostream>
using namespace std;
using namespace zitadell;
int main()
{
//create a list for integers
CObjectList<int> *list = new CObjectList<int>;
int v1, v2, v3, v4;
v1=10; v2=20; v3=30; v4=40;
//add the ptrs to the integers to the list
int *item = 0;
item = &v1
list->insertNewItem(item);
item = &v2
list->insertNewItem(item);
item = &v3
list->insertNewItem(item);
item = &v4
list->insertNewItem(item);
//check the list and print some contents
cout << "First Item: " << *list->getFirstItem() << '\n';
while(!list->isLast())
cout << *list->getNextItem() << '\n';
cout << "Number of nodes: " << list->getCount() << '\n';
list->moveFirst(&v1); //move v1 to the top of the list
while(!list->isEmpty()) //delete the nodes, could be done by destructor also
{
cout << "Last Item: " << *list->getFirstItem() << '\n';
cout << "Deleting Last Item...: " << '\n';
list->deleteItem();
cout << "Number of nodes: " << list->getCount() << '\n';
}
delete list;
return 0;
};
#ifndef ZITADELL_COBJECTLIST_H
#define ZITADELL_COBJECTLIST_H
#include "CObjectListItem.h"
namespace zitadell
{
template <class ITEM>
class CObjectList
{
private:
CObjectListItem<ITEM> *m_pFirst; //ptr to the first item in the list
CObjectListItem<ITEM> *m_pLast; //ptr to the last item in the list
CObjectListItem<ITEM> *m_pCurrent; //pointer to the current item (if any) in the list
int m_iNodes; //number of nodes in the list
public:
//CONSTRUCTOR
CObjectList();
//DESTRUCTOR
~CObjectList();
//MODIFICATION MEMBER METHODS
void insertNewItem (ITEM *item); //creates a new node and inserts it first, sets m_pCurrent
void deleteItem (ITEM *item); //delete the node containing *item. sets m_pCurrent
void deleteItem (); //delete the current item.sets m_pCurrent
void moveFirst (ITEM *item); //moves the specified item to the top if it exists
void moveLast (ITEM *item); //moves the specified item to the bottom if it exists
ITEM *getFirstItem (); //returns a ptr to the first item in the list, sets m_pCurrent
ITEM *getLastItem (); //returns a ptr to the last object. sets m_pCurrent
ITEM *getNextItem (); //advances one and returns current ptr. sets m_pCurrent
ITEM *getPrevItem (); //reverses one and returns current ptr. sets m_pCurrent
//CONSTANT MEMBER METHODS
ITEM *getCurrentItem(); //returns a ptr to the current item
int getCount() { return m_iNodes; }; //returns the number of nodes in the list
//returns true if the list is empty
bool isEmpty() { return (m_pFirst == 0 && m_pLast == 0); };
//returns true if the current position is the first node
bool isFirst() { return (m_pCurrent == m_pFirst && isEmpty() == false);};
//returns true if the current position is the last node
bool isLast() { return (m_pCurrent == m_pLast && isEmpty() == false); };
private:
//if *item exists in the list, findNode returns a ptr to the node
CObjectListItem<ITEM> *findNode (ITEM *item);
//creates a new node on the heap and returns a ptr to it
CObjectListItem<ITEM> *newNode (ITEM *item);
//extracts a node out of the list if it exists
void extractNode(CObjectListItem<ITEM> *node);
//inserts a node first in the list
void insertFirst(CObjectListItem<ITEM> *node);
//inserts a node last in the list
void insertLast (CObjectListItem<ITEM> *node);
};//end class definition
/**************************************************************************************
//CONSTRUCTOR
**************************************************************************************/
template <class ITEM>
CObjectList<ITEM>::CObjectList()
: m_pFirst(0), m_pLast(0), m_pCurrent(0), m_iNodes(0)
{
};
/**************************************************************************************
//DESTRUCTOR
**************************************************************************************/
template <class ITEM>
CObjectList<ITEM>::~CObjectList()
{
m_pCurrent = m_pFirst;
while(m_pCurrent != 0)
{
m_pFirst = m_pCurrent->getNextNode();
delete m_pCurrent;
m_pCurrent = m_pFirst;
}
m_pLast = 0;
};
/**************************************************************************************
//PUBLIC
**************************************************************************************/
///////////////////////////////////////////////////////////////////////////////////////
//MODFICATION MEMBER METHODS
///////////////////////////////////////////////////////////////////////////////////////
template <class ITEM>
void CObjectList<ITEM>::insertNewItem(ITEM *item)
{
if(findNode(item) != 0)
return; //return if node already exists
m_pCurrent = newNode(item); //create a new node
insertFirst(m_pCurrent); //insert the new node first
m_iNodes += 1; //increase the number of nodes
};
//-------------------------------------------------------------------------------------
template <class ITEM>
void CObjectList<ITEM>::deleteItem(ITEM *item)
{
m_pCurrent = findNode(item); //find the node with the correct item
deleteItem();
};
//-------------------------------------------------------------------------------------
template <class ITEM>
void CObjectList<ITEM>::deleteItem()
{
if(m_pCurrent == 0) //continue only if valid current node
return;
extractNode(m_pCurrent); //extract the node from the list if found
m_pCurrent->setItem(0); //set item to zero
delete m_pCurrent; //delete the node
m_pCurrent = m_pFirst; //reset m_pCurrent to the first node
m_iNodes -= 1; //decrease the number of nodes
};
//-------------------------------------------------------------------------------------
template <class ITEM>
void CObjectList<ITEM>::moveFirst(ITEM *item)
{
m_pCurrent = findNode(item);
if(m_pCurrent == 0)
return;
extractNode(m_pCurrent);
insertFirst(m_pCurrent);
};
//-------------------------------------------------------------------------------------
template <class ITEM>
void CObjectList<ITEM>::moveLast(ITEM *item)
{
m_pCurrent = findNode(item);
if(m_pCurrent == 0)
return;
extractNode(m_pCurrent);
insertLast(m_pCurrent);
};
//-------------------------------------------------------------------------------------
template <class ITEM>
ITEM *CObjectList<ITEM>::getFirstItem()
{
m_pCurrent = m_pFirst;
return m_pCurrent != 0 ? m_pCurrent->getItem() : 0;
};
//-------------------------------------------------------------------------------------
template <class ITEM>
ITEM *CObjectList<ITEM>::getLastItem()
{
m_pCurrent = m_pLast;
return m_pCurrent != 0 ? m_pCurrent->getItem() : 0;
};
//-------------------------------------------------------------------------------------
template <class ITEM>
ITEM *CObjectList<ITEM>::getNextItem()
{
if(m_pCurrent != 0)
m_pCurrent = m_pCurrent->getNextNode();
return m_pCurrent != 0 ? m_pCurrent->getItem() : 0;
};
//-------------------------------------------------------------------------------------
template <class ITEM>
ITEM *CObjectList<ITEM>::getPrevItem()
{
if(m_pCurrent != 0)
m_pCurrent = m_pCurrent->getPrevNode();
return m_pCurrent != 0 ? m_pCurrent->getItem() : 0;
};
///////////////////////////////////////////////////////////////////////////////////////
//CONSTANT MEMBER METHODS
///////////////////////////////////////////////////////////////////////////////////////
template <class ITEM>
ITEM *CObjectList<ITEM>::getCurrentItem()
{
return m_pCurrent != 0 ? m_pCurrent->getItem() : 0;
};
/**************************************************************************************
//PRIVATE
**************************************************************************************/
///////////////////////////////////////////////////////////////////////////////////////
//MODFICATION MEMBER METHODS
///////////////////////////////////////////////////////////////////////////////////////
template <class ITEM>
CObjectListItem<ITEM> *CObjectList<ITEM>::newNode(ITEM *item)
{
CObjectListItem<ITEM> *new_node = new CObjectListItem<ITEM>(item);
return new_node;
};
//-------------------------------------------------------------------------------------
template <class ITEM>
void CObjectList<ITEM>::extractNode(CObjectListItem<ITEM> *node)
{
//rest the nodes in front of and after the extracted node
if(node->getNextNode() != 0)
node->getNextNode()->setPrevNode(node->getPrevNode());
else
m_pLast = node->getPrevNode();
if(node->getPrevNode() != 0)
node->getPrevNode()->setNextNode(node->getNextNode());
else
m_pFirst = node->getNextNode();
//remove the node links
node->setNextNode(0);
node->setPrevNode(0);
};
///////////////////////////////////////////////////////////////////////////////////////
//CONSTANT MEMBER METHODS
///////////////////////////////////////////////////////////////////////////////////////
template <class ITEM>
CObjectListItem<ITEM> *CObjectList<ITEM>::findNode(ITEM *item)
{
if(isEmpty())
return 0; //return if list is empty
CObjectListItem<ITEM> *node = 0;
node = m_pFirst;
while(node != 0)
{
if(node->getItem() == item)
break;
node = node->getNextNode();
}
return node;
};
//-------------------------------------------------------------------------------------
template <class ITEM>
void CObjectList<ITEM>::insertFirst(CObjectListItem<ITEM> *node)
{
node->setLink(m_pFirst,0);
if(m_pFirst != 0)
m_pFirst->setPrevNode(node); //reset current first node
m_pFirst = node; //reset the first node pointer
if(m_pLast == 0) //reset last node ptr if empty
m_pLast = node;
};
//-------------------------------------------------------------------------------------
template <class ITEM>
void CObjectList<ITEM>::insertLast(CObjectListItem<ITEM> *node)
{
node->setLink(0,m_pLast);
if(m_pLast != 0)
m_pLast->setNextNode(node); //reset current first node
m_pLast = node; //reset the first node pointer
if(m_pFirst == 0) //reset last node ptr if empty
m_pFirst = node;
};
};//end namespace
#endif
#ifndef ZITADELL_COBJECTLISTITEM_H
#define ZITADELL_COBJECTLISTITEM_H
namespace zitadell
{
template <class ITEM>
class CObjectListItem
{
private:
ITEM *m_pItem;
CObjectListItem<ITEM> *m_pNext;
CObjectListItem<ITEM> *m_pPrev;
public:
//CONSTRUCTOR
CObjectListItem(ITEM *pItem = 0);
//DESTRUCTOR
~CObjectListItem();
//CONSTANT MEMBER METHODS
ITEM *getItem () { return m_pItem; };
CObjectListItem<ITEM> *getNextNode () { return m_pNext; };
CObjectListItem<ITEM> *getPrevNode () { return m_pPrev; };
//MODIFICATION MEMBER METHODS
void setItem (ITEM *pItem);
void setLink (CObjectListItem<ITEM> *pNext, CObjectListItem<ITEM> *pPrev);
void setNextNode (CObjectListItem<ITEM> *next) { m_pNext = next; };
void setPrevNode (CObjectListItem<ITEM> *prev) { m_pPrev = prev; };
};//end class definition
/**************************************************************************************
//CONSTRUCTOR
**************************************************************************************/
template <class ITEM>
CObjectListItem<ITEM>::CObjectListItem(ITEM *pItem)
: m_pItem(pItem), m_pNext(0), m_pPrev(0)
{
};
/**************************************************************************************
//DESTRUCTOR
**************************************************************************************/
template <class ITEM>
CObjectListItem<ITEM>::~CObjectListItem()
{
setItem(0);
setLink(0,0);
};
/**************************************************************************************
//PUBLIC
**************************************************************************************/
///////////////////////////////////////////////////////////////////////////////////////
//MODFICATION MEMBER METHODS
///////////////////////////////////////////////////////////////////////////////////////
template <class ITEM>
void CObjectListItem<ITEM>::setItem(ITEM *pItem)
{
m_pItem = pItem;
};
//-------------------------------------------------------------------------------------
template <class ITEM>
void CObjectListItem<ITEM>::setLink(CObjectListItem<ITEM> *pNext, CObjectListItem<ITEM> *pPrev)
{
m_pNext = pNext;
m_pPrev = pPrev;
};
///////////////////////////////////////////////////////////////////////////////////////
//CONSTANT MEMBER METHODS
///////////////////////////////////////////////////////////////////////////////////////
//-------------------------------------------------------------------------------------
/**************************************************************************************
//PRIVATE
**************************************************************************************/
///////////////////////////////////////////////////////////////////////////////////////
//MODFICATION MEMBER METHODS
///////////////////////////////////////////////////////////////////////////////////////
//-------------------------------------------------------------------------------------
///////////////////////////////////////////////////////////////////////////////////////
//CONSTANT MEMBER METHODS
///////////////////////////////////////////////////////////////////////////////////////
//-------------------------------------------------------------------------------------
};//end namespace
#endif