[libcxx-commits] [PATCH] D113417: [libcxx] Fix enable_if condition of std::reverse_iterator::operator=
Mikhail Maltsev via Phabricator via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Nov 8 09:55:24 PST 2021
miyuki created this revision.
miyuki added reviewers: Quuxplusone, ldionne.
miyuki requested review of this revision.
Herald added a project: libc++.
Herald added a subscriber: libcxx-commits.
Herald added a reviewer: libc++.
The template std::is_assignable<T, U> checks that T is assignable from
U. Hence, the order of operands in the instantiation of
std::is_assignable in the std::reverse_iterator::operator= condition
should be reversed.
This issue remained unnoticed because std::reverse_iterator has an
implicit conversion constructor. This patch adds a test to check that
the assignment operator is used directly, without any implicit
conversions.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D113417
Files:
libcxx/include/__iterator/reverse_iterator.h
libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cons/assign.pass.cpp
Index: libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cons/assign.pass.cpp
===================================================================
--- libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cons/assign.pass.cpp
+++ libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cons/assign.pass.cpp
@@ -39,8 +39,36 @@
return true;
}
+struct from_iter : bidirectional_iterator<char *> {
+ from_iter(char *p) : bidirectional_iterator(p) {}
+};
+
+typedef bidirectional_iterator<const char *> const_bidir_iter;
+
+struct to_iter : const_bidir_iter {
+ to_iter() {}
+ to_iter(const from_iter &fi) : const_bidir_iter(fi) {
+ // Ensure that the conversion constructor is not called
+ assert(false);
+ }
+ to_iter& operator=(const from_iter &fi) {
+ static_cast<const_bidir_iter &>(*this) = fi;
+ return *this;
+ }
+};
+
+void test_assign_convertible() {
+ char c;
+ from_iter fi(&c);
+ to_iter ti;
+ const std::reverse_iterator<from_iter> rev_fi(fi);
+ std::reverse_iterator<to_iter> rev_ti;
+ rev_ti = rev_fi;
+}
+
int main(int, char**) {
tests();
+ test_assign_convertible();
#if TEST_STD_VER > 14
static_assert(tests(), "");
#endif
Index: libcxx/include/__iterator/reverse_iterator.h
===================================================================
--- libcxx/include/__iterator/reverse_iterator.h
+++ libcxx/include/__iterator/reverse_iterator.h
@@ -86,7 +86,7 @@
template <class _Up, class = __enable_if_t<
!is_same<_Up, _Iter>::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 <class _Up, class = __enable_if_t<
!is_same<_Up, _Iter>::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) {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D113417.385542.patch
Type: text/x-patch
Size: 2300 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20211108/d6b52c60/attachment.bin>
More information about the libcxx-commits
mailing list