From 7c77e52509e684ba0b61d5c4e3c787da7766e827 Mon Sep 17 00:00:00 2001 From: Andrey Semashev Date: Mon, 9 Jun 2025 03:22:08 +0300 Subject: [PATCH] Always use operator_brackets_proxy in iterator_facade. This avoids returning a copy of the value from operator[], which can be unexpected by users wanting to obtain an address of the value referenced by the iterator. We still want to return a proxy instead of the iterator's reference since the iterator may be holding the value internally, and the iterator gets destroyed after returning from operator[], so the returned reference would be dangling. Closes https://github.com/boostorg/iterator/issues/61. --- include/boost/iterator/iterator_facade.hpp | 42 ++-------------------- 1 file changed, 2 insertions(+), 40 deletions(-) diff --git a/include/boost/iterator/iterator_facade.hpp b/include/boost/iterator/iterator_facade.hpp index 924bcd0..e449009 100644 --- a/include/boost/iterator/iterator_facade.hpp +++ b/include/boost/iterator/iterator_facade.hpp @@ -368,40 +368,6 @@ private: Iterator m_iter; }; -// A metafunction that determines whether operator[] must return a -// proxy, or whether it can simply return a copy of the value_type. -template< typename ValueType, typename Reference > -struct use_operator_brackets_proxy : - public detail::negation< - detail::conjunction< - std::is_trivially_copyable< ValueType >, - iterator_writability_disabled< ValueType, Reference > - > - > -{}; - -template< typename Iterator, typename Value, typename Reference > -struct operator_brackets_result -{ - using type = typename std::conditional< - use_operator_brackets_proxy< Value, Reference >::value, - operator_brackets_proxy< Iterator >, - Value - >::type; -}; - -template< typename Iterator > -inline operator_brackets_proxy< Iterator > make_operator_brackets_result(Iterator const& iter, std::true_type) -{ - return operator_brackets_proxy< Iterator >(iter); -} - -template< typename Iterator > -inline typename Iterator::value_type make_operator_brackets_result(Iterator const& iter, std::false_type) -{ - return *iter; -} - // A binary metafunction class that always returns bool. template< typename Iterator1, typename Iterator2 > using always_bool_t = bool; @@ -678,13 +644,9 @@ public: using difference_type = typename base_type::difference_type; public: - typename boost::iterators::detail::operator_brackets_result< Derived, Value, reference >::type - operator[](difference_type n) const + operator_brackets_proxy< Derived > operator[](difference_type n) const { - return boost::iterators::detail::make_operator_brackets_result< Derived >( - this->derived() + n, - std::integral_constant< bool, boost::iterators::detail::use_operator_brackets_proxy< Value, Reference >::value >{} - ); + return operator_brackets_proxy< Derived >(this->derived() + n); } Derived& operator+=(difference_type n)