Index: libcxx/include/__iterator/iter_move.h =================================================================== --- libcxx/include/__iterator/iter_move.h +++ libcxx/include/__iterator/iter_move.h @@ -49,8 +49,8 @@ concept __move_deref = !__unqualified_iter_move<_Tp> && requires (_Tp&& __t) { - *__t; - requires is_lvalue_reference_v; + *std::forward<_Tp>(__t); + requires is_lvalue_reference_v(__t))>; }; template @@ -58,8 +58,8 @@ !__unqualified_iter_move<_Tp> && !__move_deref<_Tp> && requires (_Tp&& __t) { - *__t; - requires (!is_lvalue_reference_v); + *std::forward<_Tp>(__t); + requires (!is_lvalue_reference_v(__t))>); }; // [iterator.cust.move] Index: libcxx/test/std/iterators/iterator.requirements/iterator.cust/iterator.cust.move/iter_move_rvalue.compile.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/iterators/iterator.requirements/iterator.cust/iterator.cust.move/iter_move_rvalue.compile.pass.cpp @@ -0,0 +1,47 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +// Test the constraints in libc++. + +// template +// unspecified iter_move; + +#include +#include +#include + +template +class wrapper { +public: + wrapper() = default; + + constexpr explicit wrapper(I i) noexcept : base_(std::move(i)) {} + + // This operator is used to check the constraints work. + constexpr decltype(auto) operator*() & noexcept { return base_; } + + // This operator is used to check the constraints work. + constexpr auto&& operator*() && noexcept = delete; + +private: + I base_ = I{}; +}; + +template +wrapper( I ) -> wrapper; + +void test_iter_move_rvalue() { + std::array t1; + auto first = wrapper{std::move(t1)}; + + auto helper = [](auto&& f) requires (!requires{std::ranges::iter_move(std::move(f));}) {}; + [[maybe_unused]] auto dummy = std::ranges::iter_move(first); + helper(first); +}