/////////////////////////////////////////////////////////////////////////////// // // ## ###### // ###### ### Based on: // ## ############### // ########## # # # Shark 3D Engine (www.shark3d.com) // ######## // ######### # # # Copyright (c) 1996-2001 Spinor GmbH. // ## ########## // ## // ///////////////////////////////////////////////////////////////////////////////// // // G A M E.O.N.E - LOW LEVEL LIB V1.0 // Copyright (C) 2001 LEVEL ONE ENTERTAINMENT, // Licensed under the terms of LGPL. //:--------------------------------------------------------------------------- //:Description // // LOW LEVEL QUEUE_LIST TEMPLATE HEADERFILE // #ifndef _LLQUEUE_LIST_TMPL_H #define _LLQUEUE_LIST_TMPL_H #include "llqueue_list.h" namespace llqueue { template class CListNode; template class CList; /* * Double Linked List Node Template * Template Argument ist der Node Inhalt (m_Data) */ template class CListNode: private queue_listnode { public: T m_Data; // The content carried by this node: CListNode(); // Default constructor. CListNode(const T &Data); // Constructor initializing the content. CListNode(const CListNode &Node);// Copy constructor, which copies the content. ~CListNode(); // Destructor. The node is extracted from the list automatically if necessary. CListNode &operator=(const CListNode &Node);// Assignment operator, which assigns the content. CListNode *GetPrev() const;// Get the previous node. CListNode *GetNext() const;// Get the next node. CList *GetBase() const;// Get the node owning this list. bool IsInserted() const;// Is this node part of a list? // Extract this node from the list. // Then the node is not part of the list any more. // Note that this method does not destroy the node. // If you both want to destroy the node and extract it from the list, // use the delete. void Extract(); private: friend class CList; }; /* * An intrusive list. * The template argument is the content carried by the node * in CListNode::m_Data. * * Important! * A list CList does not own its nodes. * Thus, if you insert a node into a list, the list does not copy * or take over ownership of the node. * * If the node is destroyed, it is automatically also extracted * from the list. * If the list is destroyed, all its nodes are extracted out of the list, * but not destroyed. * If you want to free all nodes, use CList::DeleteAll. * * A list has similar properties like a tree, * * CList is primary designed for performance critical * low-level code. The user has to allocate, manage and deallocate * the list nodes explicitely. * For a more high-level container template class, see CArray. * * The entries of a list can be enumerated by a loop like the following: * { * void HandleEachValue(CList *List) * { * CList::CNode *Node; * for(Node = List->GetFirst(); Node; Node = Node->GetNext()) * HandleValue(Node->m_Data); * } * } * Warning! As long as such a loop is active, you should ensure * that the list is not modified to avoid illegal node pointers. * * * Since the user manages the list nodes, they can be managed * efficiently by putting them in structures or classes * which anyway are existing. * For example, it all objects of an type should be registered * somewhere, these objects may carry by themself the list node: * * { * class CMyObj * { * public: * CMyObj() { m_Node.m_Data = this; } * friend class CMyObjManager; * private: * int m_MyData; * CList::CNode m_Node; * } * * class CMyObjManager * { * public: * CMyObj *CreateMyObj(); * private: * CList m_List; * } * * CMyObj *CMyObjManager::CreateMyObj() * { * CMyObj *MyObj = SYS_NEW CMyObj; * m_List.InsertBack(&MyObj->m_Node); * return MyObj; * } * } * By this, the manager always has an up-to-date list * of all object it has created. * But note that the manager is not the owner of these objects. * If an object created by @code{CMyObjManager::CreateMyObj} is destroyed * by the user, it also automatically is extracted from the list. */ template class CList: private queue_listhead { public: typedef CListNode CNode; CList(); ~CList(); // retrieve elements and information CListNode *GetFirst() const; CListNode *GetLast() const; bool IsEmpty() const; bool Contains(CListNode *Node); int GetCount() const; // inserting elements void InsertFront(CListNode *Node); void InsertBack(CListNode *Node); void InsertAfter(CListNode *Node, CListNode *Pos); void InsertBefore(CListNode *Node, CListNode *Pos); void CopyFrom(const CList &Base); // delete ALL void ExtractAll(); void DeleteAll(); private: CList(const CList &List); CList &operator=(const CList &List); }; /* * Implementation */ template inline CListNode::CListNode() { } template inline CListNode::CListNode(const T &Con) : m_Data(Con) { } template inline CListNode::CListNode(const CListNode &Node) : m_Data(Node.m_Data) { } template inline CListNode::~CListNode() { } template inline CListNode &CListNode::operator=( const CListNode &Node) { m_Data = Node.m_Data; return *this; } template inline CListNode *CListNode::GetPrev() const { return reinterpret_cast*>(queue_listnode::GetPrev()); } template inline CListNode *CListNode::GetNext() const { return reinterpret_cast*>(queue_listnode::GetNext()); } template inline CList *CListNode::GetBase() const { return reinterpret_cast*>(queue_listnode::GetBase()); } template inline bool CListNode::IsInserted() const { return queue_listnode::IsInserted(); } template inline void CListNode::Extract() { queue_listnode::Extract(); } template inline CList::CList() { } template inline CList::~CList() { } template inline CListNode *CList::GetFirst() const { return reinterpret_cast*>(queue_listhead::GetFirst()); } template inline CListNode *CList::GetLast() const { return reinterpret_cast*>(queue_listhead::GetLast()); } template inline bool CList::IsEmpty() const { return queue_listhead::IsEmpty(); } template inline bool CList::Contains(CListNode *Node) { return queue_listhead::Contains(Node); } template inline int CList::GetCount() const { return queue_listhead::GetCount(); } template inline void CList::InsertFront(CListNode *Node) { queue_listhead::InsertFront(Node); } template inline void CList::InsertBack(CListNode *Node) { queue_listhead::InsertBack(Node); } template inline void CList::InsertAfter(CListNode *Node, CListNode *Pos) { queue_listhead::InsertAfter(Node, Pos); } template inline void CList::InsertBefore(CListNode *Node, CListNode *Pos) { queue_listhead::InsertBefore(Node, Pos); } template inline void CList::ExtractAll() { queue_listhead::ExtractAll(); } template void CList::DeleteAll() { while(m_First) delete m_First; } template void CList::CopyFrom(const CList &Base) { DeleteAll(); CListNode *Node; for(Node = Base.m_First; Node; Node = Node->m_Next) { CListNode *Copy = new CListNode(*Node); InsertBack(Copy); } } }// namespace ll #endif // _LLQUEUE_LIST_TMPL_H