diff options
author | Arthur O'Dwyer <arthur.j.odwyer@gmail.com> | 2022-03-03 01:22:55 +0300 |
---|---|---|
committer | Arthur O'Dwyer <arthur.j.odwyer@gmail.com> | 2022-03-07 21:31:16 +0300 |
commit | fbcd5236af20e7d1373f5d88e0a9b49e34614fdc (patch) | |
tree | 333ff3939aea9a41de66ca1cd6b9470449646266 /libcxx | |
parent | e6a8b92b8959b17a140a30b340dd59cfa8781dea (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.h | 38 | ||||
-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&&>); +} |