|
Boost : |
From: Steven Watanabe (steven_at_[hidden])
Date: 2007-01-24 15:14:23
AMDG
Michael Marcin wrote:
>
>> I started using object_pool recently to solve a problem. I have lots of
>> objects being created and destroyed frequently and stored in a
>> collection. Every so often an event happens which triggers destroying
>> all the objects.
>>
>> Essentially I have:
>>
>> boost::object_pool<Object> m_object_pool;
>> std::vector<Object*> m_objects;
>>
>>
>> Then I have a function
>>
>> void DestroyAllObjects()
>> {
>> std::vector<Object*>::iterator it, iend = m_objects.end();
>> for( it = m_objects.begin(); it != iend; ++it )
>> {
>> m_object_pool.destroy(*it);
>> }
>> m_objects.clear();
>> }
>>
>> It seems like there should be a better way of doing this... i.e.
>>
>> void DestroyAllObjects()
>> {
>> m_object_pool.destroy_all();
>> m_objects.clear();
>> }
>>
>> Also it might be nice to iterate over all the objects in the pool (in
>> which case I wouldn't even need the m_objects vector.
>>
>> Perhaps there is a better way to solve the problem?
>>
>>
>
> I didn't get an answer on users so I thought I'd ping here.
>
> Thanks,
>
> Michael Marcin
Iteration seems like a good solution.
#include <iterator>
class object_pool {
//...
public:
class iterator;
friend class iterator;
class iterator {
friend class object_pool;
public:
typedef T value_type;
typedef T* pointer;
typedef T& reference;
typedef typename object_pool::difference_type difference_type;
typedef std::forward_iterator_tag iterator_category;
iterator& operator++() {
while(true) {
i += increment;
if(i == end) {
iter = iter.next();
if(iter.valid()) {
i = iter.begin();
end = iter.end();
} else {
i = 0;
}
break;
}
if(i != freed_iter) break;
freed_iter = object_pool<T,
UserAllocator>::nextof(freed_iter);
}
return(*this);
}
iterator operator++(int) {
iterator result(*this);
++*this;
return(result);
}
reference operator*() const {
return(*static_cast<T*>(static_cast<void*>(i)));
}
friend bool operator==(const iterator& self, const iterator&
other) {
return(self.i == other.i);
}
friend bool operator!=(const iterator& self, const iterator&
other) {
return(self.i != other.i);
}
private:
size_type increment;
details::PODptr<size_type> iter;
void* freed_iter;
char* i;
char* end;
};
iterator begin() {
iterator result;
if(this->list.valid()) {
result.increment = this->alloc_size();
result.iter = this->list;
result.freed_iter = this->first;
result.i = this->list.begin();
result.end = this->list.end();
} else {
result.i = 0;
}
return(result);
}
iterator end() {
iterator result;
result.i = 0;
return(result);
}
class const_iterator;
friend class const_iterator;
class const_iterator {
friend class object_pool;
public:
typedef T value_type;
typedef const T* pointer;
typedef const T& reference;
typedef typename object_pool::difference_type difference_type;
typedef std::forward_iterator_tag iterator_category;
const_iterator() {}
const_iterator(const iterator& other) :
increment(other.increment), iter(other.iter),
freed_iter(other.freed_iter), i(other.i), end(other.end) {}
const_iterator& operator++() {
while(true) {
i += increment;
if(i == end) {
iter = iter.next();
if(iter.valid()) {
i = iter.begin();
end = iter.end();
} else {
i = 0;
}
break;
}
if(i != freed_iter) break;
freed_iter = object_pool<T,
UserAllocator>::nextof(freed_iter);
}
return(*this);
}
const_iterator operator++(int) {
const_iterator result(*this);
++*this;
return(result);
}
reference operator*() const {
return(*static_cast<const T*>(static_cast<const void*>(i)));
}
friend bool operator==(const const_iterator& self, const
const_iterator& other) {
return(self.i == other.i);
}
friend bool operator!=(const const_iterator& self, const
const_iterator& other) {
return(self.i != other.i);
}
private:
size_type increment;
details::PODptr<size_type> iter;
void* freed_iter;
char* i;
char* end;
};
const_iterator begin() const {
const_iterator result;
if(this->list.valid()) {
result.increment = this->alloc_size();
result.iter = this->list;
result.freed_iter = this->first;
result.i = this->list.begin();
result.end = this->list.end();
} else {
result.i = 0;
}
return(result);
}
const_iterator end() const {
const_iterator result;
result.i = 0;
return(result);
}
};
In Christ,
Steven Watanabe
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk