Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/llvm/llvm-project.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/libcxx
diff options
context:
space:
mode:
authorArthur O'Dwyer <arthur.j.odwyer@gmail.com>2022-03-03 01:22:55 +0300
committerArthur O'Dwyer <arthur.j.odwyer@gmail.com>2022-03-07 21:31:16 +0300
commitfbcd5236af20e7d1373f5d88e0a9b49e34614fdc (patch)
tree333ff3939aea9a41de66ca1cd6b9470449646266 /libcxx
parente6a8b92b8959b17a140a30b340dd59cfa8781dea (diff)
[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
Diffstat (limited to 'libcxx')
-rw-r--r--libcxx/include/__iterator/iter_move.h38
-rw-r--r--libcxx/test/std/iterators/iterator.requirements/iterator.cust/iterator.cust.move/iter_rvalue_reference_t.compile.pass.cpp (renamed from libcxx/test/std/iterators/iterator.requirements/iterator.cust/iterator.cust.move/iter_rvalue_reference_t.pass.cpp)16
2 files changed, 36 insertions, 18 deletions
diff --git a/libcxx/include/__iterator/iter_move.h b/libcxx/include/__iterator/iter_move.h
index 97d54c4a825c..66d69af7fd84 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
index 6c19ec3ae33a..441b3caca02d 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&&>);
+}