Files
mir_server/Gateway/srvlib/include/container/linked_list.h

404 lines
7.6 KiB
C
Raw Normal View History

2025-01-09 17:45:40 +08:00
#ifndef _LINKED_LIST_H_
#define _LINKED_LIST_H_
/******************************************************************
*
* $ <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> $
*
* ʵ<EFBFBD>ֶ<EFBFBD>̬<EFBFBD><EFBFBD><EFBFBD>ӡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD><EFBFBD>Vectorһ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҳ<EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* Vector<EFBFBD>Ƚϣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڽ<EFBFBD><EFBFBD><EFBFBD>ɾ<EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD>ܹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ķ<EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD>ʣ<EFBFBD>ȱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>DZ<EFBFBD><EFBFBD>б<EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˷<EFBFBD><EFBFBD>ڴ<EFBFBD>ڴ<EFBFBD><EFBFBD>Ϊ3~4<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD>ʱ<EFBFBD><EFBFBD>Ч<EFBFBD>ʼ<EFBFBD><EFBFBD>͡<EFBFBD>
*
*****************************************************************/
#include <assert.h>
#include "memory/objpool.hpp"
namespace container
{
template <typename T>
class BaseLinkedList;
template <typename T>
class ListIterator;
/*************************
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD><EFBFBD><EFBFBD>
**************************/
template <typename T>
class LinkedNode
{
public:
LinkedNode() {}
inline operator T& ()
{
return data_;
}
T data_;
public:
LinkedNode<T>* prev_;
LinkedNode<T>* next_;
BaseLinkedList<T>* self_;
};
/*************************
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
**************************/
template <typename T>
class ListIterator
{
friend class BaseLinkedList<T>;
public:
ListIterator()
{
list_ = NULL;
enuming_ = NULL;
prev_ = next_ = NULL;
}
ListIterator(BaseLinkedList<T>& list)
{
//list_ = NULL;
//enuming_ = NULL;
//prev_ = next_ = NULL;
//setList(list);
//wuzhihong edit
list_ = &list;
enuming_ = NULL;
next_ = NULL;
prev_ = list.iterator_;
if (prev_) prev_->next_ = this;
list.iterator_ = this;
}
~ListIterator()
{
if (list_)
{
if (prev_) prev_->next_ = next_;
if (next_) next_->prev_ = prev_;
if (this == list_->iterator_)
list_->iterator_ = prev_;
list_ = NULL;
enuming_ = NULL;
prev_ = next_ = NULL;
}
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ñ<EFBFBD><C3B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
inline void setList(BaseLinkedList<T>& list)
{
this->~ListIterator();
list_ = &list;
enuming_ = NULL;
next_ = NULL;
prev_ = list.iterator_;
if (prev_) prev_->next_ = this;
list.iterator_ = this;
}
//<2F>Ƴ<EFBFBD>һ<EFBFBD><D2BB><EFBFBD>ڵ㣬<DAB5><E3A3AC><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD>Ĺ<EFBFBD><C4B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƴ<EFBFBD><C6B3>ڵ<EFBFBD><DAB5>Ӷ<EFBFBD><D3B6>ƻ<EFBFBD><C6BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
inline void remove(LinkedNode<T>* pNode, bool boFree = true)
{
if (pNode == enuming_)
enuming_ = pNode->prev_;
list_->remove(pNode, boFree);
}
//<2F><>ͷ<EFBFBD><CDB7>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD>
inline LinkedNode<T>* first()
{
return enuming_ = list_->first();
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>ڵ<EFBFBD>
inline LinkedNode<T>* next()
{
return enuming_ = (enuming_ ? enuming_->next_ : list_->first());
}
//<2F><>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ľڵ<C4BD>
inline LinkedNode<T>* current()
{
return enuming_;
}
private:
LinkedNode<T>* enuming_;
BaseLinkedList<T>* list_;
ListIterator<T>* prev_;
ListIterator<T>* next_;
};
/*************************
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
**************************/
template <typename T>
class BaseLinkedList
{
friend class ListIterator<T>;
public:
typedef T InstancesType;
typedef LinkedNode<T> NodeType;
typedef ListIterator<T> Iterator;
public:
BaseLinkedList(ObjPool< LinkedNode<T> >* alloc = NULL)
{
first_node_ = last_node_ = NULL;
iterator_ = NULL;
count_ = 0;
allocator_ = alloc;
}
virtual ~BaseLinkedList()
{
clear();
}
//<2F><>ȡ<EFBFBD><C8A1>һ<EFBFBD><D2BB><EFBFBD>ڵ<EFBFBD>
inline LinkedNode<T>* first()
{
return first_node_;
}
//<2F><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>ڵ<EFBFBD>
inline LinkedNode<T>* last()
{
return last_node_;
}
//<2F><>ȡ<EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD>
inline int count() const
{
return count_;
}
/* <20><>pNode<64>ڵ<EFBFBD><DAB5><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>½ڵ<C2BD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>pNodeΪ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼλ<EFBFBD><EFBFBD>
*/
LinkedNode<T>* linkBefore(const T& data, LinkedNode<T>* node = NULL)
{
assert(!node || node->self_ == this);
if (!node) node = first_node_;
LinkedNode<T>* pPrev = node ? node->prev_ : NULL;
LinkedNode<T>* new_node = allocNode();
new_node->data_ = data;
new_node->prev_ = pPrev;
new_node->next_ = node;
if (pPrev)
pPrev->next_ = new_node;
else first_node_ = new_node;
if (node)
node->prev_ = new_node;
else last_node_ = new_node;
new_node->self_ = this;
count_++;
return new_node;
}
/* <20><>pNode<64>ڵ<EFBFBD><DAB5>ĺ<EFBFBD><C4BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>½ڵ<C2BD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>pNodeΪ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĩβ
*/
LinkedNode<T>* linkAfter(const T& data, LinkedNode<T>* pNode = NULL)
{
assert(!pNode || pNode->self_ == this);
if (!pNode) pNode = last_node_;
LinkedNode<T>* pNext = pNode ? pNode->next_ : NULL;
LinkedNode<T>* pNewNode = allocNode();
pNewNode->data_ = data;
pNewNode->prev_ = pNode;
pNewNode->next_ = pNext;
if (pNext)
pNext->prev_ = pNewNode;
else last_node_ = pNewNode;
if (pNode)
pNode->next_ = pNewNode;
else first_node_ = pNewNode;
pNewNode->self_ = this;
count_++;
return pNewNode;
}
/* <20><>pNode<64>ڵ<EFBFBD><DAB5><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>½ڵ<C2BD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>pNodeΪ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼλ<EFBFBD><EFBFBD>
*/
LinkedNode<T>* linkBefore(LinkedNode<T>* new_node, LinkedNode<T>* node = NULL)
{
assert(!node || node->self_ == this);
if (!node) node = first_node_;
LinkedNode<T>* pPrev = node ? node->prev_ : NULL;
new_node->prev_ = pPrev;
new_node->next_ = node;
if (pPrev)
pPrev->next_ = new_node;
else first_node_ = new_node;
if (node)
node->prev_ = new_node;
else last_node_ = new_node;
new_node->self_ = this;
count_++;
return new_node;
}
//<2F><><EFBFBD><EFBFBD>linkAfer<65><72><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD>node
LinkedNode<T>* Transfer(LinkedNode<T>* pNewNode, LinkedNode<T>* pNode = NULL)
{
assert(!pNode || pNode->self_ == this);
assert(pNewNode->self_ == NULL);
if (!pNode) pNode = last_node_;
LinkedNode<T>* pNext = pNode ? pNode->next_ : NULL;
pNewNode->prev_ = pNode;
pNewNode->next_ = pNext;
if (pNext)
pNext->prev_ = pNewNode;
else last_node_ = pNewNode;
if (pNode)
pNode->next_ = pNewNode;
else first_node_ = pNewNode;
pNewNode->self_ = this;
count_++;
return pNewNode;
}
//<2F><><EFBFBD><EFBFBD><EFBFBD>ݲ<EFBFBD><DDB2><EFBFBD><EBB5BD><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7>
inline LinkedNode<T>* linkAtFirst(const T& data)
{
return linkBefore(data, first_node_);
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӵ<EFBFBD><D3B5><EFBFBD><EFBFBD><EFBFBD>β<EFBFBD><CEB2>
inline LinkedNode<T>* linkAtLast(const T& data)
{
return linkAfter(data, last_node_);
}
inline LinkedNode<T>* TransferAtLast(LinkedNode<T>* pNewNode)
{
return Transfer(pNewNode, last_node_);
}
//ͨ<><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD>
LinkedNode<T>* getNodeAt(int nIndex)
{
for (LinkedNode<T>* pNode = first_node_; pNode; pNode = pNode->next_)
{
if (nIndex <= 0)
return pNode;
nIndex--;
}
return NULL;
}
/* <20>Ƴ<EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD>
* <EFBFBD><EFBFBD>ע<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>õ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>CLinkedListIterator::remove<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
inline void remove(LinkedNode<T>* node, bool free_flag = true)
{
if (node && node->self_ == this)
{
//<2F>Ƴ<EFBFBD><C6B3>ڵ<EFBFBD>
if (node->prev_)
node->prev_->next_ = node->next_;
if (node->next_)
node->next_->prev_ = node->prev_;
if (node == first_node_)
first_node_ = node->next_;
if (node == last_node_)
last_node_ = node->prev_;
//<2F><><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD><D0B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>в<EFBFBD><D0B2>Բ<EFBFBD><D4B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD>
if (iterator_)
{
Iterator* it = iterator_;
while (it)
{
if (node == it->enuming_)
it->enuming_ = node->prev_;
it = it->prev_;
}
}
node->self_ = NULL;
//<2F><><EFBFBD>ٽڵ<D9BD>
if (free_flag) freeNode(node);
count_--;
assert(count_ >= 0);
}
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
virtual void clear()
{
LinkedNode<T>* pNode = first_node_, *pNextNode;
while (pNode)
{
pNextNode = pNode->next_;
freeNode(pNode);
pNode = pNextNode;
}
first_node_ = last_node_ = NULL;
count_ = 0;
}
protected:
/* <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĭ<EFBFBD>ϵIJ<CFB5><C4B2><EFBFBD>ʱʹ<CAB1><CAB9>new<65><77><EFBFBD><EFBFBD><EFBFBD>ڴ沢<DAB4><E6B2A2><EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǵ˷<EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
virtual LinkedNode<T>* allocNode()
{
if (allocator_)
{
return allocator_->Alloc();
}
else
{
return new LinkedNode<T>;
}
}
/* <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĭ<EFBFBD>ϵIJ<CFB5><C4B2><EFBFBD>ʱʹ<CAB1><CAB9>delete<74><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǵ˷<EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
virtual void freeNode(LinkedNode<T>* pNode)
{
if (allocator_)
{
allocator_->Free(pNode);
}
else
{
delete pNode;
}
}
private:
LinkedNode<T>* first_node_;
LinkedNode<T>* last_node_;
Iterator* iterator_;
int count_;
ObjPool< LinkedNode<T> >* allocator_;
};
};
#endif