In article <11************ **********@j55g 2000cwa.googleg roups.com>,
"esuvs" <da***@david-williams.info> wrote:
Hi, I would like to change the behavior of the std::list so that if I
set an iterator to the last element and increment it I would like it to
point to the first element, and vice vesa. That is, i would like to use
it as a circular buffer.
Is this possble? Given that the linked list is probably just a set of
nodes and 'next' pointers it doesn't seem unreasonable (just set the
last pointer to point at the start) but I suspect the std::list is to
safe/robust to allow me to abuse it in this way...
Be great if someone could prove me wrong :-D Otherwise is there an
STL/Boost container giving this behaviour? I think i could do it with
boost::graph but seems a bit of a heavyweight solution.
I posted the below back in March... (Pieter Pareit seems to have posted
something very much like it back in Jan of 2002.)
You can use the circular_iterat or on any of the standard containers. The
code below does need some fleshing out (for eg: post-increment and
decrement, operator->() and const dereference operators) but the below
is enough for most uses.
* *template < typename Container >
class circular_iterat or_t : public std::iterator<
* * * * * * * *typename Container::iter ator::iterator_ category,
* * * * * * * *typename Container::iter ator::value_typ e >
{
* *Container& rep;
* *typename Container::iter ator loc;
public:
* *explicit circular_iterat or_t( Container& container ):
* * * * * * * *rep( container ), loc( container.begin () ) { }
* *circular_itera tor_t( Container& container,
* * * * * * * *typename Container::iter ator it ):
* * * * * * * *rep( container ), loc( it ) { }
* *typename Container::valu e_type& operator*() {
* * * return *loc;
* *}
* *circular_itera tor_t& operator--() {
* * * if ( loc == rep.begin() )
* * * * *loc = --rep.end();
* * * else
* * * * *--loc;
* * * return *this;
* *}
* *circular_itera tor_t& operator++() {
* * * ++loc;
* * * if ( loc == rep.end() )
* * * * *loc = rep.begin();
* * * return *this;
* *}
* *friend bool operator==( const circular_iterat or_t& lhs,
* * * * * * * *const circular_iterat or_t& rhs ) {
* * * return lhs.rep == rhs.rep && lhs.loc == rhs.loc;
* *}
};
* *template < typename Container >
bool operator!=( const circular_iterat or_t<Container> & lhs,
* * * * * * * *const circular_iterat or_t<Container> & rhs ) {
* *return !( lhs == rhs );
}
* *template < typename Container >
circular_iterat or_t<Container> circular_iterat or( Container& container )
{
* *return circular_iterat or_t<Container> ( container );
}
* *template < typename Container >
circular_iterat or_t<Container> circular_iterat or( Container& container,
typename Container::iter ator it ) {
* *return circular_iterat or_t<Container> ( container, it );
}