Boost logo

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