Monday, 30 May 2011

A generic poolkit

//This is a generic toolkit to pool resources. I called it a poolkit :)
// You can pool objects that can have constructors that take in from 0 to 3
// arguments. You can reuse the code and suggest any changes if needed, but
// don't hold my neck if it has bugs. This is not tested extensively

using namespace std;

template <typename T, typename Container = deque<T> >
class Pool
{
Container dec;
size_t m_maxSize;
public:
typedef typename Container::iterator PoolIterator;

Pool(size_t max_size=numeric_limits<size_t>::max()) : m_maxSize(max_size)
{
}

//Default constructor version
boost::optional <pair<PoolIterator, PoolIterator> > make_pool(size_t size_)
{
        boost::optional<pair<PoolIterator, PoolIterator> > ret;

        if(size_ > m_maxSize)
        {
                return ret;
        }

        if(size_ > dec.size())
        {
                dec.resize(size_);
        }
        return make_pair(dec.begin(), dec.end());
}

//A1
template <typename A1>
boost::optional <pair<PoolIterator, PoolIterator> > make_pool(size_t size_, A1 a1)
{

        boost::optional<pair<PoolIterator, PoolIterator> > ret;

        if(size_ > m_maxSize)
        {
                return ret;
        }

        if(size_ > dec.size())
        {
                dec.resize(size_, T(a1));
        }
        return make_pair(dec.begin(), dec.end());
}

//A2
template <typename A1, typename A2>
boost::optional <pair<PoolIterator, PoolIterator> > make_pool(size_t size_, A1 a1, A2 a2)
{
        boost::optional<pair<PoolIterator, PoolIterator> > ret;

        if(size_ > m_maxSize)
        {
                return ret;
        }

        if(size_ > dec.size())
        {
                dec.resize(size_, T(a1, a2));
        }
        return make_pair(dec.begin(), dec.end());
}

//A2
template <typename A1, typename A2, typename A3>
boost::optional <pair<PoolIterator, PoolIterator> > make_pool(size_t size_, A1 a1, A2 a2, A3 a3)
{
        boost::optional<pair<PoolIterator, PoolIterator> > ret;

        if(size_ > m_maxSize)
        {
                return ret;
        }

        if(size_ > dec.size())
        {
                dec.resize(size_, T(a1, a2, a3));
        }
        return make_pair(dec.begin(), dec.end());
}

size_t size()
{
        return static_cast<size_t>(dec.size());
}


};

3 comments:

  1. Great - you've started a blog on generic programming.

    Some questions came to mind on going through your post:
    0) Can you recommend any sources for learning GP from the ground-up?

    1) Can A1 a be re-written as A1 &a (pass-by-value vs. reference) or is this required?

    2) For checking out the code giving header includes and a small usage code snippet would be helpful.

    ReplyDelete
  2. This comment has been removed by the author.

    ReplyDelete
  3. Hi Ravi,

    The code works fine on adding below header and simple test function.

    //Headers
    #include <iostream>
    #include <string>
    #include <deque>
    #include <boost/optional.hpp>
    #include <boost/numeric/interval/limits.hpp>

    //Simple test function
    int main()
    {
    Pool<string> names;
    typedef Pool<string>::PoolIterator PoolIterator;

    boost::optional< pair<PoolIterator,PoolIterator> > range = names.make_pool(10);
    if( range != boost::none ) {
    int j = 0;
    for(PoolIterator i = range->first; i != range->second; ++i, ++j) { //TODO: use for_each instead
    *i = "hello" ;
    cout << j <<") string: " << *i << endl;
    }
    }

    return 0;
    }

    ReplyDelete