Files
envi-code/SourceCode/Code2026/Dimension/superlist.h
T
gjm 164968b62e chore
把非utf8-bom编码的cpp/h文件改为 utf8 bom 编码, msvc识别utf8编码时,如果不是bom格式的,会使用当前cp_oem来解码.
2026-10-04 00:04:20 +08:00

432 lines
8.8 KiB
C++

#pragma once
#include <vector>
#include <functional>
#include <algorithm>
#define _DELETE_PTR_(ptr)\
if (ptr)\
{\
delete ptr;\
ptr = NULL;\
}
template <class K>
class PtrList
{
typedef std::vector<K*> KVec;
typedef int(*cmpFunc)(const K *, const K *); // 比较函数
typedef int(*cmpByVoidPtr)(const K *, const void *); // 比较函数
// 由于DList内的QuickSort()函数的排序结果与std::sort()的相反.
// 故用此functor在 QuickSort()内部,将 cmpFunc的结果取反,以达到与DList结果相同的目的!
struct TSort
{
cmpFunc func;
TSort (cmpFunc f): func(f){}
bool operator () (const K *p1, const K * p2)
{
bool brel = func(p1, p2) > 0 ? true : false;
return !brel;
}
};
protected:
bool m_nDelFlag; // true - 自动释放
K *head; // 头元素,为兼容DList
K *tail; // 尾元素,为兼容DList
private:
KVec m_data;
size_t m_pos; // 当前位置,为兼容DList
public:
PtrList(int dFlag = 1);
// 用数组初始化链表, 不能用于字符串数组!!
// 建议 K 有copy constructor
PtrList(K * addr, size_t nCount);
~PtrList();
int operator !() const;
// 移到当前指针到第 n 个节点, 并返回它所指的值
K * operator [](int n);
const K & operator [](int n) const;
void MoveToHead();
const K & GetAt(int n) const;
K * GetAt(int n);
//并入
//并入链表,listother被直接连接到this的末尾
//最后this链表的游标值不变, listother失去对其内数据的维护权.
PtrList<K>& operator << (PtrList<K> &listother);
//复制
//建议 K 有copy constructor
PtrList<K>& copyFrom(const PtrList<K> &listother);
void Insert(K * node);
void Append(K * node);
void Replace(K * node, int n = -1);
void Reset();
int Remove();
int Remove(int n);
// 求当前指针的位置(-1: current 为 NULL)
int CurPosition() const;
int Length() const;
int GetDelFlag() const;
void SetDelFlag(int nFlag);
K * CurData() const;
void SetCurData(K* p);
// 如cmp为空,则直接比较指针地址.
// 如cmp不为空,则比较指针所指内容.
int Find(const K * node);
int Exist(const K * node) const;
// 把指针移到最后,准备下一个插入
void MoveEnd();
K* Head() const;
K* Tail() const;
K* FindNode(const void *, cmpByVoidPtr cmp);
void QuickSort(cmpFunc cmp);
void Swap(int n1,int n2);
void Reverse();
void FindAndDel(const void *p, cmpByVoidPtr cmp);
KVec& GetData();
const KVec& GetData() const;
protected:
virtual int Compare(const K *, const K *) const;
private:
PtrList<K> & operator = (const PtrList<K> &src);
PtrList(const PtrList<K> &src);
bool judge_idx(size_t idx) const;
void set_head_tail();
};
//////////////////////////////////////////////////////////////////////////
template <class K>
void PtrList<K>::set_head_tail()
{
if (m_data.empty())
head = tail = NULL;
else
{
head = m_data.front();
tail = m_data.back();
}
}
template <class K>
std::vector<K*>& PtrList<K>::GetData() { return m_data; }
template <class K>
const std::vector<K*>& PtrList<K>::GetData() const { return m_data;}
template <class K>
bool PtrList<K>::judge_idx( size_t idx ) const
{
if (idx >= 0 && idx < m_data.size())
return true;
return false;
}
template <class K>
PtrList<K>::PtrList( int dFlag /*= 1*/ )
: m_nDelFlag(dFlag != 0 ? true : false), m_data(0),
head(NULL), tail(NULL), m_pos(0){set_head_tail();}
template <class K>
PtrList<K>::PtrList( K * addr, size_t nCount)
: m_nDelFlag(true), m_pos(0), head(NULL), tail(NULL), m_data(0)
{
m_data.resize(nCount);
for (size_t i = 0; i < nCount; ++i, ++m_pos)
m_data[i] = new K(addr[i]);
set_head_tail();
}
template <class K>
PtrList<K>::~PtrList()
{
if (!m_nDelFlag)
return;
for (size_t i = 0; i < m_data.size(); ++i)
{
K *p = m_data[i];
_DELETE_PTR_(p);
}
}
template <class K>
const K & PtrList<K>::operator[]( int n ) const { return GetAt(n); }
template <class K>
K * PtrList<K>::operator[]( int n ) { return GetAt(n); }
template <class K>
K * PtrList<K>::GetAt( int n )
{
m_pos = n;
return m_data[n];
}
template <class K>
const K & PtrList<K>::GetAt( int n ) const
{
PtrList<K> *pThis = (PtrList<K> *)this;
const K *p = pThis->GetAt(n);
return *p;
}
template <class K>
PtrList<K>& PtrList<K>::copyFrom( const PtrList<K>& listother )
{
if (this == &listother)
return *this;
Reset();
m_nDelFlag = listother.GetDelFlag() != 0 ? true : false;
m_data.resize(listother.Length());
for (size_t i = 0; i < (size_t)listother.Length(); ++i,++m_pos)
m_data[i] = new K (listother[(int)i]);
set_head_tail();
return *this;
}
template <class K>
PtrList<K>& PtrList<K>::operator << ( PtrList<K> &listother )
{
KVec &odata = listother.GetData();
m_data.insert(m_data.end(), odata.begin(), odata.end());
listother.head = listother.tail = NULL;
listother.m_pos = 0;
listother.GetData().clear();
set_head_tail();
return *this;
}
template <class K>
void PtrList<K>::Insert( K * node )
{
if (!judge_idx(m_pos))
{
Append(node);
return;
}
typename KVec::iterator it = m_data.begin();
std::advance(it , m_pos);
m_data.insert(it, node);
set_head_tail();
++m_pos;
}
template <class K>
void PtrList<K>::Append( K * node )
{
m_data.push_back(node);
// dlist在进行尾插入后,其当前索引会指到结尾的下一个内存处,而不是最后一个元素.
// 对此我表示理解无能...
m_pos = m_data.size();
set_head_tail();
}
template <class K>
void PtrList<K>::Replace( K * node, int n /*= -1*/ )
{
if (!judge_idx((size_t)n))
return;
if (m_nDelFlag)
_DELETE_PTR_(m_data[n]);
m_data[n] = node;
m_pos = n;
set_head_tail();
}
template <class K>
void PtrList<K>::Reset()
{
if (m_nDelFlag)
{
for (size_t i = 0; i < m_data.size(); ++i)
_DELETE_PTR_(m_data[i]);
}
m_data.clear();
head = tail = NULL;
m_pos = 0;
}
template <class K>
int PtrList<K>::Exist( const K * node) const
{
return const_cast<PtrList<K>*>(this)->Find(node);
}
template <class K>
int PtrList<K>::Find( const K * node)
{
PtrList<K> *p = (PtrList<K>*) this;
for ( m_pos = 0; m_pos < m_data.size(); ++m_pos)
{
if (!Compare(m_data[m_pos], node))
return 1;
}
return 0;
}
template <class K>
void PtrList<K>::SetCurData( K* p ) // dlist 在这里只是简单替换,并没有考虑内存释放问题
{
if (!judge_idx(m_pos))
return;
if (m_nDelFlag)
_DELETE_PTR_(m_data[m_pos]);
m_data[m_pos] = p;
set_head_tail();
}
template <class K>
K * PtrList<K>::CurData() const
{
if (!judge_idx(m_pos))
return NULL;
return m_data[m_pos];
}
template <class K>
void PtrList<K>::SetDelFlag( int nFlag ) { m_nDelFlag = nFlag != 0 ? true : false; }
template <class K>
int PtrList<K>::GetDelFlag() const { return m_nDelFlag; }
template <class K>
int PtrList<K>::Length() const { return (int)m_data.size(); }
template <class K>
int PtrList<K>::CurPosition() const { return m_pos < m_data.size() ? (int)m_pos : -1; }
template <class K>
int PtrList<K>::Remove( int n )
{
if (!judge_idx((size_t)n))
return 0;
m_pos = n;
return Remove();
}
template <class K>
int PtrList<K>::Remove()
{
if (!judge_idx(m_pos))
return 0;
if (m_nDelFlag)
_DELETE_PTR_(m_data[m_pos]);
typename KVec::iterator it = m_data.begin();
std::advance(it, m_pos);
m_data.erase(it);
set_head_tail();
return 1;
}
// 注意dlist用的是指针比较,所以...这里也是如此
template <class K>
int PtrList<K>::Compare( const K *p1, const K *p2 ) const
{
if (p1 == p2)
return 0;
return 1;
}
template <class K>
PtrList<K>::PtrList( const PtrList<K> &src )
: m_nDelFlag(true), m_pos(0), head(NULL), tail(NULL), m_data(0){ copyFrom(src); }
template <class K>
PtrList<K> & PtrList<K>::operator=( const PtrList<K> &src ) { return copyFrom(src); }
template <class K>
void PtrList<K>::FindAndDel( const void *p, cmpByVoidPtr cmp )
{
while (FindNode(p, cmp))
Remove();
}
template <class K>
void PtrList<K>::Reverse()
{
std::reverse(m_data.begin(), m_data.end());
set_head_tail();
}
template <class K>
void PtrList<K>::Swap( int n1, int n2 )
{
if (!judge_idx((size_t)n1) || !judge_idx((size_t)n2))
return;
K *tmp = m_data[n1];
m_data[n1] = m_data[n2];
m_data[n2] = tmp;
m_pos = n2;
set_head_tail();
}
template <class K>
void PtrList<K>::QuickSort( cmpFunc cmp )
{
std::sort(m_data.begin(), m_data.end(), TSort(cmp));
set_head_tail();
}
template <class K>
K* PtrList<K>::FindNode( const void *p, cmpByVoidPtr cmp )
{
for (size_t i = 0; i < m_data.size(); ++i)
{
m_pos = i;
K *result = m_data[i];
if (!cmp(result, p))
return result;
}
return NULL;
}
template <class K>
K* PtrList<K>::Tail() const {const_cast<PtrList<K>*>(this)->set_head_tail(); return tail; }
template <class K>
K* PtrList<K>::Head() const {const_cast<PtrList<K>*>(this)->set_head_tail(); return head; }
template <class K>
void PtrList<K>::MoveEnd() { m_pos = -1; }
template <class K>
void PtrList<K>::MoveToHead() { m_pos = 0; }
template <class K>
int PtrList<K>::operator!() const
{
if (head)
{
return 0;
}
return 1;
}