Index: boost/iterator/iterator_facade.hpp =================================================================== --- boost/iterator/iterator_facade.hpp (revision 62488) +++ boost/iterator/iterator_facade.hpp (working copy) @@ -352,7 +352,7 @@ : m_iter(iter) {} - operator reference() const + operator value_type() const { return *m_iter; } Index: boost/iterator/iterator_archetypes.hpp =================================================================== --- boost/iterator/iterator_archetypes.hpp (revision 62488) +++ boost/iterator/iterator_archetypes.hpp (working copy) @@ -84,20 +84,20 @@ assign_proxy& operator=(T) { return *this; } }; - template + template struct read_proxy { operator T() { return static_object::get(); } }; - template + template struct read_write_proxy - : read_proxy // Use to inherit from assign_proxy, but that doesn't work. -JGS + : read_proxy // Use to inherit from assign_proxy, but that doesn't work. -JGS { read_write_proxy& operator=(T) { return *this; } }; - template + template struct arrow_proxy { T const* operator->() const { return 0; } @@ -108,13 +108,13 @@ template struct readable_operator_brackets { - read_proxy operator[](std::ptrdiff_t n) const { return read_proxy(); } + read_proxy operator[](std::ptrdiff_t n) const { return read_proxy(); } }; template struct writable_operator_brackets { - read_write_proxy operator[](std::ptrdiff_t n) const { return read_write_proxy(); } + read_write_proxy operator[](std::ptrdiff_t n) const { return read_write_proxy(); } }; template @@ -307,16 +307,6 @@ template struct archetype; }; -template -struct iterator_access_archetype - : mpl::aux::msvc_eti_base< - typename iterator_access_archetype_impl< - AccessCategory - >::template archetype - >::type -{ -}; - template <> struct iterator_access_archetype_impl< iterator_archetypes::readable_iterator_t @@ -326,12 +316,11 @@ struct archetype { typedef typename remove_cv::type value_type; - typedef Value reference; - typedef Value* pointer; + typedef detail::read_proxy reference; + typedef detail::arrow_proxy pointer; - value_type operator*() const { return static_object::get(); } - - detail::arrow_proxy operator->() const { return detail::arrow_proxy(); } + reference operator*() const { return reference(); } + pointer operator->() const { return pointer(); } }; }; @@ -347,13 +336,28 @@ BOOST_STATIC_ASSERT(!is_const::value); # endif typedef void value_type; - typedef void reference; + typedef detail::assign_proxy reference; typedef void pointer; - detail::assign_proxy operator*() const { return detail::assign_proxy(); } + reference operator*() const { return reference(); } }; }; +template +struct iterator_access_archetype + : +# ifdef BOOST_MSVC + mpl::aux::msvc_eti_base< +# endif + iterator_access_archetype_impl< + AccessCategory + >::template archetype +# ifdef BOOST_MSVC + >::type +# endif +{ +}; + template <> struct iterator_access_archetype_impl< iterator_archetypes::readable_writable_iterator_t @@ -367,7 +371,7 @@ { typedef detail::read_write_proxy reference; - detail::read_write_proxy operator*() const { return detail::read_write_proxy(); } + reference operator*() const { return reference(); } }; }; @@ -511,5 +515,15 @@ } // namespace boost - +namespace std +{ + template + struct iterator_traits< + boost::iterator_archetype + > + : boost::detail::iterator_archetype_base< + Value,AccessCategory,TraversalCategory + > + {}; +} #endif // BOOST_ITERATOR_ARCHETYPES_HPP Index: boost/iterator/iterator_concepts.hpp =================================================================== --- boost/iterator/iterator_concepts.hpp (revision 62488) +++ boost/iterator/iterator_concepts.hpp (working copy) @@ -8,6 +8,7 @@ #include #include +#include // Use boost::detail::iterator_traits to work around some MSVC/Dinkumware problems. #include @@ -191,7 +192,15 @@ i -= n; i = i - n; n = i - j; + check_brackets(boost::is_readable_iterator()); } + + void check_brackets(boost::mpl::false_) {} + void check_brackets(boost::mpl::true_) + { + typename ReadableIterator::value_type x = i[n]; + boost::ignore_unused_variable_warning(x); + } private: typename BidirectionalTraversal::difference_type n; Index: boost/concept_archetype.hpp =================================================================== --- boost/concept_archetype.hpp (revision 62488) +++ boost/concept_archetype.hpp (working copy) @@ -604,8 +604,8 @@ self operator++(int) { return *this; } self& operator--() { return *this; } self operator--(int) { return *this; } - reference operator[](difference_type) const - { return static_object::get(); } + convertible_to_archetype operator[](difference_type) const + { return detail::dummy_constructor(); } self& operator+=(difference_type) { return *this; } self& operator-=(difference_type) { return *this; } difference_type operator-(const self&) const @@ -644,8 +644,8 @@ self operator++(int) { return *this; } self& operator--() { return *this; } self operator--(int) { return *this; } - reference operator[](difference_type) const - { return static_object::get(); } + convertible_to_archetype operator[](difference_type) const + { return detail::dummy_constructor(); } self& operator+=(difference_type) { return *this; } self& operator-=(difference_type) { return *this; } difference_type operator-(const self&) const Index: boost/concept_check.hpp =================================================================== --- boost/concept_check.hpp (revision 62488) +++ boost/concept_check.hpp (working copy) @@ -573,7 +573,10 @@ i -= n; // require assignment subtraction operator i = i - n; // require subtraction with difference type n = i - j; // require difference operator - (void)i[n]; // require element access operator + + // require element access operator + typename boost::detail::iterator_traits::value_type v = i[n]; + ignore_unused_variable_warning(v); } private: Index: libs/iterator/test/iterator_adaptor_cc.cpp =================================================================== --- libs/iterator/test/iterator_adaptor_cc.cpp (revision 62488) +++ libs/iterator/test/iterator_adaptor_cc.cpp (working copy) @@ -5,10 +5,31 @@ #include #include +#include #include +#include #include #include +template +struct adaptor_passthru + : boost::iterator_adaptor, archetype> +{ +}; + +struct dummy_value_type {}; + +typedef boost::iterator_archetype< + dummy_value_type, boost::iterator_archetypes::readable_iterator_t, + boost::random_access_traversal_tag> +random_traversal_archetype; + +template +void assert_not_same(T const& x, U const& y) +{ + BOOST_MPL_ASSERT_NOT((boost::is_same)); +} + int main() { { @@ -20,6 +41,23 @@ boost::function_requires< boost_concepts::RandomAccessTraversalConcept >(); boost::function_requires< boost::RandomAccessIteratorConcept >(); boost::function_requires< boost_concepts::InteroperableIteratorConcept >(); + + // Make sure we're testing what we mean to, below. Given a proxy + // iterator, its reference type and its operator brackets result + // may be unrelated. + random_traversal_archetype it; + assert_not_same(*it, it[0]); + + // In particular, tests that passing our + // random_traversal_archetype through iterator_adaptor preserves + // the ability to convert i[n] into the value type. + BOOST_CONCEPT_ASSERT(( + boost_concepts::RandomAccessTraversal< + adaptor_passthru< + random_traversal_archetype + > + > + )); } // Many compilers' builtin container iterators don't interoperate well, though Index: libs/iterator/test/concept_tests.cpp =================================================================== --- libs/iterator/test/concept_tests.cpp (revision 62488) +++ libs/iterator/test/concept_tests.cpp (working copy) @@ -16,6 +16,7 @@ : public boost::iterator< new_random_access, int > { int& operator*() const { return *m_x; } + int& operator[](difference_type n) const { return *(m_x+n); } new_iterator& operator++() { return *this; } new_iterator operator++(int) { return *this; } new_iterator& operator--() { return *this; } @@ -36,6 +37,7 @@ : public boost::iterator { int& operator*() const { return *m_x; } + int& operator[](difference_type n) const { return *(m_x+n); } old_iterator& operator++() { return *this; } old_iterator operator++(int) { return *this; } old_iterator& operator--() { return *this; }