Opened 14 years ago
Closed 14 years ago
#2669 closed Bugs (invalid)
Boost 1.37 breaks spirit iterator differencing
| Reported by: | 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)
Change History (4)
by , 14 years ago
| Attachment: | test-iter.cpp added |
|---|
by , 14 years ago
| Attachment: | iter-difference.cpp added |
|---|
comment:1 by , 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 , 14 years ago
| Resolution: | → invalid |
|---|---|
| Status: | new → closed |
We can use the base() method for our purposes. Thanks, consider this resolved.

Demonstration of problem with boost 1.35