Rearranged DataArray/List/ObjectList/SortedSets

This commit is contained in:
2023-07-21 10:52:29 +08:00
parent 2443aa9b9d
commit c3e8db3104
7 changed files with 634 additions and 1348 deletions

View File

@@ -39,10 +39,10 @@ namespace hgl
/**
* 分配指定空间出来,供未来使用
*/
void Alloc(int size)
bool Alloc(int size)
{
if(size<=alloc_count)
return;
return(true);
alloc_count=power_to_2(size);
@@ -50,6 +50,8 @@ namespace hgl
items=hgl_align_malloc<T>(alloc_count);
else
items=hgl_align_realloc<T>(items,alloc_count);
return(items!=nullptr);
}
/**
@@ -157,27 +159,40 @@ namespace hgl
return items[n];
}
const bool Read(T *obj,int index)const
T *GetPointer(int n)const
{
if(!obj||index<0||index>=count)return(false);
return (n<0||n>=count)?nullptr:items+n;
}
hgl_cpy(*obj,items[index]);
const bool ReadAt(T &obj,int const index)const
{
if(index<0||index>=count)return(false);
hgl_cpy(obj,items[index]);
return(true);
}
const bool Write(const T *obj,int index)
const bool ReadAt(T *obj,int const start,const int num)const
{
if(!obj||index<0||index>=count)return(false);
if(!obj||start<0||start+num>count)return(false);
hgl_cpy(items[index],*obj);
hgl_cpy(obj,items+start,num);
return(true);
}
const bool Write(const T *obj,int start,const int num=1)
const bool WriteAt(const T &obj,const int index)
{
if(!obj||start<0||start>=count||start+num>count)return(false);
if(index<0||index>=count)return(false);
hgl_cpy(items+start,*obj,num);
hgl_cpy(items[index],obj);
return(true);
}
const bool WriteAt(const T *obj,const int start,const int num)
{
if(!obj||start<0||start+num>count)return(false);
hgl_cpy(items+start,obj,num);
return(true);
}
@@ -186,7 +201,7 @@ namespace hgl
*/
void operator = (const DataArray<T> &da)
{
if(lt.count<=0)
if(da.count<=0)
{
count=0;
return;
@@ -526,9 +541,9 @@ namespace hgl
* @param data 要查找的数据
* @return <0 未找到或其它错误
*/
int Find(const T &data)
const int Find(const T &data)const
{
return FindDataAtArray<T>(items,count,data);
return FindDataPositionInArray<T>(items,count,data);
}
/**
@@ -558,7 +573,9 @@ namespace hgl
}
else
{
hgl_move(items+pos+data_number,items+pos,count-pos);
if(pos<count)
hgl_move(items+pos+data_number,items+pos,count-pos);
hgl_cpy(items+pos,data,data_number);
}
@@ -566,5 +583,143 @@ namespace hgl
return(true);
}
bool Insert(int pos,const T &data)
{
return Insert(pos,&data,1);
}
/**
* 统计出不在without_list中的数据产生的结果写入result_list
*/
void WithoutList(DataArray<T> &result_list,const DataArray<T> &without_list)
{
result_list.ClearData();
const int count=this->GetCount();
if(count<=0)return;
result_list.ClearData();
result_list.PreAlloc(count);
int result=0;
T *p=result_list.items;
for(const T *sp:*this)
{
if(!without_list.IsExist(*sp))
{
*p=*sp;
++p;
++result;
}
}
result_list.SetCount(result);
}
//int Intersection (SortedSets<T> &result,const SortedSets<T> &sets); ///<取得与指定合集的交集
//int Intersection (const SortedSets<T> &set); ///<取得与指定合集的交集数量
///**
// * 取得与指定交集is的合集但排斥cs合集中的数据
// * @param result 结果合集
// * @param is 求交集的合集
// * @param cs 求排斥的合集
// * @return 结果数量
// */
//int Intersection (SortedSets<T> &result,const SortedSets<T> &is,const SortedSets<T> &cs);
//int Difference (const SortedSets<T> &is); ///<求差集数量
///**
// * 求当前合集与另一个数据集的交集
// * @param result 结果存放合集
// * @param list 要计算交集的数据集
// * @return 交集数量
// */
//int Intersection(SortedSets<T> &result,const SortedSets<T> &list)
//{
// if(data_list.GetCount()<=0)
// return(0);
// if(list.GetCount()<=0)
// return(0);
// data_list.Enum([&](T &obj)
// {
// if(list->IsMember(obj))
// result.Add(obj);
// });
// return result.GetCount();
//}
//int Intersection(const SortedSets<T> &list)
//{
// if(data_list.GetCount()<=0)
// return(0);
// if(list.GetCount()<=0)
// return(0);
// int count=0;
// T *obj=data_list.GetData();
// for(int i=0;i<data_list.GetCount();i++)
// {
// if(list.IsMember(*obj))
// ++count;
// ++obj;
// }
// return count;
//}
//int Intersection(SortedSets<T> &result,const SortedSets<T> &il,const SortedSets<T> &cl)
//{
// if(data_list.GetCount()<=0)
// return(0);
// if(il.GetCount()<=0)
// return(0);
// T *obj=data_list.GetData();
// for(int i=0;i<data_list.GetCount();i++)
// {
// if(il.IsMember(*obj))
// if(!cl.IsMember(*obj))
// result.Add(*obj);
// ++obj;
// }
// return result.GetCount();
//}
//int Difference(const DataArray &is)
//{
// if(data_list.GetCount()<=0)
// return(is.GetCount());
// if(is.GetCount()<=0)
// return(data_list.GetCount());
// int count=0;
// T *obj=data_list.GetData();
// for(int i=0;i<data_list.GetCount();i++)
// {
// if(!is.IsMember(*obj))
// ++count;
// ++obj;
// }
// return count;
//}
//int Clear (const SortedSets<T> &clear_sets); ///<清除指定合集中所有数据
};//template<typename T> class DataArray
}//namespace hgl

View File

@@ -1,458 +0,0 @@
#ifndef HGL_LIST_CPP
#define HGL_LIST_CPP
#ifdef _WIN32
#include <time.h>
#endif
#include<hgl/log/LogInfo.h>
#include<hgl/type/String.h>
//--------------------------------------------------------------------------------------------------
// 代码中的部分memcpy可替换为memmove,但这样会引起CodeGuard/Valgrind之类的内存调试器报错
//--------------------------------------------------------------------------------------------------
namespace hgl
{
template<typename T>
bool List<T>::Get(int index,T &ti)const
{
if(!items||index<0||index>=count)
return(false);
hgl_cpy<T>(ti,items[index]);
return(true);
}
template<typename T>
bool List<T>::First(T &ti)const
{
if(!items||count<=0)
return(false);
hgl_cpy<T>(ti,*items);
return(true);
}
template<typename T>
bool List<T>::Last(T &ti)const
{
if(!items||count<=0)
return(false);
hgl_cpy<T>(ti,items[count-1]);
return(true);
}
template<typename T>
bool List<T>::Set(int index,const T &val)
{
if(!items||index<0||index>=count)
return(false);
hgl_cpy<T>(items[index],val);//items[index]=val;
return(true);
}
/**
* 向列表中添加一个空数据
* @return 这个数据的指针
*/
template<typename T>
T *List<T>::Add()
{
if(!PreAlloc(count+1))
return(nullptr);
++count;
return(items+(count-1));
}
/**
* 向列表中添加一个数据对象
* @param data 要添加的数据对象
* @return 这个数据的索引号
*/
template<typename T>
int List<T>::Add(const T &data)
{
if(!PreAlloc(count+1))
return(-1);
hgl_cpy<T>(items[count],data);//items[count]=data;
return(count++);
}
/**
* 重复向列表中添加一个数据对象
* @param data 要添加的数据对象
* @param n 要添加的数据个数
* @return 这个数据的索引号
* @return -1 出错
*/
template<typename T>
int List<T>::RepeatAdd(const T &data,int n)
{
if(n<=0)return(-1);
if(!PreAlloc(count+n))
return(-2);
T *p=items;
int result=count;
for(int i=0;i<n;i++)
{
hgl_cpy<T>(*p,data);//items[count]=data;
++p;
}
count+=n;
return(result);
}
/**
* 向列表中添加一批数据对象
* @param data 要添加的数据对象
* @param n 要添加的数据数量
* @return 起始数据的索引号
*/
template<typename T>
int List<T>::Add(const T *data,int n)
{
if(!data||n<=0)
return(-1);
if(!PreAlloc(count+n))
return(-1);
hgl_cpy<T>(items+count,data,n);
int r=count;
count+=n;
return(r);
}
/**
* 清除整个列表
*/
template<typename T>
void List<T>::Clear()
{
count=0;
alloc_count=0;
if(items)
{
hgl_free(items);
items=0;
}
}
/**
* 清除整个列表,但不清除缓冲区
*/
template<typename T>
void List<T>::ClearData()
{
count=0;
}
template<typename T>
void List<T>::DeleteClear()
{
if(count)
{
T *p=items;
while(count--)
{
delete *p;
++p;
}
count=0;
}
}
/**
* 在列表中查找指定的数据项
* @param data 要查找的数据项
* @return 数据在列表中的位置
*/
template<typename T>
int List<T>::Find(const T &data)const
{
int n=count;
while(n--)
// if(items[n]==data)return(n);
if(memcmp(items+n,&data,sizeof(T))==0)
return(n);
return(-1);
}
/**
* 删除列表中的指定项(关心顺序,删除中间数据后,会将后面的数据整体前移)
* @param start 要删除的数据项的索引值
* @return 是否成功
*/
template<typename T>
bool List<T>::DeleteMove(int start,int delete_count)
{
if(start>=count)return(false);
if(start<0)
{
delete_count+=start;
start=0;
}
if(start+delete_count>count)
delete_count=count-start;
if(delete_count<=0)return(false);
const int end_count=count-(start+delete_count);
if(end_count>0)
hgl_cpy<T>(items+start,items+start+delete_count,end_count);
count-=delete_count;
return(true);
}
/**
* 删除列表中的指定项(不关心顺序,如果删除中间的数据,可能会将最后面的数据拿过来填补)
* @param start 要删除的数据项的索引起始值
* @param delete_count 要删除的数据项数量
* @return 是否成功
*/
template<typename T>
bool List<T>::Delete(int start,int delete_count)
{
if(start>=count)return(false);
if(start<0)
{
delete_count+=start;
start=0;
}
if(start+delete_count>count)
delete_count=count-start;
if(delete_count<=0)return(false);
const int64 end_count=count-(start+delete_count); //删除的数据段后面的数据个数
if(end_count>0)
{
if(end_count<=delete_count) //后面的数据个数比删除的数据个数少,直接整体移动
{
//[------------][***********]
// ^ v
// ^ v
// +<<<<<<<<<<<<<+
hgl_cpy<T>(items+start,items+start+delete_count,end_count);
}
else //后面的数据个数比删除的数据个数多,那就只移动等长的最后一段数据
{
//[---][**********][***]
// ^ v
// ^ v
// +<<<<<<<<<<<<<<<<+
hgl_cpy<T>(items+start,items+(count-delete_count),delete_count);
}
count-=delete_count;
}
//else{后面都没数据了,那就啥都不用干了}
return(true);
}
/**
* 删除列表中的指定项
* @param data 要删除的数据项
* @return 是否成功
*/
template<typename T>
bool List<T>::DeleteByValue(const T &dat)
{
int index=Find(dat);
if(index!=-1)
{
Delete(index);
return(true);
}
else
return(false);
}
/**
* 删除列表中的指定项
* @param data 要删除的数据项
* @param n 要删除的数据个数
*/
template<typename T>
void List<T>::DeleteByValue(const T *data,int n)
{
while(n--)
{
int index=Find(*data);
++data;
if(index!=-1)
Delete(index);
}
}
/**
* 交换列表中两个数据的位置
* @param a 第一个数据的位置
* @param b 第二个数据的位置
*/
template<typename T>
void List<T>::Exchange(int a,int b)
{
//T t;
//char t[sizeof(T)];
// t=items[a];
// items[a]=items[b];
// items[b]=t;
hgl_swap(items[a],items[b]);
}
/**
* 在列表的指定位置中插入一个数据
* @param index 插入数据的位置
* @param data 要插入的数据
*/
template<typename T>
bool List<T>::Insert(int index,const T &data)
{
if(index<0)index=0;
if(index<count)
{
if(!PreAlloc(count+1))
return(false);
hgl_move<T>(items+index+1,items+index,count-index);
hgl_cpy<T>(items[index],data);//items[index]=data;
++count;
}
else
Add(data);
return(true);
}
/**
* 移动列表中的某一项到新的位置
* @param index 要移动的数据位置
* @param newindex 新的位置
*/
template<typename T>
void List<T>::Move(int index,int newindex)
{
if(index==newindex)return;
if(index<=0||index>=count)return;
if(newindex<0)newindex=0;
if(newindex>=count)newindex=count-1;
//T t;
char t[sizeof(T)];
hgl_cpy<T>(*(T *)&t,items[index]);//t=items[index];
if(index<newindex)hgl_move<T>(items+index ,items+index+1 ,newindex-index);
else hgl_move<T>(items+newindex+1 ,items+newindex ,index-newindex);
hgl_cpy<T>(items[newindex],*(T *)&t);//items[newindex]=t;
}
template<typename T>
bool List<T>::PreAlloc(int new_count)
{
if(alloc_count>=new_count)return(true);
alloc_count=power_to_2(new_count);
if(!items)
{
items=hgl_align_malloc<T>(alloc_count);
return items;
}
else
{
T *new_items=hgl_align_realloc<T>(items,alloc_count);
if(!new_items)return(false);
items=new_items;
return(true);
}
}
template<typename T>
bool List<T>::SetCount(int new_count)
{
if(count==new_count)return(true);
if(new_count<=0)
{
ClearData();
return(true);
}
if(!PreAlloc(new_count))
return(false);
count=new_count;
return(true);
}
/**
* 复制整个列表
* @param lt 列表
*/
template<typename T>
void List<T>::operator = (const List<T> &lt)
{
if(lt.count<=0)
{
count=0;
return;
}
SetCount(lt.count);
hgl_cpy<T>(items,lt.items,count);
}
template<typename T>
void List<T>::operator = (const std::initializer_list<T> &l)
{
ClearData();
SetCount((int)l.size());
hgl_cpy<T>(items,l.begin(),count);
}
}//namespace hgl
#endif//HGL_LIST_CPP

View File

@@ -1,68 +1,189 @@
#ifndef HGL_LIST_INCLUDE
#define HGL_LIST_INCLUDE
#pragma once
#include<stdlib.h>
#include<initializer_list>
#include<hgl/type/DataType.h>
#include<hgl/type/DataArray.h>
namespace hgl
{
/**
* List类用于保存数据列表。可以在列表中添加、删除、查找、访问和排序数据。
*/
template <typename T> class List ///列表处理类
template<typename T> class List ///列表处理类
{
protected:
int count=0; ///<当前数据数量
int alloc_count=0; ///<当前已分配空间数量
T *items=nullptr;
DataArray<T> data_array;
public: //属性
int GetAllocCount ()const{return alloc_count;} ///<取得已分配容量
int GetCount ()const{return count;} ///<取得列表内数据数量
virtual bool SetCount (int); ///<设置列表内数据数量
virtual bool PreAlloc (int); ///<预分配指定数量的数据空间
T * GetData ()const{return items;} ///<提供原始数据项
int GetBytes ()const{return count*sizeof(T);} ///<取得原始数据总字节数
const int GetAllocCount ()const{return data_array.GetAllocCount();} ///<取得已分配容量
const int GetCount ()const{return data_array.GetCount();} ///<取得列表内数据数量
virtual bool SetCount (int count){return data_array.SetCount(count);} ///<设置列表内数据数量
virtual bool PreAlloc (int count){return data_array.Alloc(count);} ///<预分配指定数量的数据空间
T * begin ()const{return items;}
T * end ()const{return items+count;}
const bool IsEmpty ()const{return data_array.IsEmpty();} ///<确认列表是否为空
T * GetData ()const{return data_array.GetData();} ///<提供原始数据项
int GetBytes ()const{return data_array.GetBytes();} ///<取得原始数据总字节数
T * begin ()const{return data_array.begin();}
T * end ()const{return data_array.end();}
public:
operator DataArray<T> & () {return data_array;}
operator const DataArray<T> & ()const {return data_array;}
public: //方法
List(){}; ///<本类构造函数
List()=default; ///<本类构造函数
List(const T *lt,const int n){Add(lt,n);} ///<本类构造函数
List(const List<T> &lt){operator=(lt);} ///<本类构造函数
List(const std::initializer_list<T> &lt){operator=(lt);}
virtual ~List(){Clear();} ///<本类析构函数
virtual T * Add(); ///<添加一个空数据
virtual int Add(const T &); ///<增加一个数据
virtual int RepeatAdd(const T &,int n); ///<重复增加一个数据
virtual int Add(const T *,int n); ///<增加一批数据
/**
* 向列表中添加一个数据
* @return 这个数据的指针
*/
virtual T * Add()
{
data_array.AddCount(1);
return data_array.last();
}
/**
* 向列表中添加一个数据对象
* @param data 要添加的数据对象
* @return 这个数据的索引号
*/
virtual int Add(const T &data)
{
const int index=GetCount();
data_array.AddCount(1);
data_array.WriteAt(data,index);
return index;
}
/**
* 重复向列表中添加一个数据对象
* @param data 要添加的数据对象
* @param n 要添加的数据个数
* @return 这个数据的索引号
* @return -1 出错
*/
virtual int RepeatAdd(const T &data,int n)
{
if(n<=0)return(-1);
const int ec=data_array.GetCount();
data_array.AddCount(n);
hgl_set(data_array.data()+ec,data,n);
return(ec);
}
/**
* 向列表中添加一批数据对象
* @param data 要添加的数据对象
* @param n 要添加的数据数量
* @return 起始数据的索引号
*/
virtual int Add(const T *data,int n)
{
if(!data||n<=0)
return(-1);
const int ec=data_array.GetCount();
data_array.AddCount(n);
data_array.WriteAt(data,ec,n);
return(ec);
}
int Add(const List<T> &l){return Add(l.items,l.count);} ///<增加一批数据
const bool IsEmpty()const{return count==0;} ///<是否是空的
virtual void Clear(){data_array.Clear();} ///<清除所有数据
virtual void ClearData(){data_array.ClearData();} ///<清除所有数据,但不清空缓冲区
virtual void Clear(); ///<清除所有数据
virtual void ClearData(); ///<清除所有数据,但不清空缓冲区
virtual int Find(const T &)const; ///<查找指定数据的索引
virtual int Find(const T &data)const{return data_array.Find(data);} ///<查找指定数据的索引
virtual bool IsExist(const T &flag)const{return Find(flag)!=-1;} ///<确认数据项是否存在
virtual bool Delete(int,int=1); ///<删除指定索引的数据
virtual bool DeleteMove(int,int=1); ///<删除指定索引的数据,将后面紧邻的数据前移
virtual bool DeleteByValue(const T &); ///<删除一个指定数据
virtual void DeleteByValue(const T *,int); ///<删除一批指定的数据
virtual void Exchange(int,int); ///<根据索引交换两个数据
virtual bool Insert(int,const T &); ///<在指定索引处插入一个数据
virtual void Move(int,int); ///<移动一个数据到移指索引处
void DeleteClear(); ///<清除所有数据并全部调用delete
virtual bool Delete(int start,int num=1){return data_array.Delete(start,num);} ///<删除指定索引的数据
virtual bool DeleteMove(int start,int num=1){return data_array.DeleteMove(start,num);} ///<删除指定索引的数据,将后面紧邻的数据前移
virtual void operator = (const List<T> &); ///<操作符重载复制一个列表
virtual void operator = (const std::initializer_list<T> &l);
/**
* 删除列表中的指定项
* @param data 要删除的数据项
* @return 是否成功
*/
virtual bool DeleteByValue(const T &data)
{
const int pos=Find(data);
return(pos>=0?Delete(pos,1):pos);
}
/**
* 删除列表中的指定项
* @param data 要删除的数据项
* @param n 要删除的数据个数
* @return 成功删除的数据个数
*/
virtual int DeleteByValue(const T *data,int n)
{
int result=0;
while(n--)
{
int index=Find(*data);
++data;
if(index!=-1)
if(Delete(index))
++result;
}
return result;
}
virtual void Exchange(int a,int b){data_array.Exchange(a,b);} ///<根据索引交换两个数据
virtual bool Insert(int pos,const T &data){return data_array.Insert(pos,&data,1);} ///<在指定索引处插入一个数据
/**
* 在指定索引处插入一批数据
* @param pos 插入的位置
* @param data 要插入的数据
* @param number 要插入的数据个数
*/
virtual bool Insert(int pos,const T *data,const int number)
{
return data_array.Insert(pos,data,number);
}
/**
* 移动一批数据到新的位置
* @param new_pos 新的位置
* @param old_pos 原来的位置
* @param move_count 要移动的数据个数
*/
virtual bool Move(const int new_pos,const int old_pos,const int move_count)
{
return data_array.Move(new_pos,old_pos,move_count);
}
virtual void operator = (const DataArray<T> &da){data_array=da;} ///<操作符重载复制一个列表
virtual void operator = (const std::initializer_list<T> &l){data_array=l;} ///<操作符重载复制一个列表
virtual void operator += (const T &obj){Add(obj);} ///<操作符重载添加一个数据
virtual void operator << (const T &obj){Add(obj);} ///<操作符重载添加一个数据
@@ -78,45 +199,11 @@ namespace hgl
return(index>=count?nullptr:items+index);
}
bool Get(int,T &)const; ///<取得指定索引处的数据
bool Set(int,const T &); ///<设置指定索引处的数据
bool Get(int index, T &data)const {return data_array.ReadAt (data,index);} ///<取得指定索引处的数据
virtual bool Set(int index,const T &data) {return data_array.WriteAt(data,index);} ///<设置指定索引处的数据
virtual bool First(T &)const; ///<取第一个数据
virtual bool Last(T &)const; ///<取最后一个数据
virtual void Enum(void (*enum_func)(int,T &)) ///<枚举所有数据成员
{
T *obj=items;
for(int i=0;i<count;i++)
{
enum_func(i,*obj);
++obj;
}
}
/**
* 统计出不在in_list中的数据产生的结果写入without_list
*/
void WithoutList(List<T> &without_list,const List<T> &in_list)
{
without_list.ClearData();
const int count=this->GetCount();
if(count<=0)return;
without_list.PreAlloc(count);
const T *sp=this->GetData();
for(int i=0;i<count;i++)
{
if(!in_list.IsExist(*sp))
without_list.Add(*sp);
++sp;
}
}
virtual bool GetFirst (T &data)const{return data_array.ReadAt(data,0);} ///<取第一个数据
virtual bool GetLast (T &data)const{return data_array.ReadAt(data,GetCount()-1);} ///<取最后一个数据
};//template <typename T> class List
template<typename T> T *GetListObject(const List<T *> &list,const int index)
@@ -129,105 +216,3 @@ namespace hgl
return(nullptr);
}
}//namespace hgl
#include<hgl/type/List.cpp>
//--------------------------------------------------------------------------------------------------
namespace hgl
{
/**
* 自定义对象列表处理类与标准列表处理类的区别在于它对数据生成/清除时会多调用虚拟函数Create/Delte
*/
template<typename T> class CusObjectList:public List<T *> ///对象列表处理类
{
public:
virtual bool SetCount(int) override;
// virtual T * CreateObject()=0; ///<创建一个数据,但不加入列表
virtual void DeleteObject(T *)=0; ///<删除一个数据
public:
typedef T *ItemPointer;
public: //方法
CusObjectList(){}
virtual ~CusObjectList();
public:
// virtual T * Append(); ///<追加一个数据
// virtual T * Insert(int); ///<在指定索引处创建一个数据
bool Insert(int,const ItemPointer &); ///<在指定索引处插入一个数据
virtual void Clear(); ///<清除所有数据
virtual void ClearData(); ///<清除所有数据,但不清空缓冲区
virtual bool IsExist(const T *flag)const{return this->Find((T *)flag)!=-1;} ///<确认数据项是否存在
virtual bool Unlink(int index){return List<T *>::Delete(index);} ///<将指定索引处的数据与列表断开
virtual bool UnlinkMove(int index){return List<T *>::DeleteMove(index);} ///<将指定索引处的数据与列表断开,将前移后面的数据
virtual bool Unlink(int start,int number){return List<T *>::Delete(start,number);} ///<将指定索引处的数据与列表断开
virtual bool UnlinkByValue(const ItemPointer &ip){return List<T *>::DeleteByValue(ip);} ///<将一个指定数据与列表断开
virtual void UnlinkByValue(const ItemPointer *ip,int n){List<T *>::DeleteByValue(ip,n);} ///<将一批指定数据与列表断开
virtual void UnlinkAll(){List<T *>::ClearData();} ///<断开所有数据
virtual bool Delete(int); ///<删除指定索引处的数据
virtual bool DeleteMove(int); ///<删除指定索引处的数据
virtual bool DeleteByValue(const ItemPointer &); ///<删除指定的一个数据
virtual void DeleteByValue(const ItemPointer *,int); ///<删除指定的一批数据
virtual void DeleteAll(); ///<删除所有数据
virtual ItemPointer &operator[](int n)const ///<操作符重载取得指定索引处的数据
{
static T *null_pointer=nullptr;
if(n<0||n>=this->count)
return(null_pointer);
return this->items[n];
}
virtual void Enum(void (*enum_func)(T *)) ///<枚举所有数据成员
{
T **obj=this->items;
for(int i=0;i<this->count;i++)
{
enum_func(*obj);
++obj;
}
}
};//template <typename T> class CusObjectList
/**
* 对象列表处理类<br>
* 将自定义对象列表中的Create重载为new,Delete重载为delete
*/
template<typename T> class ObjectList:public CusObjectList<T>
{
private:
// virtual T * CreateObject(){return(new T);} ///<创建一个数据
virtual void DeleteObject(T *obj){if(obj)delete obj;} ///<删除一个数据
public:
T **begin()const{return this->items;}
T **end()const{return this->items+this->count;}
public:
virtual ~ObjectList()
{
CusObjectList<T>::Clear();
}
};//class ObjectList
#define OBJECT_LIST_ARRAY_CLEAR(object_list) for(auto &obj:object_list)obj.Clear();
#define OBJECT_LIST_ARRAY_CLEAR_DATA(object_list) for(auto &obj:object_list)obj.ClearData();
}//namespace hgl
#include<hgl/type/ObjectList.cpp>
#endif//HGL_LIST_INCLUDE

View File

@@ -1,260 +0,0 @@
#ifndef HGL_OBJECT_LIST_CPP
#define HGL_OBJECT_LIST_CPP
#include<hgl/type/List.h>
namespace hgl
{
/**
* 对象列表析构函数会调用DeleteAll函数
*/
template<typename T>
CusObjectList<T>::~CusObjectList()
{
Clear();
}
// /**
// * 生成一个对象,并返回它的指针
// */
// template<typename T>
// T *CusObjectList<T>::Append()
// {
// if(!this->items)
// {
// this->alloc_count=1;
// this->items=(T **)hgl_align_malloc<T *>(1);
// }
// else
// {
// if(this->count>=this->alloc_count)
// this->alloc_count<<=1;
//
// this->items=(T **)hgl_realloc(this->items,this->alloc_count*sizeof(T *));
// }
//
// return(this->items[this->count++]=CreateObject());
// }
// /**
// * 在指定位置插入一个对象
// */
// template<typename T>
// T *CusObjectList<T>::Insert(int index)
// {
// if(index<0)index=0;
//
// if(index<this->count)
// {
// if(this->count>=this->alloc_count)
// this->alloc_count<<=1;
//
// this->items=(T **)hgl_realloc(this->items,this->alloc_count*sizeof(T *));
//
// memmove(this->items+index+1,this->items+index,(this->count-index)*sizeof(T *));
//
// this->count++;
//
// return(this->items[index]=CreateObject());
// }
//
// return(Append());
// }
/**
* 在指定位置插入一个对象
*/
template<typename T>
bool CusObjectList<T>::Insert(int index,const ItemPointer &obj)
{
return List<T *>::Insert(index,obj);
}
/**
* 清除所有对象,作用和DeleteAll一样
*/
template<typename T>
void CusObjectList<T>::Clear()
{
DeleteAll();
List<T *>::Clear();
}
/**
* 清除所有对象,但不释放内存
*/
template<typename T>
void CusObjectList<T>::ClearData()
{
DeleteAll();
List<T *>::ClearData();
}
/**
* 删除列表中的指定项
*
* 这个函数在删除指定对象时附加使用delete方法
* @param index 要删除的对象的索引值
* @return 是否成功
*/
template<typename T>
bool CusObjectList<T>::Delete(int index)
{
if(index>=0&&index<this->count)
{
DeleteObject(this->items[index]);
this->count--;
if(index<this->count)
memcpy(this->items+index,this->items+this->count,sizeof(T *));
return(true);
}
else
return(false);
}
/**
* 删除列表中的指定项
*
* 这个函数在删除指定对象时附加使用delete方法
* @param index 要删除的对象的索引值
* @return 是否成功
*/
template<typename T>
bool CusObjectList<T>::DeleteMove(int index)
{
if(index>=0&&index<this->count)
{
DeleteObject(this->items[index]);
this->count--;
if(index<this->count)
memmove(this->items+index,this->items+index+1,(this->count-index)*sizeof(T *));
return(true);
}
else
return(false);
}
/**
* 删除列表中的指定项
*
* 这个函数在删除指定对象时附加使用delete方法
* @param obj 要删除的对象
* @return 是否成功
*/
template<typename T>
bool CusObjectList<T>::DeleteByValue(const ItemPointer &obj)
{
int n=this->count;
while(n--)
{
if(this->items[n]==obj)
{
DeleteObject(this->items[n]);
this->count--;
if(n<this->count)
memmove(this->items+n,this->items+n+1,(this->count-n)*sizeof(T *));
return(true);
}
}
return(false);
}
/**
* 将一批对象从列表中删除
* @param obj 要删除的对象
* @param n 要删除的对象个数
*/
template<typename T>
void CusObjectList<T>::DeleteByValue(const ItemPointer *obj,int n)
{
while(n--)
{
int index=List<T *>::Find(*obj);
obj++;
if(index!=-1)
Delete(index);
}
}
/**
* 删除整个列表中的所有对象
*
* 这个函数在删除每一个对象时都会使用一次delete
*/
template<typename T>
void CusObjectList<T>::DeleteAll()
{
if(this->count)
{
int n=this->count;
while(n--)
DeleteObject(this->items[n]);
this->count=0;
}
}
template<typename T>
bool CusObjectList<T>::SetCount(int new_count)
{
if(this->count==new_count)return(true);
if(new_count<=0)
{
DeleteAll();
return(true);
}
else
{
this->alloc_count=power_to_2(new_count);
T **new_items;
if(this->items)
{
if(new_count>this->count)
{
new_items=hgl_align_realloc<T *>(this->items,this->alloc_count);
// for(;this->count<new_count;this->count++)
// this->items[this->count]=CreateObject();
}
else
{
while(this->count-->new_count)
DeleteObject(this->items[this->count]);
new_items=hgl_align_realloc<T *>(this->items,this->alloc_count);
}
}
else
{
new_items=hgl_align_malloc<T *>(this->alloc_count);
// while(new_count--)
// this->items[this->count++]=CreateObject();
}
if(!new_items)
return(false);
this->items=new_items;
}
return(true);
}
}//namespace hgl
#endif//HGL_OBJECT_LIST_CPP

199
inc/hgl/type/ObjectList.h Normal file
View File

@@ -0,0 +1,199 @@
#pragma once
#include<hgl/type/List.h>
namespace hgl
{
/**
* 对象列表处理类与标准列表处理类的区别在于它对数据清除时会调用delete
*/
template<typename T> class ObjectList:public List<T *> ///对象列表处理类
{
public:
using ItemPointer=T *;
virtual void DeleteObject(T *obj){if(obj)delete obj;}
public: //方法
using List<T *>::List;
virtual ~ObjectList(){Clear();}
public:
/**
* 在指定位置插入一个对象
*/
bool Insert(int index,const ItemPointer &obj) override
{
return List<T *>::Insert(index,obj);
}
virtual void Clear() override ///<清除所有数据
{
ClearData();
List<T *>::Clear();
}
virtual void ClearData() override ///<清除所有数据,但不清空缓冲区
{
for(auto *obj:data_array)
DeleteObject(obj);
List<T *>::ClearData();
}
virtual bool IsExist(const ItemPointer &flag)const override ///<确认数据项是否存在
{
return this->Find((T *)flag)!=-1;
}
virtual bool Unlink(int index){return List<T *>::Delete(index);} ///<将指定索引处的数据与列表断开
virtual bool UnlinkMove(int index){return List<T *>::DeleteMove(index);} ///<将指定索引处的数据与列表断开,将前移后面的数据
virtual bool Unlink(int start,int number){return List<T *>::Delete(start,number);} ///<将指定索引处的数据与列表断开
virtual bool UnlinkByValue(const ItemPointer &ip){return List<T *>::DeleteByValue(ip);} ///<将一个指定数据与列表断开
virtual void UnlinkByValue(const ItemPointer *ip,int n){List<T *>::DeleteByValue(ip,n);} ///<将一批指定数据与列表断开
virtual void UnlinkAll(){List<T *>::ClearData();} ///<断开所有数据
private:
bool _Delete(int index,int num)
{
if(index<0||num<=0||index+num>=GetCount())
return(false);
ItemPointer *p=data_array.data()+index;
for(int i=0;i<num;i++)
{
DeleteObject(*p);
++p;
}
return true;
}
public:
/**
* 删除列表中的指定项
*
* 这个函数在删除指定对象时附加使用delete方法
* @param index 要删除的对象的索引值
* @param num 要删除的对象数量
* @return 是否成功
*/
virtual bool Delete(int index,int num=1) override
{
if(!_Delete(index,num))
return(false);
return List<T *>::Delete(index,num);
}
/**
* 删除列表中的指定项
*
* 这个函数在删除指定对象时附加使用delete方法
* @param index 要删除的对象的索引值
* @param num 要删除的对象数量
* @return 是否成功
*/
virtual bool DeleteMove(int index,int num=1) override
{
if(!_Delete(index,num))
return(false);
return List<T *>::DeleteMove(index,num);
}
virtual bool DeleteByValue(const ItemPointer &obj) override ///<删除指定的一个数据
{
if(!obj)return(false);
delete obj;
return List<T *>::DeleteByValue(obj);
}
virtual int DeleteByValue(const ItemPointer *obj_list,int num) override ///<删除指定的一批数据
{
if(!obj_list||num<=0)return(-1);
ItemPointer *p=(ItemPointer *)obj_list;
for(int i=0;i<num;i++)
{
DeleteObject(*p);
++p;
}
return List<T *>::DeleteByValue(obj_list,num);
}
virtual T *operator[](int n)const ///<操作符重载取得指定索引处的数据
{
T **obj=data_array.GetPointer(n);
if(!obj)return(nullptr);
return(*obj);
}
virtual void Enum(void (*enum_func)(T *)) ///<枚举所有数据成员
{
if(!enum_func)return;
for(auto *obj:data_array)
enum_func(obj);
}
virtual bool SetCount(const int new_count) override
{
const int cur_count=GetCount();
if(new_count==cur_count)return(true);
if(new_count<=0)
{
ClearData();
return(true);
}
if(new_count>cur_count)
{
if(!data_array.SetCount(new_count))
return(false);
ItemPointer *p=data_array.GetPointer(cur_count);
hgl_zero<ItemPointer>(p,new_count-cur_count);
return(true);
}
else
{
const int del_count=cur_count-new_count;
Delete(GetCount()-del_count,del_count);
return(true);
}
}
virtual bool Set(int index,const ItemPointer &data) override
{
ItemPointer *p=data_array.GetPointer(index);
if(!p)return(false);
DeleteObject(*p);
*p=data;
return(true);
}
};//template <typename T> class ObjectList
#define OBJECT_LIST_ARRAY_CLEAR(object_list) for(auto &obj:object_list)obj.Clear();
#define OBJECT_LIST_ARRAY_CLEAR_DATA(object_list) for(auto &obj:object_list)obj.ClearData();
}//namespace hgl

View File

@@ -1,390 +0,0 @@
#ifndef HGL_TYPE_SORTED_SETS_CPP
#define HGL_TYPE_SORTED_SETS_CPP
#include<hgl/type/SortedSets.h>
namespace hgl
{
/**
* 查找数据是否存在
* @param flag 数据
* @return 数据所在索引,-1表示不存在
*/
template<typename T>
const int SortedSets<T>::Find(const T &flag)const
{
int left=0,right=data_list.GetCount()-1; //使用left,right而不使用min,max是为了让代码能够更好的阅读。
int mid;
T *data_array=data_list.GetData();
while(left<=right)
{
if(data_array[left ]==flag)return(left);
if(data_array[right]==flag)return(right);
mid=(right+left)>>1;
if(data_array[mid]==flag)return(mid);
if(data_array[mid]>flag)
{
left++;
right=mid-1;
}
else
{
right--;
left=mid+1;
}
}
return(-1);
}
template<typename T>
bool SortedSets<T>::FindPos(const T &flag,int &pos)const
{
int left=0,right=data_list.GetCount()-1;
int mid;
T *data_array=data_list.GetData();
while(left<=right)
{
if(data_array[left]>flag)
{
pos=left;
return(false);
}
else
if(data_array[left]==flag)
{
pos=left;
return(true);
}
if(data_array[right]<flag)
{
pos=right+1;
return(false);
}
else
if(data_array[right]==flag)
{
pos=right;
return(true);
}
mid=(right+left)>>1;
if(data_array[mid]==flag)
{
pos=mid;
return(true);
}
if(data_array[mid]>flag)
{
if(data_array[mid-1]<flag)
{
pos=mid;
return(false);
}
else
if(data_array[mid-1]==flag)
{
pos=mid-1;
return(true);
}
++left;
right=mid-1;
}
else
{
if(data_array[mid+1]>flag)
{
pos=mid+1;
return(false);
}
else
if(data_array[mid+1]==flag)
{
pos=mid+1;
return(true);
}
--right;
left=mid+1;
}
}
return(false);
}
/**
* 添加一个数据
* @param data 数据
* @return 位置
*/
template<typename T>
int SortedSets<T>::Add(const T &data)
{
if(data_list.GetCount()<=0)
{
data_list.Add(data);
return 0;
}
else
{
int pos;
if(FindPos(data,pos))
return(-1); //数据已存在
data_list.Insert(pos,data);
return(pos);
}
}
/**
* 添加一批数据
* @param dp 数据指针
* @param count 数据个数
* @return 成功加入的数据个数
*/
template<typename T>
int SortedSets<T>::Add(const T *dp,const int count)
{
int total=0;
for(int i=0;i<count;i++)
{
if(Add(*dp)!=-1)
++total;
++dp;
}
return total;
}
/**
* 更新一个数据
* @param data 数据
* @return 是否成功
*/
template<typename T>
bool SortedSets<T>::Update(const T &data)
{
if(data_list.GetCount()<=0)
return(false);
int pos;
if(!FindPos(data,pos))
return(false);
data_list.Set(pos,data);
return(true);
}
/**
* 删除一个数据
* @param pos 索引编号
*/
template<typename T>
bool SortedSets<T>::DeleteBySerial(int pos)
{
if(pos<0||pos>=data_list.GetCount())return(false);
return data_list.DeleteMove(pos);
}
/**
* 删除一个数据
* @param data 数据
*/
template<typename T>
bool SortedSets<T>::Delete(const T &data)
{
int pos=Find(data);
if(pos==-1)return(false);
return DeleteBySerial(pos);
}
/**
* 删除一批数据
* @param dp 数据指针
* @param count 数据个数
* @return 成功删除的数据个数
*/
template<typename T>
int SortedSets<T>::Delete(T *dp,const int count)
{
int total=0;
int pos;
for(int i=0;i<count;i++)
{
pos=Find(*dp);
if(pos!=-1)
{
DeleteBySerial(pos);
++total;
}
++dp;
}
return total;
}
/**
* 清除所有数据
*/
template<typename T>
void SortedSets<T>::Clear()
{
data_list.Clear();
}
/**
* 清除所有数据,但不释放内存
*/
template<typename T>
void SortedSets<T>::ClearData()
{
data_list.ClearData();
}
/**
* 随机取得一个数据
*/
template<typename T>
bool SortedSets<T>::Rand(T &result)const
{
return data_list.Rand(result);
}
/**
* 如果成员在clear_sets中存在则清除它
* @return 剩作的数据数量
*/
template<typename T>
int SortedSets<T>::Clear(const SortedSets<T> &clear_sets)
{
if(GetCount()==0)return 0;
if(clear_sets.GetCount()==0)return GetCount();
int count=data_list.GetCount();
T *bp=begin();
T *ep=end();
while(bp>=ep)
{
if(clear_sets.IsMember(*ep))
data_list.DeleteMove(ep-bp);
--ep;
}
return GetCount();
}
/**
* 求当前合集与另一个数据集的交集
* @param result 结果存放合集
* @param list 要计算交集的数据集
* @return 交集数量
*/
template<typename T>
int SortedSets<T>::Intersection(SortedSets<T> &result,const SortedSets<T> &list)
{
if(data_list.GetCount()<=0)
return(0);
if(list.GetCount()<=0)
return(0);
data_list.Enum([&](T &obj)
{
if(list->IsMember(obj))
result.Add(obj);
});
return result.GetCount();
}
template<typename T>
int SortedSets<T>::Intersection(const SortedSets<T> &list)
{
if(data_list.GetCount()<=0)
return(0);
if(list.GetCount()<=0)
return(0);
int count=0;
T *obj=data_list.GetData();
for(int i=0;i<data_list.GetCount();i++)
{
if(list.IsMember(*obj))
++count;
++obj;
}
return count;
}
template<typename T>
int SortedSets<T>::Intersection(SortedSets<T> &result,const SortedSets<T> &il,const SortedSets<T> &cl)
{
if(data_list.GetCount()<=0)
return(0);
if(il.GetCount()<=0)
return(0);
T *obj=data_list.GetData();
for(int i=0;i<data_list.GetCount();i++)
{
if(il.IsMember(*obj))
if(!cl.IsMember(*obj))
result.Add(*obj);
++obj;
}
return result.GetCount();
}
template<typename T>
int SortedSets<T>::Difference(const SortedSets<T> &is)
{
if(data_list.GetCount()<=0)
return(is.GetCount());
if(is.GetCount()<=0)
return(data_list.GetCount());
int count=0;
T *obj=data_list.GetData();
for(int i=0;i<data_list.GetCount();i++)
{
if(!is.IsMember(*obj))
++count;
++obj;
}
return count;
}
}//namespace hgl
#endif//HGL_TYPE_SORTED_SETS_CPP

View File

@@ -1,86 +1,141 @@
#ifndef HGL_TYPE_SORTED_SETS_INCLUDE
#define HGL_TYPE_SORTED_SETS_INCLUDE
#pragma once
#include<hgl/type/List.h>
#include<hgl/type/DataArray.h>
namespace hgl
{
/**
* 有序合集</br>
* 集合数据列表中不允许数据出现重复性,同时它会将数据排序
* 集合数据列表中不允许数据出现重复性,同时它会将数据排序</br>
* 我们删除了批量添加数据的Add函数因为每一次添加数据都会导致一次插入这样效率太低了。我们建议将数据全部添加到List再转换为SortedSets。</br>
*/
template<typename T> class SortedSets
{
protected:
List<T> data_list;
DataArray<T> data_list;
bool FindPos(const T &flag,int &pos)const ///<查找数据如果插入后,会所在的位置,返回是否存在这个数据
{return FindInsertPositionInSortedArray(&pos,data_list,flag);}
bool FindPos(const T &,int &)const; ///<查找数据如果插入后,会所在的位置,返回是否存在这个数据
int FindPos(const T &flag)const{int pos;return FindPos(flag,pos)?pos:-1;} ///<查找数据如果插入后,会所在的位置
public: //属性
const List<T> & GetList ()const{return data_list;} ///<取得数据原始列表
T * GetData ()const{return data_list.GetData();} ///<取得数据指针
int GetCount ()const{return data_list.GetCount();} ///<取得数据总量
T * GetData ()const{return data_list.GetData();} ///<取得数据指针
int GetCount ()const{return data_list.GetCount();} ///<取得数据总量
T * begin ()const{return data_list.begin();}
T * end ()const{return data_list.end();}
const bool IsEmpty ()const{return data_list.IsEmpty();} ///<确认列表是否为空
T * begin ()const{return data_list.begin();}
T * end ()const{return data_list.end();}
T * last ()const{return data_list.last();}
public:
operator DataArray<T> & () {return data_list;} ///<取得原始数据阵列
operator const DataArray<T> & ()const {return data_list;} ///<取得原始数据阵列
public:
SortedSets()=default;
virtual ~SortedSets()=default;
void SetCount (int count){data_list.SetCount(count);} ///<指定数据数量,一般用于批量加载前的处理
void PreAlloc (int count){data_list.PreAlloc(count);} ///<预分配指定数量的数据空间
void SetCount (int count){data_list.SetCount(count);} ///<指定数据数量,一般用于批量加载前的处理
void PreAlloc (int count){data_list.Alloc(count);} ///<预分配指定数量的数据空间
const int Find (const T &)const; ///<查找数据位置,不存在返回-1
const bool IsMember (const T &v)const{return(Find(v)!=-1);} ///<确认是否成员
int Add (const T &); ///<添加一个数据,返回索引号,返回-1表示数据已存在
int Add (const T *,const int); ///<添加一批数据
int Add (const SortedSets<T> &s){return Add(s.GetData(),s.GetCount());} ///<添加一批数据
bool Update (const T &); ///<更新一个数据
bool Delete (const T &); ///<删除一个数据
int Delete (T *,const int); ///<删除一批数据
bool DeleteBySerial (int); ///<删除一个数据,使用序号
void Clear (); ///<清除数据
void ClearData (); ///<清除数据,但不释放内存
void DeleteClear (){data_list.DeleteClear();} ///<清除所有数据并全部调用delete
/**
* 查找数据是否存在
* @param flag 数据
* @return 数据所在索引,-1表示不存在
*/
int Find (const T &flag)const
{
return FindDataPositionInSortedArray(data_list,flag);
}
bool Get (const int index,T &data) ///<根据序列号取得指定数据
bool IsMember (const T &v)const{return(Find(v)!=-1);} ///<确认是否成员
/**
* 添加一个数据
* @param data 数据
* @return 插入的位置
* @reutrn -1 数据已存在,添加失败
*/
int Add (const T &data)
{
if(data_list.GetCount()<=0)
{
data_list.SetCount(1);
data_list.WriteAt(data,0);
return 0;
}
else
{
int pos;
if(FindPos(data,pos))
return(-1); //数据已存在
data_list.Insert(pos,data);
return(pos);
}
}
bool DeleteAt (const int pos){return data_list.DeleteMove(pos,1);} ///<删除一个数据,使用序号
bool Delete (const T &data) ///<删除一个数据
{
int pos=Find(data);
if(pos==-1)return(false);
return DeleteAt(pos);
}
/**
* 删除一批数据
* @param dp 数据指针
* @param count 数据个数
* @return 成功删除的数据个数
*/
int Delete(T *dp,const int count)
{
int total=0;
int pos;
for(int i=0;i<count;i++)
{
pos=Find(*dp);
if(pos!=-1)
{
if(index<0||index>=data_list.GetCount())
return(false);
data=*(data_list.GetData()+index);
return(true);
DeleteAt(pos);
++total;
}
bool GetBegin (T &data){return data_list.Begin(data);} ///<取得最前面一个数据
bool GetEnd (T &data){return data_list.End(data);} ///<取得最后面一个数据
++dp;
}
int Clear (const SortedSets<T> &clear_sets); ///<清除指定合集中所有数据
return total;
}
int Intersection (SortedSets<T> &result,const SortedSets<T> &sets); ///<取得与指定合集的交集
int Intersection (const SortedSets<T> &set); ///<取得与指定合集的交集数量
void Clear (){delete_list.Clear();} ///<清除数据
void ClearData (){delete_list.ClearData();} ///<清除数据,但不释放内存
/**
* 取得与指定交集is的合集但排斥cs合集中的数据
* @param result 结果合集
* @param is 求交集的合集
* @param cs 求排斥的合集
* @return 结果数量
*/
int Intersection (SortedSets<T> &result,const SortedSets<T> &is,const SortedSets<T> &cs);
bool Get (const int index,T &data) ///<根据序列号取得指定数据
{
if(index<0||index>=data_list.GetCount())
return(false);
int Difference (const SortedSets<T> &is); ///<求差集数量
data=*(data_list.GetData()+index);
return(true);
}
void operator =(const SortedSets<T> &set){data_list=set.data_list;} ///<等号操作符重载
bool GetFirst (T &data){return hgl_cpy(data,*begin());} ///<取得最前面一个数据
bool GetLast (T &data){return hgl_cpy(data,*last());} ///<取得最后面一个数据
bool Rand (T &)const; ///<随机取得一个
virtual void Enum (void (*enum_func)(int,T &)){data_list.Enum(enum_func);} ///<枚举所有数据成员
void operator =(const SortedSets<T> &set){data_list=set.data_list;} ///<等号操作符重载
};//template<typename T> class SortedSets
}//namespace hgl
#include<hgl/type/SortedSets.cpp>
#endif//HGL_TYPE_SORTED_SETS_INCLUDE