|
|
???????????????????????????
#ifndef _TObjectPoolV12_H_
#define _TObjectPoolV12_H_
#include<iostream>
#pragma warning(disable: 4786)//??4786??(STL?????????255??)
#include<list>
#include<algorithm>
namespace Aura
{
//TObjectPool1.2
//???????????????????????????????????????????????
enum TObjectPool_error
{
TObjectPool_error_no,
TObjectPool_error_memory, //??????
TObjectPool_error_null_pointer, //??????
TObjectPool_error_multiple_return, //??????
};
template <typename T,int k=16>
class TObjectPool
{
private:
class page;
public:
//proxy classes
class Ptr
{
public:
friend class page;
Ptr():m_p(NULL){}
~Ptr(){}
T* operator->()const{return m_p;}
T& operator*()const{return *m_p;}
bool is_null()const{return NULL==m_p;}
private:
Ptr(T* p){}
Ptr(const Ptr& rhs){}
Ptr& operator=(const Ptr& rhs){}
T* m_p;
};
public:
TObjectPool();
~TObjectPool();
//??????
bool operator >>(Ptr& ptr);
//??????(?????ptr?NULL?)?
bool operator <<(Ptr& ptr);
//??????
TObjectPool_error error()const{return m_error;}
private:
class page
{
public:
T m_objects[k]; //????
T* m_objects_statck[k]; //??????????????
bool m_objects_idle_flag[k];//???????
unsigned long m_statck_top; //?????0????????
unsigned long m_object_count; //????
page():m_object_count(k)
{
for(m_statck_top=0; m_statck_top<m_object_count; ++m_statck_top)
{
m_objects_statck[m_statck_top]=&m_objects[m_statck_top];
m_objects_idle_flag[m_statck_top]=true;
}
}
bool is_empty(){return 0==m_statck_top;}
bool is_full(){return m_statck_top==m_object_count;}
bool is_member(const Ptr& ptr){return ((&(*ptr)>=m_objects)&&(&(*ptr)<=&m_objects[m_object_count-1]));}
void operator >>(Ptr& ptr)
{
--m_statck_top;
m_objects_idle_flag[m_objects_statck[m_statck_top]-m_objects]=false;
ptr.m_p=m_objects_statck[m_statck_top];
}
TObjectPool_error operator <<(Ptr& ptr)
{
T* p=ptr.m_p;
long a=p-m_objects;
long b=(long)p-(long)m_objects;
if((b%sizeof(T))!=0)return TObjectPool_error_null_pointer;
if(is_full()||m_objects_idle_flag[a])return TObjectPool_error_multiple_return;
m_objects_idle_flag[a]=true;
m_objects_statck[m_statck_top]=p;
++m_statck_top;
ptr.m_p=NULL;
return TObjectPool_error_no;
}
};
std::list<page*> m_lspage;
std::list<page*>::iterator m_current_page;
unsigned long m_idle_object_count; //??????
TObjectPool_error m_error; //????
};
//end
//////////////////////////////////
//TObjectPool Class template implement
//////////////////////////////////////
template <typename T,int k>
TObjectPool<T,k>::TObjectPool():m_idle_object_count(0),m_error(TObjectPool_error_no)
{
m_lspage.push_back(new page);
m_current_page=m_lspage.begin();
m_idle_object_count+=k;
}
//????????????new?????
struct DeleteObject{
template<typename T>
void operator()(T* p)const{delete p;}
};
template <typename T,int k>
TObjectPool<T,k>::~TObjectPool(){std::for_each(m_lspage.begin(), m_lspage.end(),DeleteObject());}
template <typename T,int k>
bool TObjectPool<T,k>: perator >>(TObjectPool<T,k>: tr& ptr)
{
if(m_error!=TObjectPool_error_no)return false;
if(!ptr.is_null()){if(!operator <<(ptr))return false;}
std::list<TObjectPool<T,k>::page*>::iterator end=m_current_page;
for(; m_current_page!=m_lspage.end(); ++m_current_page)
{
if(!(*(*m_current_page)).is_empty()) //????????????
{
--m_idle_object_count; //????????????????1
(*(*m_current_page))>>(ptr);
return true;
}
}
for(m_current_page=m_lspage.begin(); m_current_page!=end; ++m_current_page)
{
if(!(*(*m_current_page)).is_empty()) //????????????
{
--m_idle_object_count; //????????????????1
(*(*m_current_page))>>(ptr);
return true;
}
}
//???????????????????????????????
m_lspage.push_back(new page);
m_current_page=m_lspage.end();
--m_current_page;
m_idle_object_count+=k-1; //???????????????-1
(*(*m_current_page))>>(ptr);
return true;
}
template <typename T,int k>
bool TObjectPool<T,k>::operator <<(TObjectPool<T,k>::Ptr& ptr)
{
if(m_error!=TObjectPool_error_no)return false;
if(ptr.is_null())
{
m_error=TObjectPool_error_null_pointer;
return false;
}
bool ok=false;
std::list<TObjectPool<T,k>::page*>::iterator end=m_current_page;
for(; m_current_page!=m_lspage.end(); ++m_current_page)
{
if((*(*m_current_page)).is_member(ptr))//????????
{
TObjectPool_error Ret=(*(*m_current_page))<<(ptr);
if(TObjectPool_error_no!=Ret)
{
m_error=Ret;
return false;
}
++m_idle_object_count; //????????????????1
ok=true;
break;
}
}
if(!ok)
{
for(m_current_page=m_lspage.begin(); m_current_page!=end; ++m_current_page)
{
if((*(*m_current_page)).is_member(ptr))//????????
{
TObjectPool_error Ret=(*(*m_current_page))<<(ptr);
if(TObjectPool_error_no!=Ret)
{
m_error=Ret;
return false;
}
++m_idle_object_count; //????????????????1
ok=true;
break;
}
}
}
//??????????2?????????????????????????????
if(m_idle_object_count>=(k<<1))
{
//????????????????
for(std::list<TObjectPool<T,k>::page*>::iterator i=m_lspage.begin(); i!=m_lspage.end();)
{
if((*(*i)).is_full())
{
delete *i;
i=m_lspage.erase(i);
m_idle_object_count -= k;
}
else ++i;
}
}
return true;
}
};
#endif
|
|