From 965b1119cb1d8533cdc48101378c661871a5d290 Mon Sep 17 00:00:00 2001 From: Zach Laine Date: Sun, 26 Mar 2023 14:14:00 -0500 Subject: [PATCH] Disable iterator_interface::operator-> when pointer is void or reference is not a language reference. --- .../stl_interfaces/iterator_interface.hpp | 40 ++++++++++++------- test/compile_sfinae_path_mutable_iterator.cpp | 4 +- test/input.cpp | 8 ++-- 3 files changed, 31 insertions(+), 21 deletions(-) diff --git a/include/boost/stl_interfaces/iterator_interface.hpp b/include/boost/stl_interfaces/iterator_interface.hpp index 304de2b..037b801 100644 --- a/include/boost/stl_interfaces/iterator_interface.hpp +++ b/include/boost/stl_interfaces/iterator_interface.hpp @@ -70,19 +70,25 @@ namespace boost { namespace stl_interfaces { }; namespace detail { - template + template auto make_pointer( T && value, - std::enable_if_t::value, int> = 0) - -> decltype(std::addressof(value)) + std::enable_if_t< + std::is_pointer::value && + std::is_reference::value, + int> = 0) -> decltype(std::addressof(value)) { return std::addressof(value); } - template + template auto make_pointer( T && value, - std::enable_if_t::value, int> = 0) + std::enable_if_t< + !std::is_pointer::value && + !std::is_same::value && + std::is_reference::value, + int> = 0) { return Pointer(std::forward(value)); } @@ -368,20 +374,22 @@ namespace boost { namespace stl_interfaces { BOOST_STL_INTERFACES_NAMESPACE_V1 { } template - constexpr auto operator-> () noexcept( - noexcept(detail::make_pointer(*std::declval()))) + constexpr auto operator->() noexcept(noexcept( + detail::make_pointer(*std::declval()))) -> decltype( - detail::make_pointer(*std::declval())) + detail::make_pointer(*std::declval())) { - return detail::make_pointer(*derived()); + return detail::make_pointer(*derived()); } template - constexpr auto operator-> () const noexcept( - noexcept(detail::make_pointer(*std::declval()))) + constexpr auto operator->() const noexcept(noexcept( + detail::make_pointer( + *std::declval()))) -> decltype( - detail::make_pointer(*std::declval())) + detail::make_pointer( + *std::declval())) { - return detail::make_pointer(*derived()); + return detail::make_pointer(*derived()); } template @@ -757,11 +765,13 @@ namespace boost { namespace stl_interfaces { BOOST_STL_INTERFACES_NAMESPACE_V2 { } constexpr auto operator->() - requires requires (D d) { *d; } { + requires (!std::same_as && std::is_reference_v && + requires (D d) { *d; }) { return detail::make_pointer(*derived()); } constexpr auto operator->() const - requires requires (D const d) { *d; } { + requires (!std::same_as && std::is_reference_v && + requires (D const d) { *d; }) { return detail::make_pointer(*derived()); } diff --git a/test/compile_sfinae_path_mutable_iterator.cpp b/test/compile_sfinae_path_mutable_iterator.cpp index bdec0d7..c499370 100644 --- a/test/compile_sfinae_path_mutable_iterator.cpp +++ b/test/compile_sfinae_path_mutable_iterator.cpp @@ -68,7 +68,7 @@ private: void compile_sfinae_path_mutable_iterator() { auto it = iterator{}; - if (it->first == 42) { - it->second = 13; + if ((*it).first == 42) { + (*it).second = 13; } } diff --git a/test/input.cpp b/test/input.cpp index 8000bc3..27c90b0 100644 --- a/test/input.cpp +++ b/test/input.cpp @@ -315,7 +315,7 @@ int main() pair_input first(pairs.data()); pair_input last(pairs.data() + pairs.size()); for (auto out = firsts_copy.begin(); first != last; ++first) { - *out++ = first->first; + *out++ = (*first).first; } BOOST_TEST(firsts_copy == ints); } @@ -325,7 +325,7 @@ int main() proxy_input_iter> first(pairs.data()); proxy_input_iter> last(pairs.data() + pairs.size()); for (auto out = firsts_copy.begin(); first != last; ++first) { - *out++ = first->first; + *out++ = (*first).first; } BOOST_TEST(firsts_copy == ints); } @@ -354,7 +354,7 @@ int main() const_pair_input first(pairs.data()); const_pair_input last(pairs.data() + pairs.size()); for (auto out = firsts_copy.begin(); first != last; ++first) { - *out++ = first->first; + *out++ = (*first).first; } BOOST_TEST(firsts_copy == ints); } @@ -365,7 +365,7 @@ int main() proxy_input_iter const> last( pairs.data() + pairs.size()); for (auto out = firsts_copy.begin(); first != last; ++first) { - *out++ = first->first; + *out++ = (*first).first; } BOOST_TEST(firsts_copy == ints); }