On 22.08.2011 10:51, Ovanes Markarian wrote:
Hi!
Is someone responsible for iterator_facade? Would be great if I'd be able to clarify this with one of the authors...

Many thanks,
Ovanes

On Wed, Aug 17, 2011 at 2:58 PM, Ovanes Markarian <om_boost@keywallet.com> wrote:
Hello *!

I defined a custom bidi-iterator and assumed it was going to support std::advance(iterator, Difference n), where n can be negative for random access and bidirectional iterators.

The definition of my iterator's facade base looks like:
struct my_iter 
  : boost::iterator_facade
      < my_iter
      , const byte
      , boost::bidirectional_traversal_tag 
      , const byte
      >
{

// some impl stuff follows...
};


My tests show that calling:
advance(instance_of_my_iter, N) works fine (increment implementation is called)

advance(instance_of_my_iter, -N) does not work, because increment (instead of decrement) is called as well

The problem is not with Boost. std::advance is a standard library algorithm, and its behavior is up to the standard library implementation.
What happens here is that while your iterator has bidirectional traversal, std::advance queries the standard iterator tag, which is (because your reference is not a proper reference type) input_iterator_tag. Thus, std::advance dispatches to the input iterator version, which does not support negative offsets.
This mismatch is why the split of traversal and access categories was introduced in Boost.Iterator, but it didn't make it into the new standard, and it was never in the old to begin with, so std::advance is not aware of it. What you basically need is a traversal-aware std::advance.

For the advance implementation is stated there that it is only gets called for Random Access Iterators.

The advance operation of iterator_facade has nothing to do with std::advance.

Sebastian