diff --git a/libcxx/include/__iterator/reverse_iterator.h b/libcxx/include/__iterator/reverse_iterator.h --- a/libcxx/include/__iterator/reverse_iterator.h +++ b/libcxx/include/__iterator/reverse_iterator.h @@ -86,7 +86,7 @@ template ::value && is_convertible<_Up const&, _Iter>::value && - is_assignable<_Up const&, _Iter>::value + is_assignable<_Iter, _Up const&>::value > > _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reverse_iterator& operator=(const reverse_iterator<_Up>& __u) { @@ -111,7 +111,7 @@ template ::value && is_convertible<_Up const&, _Iter>::value && - is_assignable<_Up const&, _Iter>::value + is_assignable<_Iter, _Up const&>::value > > _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reverse_iterator& operator=(const reverse_iterator<_Up>& __u) { diff --git a/libcxx/test/std/iterators/predef.iterators/move.iterators/move.iter.ops/move.iter.op=/move_iterator.pass.cpp b/libcxx/test/std/iterators/predef.iterators/move.iterators/move.iter.ops/move.iter.op=/move_iterator.pass.cpp --- a/libcxx/test/std/iterators/predef.iterators/move.iterators/move.iter.ops/move.iter.op=/move_iterator.pass.cpp +++ b/libcxx/test/std/iterators/predef.iterators/move.iterators/move.iter.ops/move.iter.op=/move_iterator.pass.cpp @@ -37,6 +37,39 @@ struct Base {}; struct Derived : Base {}; +struct ToIter { + typedef std::forward_iterator_tag iterator_category; + typedef char *pointer; + typedef char &reference; + typedef char value_type; + typedef value_type difference_type; + + explicit TEST_CONSTEXPR_CXX17 ToIter() : m_value(0) {} + TEST_CONSTEXPR_CXX17 ToIter(const ToIter &src) : m_value(src.m_value) {} + // Intentionally not defined, must not be called. + ToIter(char *src); + TEST_CONSTEXPR_CXX17 ToIter &operator=(char *src) { + m_value = src; + return *this; + } + TEST_CONSTEXPR_CXX17 ToIter &operator=(const ToIter &src) { + m_value = src.m_value; + return *this; + } + char *m_value; +}; + +TEST_CONSTEXPR_CXX17 bool test_conv_assign() +{ + char c = '\0'; + char *fi = &c; + const std::move_iterator move_fi(fi); + std::move_iterator move_ti; + move_ti = move_fi; + assert(move_ti.base().m_value == fi); + return true; +} + int main(int, char**) { Derived d; @@ -46,6 +79,7 @@ test >(bidirectional_iterator(&d)); test >(random_access_iterator(&d)); test(&d); + test_conv_assign(); #if TEST_STD_VER > 14 { using BaseIter = std::move_iterator; @@ -54,6 +88,7 @@ constexpr DerivedIter it1 = std::make_move_iterator(p); constexpr BaseIter it2 = (BaseIter{nullptr} = it1); static_assert(it2.base() == p, ""); + static_assert(test_conv_assign(), ""); } #endif diff --git a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cons/assign.pass.cpp b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cons/assign.pass.cpp --- a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cons/assign.pass.cpp +++ b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cons/assign.pass.cpp @@ -31,11 +31,41 @@ struct Base { }; struct Derived : Base { }; +struct ToIter { + typedef std::bidirectional_iterator_tag iterator_category; + typedef char *pointer; + typedef char &reference; + typedef char value_type; + typedef value_type difference_type; + + explicit TEST_CONSTEXPR_CXX17 ToIter() : m_value(0) {} + TEST_CONSTEXPR_CXX17 ToIter(const ToIter &src) : m_value(src.m_value) {} + // Intentionally not defined, must not be called. + ToIter(char *src); + TEST_CONSTEXPR_CXX17 ToIter &operator=(char *src) { + m_value = src; + return *this; + } + TEST_CONSTEXPR_CXX17 ToIter &operator=(const ToIter &src) { + m_value = src.m_value; + return *this; + } + char *m_value; +}; + TEST_CONSTEXPR_CXX17 bool tests() { Derived d; test >(bidirectional_iterator(&d)); test >(random_access_iterator(&d)); test(&d); + + char c = '\0'; + char *fi = &c; + const std::reverse_iterator rev_fi(fi); + std::reverse_iterator rev_ti; + rev_ti = rev_fi; + assert(rev_ti.base().m_value == fi); + return true; }