整合List到Type,增加Array.FindIndex
This commit is contained in:
parent
7a5f259ea3
commit
c1544f64e1
|
@ -2,7 +2,6 @@
|
|||
#define __Controller_H__
|
||||
|
||||
#include "Sys.h"
|
||||
#include "List.h"
|
||||
#include "Net\ITransport.h"
|
||||
|
||||
#include "Message.h"
|
||||
|
|
|
@ -38,6 +38,11 @@ private:
|
|||
|
||||
Area();
|
||||
bool Contain(uint offset, uint size);
|
||||
|
||||
friend bool operator==(const Area& a1, const Area& a2)
|
||||
{
|
||||
return a1.Offset == a2.Offset && a1.Size == a2.Size;
|
||||
}
|
||||
};
|
||||
|
||||
Array<Area, 0x08> Areas;
|
||||
|
|
3
Sys.h
3
Sys.h
|
@ -119,9 +119,6 @@ public:
|
|||
|
||||
extern TSys Sys; //创建一个全局的Sys对象 会在main函数之前执行构造函数(!!!!!)
|
||||
|
||||
// 内存管理
|
||||
#include "Memory.h"
|
||||
|
||||
//#include "Time.h"
|
||||
#include "Interrupt.h"
|
||||
|
||||
|
|
3
Task.h
3
Task.h
|
@ -2,7 +2,6 @@
|
|||
#define __Task_H__
|
||||
|
||||
#include "Sys.h"
|
||||
#include "List.h"
|
||||
|
||||
class TaskScheduler;
|
||||
|
||||
|
@ -46,6 +45,8 @@ public:
|
|||
// 显示状态
|
||||
void ShowStatus();
|
||||
|
||||
friend bool operator==(const Task& t1, const Task& t2) { return &t1 == &t2; }
|
||||
|
||||
// 全局任务调度器
|
||||
static TaskScheduler* Scheduler();
|
||||
static Task* Get(int taskid);
|
||||
|
|
1
Thread.h
1
Thread.h
|
@ -2,7 +2,6 @@
|
|||
#define __Thread_H__
|
||||
|
||||
#include "Sys.h"
|
||||
#include "List.h"
|
||||
|
||||
class Thread;
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#define _TinyIP_ICMP_H_
|
||||
|
||||
#include "Sys.h"
|
||||
#include "List.h"
|
||||
#include "Stream.h"
|
||||
#include "TinyIP.h"
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ void TinyIP::Init()
|
|||
Mask = 0x00FFFFFF;
|
||||
DHCPServer = Gateway = DNSServer = IP = 0;
|
||||
|
||||
Sockets.SetCapacity(0x10);
|
||||
//Sockets.SetCapacity(0x10);
|
||||
Arp = NULL;
|
||||
}
|
||||
|
||||
|
@ -162,7 +162,7 @@ void TinyIP::Process(Stream& ms)
|
|||
// 各处理器有可能改变数据流游标,这里备份一下
|
||||
uint p = ms.Position();
|
||||
// 考虑到可能有通用端口处理器,也可能有专用端口处理器(一般在后面),这里偷懒使用倒序处理
|
||||
uint count = Sockets.Count();
|
||||
uint count = Sockets.Length();
|
||||
for(int i=count-1; i>=0; i--)
|
||||
{
|
||||
TinySocket* socket = Sockets[i];
|
||||
|
@ -417,6 +417,19 @@ TinySocket::TinySocket(TinyIP* tip, IP_TYPE type)
|
|||
|
||||
// 除了ARP以外,加入到列表
|
||||
if(type != IP_NONE) tip->Sockets.Add(this);
|
||||
/*if(type != IP_NONE)
|
||||
{
|
||||
for(int i=0; i<tip->Sockets.Length(); i++)
|
||||
{
|
||||
if(tip->Sockets[i] == NULL)
|
||||
{
|
||||
tip->Sockets[i] = this;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
//int idx = tip->Sockets.FindIndex(NULL);
|
||||
//if(idx >= 0) tip->Sockets[idx] = this;
|
||||
}
|
||||
|
||||
TinySocket::~TinySocket()
|
||||
|
@ -426,12 +439,21 @@ TinySocket::~TinySocket()
|
|||
Enable = false;
|
||||
// 从TinyIP中删除当前Socket
|
||||
Tip->Sockets.Remove(this);
|
||||
/*for(int i=0; i<Tip->Sockets.Length(); i++)
|
||||
{
|
||||
if(Tip->Sockets[i] == this)
|
||||
{
|
||||
Tip->Sockets[i] = NULL;
|
||||
break;
|
||||
}
|
||||
}*/
|
||||
//int idx = Tip->Sockets.FindIndex(this);
|
||||
//if(idx >= 0) Tip->Sockets[idx] = NULL;
|
||||
}
|
||||
|
||||
TinySocket* SocketList::FindByType(ushort type)
|
||||
{
|
||||
uint count = Count();
|
||||
for(int i=count-1; i>=0; i--)
|
||||
for(int i=Length()-1; i>=0; i--)
|
||||
{
|
||||
TinySocket* socket = (*this)[i];
|
||||
if(socket)
|
||||
|
@ -443,3 +465,18 @@ TinySocket* SocketList::FindByType(ushort type)
|
|||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void SocketList::Add(const TinySocket* socket)
|
||||
{
|
||||
int idx = FindIndex(NULL);
|
||||
// 如果找不到空位,则加在最后
|
||||
if(idx < 0) idx = Length();
|
||||
SetAt(idx, (TinySocket*)socket);
|
||||
}
|
||||
|
||||
void SocketList::Remove(const TinySocket* socket)
|
||||
{
|
||||
int idx = FindIndex((TinySocket*)socket);
|
||||
if(idx >= 0) (*this)[idx] = NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
// 模块开发使用说明见后
|
||||
|
||||
#include "Sys.h"
|
||||
#include "List.h"
|
||||
#include "Stream.h"
|
||||
#include "Net\ITransport.h"
|
||||
#include "Net\Net.h"
|
||||
|
@ -28,10 +27,12 @@ public:
|
|||
};
|
||||
|
||||
// Socket列表
|
||||
class SocketList : public List<TinySocket*>
|
||||
class SocketList : public Array<TinySocket*>
|
||||
{
|
||||
public:
|
||||
TinySocket* FindByType(ushort type);
|
||||
void Add(const TinySocket* socket);
|
||||
void Remove(const TinySocket* socket);
|
||||
};
|
||||
|
||||
// 精简以太网协议。封装以太网帧以及IP协议,不包含其它协议实现,仅提供底层支持。
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#define __TinyMessage_H__
|
||||
|
||||
#include "Sys.h"
|
||||
#include "List.h"
|
||||
#include "Net\ITransport.h"
|
||||
#include "Stream.h"
|
||||
|
||||
|
|
|
@ -196,7 +196,7 @@ bool TinyServer::OnJoin(const TinyMessage& msg)
|
|||
// 节点注册
|
||||
dv->RegTime = now;
|
||||
|
||||
Devices.Add(dv);
|
||||
Devices.Push(dv);
|
||||
|
||||
SaveDevices();
|
||||
}
|
||||
|
@ -482,7 +482,7 @@ Device* TinyServer::FindDevice(byte id)
|
|||
{
|
||||
if(id == 0) return NULL;
|
||||
|
||||
for(int i=0; i<Devices.Count(); i++)
|
||||
for(int i=0; i<Devices.Length(); i++)
|
||||
{
|
||||
if(id == Devices[i]->Address) return Devices[i];
|
||||
}
|
||||
|
@ -494,7 +494,7 @@ Device* TinyServer::FindDevice(const ByteArray& hardid)
|
|||
{
|
||||
if(hardid.Length() == 0) return NULL;
|
||||
|
||||
for(int i=0; i<Devices.Count(); i++)
|
||||
for(int i=0; i<Devices.Length(); i++)
|
||||
{
|
||||
if(hardid == Devices[i]->HardID) return Devices[i];
|
||||
}
|
||||
|
@ -507,7 +507,9 @@ bool TinyServer::DeleteDevice(byte id)
|
|||
Device* dv = FindDevice(id);
|
||||
if(dv && dv->Address == id)
|
||||
{
|
||||
Devices.Remove(dv);
|
||||
//Devices.Remove(dv);
|
||||
int idx = Devices.FindIndex(dv);
|
||||
if(idx >= 0) Devices[idx] = NULL;
|
||||
delete dv;
|
||||
return true;
|
||||
}
|
||||
|
@ -537,7 +539,9 @@ int TinyServer::LoadDevices()
|
|||
if(!dv) dv = new Device();
|
||||
dv->Read(ms);
|
||||
|
||||
Devices.Add(dv);
|
||||
//Devices.Add(dv);
|
||||
int idx = Devices.FindIndex(NULL);
|
||||
if(idx >= 0) Devices[idx] = dv;
|
||||
}
|
||||
|
||||
debug_printf("TinyServer::LoadDevices 从 0x%08X 加载 %d 个设备!\r\n", addr, i);
|
||||
|
@ -556,7 +560,7 @@ void TinyServer::SaveDevices()
|
|||
|
||||
Stream ms(buf, ArrayLength(buf));
|
||||
// 设备个数
|
||||
int count = Devices.Count();
|
||||
int count = Devices.Length();
|
||||
ms.Write((byte)count);
|
||||
for(int i = 0; i<count; i++)
|
||||
{
|
||||
|
|
|
@ -35,15 +35,15 @@ public:
|
|||
MessageHandler Received;
|
||||
void* Param;
|
||||
|
||||
List<Device*> Devices;
|
||||
Array<Device*> Devices;
|
||||
Device* FindDevice(byte id);
|
||||
Device* FindDevice(const ByteArray& hardid);
|
||||
bool DeleteDevice(byte id);
|
||||
|
||||
|
||||
int LoadDevices();
|
||||
void SaveDevices();
|
||||
void ClearDevices();
|
||||
|
||||
|
||||
bool LoadConfig();
|
||||
void SaveConfig();
|
||||
void ClearConfig();
|
||||
|
@ -59,7 +59,7 @@ public:
|
|||
|
||||
// 组网
|
||||
bool OnJoin(const TinyMessage& msg);
|
||||
|
||||
|
||||
bool ResetPassword(byte id);
|
||||
|
||||
bool OnDisjoin(const TinyMessage& msg);
|
||||
|
|
|
@ -59,7 +59,7 @@ void Gateway::Start()
|
|||
Server->Start();
|
||||
|
||||
// 添加网关这一条设备信息
|
||||
if(Server->Devices.Count() == 0)
|
||||
if(Server->Devices.Length() == 0)
|
||||
{
|
||||
Device* dv = new Device();
|
||||
dv->Address = Server->Cfg->Address;
|
||||
|
@ -69,7 +69,7 @@ void Gateway::Start()
|
|||
dv->LastTime = Time.Current();
|
||||
dv->Name = Sys.Name;
|
||||
|
||||
Server->Devices.Add(dv);
|
||||
Server->Devices.Push(dv);
|
||||
Server->SaveDevices();
|
||||
}
|
||||
|
||||
|
@ -218,7 +218,7 @@ bool Gateway::OnRemote(const TokenMessage& msg)
|
|||
rs.Code = 0x21;
|
||||
OnGetDeviceList(rs);
|
||||
// 遍历发送所有设备信息
|
||||
for(int i=0; i<Server->Devices.Count(); i++)
|
||||
for(int i=0; i<Server->Devices.Length(); i++)
|
||||
SendDeviceInfo(Server->Devices[i]);
|
||||
}
|
||||
break;
|
||||
|
@ -334,7 +334,7 @@ bool Gateway::OnGetDeviceList(const Message& msg)
|
|||
TokenMessage rs;
|
||||
rs.Code = msg.Code;
|
||||
|
||||
if(Server->Devices.Count() == 0)
|
||||
if(Server->Devices.Length() == 0)
|
||||
{
|
||||
rs.Data[0] = 0;
|
||||
rs.Length = 1;
|
||||
|
@ -342,12 +342,12 @@ bool Gateway::OnGetDeviceList(const Message& msg)
|
|||
else
|
||||
{
|
||||
int i = 0;
|
||||
for(i=0; i<Server->Devices.Count(); i++)
|
||||
for(i=0; i<Server->Devices.Length(); i++)
|
||||
rs.Data[i] = Server->Devices[i]->Address;
|
||||
rs.Length = i;
|
||||
}
|
||||
|
||||
debug_printf("获取设备列表 共%d个\r\n", Server->Devices.Count());
|
||||
debug_printf("获取设备列表 共%d个\r\n", Server->Devices.Length());
|
||||
|
||||
return Client->Reply(rs);
|
||||
}
|
||||
|
|
788
Type.h
788
Type.h
|
@ -385,6 +385,17 @@ public:
|
|||
return _Arr[--_Length];
|
||||
}
|
||||
|
||||
// 查找元素
|
||||
virtual int FindIndex(const T item)
|
||||
{
|
||||
for(int i=0; i<Length(); i++)
|
||||
{
|
||||
if(_Arr[i] == item) return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 重载索引运算符[],让它可以像数组一样使用下标索引。
|
||||
virtual T& operator[](int i) const
|
||||
{
|
||||
|
@ -511,4 +522,781 @@ public:
|
|||
String operator+(const char* str, const Object& obj);
|
||||
String operator+(const Object& obj, const char* str);
|
||||
|
||||
// 从数组创建列表
|
||||
#define MakeList(T, arr) List<T>(&arr[0], sizeof(arr)/sizeof(arr[0]))
|
||||
|
||||
// 数组
|
||||
class JArray
|
||||
{
|
||||
private:
|
||||
void** _Arr;
|
||||
int _Count;
|
||||
int _Capacity;
|
||||
|
||||
public:
|
||||
// 有效元素个数
|
||||
int Count() const { return _Count; }
|
||||
// 最大元素个数
|
||||
int Capacity() const { return _Capacity; }
|
||||
|
||||
JArray(int capacity = 0x10)
|
||||
{
|
||||
_Capacity = capacity;
|
||||
_Count = 0;
|
||||
|
||||
_Arr = new void*[capacity];
|
||||
ArrayZero2(_Arr, capacity);
|
||||
}
|
||||
|
||||
~JArray()
|
||||
{
|
||||
if(_Arr) delete _Arr;
|
||||
_Arr = NULL;
|
||||
}
|
||||
|
||||
// 压入一个元素
|
||||
int Push(void* item)
|
||||
{
|
||||
assert_param(_Count < _Capacity);
|
||||
|
||||
// 找到空闲位放置
|
||||
int idx = _Count++;
|
||||
_Arr[idx] = item;
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
// 弹出一个元素
|
||||
const void* Pop()
|
||||
{
|
||||
assert_param(_Count > 0);
|
||||
|
||||
return _Arr[--_Count];
|
||||
}
|
||||
|
||||
// 重载索引运算符[],让它可以像数组一样使用下标索引。
|
||||
void* operator[](int i)
|
||||
{
|
||||
assert_param(i >= 0 && i < _Count);
|
||||
return _Arr[i];
|
||||
}
|
||||
// 列表转为指针,注意安全
|
||||
//T* operator=(Array arr) { return arr.Arr; }
|
||||
};
|
||||
|
||||
// 固定大小的指针数组。
|
||||
/*
|
||||
用于数据元素不多,有个上限的场合。主要为了方便遍历。
|
||||
存储数据时,从头开始找到空位来存放,不用时清空相应空位。
|
||||
所以需要注意的是,在数组里面存储的元素不一定连续。
|
||||
*/
|
||||
template<typename T, int ArraySize>
|
||||
class FixedArray
|
||||
{
|
||||
private:
|
||||
uint _Count;
|
||||
T* Arr[ArraySize];
|
||||
|
||||
public:
|
||||
// 默认初始化。大小和数组元素全部清零
|
||||
FixedArray()
|
||||
{
|
||||
_Count = 0;
|
||||
ArrayZero(Arr);
|
||||
}
|
||||
|
||||
// 使用另一个固定数组来初始化
|
||||
FixedArray(FixedArray& arr)
|
||||
{
|
||||
_Count = arr._Count;
|
||||
ArrayCopy(Arr, arr.Arr);
|
||||
}
|
||||
|
||||
// 重载等号运算符,使用另一个固定数组来初始化
|
||||
FixedArray& operator=(FixedArray& arr)
|
||||
{
|
||||
_Count = arr._Count;
|
||||
ArrayCopy(Arr, arr.Arr);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
~FixedArray() { DeleteAll(); }
|
||||
|
||||
// 实际元素个数
|
||||
uint Count() const { return _Count; }
|
||||
|
||||
// 数组总长度
|
||||
uint Length() const { return ArraySize; }
|
||||
|
||||
// 压入一个元素。返回元素所存储的索引
|
||||
int Add(T* item)
|
||||
{
|
||||
assert_ptr(item);
|
||||
//assert_param(_Count < ArraySize);
|
||||
|
||||
if(_Count >= ArraySize) return -1;
|
||||
|
||||
// 找到空闲位放置
|
||||
int i = 0;
|
||||
for(; i < ArraySize && Arr[i]; i++);
|
||||
// 检查是否还有空位
|
||||
if(i >= ArraySize) return -1;
|
||||
|
||||
Arr[i] = item;
|
||||
_Count++;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
// 弹出最后一个元素
|
||||
T* Pop()
|
||||
{
|
||||
if(_Count == 0) return NULL;
|
||||
|
||||
// 找到最后一个元素
|
||||
int i = ArraySize - 1;
|
||||
for(; i >=0 && !Arr[i]; i--);
|
||||
|
||||
T* item = Arr[i];
|
||||
_Count--;
|
||||
Arr[i] = NULL;
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
// 删除元素
|
||||
bool Remove(T* item)
|
||||
{
|
||||
int idx = Find(item);
|
||||
if(idx < 0) return false;
|
||||
|
||||
RemoveAt(idx);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// 删除指定位置的元素
|
||||
void RemoveAt(int idx)
|
||||
{
|
||||
assert_param(idx >= 0 && idx < ArraySize);
|
||||
|
||||
_Count--;
|
||||
Arr[idx] = NULL;
|
||||
}
|
||||
|
||||
// 清空数组。个数设0,所有元素清零
|
||||
FixedArray& Clear()
|
||||
{
|
||||
_Count = 0;
|
||||
ArrayZero(Arr);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// 释放所有指针指向的内存
|
||||
FixedArray& DeleteAll()
|
||||
{
|
||||
for(int i=0; i < ArraySize; i++)
|
||||
{
|
||||
if(Arr[i]) delete Arr[i];
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// 查找元素
|
||||
int Find(T* item)
|
||||
{
|
||||
assert_ptr(item);
|
||||
|
||||
int i = 0;
|
||||
for(; i < ArraySize && Arr[i] != item; i++);
|
||||
if(i >= ArraySize) return -1;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
// 移到下一个元素,累加参数,如果没有下一个元素则返回false。
|
||||
bool MoveNext(int& idx)
|
||||
{
|
||||
//assert_ptr(idx);
|
||||
|
||||
// 从idx开始,找到第一个非空节点。注意,存储不一定连续
|
||||
int i = idx + 1;
|
||||
for(; i < ArraySize && !Arr[i]; i++);
|
||||
if(i >= ArraySize) return false;
|
||||
|
||||
idx = i;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// 重载索引运算符[],让它可以像数组一样使用下标索引。
|
||||
/*T*& operator[](int i)
|
||||
{
|
||||
assert_param(i >= 0 && i < ArraySize);
|
||||
return Arr[i];
|
||||
}*/
|
||||
// 不能允许[]作为左值,否则外部直接设置数据以后,Count并没有改变
|
||||
T* operator[](int i)
|
||||
{
|
||||
assert_param(i >= 0 && i < ArraySize);
|
||||
return Arr[i];
|
||||
}
|
||||
};
|
||||
|
||||
// 变长列表模版
|
||||
// T一般是指针,列表内部有一个数组用于存放指针
|
||||
template<typename T>
|
||||
class List
|
||||
{
|
||||
private:
|
||||
uint _Count;// 拥有实际元素个数
|
||||
uint _total;// 可容纳元素总数
|
||||
T* _Arr; // 存储数据的数组
|
||||
|
||||
void ChangeSize(int newSize)
|
||||
{
|
||||
if(_total == newSize) return;
|
||||
|
||||
T* arr2 = new T[newSize];
|
||||
if(_Arr)
|
||||
{
|
||||
// 如果新数组较小,则直接复制;如果新数组较大,则先复制,再清空余下部分
|
||||
if(newSize < _Count)
|
||||
{
|
||||
// 此时有数据丢失
|
||||
memcpy(arr2, _Arr, newSize * sizeof(T));
|
||||
_Count = newSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(arr2, _Arr, _Count * sizeof(T));
|
||||
memset(&arr2[_Count], 0, (newSize - _Count) * sizeof(T));
|
||||
}
|
||||
delete[] _Arr;
|
||||
}
|
||||
else
|
||||
ArrayZero2(arr2, newSize);
|
||||
_Arr = arr2;
|
||||
_total = newSize;
|
||||
}
|
||||
|
||||
void CheckSize()
|
||||
{
|
||||
// 如果数组空间已用完,则两倍扩容
|
||||
if(_Count >= _total) ChangeSize(_Count > 0 ? _Count * 2 : 4);
|
||||
}
|
||||
|
||||
public:
|
||||
List(int size = 0)
|
||||
{
|
||||
_Count = 0;
|
||||
_total = size;
|
||||
_Arr = NULL;
|
||||
if(size)
|
||||
{
|
||||
_Arr = new T[size];
|
||||
ArrayZero2(_Arr, size);
|
||||
}
|
||||
}
|
||||
|
||||
List(T* items, uint count)
|
||||
{
|
||||
_Arr = new T[count];
|
||||
|
||||
_Count = 0;
|
||||
_total = count;
|
||||
for(int i=0; i<count; i++)
|
||||
{
|
||||
_Arr[_Count++] = *items++;
|
||||
}
|
||||
}
|
||||
|
||||
~List() { if(_Arr) delete[] _Arr; _Arr = NULL; }
|
||||
|
||||
// 重载等号运算符,使用另一个列表来初始化
|
||||
List& operator=(List& list)
|
||||
{
|
||||
Clear();
|
||||
for(int i=0; i<list.Count(); i++)
|
||||
Add(list[i]);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// 添加单个元素
|
||||
virtual void Add(const T& item)
|
||||
{
|
||||
// 检查大小
|
||||
CheckSize();
|
||||
|
||||
_Arr[_Count++] = item;
|
||||
}
|
||||
|
||||
// 添加多个元素
|
||||
void Add(T* items, int count)
|
||||
{
|
||||
int size = _Count + count;
|
||||
if(size >= _total) ChangeSize(_Count > 0 ? _Count * 2 : 4);
|
||||
|
||||
for(int i=0; i<count; i++)
|
||||
{
|
||||
_Arr[_Count++] = *items++;
|
||||
}
|
||||
}
|
||||
|
||||
// 查找元素
|
||||
int Find(const T& item)
|
||||
{
|
||||
for(int i=0; i<_Count; i++)
|
||||
{
|
||||
if(_Arr[i] == item) return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
virtual bool Contains(const T& item)
|
||||
{
|
||||
return Find(item) > -1;
|
||||
}
|
||||
|
||||
// 删除指定位置元素
|
||||
void RemoveAt(int index)
|
||||
{
|
||||
if(_Count <= 0 || index >= _Count) return;
|
||||
|
||||
// 复制元素
|
||||
if(index < _Count - 1) memcpy(&_Arr[index], &_Arr[index + 1], (_Count - index - 1) * sizeof(T));
|
||||
_Count--;
|
||||
}
|
||||
|
||||
// 删除指定元素
|
||||
virtual void Remove(const T& item)
|
||||
{
|
||||
int index = Find(item);
|
||||
if(index >= 0) RemoveAt(index);
|
||||
}
|
||||
|
||||
// 释放所有指针指向的内存
|
||||
List& DeleteAll()
|
||||
{
|
||||
for(int i=0; i < _Count; i++)
|
||||
{
|
||||
if(_Arr[i]) delete _Arr[i];
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
virtual void Clear()
|
||||
{
|
||||
_Count = 0;
|
||||
}
|
||||
|
||||
virtual void CopyTo(T* arr)
|
||||
{
|
||||
assert_ptr(arr);
|
||||
if(!_Count) return;
|
||||
|
||||
memcpy(arr, _Arr, _Count * sizeof(T));
|
||||
}
|
||||
|
||||
// 返回内部指针
|
||||
const T* ToArray() { return _Arr; }
|
||||
|
||||
// 有效元素个数
|
||||
virtual int Count() const { return _Count; }
|
||||
|
||||
// 设置新的容量,如果容量比元素个数小,则会丢失数据
|
||||
void SetCapacity(int capacity) { ChangeSize(capacity); }
|
||||
|
||||
// 重载索引运算符[],让它可以像数组一样使用下标索引。
|
||||
T operator[](int i)
|
||||
{
|
||||
assert_param(i >= 0 && i < _Count);
|
||||
// 有可能多线程冲突
|
||||
//if(i < 0 || i >= _Count) return NULL;
|
||||
|
||||
return _Arr[i];
|
||||
}
|
||||
};
|
||||
|
||||
// 双向链表
|
||||
template <class T> class LinkedList;
|
||||
|
||||
// 双向链表节点。实体类继承该类
|
||||
template <class T> class LinkedNode
|
||||
{
|
||||
// 友元类。允许链表类控制本类私有成员
|
||||
friend class LinkedList<T>;
|
||||
|
||||
public:
|
||||
T* Prev; // 上一个节点
|
||||
T* Next; // 下一个节点
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
Next = NULL;
|
||||
Prev = NULL;
|
||||
}
|
||||
|
||||
// 从链表中删除。需要修改前后节点的指针指向,但当前节点仍然指向之前的前后节点
|
||||
void RemoveFromList()
|
||||
{
|
||||
if(Prev) Prev->Next = Next;
|
||||
if(Next) Next->Prev = Prev;
|
||||
}
|
||||
|
||||
// 完全脱离链表。不再指向其它节点
|
||||
void Unlink()
|
||||
{
|
||||
if(Prev) Prev->Next = Next;
|
||||
if(Next) Next->Prev = Prev;
|
||||
|
||||
Next = NULL;
|
||||
Prev = NULL;
|
||||
}
|
||||
|
||||
// 把当前节点附加到另一个节点之后
|
||||
void LinkAfter(T* node)
|
||||
{
|
||||
node->Next = (T*)this;
|
||||
Prev = node;
|
||||
// 不能清空Next,因为可能是两个链表的合并
|
||||
//Next = NULL;
|
||||
}
|
||||
|
||||
// 最后一个节点
|
||||
T* Last()
|
||||
{
|
||||
T* node = (T*)this;
|
||||
while(node->Next) node = node->Next;
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
// 附加到当前节点后面
|
||||
void Append(T* node)
|
||||
{
|
||||
Next = node;
|
||||
node->Prev = (T*)this;
|
||||
//node->Next = NULL;
|
||||
}
|
||||
};
|
||||
|
||||
// 双向链表
|
||||
template <class T>
|
||||
class LinkedList
|
||||
{
|
||||
public:
|
||||
// 链表节点。实体类不需要继承该内部类
|
||||
class Node
|
||||
{
|
||||
public:
|
||||
T Item; // 元素
|
||||
Node* Prev; // 前一节点
|
||||
Node* Next; // 下一节点
|
||||
|
||||
Node()
|
||||
{
|
||||
Prev = NULL;
|
||||
Next = NULL;
|
||||
}
|
||||
|
||||
// 从队列中脱离
|
||||
void RemoveFromList()
|
||||
{
|
||||
// 双保险,只有在前后节点指向当前节点时,才修改它们的值
|
||||
if(Prev && Prev->Next == this) Prev->Next = Next;
|
||||
if(Next && Next->Prev == this) Next->Prev = Prev;
|
||||
}
|
||||
|
||||
// 附加到当前节点后面
|
||||
void Append(Node* node)
|
||||
{
|
||||
Next = node;
|
||||
node->Prev = this;
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
Node* _Head; // 链表头部
|
||||
Node* _Tail; // 链表尾部
|
||||
int _Count; // 元素个数
|
||||
|
||||
void Init()
|
||||
{
|
||||
_Head = NULL;
|
||||
_Tail = NULL;
|
||||
_Count = 0;
|
||||
}
|
||||
|
||||
void Remove(Node* node)
|
||||
{
|
||||
// 脱离队列
|
||||
node->RemoveFromList();
|
||||
// 特殊处理头尾
|
||||
if(node == _Head) _Head = node->Next;
|
||||
if(node == _Tail) _Tail = node->Prev;
|
||||
|
||||
delete node;
|
||||
_Count--;
|
||||
}
|
||||
|
||||
public:
|
||||
LinkedList()
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
// 计算链表节点数
|
||||
virtual int Count() const { return _Count; }
|
||||
|
||||
// 将某项添加到集合
|
||||
virtual void Add(const T& item)
|
||||
{
|
||||
Node* node = new Node();
|
||||
node->Item = item;
|
||||
|
||||
if(_Tail)
|
||||
_Tail->Append(node);
|
||||
else
|
||||
_Head = _Tail = node;
|
||||
|
||||
_Count++;
|
||||
}
|
||||
|
||||
// 从集合中移除特定对象的第一个匹配项
|
||||
virtual void Remove(const T& item)
|
||||
{
|
||||
if(!_Count) return;
|
||||
|
||||
Node* node;
|
||||
for(node = _Head; node; node = node->Next)
|
||||
{
|
||||
if(node->Item == item) break;
|
||||
}
|
||||
|
||||
if(node) Remove(node);
|
||||
}
|
||||
|
||||
// 确定集合是否包含特定值
|
||||
virtual bool Contains(const T& item)
|
||||
{
|
||||
if(!_Count) return false;
|
||||
|
||||
Node* node;
|
||||
for(node = _Head; node; node = node->Next)
|
||||
{
|
||||
if(node->Item == item) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// 从集合中移除所有项。注意,该方法不会释放元素指针
|
||||
virtual void Clear()
|
||||
{
|
||||
if(!_Count) return;
|
||||
|
||||
Node* node;
|
||||
for(node = _Head; node;)
|
||||
{
|
||||
// 先备份,待会删除可能影响指针
|
||||
Node* next = node->Next;
|
||||
delete node;
|
||||
node = next;
|
||||
}
|
||||
|
||||
Init();
|
||||
}
|
||||
|
||||
// 将集合元素复制到数组中
|
||||
virtual void CopyTo(T* arr)
|
||||
{
|
||||
assert_ptr(arr);
|
||||
|
||||
if(!_Count) return;
|
||||
|
||||
Node* node;
|
||||
for(node = _Head; node; node = node->Next)
|
||||
{
|
||||
*arr++ = node->Item;
|
||||
}
|
||||
}
|
||||
|
||||
T& First() { return _Head->Item; }
|
||||
T& Last() { return _Tail->Item; }
|
||||
|
||||
// 释放第一个有效节点
|
||||
T& ExtractFirst()
|
||||
{
|
||||
if(!_Count) return NULL;
|
||||
|
||||
Node* node = _Head;
|
||||
_Head = _Head->Next;
|
||||
// 可能只有一个节点
|
||||
if(!_Head)
|
||||
_Tail = NULL;
|
||||
else
|
||||
_Head->Prev = NULL;
|
||||
|
||||
T& item = node->Item;
|
||||
delete node;
|
||||
_Count--;
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
// 释放最后一个有效节点
|
||||
T& ExtractLast()
|
||||
{
|
||||
if(!_Count) return NULL;
|
||||
|
||||
Node* node = _Tail;
|
||||
_Tail = _Tail->Prev;
|
||||
// 可能只有一个节点
|
||||
if(!_Tail)
|
||||
_Head = NULL;
|
||||
else
|
||||
_Tail->Next = NULL;
|
||||
|
||||
T& item = node->Item;
|
||||
delete node;
|
||||
_Count--;
|
||||
|
||||
return item;
|
||||
}
|
||||
};
|
||||
|
||||
void* operator new(uint size);
|
||||
void* operator new[](uint size);
|
||||
void operator delete(void* p);
|
||||
void operator delete [] (void* p);
|
||||
|
||||
//#define DEBUG_NEW new(__FILE__, __LINE__)
|
||||
//#define new DEBUG_NEW
|
||||
//#endif
|
||||
|
||||
// 自动释放的智能指针
|
||||
class SmartPtr
|
||||
{
|
||||
private:
|
||||
// 内部包装。指针的多个智能指针SmartPtr对象共用该内部包装
|
||||
class WrapPtr
|
||||
{
|
||||
public:
|
||||
void* Ptr; // 目标指针
|
||||
uint Count; // 引用计数
|
||||
|
||||
WrapPtr(void* ptr) { Ptr = ptr; Count = 1; }
|
||||
~WrapPtr() { delete Ptr; }
|
||||
};
|
||||
WrapPtr* _ptr;
|
||||
|
||||
public:
|
||||
// 为某个指针封装
|
||||
SmartPtr(void* ptr)
|
||||
{
|
||||
assert_ptr(ptr);
|
||||
|
||||
_ptr = new WrapPtr(ptr);
|
||||
}
|
||||
|
||||
// 拷贝智能指针。仅拷贝内部包装,然后引用计数加一
|
||||
SmartPtr(const SmartPtr& ptr)
|
||||
{
|
||||
assert_ptr(ptr._ptr);
|
||||
assert_ptr(ptr._ptr->Ptr);
|
||||
|
||||
_ptr = ptr._ptr;
|
||||
_ptr->Count++;
|
||||
}
|
||||
|
||||
~SmartPtr()
|
||||
{
|
||||
// 释放智能指针时,指针引用计数减一
|
||||
_ptr->Count--;
|
||||
// 如果指针引用计数为0,则释放指针
|
||||
if(!_ptr->Count)
|
||||
{
|
||||
delete _ptr;
|
||||
_ptr = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void* ToPtr() { return _ptr->Ptr; }
|
||||
};
|
||||
|
||||
// 经典的C++自动指针
|
||||
// 超出对象作用域时自动销毁被管理指针
|
||||
template<class T>
|
||||
class auto_ptr
|
||||
{
|
||||
private:
|
||||
T* _ptr;
|
||||
|
||||
public:
|
||||
// 普通指针构造自动指针,隐式转换
|
||||
// 构造函数的explicit关键词有效阻止从一个“裸”指针隐式转换成auto_ptr类型
|
||||
explicit auto_ptr(T* p = 0) : _ptr(p) { }
|
||||
// 拷贝构造函数,解除原来自动指针的管理权
|
||||
auto_ptr(auto_ptr& ap) : _ptr(ap.release()) { }
|
||||
// 析构时销毁被管理指针
|
||||
~auto_ptr()
|
||||
{
|
||||
// 因为C++保证删除一个空指针是安全的,所以我们没有必要判断空
|
||||
/*if(_ptr)
|
||||
{
|
||||
delete _ptr;
|
||||
_ptr = NULL;
|
||||
}*/
|
||||
delete _ptr;
|
||||
}
|
||||
|
||||
// 自动指针拷贝,解除原来自动指针的管理权
|
||||
auto_ptr& operator=(T* p)
|
||||
{
|
||||
_ptr = p;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// 自动指针拷贝,解除原来自动指针的管理权
|
||||
auto_ptr& operator=(auto_ptr& ap)
|
||||
{
|
||||
reset(ap.release());
|
||||
return *this;
|
||||
}
|
||||
|
||||
// 获取原始指针
|
||||
T* get() const { return _ptr; }
|
||||
|
||||
// 重载*和->运算符
|
||||
T& operator*() const { assert_param(_ptr); return *_ptr; }
|
||||
T* operator->() const { return _ptr; }
|
||||
|
||||
// 接触指针的管理权
|
||||
T* release()
|
||||
{
|
||||
T* p = _ptr;
|
||||
_ptr = 0;
|
||||
return p;
|
||||
}
|
||||
|
||||
// 销毁原指针,管理新指针
|
||||
void reset(T* p = 0)
|
||||
{
|
||||
if(_ptr != p)
|
||||
{
|
||||
//if(_ptr) delete _ptr;
|
||||
// 因为C++保证删除一个空指针是安全的,所以我们没有必要判断空
|
||||
delete _ptr;
|
||||
_ptr = p;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue