$include_dir="/home/hyper-archives/boost-users/include"; include("$include_dir/msg-header.inc") ?>
Subject: Re: [Boost-users] [iterator] [iterator_facade] Why is advance not defined for bidirectional iterators?
From: Sebastian Redl (sebastian.redl_at_[hidden])
Date: 2011-08-22 05:40:05
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_at_[hidden] <mailto:om_boost_at_[hidden]>> 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