Opened 12 years ago

Closed 12 years ago

#4647 closed Bugs (invalid)

BOOST_CONCEPT_ASSERT((RandomAccessIterator<boost::transform_iterator>)) fails

Reported by: Ilya Murav'jov <muravev@…> Owned by:
Milestone: To Be Determined Component: iterator
Version: Boost 1.44.0 Severity: Problem
Keywords: Cc:

Description

#include <boost/iterator/transform_iterator.hpp>
#include <boost/concept_check.hpp> // RandomAccessIterator
#include <vector>

typedef std::vector<int>::iterator int_iterator;
typedef boost::transform_iterator<int(*)(int), int_iterator> tr_iterator;
BOOST_CONCEPT_ASSERT((boost::RandomAccessIterator<tr_iterator>)); // fails

with an error like this:

libs/boost-lib/boost/concept_check.hpp: In destructor 'boost::Convertible<X, Y>::~Convertible() [with X = boost::detail::iterator_category_with_traversal<std::input_iterator_tag, boost::random_access_traversal_tag>, Y = std::random_access_iterator_tag]': libs/boost-lib/boost/concept/detail/general.hpp:38: instantiated from 'static void boost::concepts::requirement<boost::concepts::failed************ Model::************>::failed() [with Model = boost::Convertible<boost::detail::iterator_category_with_traversal<std::input_iterator_tag, boost::random_access_traversal_tag>, std::random_access_iterator_tag>]' libs/boost-lib/boost/concept_check.hpp:566: instantiated from 'boost::RandomAccessIterator<TT>::~RandomAccessIterator() [with TT = boost::transform_iterator<int (*)(int), gnu_cxx::normal_iterator<int*, std::vector<int, std::allocator<int> > >, boost::use_default, boost::use_default>]' libs/boost-lib/boost/concept/detail/general.hpp:38: instantiated from 'static void boost::concepts::requirement<boost::concepts::failed************ Model::************>::failed() [with Model = boost::RandomAccessIterator<boost::transform_iterator<int (*)(int), __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, boost::use_default, boost::use_default> >]' src/mlib/tests/test_iterator.cpp:123: instantiated from here libs/boost-lib/boost/concept_check.hpp:207: error: conversion from 'boost::detail::iterator_category_with_traversal<std::input_iterator_tag, boost::random_access_traversal_tag>' to non-scalar type 'std::random_access_iterator_tag' requested

This is because iterator_adaptor turns std::random_access_iterator_tag into boost::random_access_traversal_tag, then iterator_facade turns it into iterator_category_with_traversal<std::input_iterator_tag, boost::random_access_traversal_tag>. The check fails if

typedef boost::transform_iterator<int(*)(int), int_iterator> tr_iterator;

but not if

typedef boost::transform_iterator<int&(*)(int), int_iterator> tr_iterator;

Why it matters for me: I try to use "any_iterator", which has two versions, http://thbecker.net/free_software_utilities/type_erasure_for_cpp_iterators/start_page.html (Thomas Becker's) and http://stlab.adobe.com/classadobe_1_1any__iterator.html (Adobe's). The first one do many efforts to avoid this bug but still check iterators for compatibility (see traversal_types_erasure_compatible<>), the second just fails with an error like this.

Change History (1)

in reply to:  description comment:1 by Steven Watanabe, 12 years ago

Component: Noneiterator
Resolution: invalid
Status: newclosed

Replying to Ilya Murav'jov <muravev@…>:

This is because iterator_adaptor turns std::random_access_iterator_tag into boost::random_access_traversal_tag, then iterator_facade turns it into iterator_category_with_traversal<std::input_iterator_tag, boost::random_access_traversal_tag>. The check fails if 

typedef boost::transform_iterator<int(*)(int), int_iterator> tr_iterator;

but not if 

typedef boost::transform_iterator<int&(*)(int), int_iterator> tr_iterator;

This is the correct behavior because of the way the standard defines RandomAccessIterators.

Note: See TracTickets for help on using tickets.