|
Boost : |
From: Howard Hinnant (hinnant_at_[hidden])
Date: 2002-10-01 13:14:26
On Tuesday, October 1, 2002, at 01:11 PM, Thomas Wenisch wrote:
> I am also interested in a cyclic container or cyclic buffer. In
> particular, I have use for a container with deque-like interface which
> has
> fixed capacity, but for which insertion at the head or the tail does
> not invalidate any iterators into the container (ie a circular
> buffer). Is this what you are describing?
Fwiw, Metrowerks has a container similar to this. The capacity is not
fixed, but grows like vector (and has a reserve and capacity like
vector). But otherwise it looks like a deque, except for invalidating
pointers during a realloc.
You could turn it in to a fixed capacity circular buffer with an
allocator that would only allocate once.
-Howard
#include <cstddef>
#include <new>
#include <limits>
#include <memory>
template <class T>
class alloc_once
{
public:
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef T value_type;
template <class U> struct rebind { typedef alloc_once<U> other; };
explicit alloc_once() throw() : allocated_(false) {}
alloc_once(const alloc_once& a) throw() : allocated_(a.allocated_) {}
template <class U>
alloc_once(const alloc_once<U>& a) throw() :
allocated_(a.allocated_) {}
~alloc_once() throw() {}
pointer address(reference x) const {return &x;}
const_pointer address(const_reference x) const {return &x;}
pointer allocate(size_type n, const void* = 0);
void deallocate(pointer p, size_type)
{::operator delete((void*)p);}
size_type max_size() const throw()
{return std::numeric_limits<size_type>::max() / sizeof(T);}
void construct(pointer p, const T& val) {::new((void*)p) T(val);}
void destroy(pointer p) {p->~T();}
friend bool operator == (const alloc_once&, const alloc_once&)
{return true;}
friend bool operator != (const alloc_once&, const alloc_once&)
{return false;}
private:
bool allocated_;
};
template <class T>
typename alloc_once<T>::pointer
alloc_once<T>::allocate(size_type n, const void*)
{
if (allocated_)
throw std::bad_alloc();
allocated_ = true;
return static_cast<pointer>(::operator new(n * sizeof(T)));
}
#include <cdeque>
#include <iostream>
int main()
{
try
{
typedef Metrowerks::cdeque<int, alloc_once<int> > CircularBuffer;
CircularBuffer c;
c.reserve(10);
for (int i = 0; i < 10; ++i)
if (i % 2)
c.push_front(i);
else
c.push_back(i);
} catch (std::exception& e)
{
std::cout << e.what() << '\n';
return 1;
}
std::cout << "done\n";
}
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk