boost::iterator_adapter not working with STL algorithms

Consider the following "round trip" iterator, which tries to iterate over all the elements in a collection, eventually iterating over the first element again as its final step:

#include <boost/iterator/iterator_adaptor.hpp>

template<typename IteratorBase>
class roundtrip_iterator 
     : public boost::iterator_adaptor< 
          roundtrip_iterator<IteratorBase>, // the derived class overriding iterator behavior
          IteratorBase,                     // the base class providing default behavior
          boost::use_default,               // iterator value type, will be IteratorBase::value_type
          std::forward_iterator_tag,        // iterator category
          boost::use_default                // iterator reference type
       > 
{
private:
  IteratorBase m_itBegin;
  IteratorBase m_itEnd;
  bool m_complete;

public:
  roundtrip_iterator( IteratorBase itBegin, IteratorBase itEnd ) 
    : iterator_adaptor_(itBegin), m_itBegin(itBegin), m_itEnd(itEnd), m_complete(false)
  {}

  void increment()
  { 
    if( m_complete )
    {
      base_reference() = m_itEnd;
      return;
    }

    ++base_reference();

    if(base_reference() == m_itEnd)
    {
      base_reference() = m_itBegin;
      m_complete = true;
    }
  }
};

I have only implemented increment for now.

As it stands, the iterator seems to work well in standard "for" loops, but I can't get it to work with STL algorithms. For example:

int main(int argc, char *argv[])
{
  std::vector<int> v;

  v.push_back(1);
  v.push_back(2);
  v.push_back(3);

  roundtrip_iterator<std::vector<int>::iterator> roundtrip(v.begin(), v.end());

  for( ; roundtrip.base() != v.end(); ++roundtrip)
    std::cout << *roundtrip << std::endl;

  std::cout << std::endl;

  roundtrip_iterator<std::vector<int>::iterator> roundtrip2(v.begin(), v.end());

  std::for_each(
    roundtrip2.base(), v.end(),
    print);

}

Prints:

1
2    
3
1 // First element printed out using standard for loop.

1
2
3 // The for_each algo stops here for some reason.

Does anybody have any ideas as to the difference between the two?

Answers


By calling roundtrip2.base(), you're effectively passing the range [v.begin(), v.end) to std::for_each. You need to be able to construct a one-past-the-end value e such that you can pass [roundtrip2, e) instead.


Need Your Help

find the lexicographically minimal string rotation without suffix tree and in O(n)

string algorithm complexity-theory circular-buffer

how to find the index in an circular array such that the string that is formed starting from that index is first in lexicographic order.

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.