[libcxx-commits] [libcxx] fbcd523 - [libc++] [ranges] Fix `decltype(auto) ranges::iter_move`.
Arthur O'Dwyer via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Mar 7 10:31:25 PST 2022
Author: Arthur O'Dwyer
Date: 2022-03-07T13:31:16-05:00
New Revision: fbcd5236af20e7d1373f5d88e0a9b49e34614fdc
URL: https://github.com/llvm/llvm-project/commit/fbcd5236af20e7d1373f5d88e0a9b49e34614fdc
DIFF: https://github.com/llvm/llvm-project/commit/fbcd5236af20e7d1373f5d88e0a9b49e34614fdc.diff
LOG: [libc++] [ranges] Fix `decltype(auto) ranges::iter_move`.
See
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92894#c3
https://reviews.llvm.org/D119589#inline-1151299
Differential Revision: https://reviews.llvm.org/D120417
Added:
libcxx/test/std/iterators/iterator.requirements/iterator.cust/iterator.cust.move/iter_rvalue_reference_t.compile.pass.cpp
Modified:
libcxx/include/__iterator/iter_move.h
Removed:
libcxx/test/std/iterators/iterator.requirements/iterator.cust/iterator.cust.move/iter_rvalue_reference_t.pass.cpp
################################################################################
diff --git a/libcxx/include/__iterator/iter_move.h b/libcxx/include/__iterator/iter_move.h
index 97d54c4a825cf..66d69af7fd841 100644
--- a/libcxx/include/__iterator/iter_move.h
+++ b/libcxx/include/__iterator/iter_move.h
@@ -39,6 +39,23 @@ concept __unqualified_iter_move =
iter_move(std::forward<_Tp>(__t));
};
+template<class _Tp>
+concept __move_deref =
+ !__unqualified_iter_move<_Tp> &&
+ requires (_Tp&& __t) {
+ *__t;
+ requires is_lvalue_reference_v<decltype(*__t)>;
+ };
+
+template<class _Tp>
+concept __just_deref =
+ !__unqualified_iter_move<_Tp> &&
+ !__move_deref<_Tp> &&
+ requires (_Tp&& __t) {
+ *__t;
+ requires (!is_lvalue_reference_v<decltype(*__t)>);
+ };
+
// [iterator.cust.move]
struct __fn {
@@ -51,17 +68,18 @@ struct __fn {
}
template<class _Ip>
- requires (!__unqualified_iter_move<_Ip>) &&
- requires { *declval<_Ip>(); }
- [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator()(_Ip&& __i) const
+ requires __move_deref<_Ip>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Ip&& __i) const
+ noexcept(noexcept(std::move(*std::forward<_Ip>(__i))))
+ -> decltype( std::move(*std::forward<_Ip>(__i)))
+ { return std::move(*std::forward<_Ip>(__i)); }
+
+ template<class _Ip>
+ requires __just_deref<_Ip>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Ip&& __i) const
noexcept(noexcept(*std::forward<_Ip>(__i)))
- {
- if constexpr (is_lvalue_reference_v<decltype(*declval<_Ip>())>) {
- return std::move(*std::forward<_Ip>(__i));
- } else {
- return *std::forward<_Ip>(__i);
- }
- }
+ -> decltype( *std::forward<_Ip>(__i))
+ { return *std::forward<_Ip>(__i); }
};
} // namespace __iter_move
diff --git a/libcxx/test/std/iterators/iterator.requirements/iterator.cust/iterator.cust.move/iter_rvalue_reference_t.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/iterator.cust/iterator.cust.move/iter_rvalue_reference_t.compile.pass.cpp
similarity index 57%
rename from libcxx/test/std/iterators/iterator.requirements/iterator.cust/iterator.cust.move/iter_rvalue_reference_t.pass.cpp
rename to libcxx/test/std/iterators/iterator.requirements/iterator.cust/iterator.cust.move/iter_rvalue_reference_t.compile.pass.cpp
index 6c19ec3ae33af..441b3caca02db 100644
--- a/libcxx/test/std/iterators/iterator.requirements/iterator.cust/iterator.cust.move/iter_rvalue_reference_t.pass.cpp
+++ b/libcxx/test/std/iterators/iterator.requirements/iterator.cust/iterator.cust.move/iter_rvalue_reference_t.compile.pass.cpp
@@ -14,12 +14,12 @@
#include <iterator>
-#include <concepts>
-#include <list>
-#include <vector>
+static_assert(std::same_as<std::iter_rvalue_reference_t<int*>, int&&>);
+static_assert(std::same_as<std::iter_rvalue_reference_t<const int*>, const int&&>);
-static_assert(std::same_as<std::iter_rvalue_reference_t<std::vector<int>::iterator&>, int&&>);
-static_assert(std::same_as<std::iter_rvalue_reference_t<std::vector<int>::const_iterator>, int const&&>);
-static_assert(std::same_as<std::iter_rvalue_reference_t<std::list<int const>::iterator>, int const&&>);
-
-int main(int, char**) { return 0; }
+void test_undefined_internal() {
+ struct A {
+ int& operator*() const;
+ };
+ static_assert(std::same_as<std::iter_rvalue_reference_t<A>, int&&>);
+}
More information about the libcxx-commits
mailing list