[cfe-dev] [patch] [libc++] missing difference_type in advance implementation

Marshall Clow mclow.lists at gmail.com
Sat Apr 19 22:49:06 PDT 2014


On Apr 19, 2014, at 7:52 AM, Gonzalo BG <gonzalobg88 at gmail.com> wrote:

> Thanks for adding the section.
> 
> I've tried hard to come up with a MWE that is simpler than this, but I've failed. This is the simplest thing I've been able to come up with. As you can see, the code works fine for random access iterators, but fails for bidirectional and forward iterators (see the errors below in the comments):

Thanks for the example; I’ll try it out on Monday.

However, I think you’re out of luck, anyway, because of [iterator.requirements.general]/p1; the last sentence:

    For every iterator type X for which equality is defined, there is a corresponding signed integer type called the difference type of the iterator.

And [basic.fundamental]/p2, which says:

    There are five standard signed integer types : “signed char”, “short int”, “int”, “long int”, and “long long int”.
followed by:
	There may also be implementation-defined extended signed integer types. The standard and extended signed integer types are collectively called signed integer types. 

To me this says that you can’t have an standard-conforming iterator with a difference_type that isn’t one of those types.

[ And a brief search of the standards committee mailing list found a discussion on exactly this point back in August of 2012,
and the consensus was that the standard did not allow iterators with such difference types.  ]

Just FYI: The difference_type of the standard containers and allocators is defined the same way.

— Marshall


> 
> #include <algorithm>
> #include <boost/iterator/counting_iterator.hpp>
> // From https://github.com/gnzlbg/arithmetic_type :
> #include <arithmetic_type/arithmetic_type.hpp> 
> 
> int main() {
>   /// Opaque Integer without implicit conversions:
>   struct tag {};
>   using Int = arithmetic::Arithmetic<int, tag>;
> 
>   /// Works as expected
>   boost::counting_iterator<Int, boost::random_access_traversal_tag, Int> a(Int{10});
>   std::advance(a, Int{5});
> 
>   /// Fails: libcxx/iterator:458:13: error: invalid operands to
>   ///   binary expression ('typename
>   ///   iterator_traits<counting_iterator<Arithmetic<int, tag>,
>   ///   bidirectional_traversal_tag, Arithmetic<int, tag> > >::difference_type'
>   ///   (aka 'arithmetic::Arithmetic<int, tag>') and 'int')
>   /// if (__n >= 0)
>   ///     ~~~ ^  ~
>   boost::counting_iterator<Int, boost::bidirectional_traversal_tag, Int> b(Int{10});
>   std::advance(b, Int{5});
> 
>   /// Fails: libcxx/iterator:449:16: error: invalid operands to binary
>   ///   expression ('typename iterator_traits<counting_iterator<Arithmetic<int, tag>,
>   ///   forward_traversal_tag, Arithmetic<int, tag> > >::difference_type' (aka
>   ///   'arithmetic::Arithmetic<int, tag>') and 'int')
>   /// for (; __n > 0; --__n)
>   ///        ~~~ ^ ~
>   boost::counting_iterator<Int, boost::forward_traversal_tag, Int> c(Int{10});
>   std::advance(c, Int{5});
> }
> 
> 
> 
> On Thu, Apr 3, 2014 at 5:20 AM, Marshall Clow <mclow.lists at gmail.com> wrote:
> On Mar 22, 2014, at 8:45 AM, Marshall Clow <mclow.lists at gmail.com> wrote:
> 
> > P.P.S.        I’ll take a look at adding info to the libc++ web page.
> 
> I’ve added a section to http://libcxx.llvm.org about reporting bugs and contributing patches
> 
> — Marshall
> 
> 
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20140419/daf26c34/attachment.html>


More information about the cfe-dev mailing list