[range] SinglePassIterator concept check is too strict

Hello, It seems to me the concept checking performed by Boost.Range for the SinglePassIterator concept is too strict. In boost/range/concepts.hpp, SinglePassIteratorConcept checks for the following usage (line 157 in trunk): BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<Iterator>::reference r1(*i); This requires that the return type of operator* be convertible to the iterator's reference type. However, looking at the specification for single pass iterators [1], I don't see any requirement that the return type of operator* be convertible to the reference type - it just needs to be convertible to the value type. An example of an iterator for which the return type of operator* is not convertible to the iterator's reference type is std::istreambuf_iterator<charT>, whose reference type is charT&, but the return type of its operator* is charT. (Both of these are specified explicitly in section 24.5.3 of the C++03 standard.) As a result, code such as the following fails to compile with GCC or MSVC in C++03 mode: #include <boost/range/concepts.hpp> #include <boost/range/iterator_range.hpp> #include <iterator> #include <istream> int main() { BOOST_CONCEPT_ASSERT (( boost::SinglePassRangeConcept< boost::iterator_range< std::istreambuf_iterator<char> > > )); } (In C++11, things changed - a requirement was added that the return type of operator* be the same as the iterator's reference type, and correspondingly std::istreambuf_iterator<charT>'s reference type was changed to be charT). What can be done about this? Regards, Nate [1] http://www.boost.org/doc/libs/1_48_0/libs/iterator/doc/new-iter-concepts.htm...

on Mon Jan 09 2012, Nathan Ridge <zeratul976-AT-hotmail.com> wrote:
Hello,
It seems to me the concept checking performed by Boost.Range for the SinglePassIterator concept is too strict.
In boost/range/concepts.hpp, SinglePassIteratorConcept checks for the following usage (line 157 in trunk):
BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<Iterator>::reference r1(*i);
This requires that the return type of operator* be convertible to the iterator's reference type.
However, looking at the specification for single pass iterators [1], I don't see any requirement that the return type of operator* be convertible to the reference type - it just needs to be convertible to the value type.
An example of an iterator for which the return type of operator* is not convertible to the iterator's reference type is std::istreambuf_iterator<charT>, whose reference type is charT&, but the return type of its operator* is charT. (Both of these are specified explicitly in section 24.5.3 of the C++03 standard.)
I agree with your analysis.
As a result, code such as the following fails to compile with GCC or MSVC in C++03 mode:
#include <boost/range/concepts.hpp> #include <boost/range/iterator_range.hpp> #include <iterator> #include <istream>
int main() { BOOST_CONCEPT_ASSERT (( boost::SinglePassRangeConcept< boost::iterator_range< std::istreambuf_iterator<char> > > )); }
(In C++11, things changed - a requirement was added that the return type
of operator* be the same as the iterator's reference type, and
correspondingly std::istreambuf_iterator<charT>'s reference type was
changed to be charT).
What can be done about this?
The code could be fixed? Submit a patch I suppose. -- Dave Abrahams BoostPro Computing http://www.boostpro.com
participants (3)
-
Dave Abrahams
-
Nathan Ridge
-
Neil Groves