mirror of
https://github.com/boostorg/iterator.git
synced 2025-07-30 04:47:20 +02:00
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.
This commit is contained in:
@ -368,40 +368,6 @@ private:
|
|||||||
Iterator m_iter;
|
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.
|
// A binary metafunction class that always returns bool.
|
||||||
template< typename Iterator1, typename Iterator2 >
|
template< typename Iterator1, typename Iterator2 >
|
||||||
using always_bool_t = bool;
|
using always_bool_t = bool;
|
||||||
@ -678,13 +644,9 @@ public:
|
|||||||
using difference_type = typename base_type::difference_type;
|
using difference_type = typename base_type::difference_type;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typename boost::iterators::detail::operator_brackets_result< Derived, Value, reference >::type
|
operator_brackets_proxy< Derived > operator[](difference_type n) const
|
||||||
operator[](difference_type n) const
|
|
||||||
{
|
{
|
||||||
return boost::iterators::detail::make_operator_brackets_result< Derived >(
|
return operator_brackets_proxy< Derived >(this->derived() + n);
|
||||||
this->derived() + n,
|
|
||||||
std::integral_constant< bool, boost::iterators::detail::use_operator_brackets_proxy< Value, Reference >::value >{}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Derived& operator+=(difference_type n)
|
Derived& operator+=(difference_type n)
|
||||||
|
Reference in New Issue
Block a user