Don't do this:
using namespace std;
In anything other than a toy this will cause problems.
I don't like this:
#define itv(TYPE) std::vector<TYPE>::iterator
With C++11 this type if thing has been resolved by auto
.
I would also define the iterator in terms of the object pool:
template <class TYPE>
struct object_pool
{
typedef std::vector<TYPE>::iterator iterator;
I would hide the fact that internally the object_pool
uses a vector and queue. I would then add the obligatory functions to extract information:
template <class TYPE>
class object_pool
{
std::vector<TYPE> pool;
std::queue<size_t> avail;
public:
typedef std::vector<TYPE>::iterator iterator;
typedef std::vector<TYPE>::const_iterator const_iterator;
iterator begin() { return pool.begin();}
iterator end() { return pool.end();}
const_iterator begin() const { return pool.begin();}
const_iterator end() const { return pool.end();}
To access elements I would also provide const version
TYPE& operator[](std::size_t index) { return pool[index];}
TYPE& at(std::size_t index) { return pool.at(index);}
TYPE const& operator[](std::size_t index) const { return pool[index];}
TYPE const& at(std::size_t index) const { return pool.at(index);}
The methods that can be const should be const:
size_t size() const { return pool.size(); }
// ^^^^^^^
The implementation details are fine.
void add(size_t & pos)
{
if(avail.empty()) // no reusable object
{ pool.push_back(TYPE()); pos = pool.size()-1; }
else
{ pos = avail.back(); avail.pop(); }
}
void rem(size_t & a) { avail.push(a); }
I would change the add() so it returned pos:
size_t add();
Also the vector starts off very small and re-sizes to get bigger.
To make sure that it does not re-size too often I would add a constructor that gives the vector a reasonable size to start with:
object_pool::object_pool()
{
pool.reserve(1000);
}
But I think you are using the wrong technique.
I would use a pool allocator and plug it into the vector.
You can read more about it here: http://stackoverflow.com/q/2984434/14065