Hi all<div>Here is my objectpool implemention which inspired by boost pool.</div><div>Which have following features.</div><div><div>Features:</div><div>1.Allocate an object from pre-allocate memory, when free an object just put it back to pool.</div>
<div>2.Call object&#39;s contructor at pool memory allocating or get object from pool, or do nothing.</div><div>3.Call object&#39;s deconstructor when &quot;delete&quot; object if constructor&#39;s been calling at &quot;new&quot; object</div>
<div>3.Call object&#39;s deconstructor when destroy objectpool  if constructor&#39;s been calling at memory allocating</div><div>4.Can pass an function object to be invoke when &quot;new&quot; object, this can be used as a constructor if object&#39;s constructor  don&#39;t be invokded when &quot;new&quot; object</div>
<div><div>5.Thread safe can be enable/disable by tempalte parameter</div><div>6.Callback can be raw pointer is T is not inherit from enable_shared_from this</div><div>can be shared_ptr vers vice.</div></div>
<div><br></div><div>There are several tasks need to do, like the allnodesset can be generated at callring of foreach. Delegate memory allocating to allocator, etc..</div><div><br></div><div><br></div><div> The whole project and unit test can be found at</div>
<div><a href="https://maxsrecyclebin.svn.sourceforge.net/svnroot/maxsrecyclebin/objectpool/">https://maxsrecyclebin.svn.sourceforge.net/svnroot/maxsrecyclebin/objectpool/</a></div><div><div><br></div><div>Is there any comments?</div>
<div>Thanks</div><div>//////////////////////////////////////////////////////////////////////////////////////</div><div>#include &lt;istream&gt;</div><div>#include &lt;list&gt;</div><div>#include &lt;boost/shared_ptr.hpp&gt;</div>
<div>#include &lt;boost/bind.hpp&gt;</div><div>#include &lt;set&gt;</div><div>#include &lt;algorithm&gt;</div><div>#include &lt;boost/type_traits.hpp&gt;</div><div>#include &lt;boost/enable_shared_from_this.hpp&gt;</div><div>
#include &lt;boost/thread/pthread/mutex.hpp&gt;</div><div>namespace maxutility {</div><div>enum InitialType {None,ObjInitial,PoolAllocate};</div><div>template &lt;typename T&gt;</div><div>class DummyCallableObj</div><div>
{</div><div>public:</div><div>    void operator ()(boost::shared_ptr&lt;T&gt; &amp;ptr)</div><div>    {</div><div>        //do nothing</div><div>    }</div><div>};</div><div>template&lt;bool isthreadsafe&gt;</div><div>class obthreadlock;</div>
<div>template&lt;&gt;</div><div>class obthreadlock&lt;true&gt;</div><div>{</div><div>public:</div><div>    void lock(){obmutex.lock();}</div><div>    bool try_lock(){return obmutex.try_lock();}</div><div>    void unlock(){obmutex.unlock();}</div>
<div>private:</div><div>    boost::mutex obmutex;</div><div>};</div><div>template&lt;&gt;</div><div>class obthreadlock&lt;false&gt;</div><div>{</div><div>public:</div><div>    void lock(){};</div><div>    bool try_lock(){return true;};</div>
<div>    void unlock(){};</div><div>};</div><div>template &lt;typename T,bool isthreadsafe=false,typename InitalFunction=DummyCallableObj&lt;T&gt; &gt;</div><div>class ObjectPool</div><div>{</div><div>#define LOCAL_LOCK boost::lock_guard&lt;obthreadlock&lt;isthreadsafe&gt; &gt; lg(obthreadlock_);</div>
<div>protected:</div><div>    /**</div><div>     * @brief Declaration for furture usage</div><div>     **/</div><div>    typedef  T Node;</div><div>    typedef std::list&lt;char *&gt;  FRAGMENTTYPE;</div><div>    typedef std::list&lt;Node *&gt; NODELIST;</div>
<div>    </div><div>public:</div><div>    ObjectPool(InitialType initialtype=ObjInitial,size_t initialsize=512,size_t maxsize=0)</div><div>    {</div><div><br></div><div>        busyCount=0;</div><div>        this-&gt;poolsize=0;</div>
<div>        this-&gt;initialtype=initialtype;</div><div>        this-&gt;maxsize=maxsize;</div><div>        extend(initialsize);</div><div>    }</div><div>    ObjectPool(InitalFunction initalFunction=DummyCallableObj&lt;T&gt;(),</div>
<div>               InitialType initialtype=PoolAllocate,</div><div>               size_t initialsize=512,</div><div>               size_t maxsize=0) //:ObjectPool(initialtype,initialsize,maxsize) //Delegating constructors, c++11 only</div>
<div>    {</div><div>        busyCount=0;</div><div>        this-&gt;poolsize=0;</div><div>        this-&gt;initialtype=initialtype;</div><div>        this-&gt;maxsize=maxsize;</div><div>        this-&gt;initalFunction=initalFunction;</div>
<div>        extend(initialsize);</div><div>    }</div><div>    ~ObjectPool()</div><div>    {</div><div>        if(0!=busyCount)</div><div>            throw new std::exception();</div><div>        if(PoolAllocate==initialtype)</div>
<div>            for(Node *p:allnodes)</div><div>                p-&gt;~Node();</div><div>        for(char *pFragment:fragments)</div><div>            delete pFragment;</div><div>    }</div><div>    virtual boost::shared_ptr&lt;T&gt; create()</div>
<div>    {</div><div>        LOCAL_LOCK;</div><div>        boost::shared_ptr&lt;T&gt; ptr(static_cast&lt;T*&gt;(getFreeNode()),boost::bind(&amp;ObjectPool&lt;T,isthreadsafe,InitalFunction&gt;::free,this,_1));</div><div>        initalFunction(ptr);</div>
<div>        return ptr;</div><div>    }</div><div><br></div><div><br></div><div>    bool empty()</div><div>    {</div><div>        return !busyCount;</div><div>    }</div><div>    size_t size()</div><div>    {</div><div>
        return busyCount;</div><div>    }</div><div>    size_t capacity()</div><div>    {</div><div>        return poolsize;</div><div>    }</div><div>    template &lt;typename FUNCTION&gt;</div><div>    void foreach(FUNCTION f)</div>
<div>    {</div><div>        LOCAL_LOCK;</div><div>        NODELIST freenodes=this-&gt;freenodes; //make a local copy</div><div>        freenodes.sort();</div><div>        NODELIST busynodes(allnodes.size());</div><div>        typename NODELIST::iterator busynodesend=std::set_difference(</div>
<div>            allnodes.begin(),allnodes.end(),freenodes.begin(),freenodes.end(),busynodes.begin()</div><div>        );</div><div><br></div><div>        for(typename NODELIST::iterator iter=busynodes.begin();</div><div>
            iter!=busynodesend;</div><div>            iter++)</div><div>            {</div><div>                invokeFunction&lt;FUNCTION,Node,</div><div>                boost::is_base_of&lt;boost::enable_shared_from_this&lt;Node&gt;,Node &gt;::value &gt;()(f,*iter);</div>
<div>            }</div><div>    }</div><div>protected:</div><div>    template&lt;typename _Function,typename N,bool isuseshareptr&gt;</div><div>    class invokeFunction;</div><div>    template&lt;typename _Function,typename N&gt;</div>
<div>    class invokeFunction&lt;_Function,N,false&gt;</div><div>    {</div><div>    public:</div><div>        void operator ()(_Function __f,N *p)</div><div>        {</div><div>            __f(p);</div><div>        }</div>
<div>    };</div><div>    template&lt;typename _Function,typename N&gt;</div><div>    class invokeFunction&lt;_Function,N,true&gt;</div><div>    {</div><div>    public:</div><div>        void operator ()(_Function __f,N *p)</div>
<div>        {</div><div>            boost::shared_ptr&lt;N&gt; ptr=p-&gt;shared_from_this();</div><div>            __f(ptr);</div><div>        }</div><div>    };</div><div>   </div><div>    </div><div>protected:</div><div>
    void free(T *p)</div><div>    {</div><div>        LOCAL_LOCK;</div><div>        if(!p)</div><div>            return;</div><div>        destroyObj(static_cast&lt;Node*&gt;(p),ObjInitial);</div><div>        //removeBusyNode(static_cast&lt;Node*&gt;(p));</div>
<div>        freenodes.push_back(static_cast&lt;Node*&gt;(p));</div><div>        busyCount--;</div><div>    }</div><div>    Node *getFreeNode()</div><div>    {</div><div>        Node *ptr=nullptr;</div><div>        if(freenodes.empty()) //no new free node</div>
<div>            if(!extend())      //try to extend</div><div>                return ptr;   //false</div><div>        ptr=freenodes.front(); //now it must contain free node</div><div>        freenodes.pop_front();</div><div>
        </div><div><br></div><div>        constructObj(ptr,ObjInitial);</div><div>        busyCount++;</div><div>        return ptr;</div><div>    }</div><div>    bool extend(size_t size=0)</div><div>    {</div><div>        if((0!=maxsize&amp;&amp;poolsize&gt;=maxsize&amp;&amp;poolsize!=0)</div>
<div><br></div><div>          )</div><div>            return false; //we reach the maximum size</div><div>        //poolsize=0 first allocation</div><div>        //size=0 extend twice size of current size</div><div>        //poolsize=size=0 we got a problem</div>
<div>        size_t extSize=((0==poolsize)?size:2*poolsize);</div><div>        char *pFragment=new char[extSize*sizeof(Node)];</div><div>        if(!pFragment)</div><div>            return false;</div><div>        fragments.push_back(pFragment);</div>
<div>        poolsize+=extSize;</div><div>        for(Node *p=(Node*)pFragment; extSize--; p++)</div><div>        {</div><div>            constructObj(p,PoolAllocate);</div><div>            freenodes.push_back(p);</div><div>
            allnodes.push_back(p);</div><div>        }</div><div>        allnodes.sort();</div><div>        return true;</div><div>    }</div><div>    void constructObj(Node *p,InitialType phase)</div><div>    {</div><div>
        if(phase==initialtype)</div><div>            ::new(p)Node;</div><div>    }</div><div>    void destroyObj(Node *p,InitialType phase)</div><div>    {</div><div>        if(phase==initialtype)</div><div>            p-&gt;~Node();</div>
<div>    }</div><div><br></div><div>    size_t poolsize;</div><div>    InitialType initialtype;</div><div>    size_t maxsize;</div><div>    FRAGMENTTYPE fragments;</div><div>    NODELIST freenodes;</div><div>    NODELIST allnodes;</div>
<div>    size_t busyCount;</div><div>    InitalFunction initalFunction;</div><div>    obthreadlock&lt;isthreadsafe&gt; obthreadlock_;</div><div>};</div><div>};</div></div><div><br></div></div>