'Looping' an std::list

Discussion in 'C++' started by esuvs, May 27, 2006.

  1. esuvs

    esuvs Guest

    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.

    Thanks,

    David
     
    esuvs, May 27, 2006
    #1
    1. Advertising

  2. esuvs

    Daniel T. Guest

    In article <>,
    "esuvs" <> 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_iterator 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_iterator_t : public std::iterator<
                   typename Container::iterator::iterator_category,
                   typename Container::iterator::value_type >
    {
       Container& rep;
       typename Container::iterator loc;
    public:
       explicit circular_iterator_t( Container& container ):
                   rep( container ), loc( container.begin() ) { }
       circular_iterator_t( Container& container,
                   typename Container::iterator it ):
                   rep( container ), loc( it ) { }
       typename Container::value_type& operator*() {
          return *loc;
       }
       circular_iterator_t& operator--() {
          if ( loc == rep.begin() )
             loc = --rep.end();
          else
             --loc;
          return *this;
       }
       circular_iterator_t& operator++() {
          ++loc;
          if ( loc == rep.end() )
             loc = rep.begin();
          return *this;
       }
       friend bool operator==( const circular_iterator_t& lhs,
                   const circular_iterator_t& rhs ) {
          return lhs.rep == rhs.rep && lhs.loc == rhs.loc;
       }
    };

       template < typename Container >
    bool operator!=( const circular_iterator_t<Container>& lhs,
                   const circular_iterator_t<Container>& rhs ) {
       return !( lhs == rhs );

    }

       template < typename Container >
    circular_iterator_t<Container> circular_iterator( Container& container )
    {
       return circular_iterator_t<Container>( container );
    }

       template < typename Container >
    circular_iterator_t<Container> circular_iterator( Container& container,
    typename Container::iterator it ) {
       return circular_iterator_t<Container>( container, it );
    }
     
    Daniel T., May 27, 2006
    #2
    1. Advertising

  3. esuvs

    esuvs Guest

    That's excellent, thanks. I was wondering if I should implement my own
    container but yours is a more elegant solution.

    David
     
    esuvs, May 28, 2006
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Peter Jansson
    Replies:
    5
    Views:
    6,439
    Ivan Vecerina
    Mar 17, 2005
  2. Replies:
    6
    Views:
    698
    Jim Langston
    Oct 30, 2005
  3. Andy
    Replies:
    3
    Views:
    501
    James Kanze
    Jun 8, 2007
  4. Juha Nieminen
    Replies:
    22
    Views:
    1,078
    Kai-Uwe Bux
    Oct 12, 2007
  5. Replies:
    5
    Views:
    307
Loading...

Share This Page