Opened 14 years ago

Closed 14 years ago

#2669 closed Bugs (invalid)

Boost 1.37 breaks spirit iterator differencing

Reported by: S Roderick <kiwi.net@…> Owned by: Joel de Guzman
Milestone: Boost 1.38.0 Component: spirit
Version: Boost 1.37.0 Severity: Problem
Keywords: Cc:

Description

Attached minimal test file compiles fine under Boost v1.35, but fails to compile with Boost v1.37 (from Macports) and Darwin gcc 4.0.1. The problem has also been noted on other OS's with our software.

The commented out iterator_difference attempt fails in the same manner with v1.37.

$ gcc -o test-iter.o -c /z/o/test-iter.cpp -I/opt/local/include

/opt/local/include/boost/iterator/iterator_adaptor.hpp: In function ‘void boost::detail::iterator_adaptor_assert_traversal() [with Tr1 = boost::forward_traversal_tag, Tr2 = boost::random_access_traversal_tag]’:
/opt/local/include/boost/iterator/iterator_adaptor.hpp:353:   instantiated from ‘typename boost::detail::iterator_adaptor_base<Derived, Base, Value, Traversal, Reference, Difference>::type::difference_type boost::iterator_adaptor<Derived, Base, Value, Traversal, Reference, Difference>::distance_to(const boost::iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D>&) const [with OtherDerived = boost::spirit::position_iterator<__gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::spirit::file_position_base<std::string>, boost::spirit::nil_t>, OtherIterator = __gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, V = const char, C = boost::forward_traversal_tag, R = boost::use_default, D = boost::use_default, Derived = boost::spirit::position_iterator<__gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::spirit::file_position_base<std::string>, boost::spirit::nil_t>, Base = __gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, Value = const char, Traversal = boost::forward_traversal_tag, Reference = boost::use_default, Difference = boost::use_default]’
/opt/local/include/boost/iterator/iterator_facade.hpp:553:   instantiated from ‘static typename Facade1::difference_type boost::iterator_core_access::distance_from(const Facade1&, const Facade2&, mpl_::true_) [with Facade1 = boost::spirit::position_iterator<__gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::spirit::file_position_base<std::string>, boost::spirit::nil_t>, Facade2 = boost::spirit::position_iterator<__gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::spirit::file_position_base<std::string>, boost::spirit::nil_t>]’
/opt/local/include/boost/iterator/iterator_facade.hpp:846:   instantiated from ‘typename boost::detail::enable_if_interoperable<Derived1, Derived2, typename boost::mpl::apply2<boost::detail::choose_difference_type, Derived1, Derived2>::type>::type boost::operator-(const boost::iterator_facade<Derived1, V1, TC1, Reference1, Difference1>&, const boost::iterator_facade<Derived2, V2, TC2, Reference2, Difference2>&) [with Derived1 = boost::spirit::position_iterator<__gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::spirit::file_position_base<std::string>, boost::spirit::nil_t>, V1 = const char, TC1 = boost::forward_traversal_tag, Reference1 = const char&, Difference1 = ptrdiff_t, Derived2 = boost::spirit::position_iterator<__gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::spirit::file_position_base<std::string>, boost::spirit::nil_t>, V2 = const char, TC2 = boost::forward_traversal_tag, Reference2 = const char&, Difference2 = ptrdiff_t]’
/z/o/test-iter.cpp:10:   instantiated from here
/opt/local/include/boost/iterator/iterator_adaptor.hpp:230: error: invalid application of ‘sizeof’ to incomplete type ‘boost::STATIC_ASSERTION_FAILURE<false>’ 

Attachments (2)

test-iter.cpp (271 bytes ) - added by S Roderick <kiwi.net@…> 14 years ago.
iter-difference.cpp (269 bytes ) - added by Daniel James 14 years ago.
Demonstration of problem with boost 1.35

Download all attachments as: .zip

Change History (4)

by S Roderick <kiwi.net@…>, 14 years ago

Attachment: test-iter.cpp added

by Daniel James, 14 years ago

Attachment: iter-difference.cpp added

Demonstration of problem with boost 1.35

comment:1 by Daniel James, 14 years ago

position_iterator was always meant to be a forward iterator and only had a difference operator by mistake, which didn't work in many cases (I've just attached an example which gives an incorrect result with boost 1.35, operator- also gives incorrect results if the string contains windows newlines). There are two possible fixes: the safe, but slow way, is to use std::difference, or if you're sure that both iterators contain a valid iterator (they haven't been default constructed, and have been constructed with an iterator from the same container) then you can access the underlying iterator using the base method - end.base() - begin.base().

comment:2 by S Roderick <kiwi.net@…>, 14 years ago

Resolution: invalid
Status: newclosed

We can use the base() method for our purposes. Thanks, consider this resolved.

Note: See TracTickets for help on using tickets.