diff --git a/include/boost/iterator/iterator_facade.hpp b/include/boost/iterator/iterator_facade.hpp index 0604b3c..0c6b356 100644 --- a/include/boost/iterator/iterator_facade.hpp +++ b/include/boost/iterator/iterator_facade.hpp @@ -365,12 +365,25 @@ public: typename std::remove_cv< typename std::remove_reference< T >::type >::type >::value, operator_brackets_proxy& - >::type operator= (T&& val) noexcept(std::is_nothrow_assignable< reference, T&& >::value) + >::type operator= (T&& val) noexcept(noexcept(*std::declval< Iterator const& >() = std::declval< T&& >())) { *m_iter = static_cast< T&& >(val); return *this; } + // Provides it[n]->foo(). Leverages chaining of operator->. + reference operator->() const noexcept(noexcept(*std::declval< Iterator const& >())) + { + return *m_iter; + } + + // Provides (*it[n]).foo() + template< typename Ref = reference, typename Result = decltype(*std::declval< Ref >()) > + Result operator*() const noexcept(noexcept(**std::declval< Iterator const& >())) + { + return **m_iter; + } + private: Iterator m_iter; }; diff --git a/test/iterator_adaptor_test.cpp b/test/iterator_adaptor_test.cpp index d237ac4..dc67e2a 100644 --- a/test/iterator_adaptor_test.cpp +++ b/test/iterator_adaptor_test.cpp @@ -189,6 +189,16 @@ main() boost::const_nonconst_iterator_test(i, ++j); } + // Test that operator_brackets_proxy forwards operator-> and operator* + { + dummyT* ptr_array[] = { array + 0, array + 1, array + 2, + array + 3, array + 4, array + 5 }; + + ptr_iterator i(ptr_array); + BOOST_TEST_EQ(i[2]->foo(), 2); + BOOST_TEST_EQ((*i[2]).foo(), 2); + } + int test; // Test the iterator_traits {