On Thu, 7 May 2026 at 06:39, Tomasz Kaminski <[email protected]> wrote: > > > > On Wed, May 6, 2026 at 10:10 PM Jonathan Wakely <[email protected]> wrote: >> >> On Wed, 6 May 2026 at 15:49, Tomasz Kaminski <[email protected]> wrote: >> > >> > >> > >> > On Wed, May 6, 2026 at 4:16 PM Jonathan Wakely <[email protected]> wrote: >> >> >> >> Since C++20 the std::tuple move constructor should be constrained (as >> >> modified by LWG 2899). >> >> >> >> We already define the move constructor as defaulted, but it's not >> >> implicitly defined as deleted for non-move-constructible element types >> >> because the _Tuple_impl(_Tuple_impl&&) constructor is user-provided and >> >> unconstrained. For C++20 and later we use a requires-clause to constrain >> >> the defaulted tuple(tuple&&) constructor. >> >> >> >> Ideally we'd make this change pre-C++20 as well, but that's harder to do >> >> without using a requires-clause, so this change is only for C++20 and >> >> later. I think that's OK, but if we need to change it for pre-C++20 >> >> later we can consider inheriting from _Enable_copy_move<..., tuple> to >> >> make the defaulted move constructor defined as deleted. >> >> >> >> libstdc++-v3/ChangeLog: >> >> >> >> PR libstdc++/78302 >> >> PR libstdc++/71301 >> >> * include/std/tuple [C++20] (tuple(tuple&&)): Add >> >> requires-clause. >> >> * testsuite/20_util/tuple/cons/78302.cc: New test. >> >> --- >> >> >> >> Tested x86_64-linux. >> >> >> >> libstdc++-v3/include/std/tuple | 4 +++- >> >> libstdc++-v3/testsuite/20_util/tuple/cons/78302.cc | 11 +++++++++++ >> >> 2 files changed, 14 insertions(+), 1 deletion(-) >> >> create mode 100644 libstdc++-v3/testsuite/20_util/tuple/cons/78302.cc >> >> >> >> diff --git a/libstdc++-v3/include/std/tuple >> >> b/libstdc++-v3/include/std/tuple >> >> index cbacd5a3c977..64b96fe4f599 100644 >> >> --- a/libstdc++-v3/include/std/tuple >> >> +++ b/libstdc++-v3/include/std/tuple >> >> @@ -954,7 +954,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION >> >> >> >> constexpr tuple(const tuple&) = default; >> >> >> >> - constexpr tuple(tuple&&) = default; >> >> + constexpr >> >> + tuple(tuple&&) requires (is_move_constructible_v<_Elements> && ...) >> > >> > Could you add test for tuple of references (lvalue and rvalue)? I think >> > the traits >> > gives correct result, but I am not sure. >> >> >> >> + = default; >> >> >> >> template<typename... _UTypes> >> >> requires (__constructible<const _UTypes&...>()) >> >> diff --git a/libstdc++-v3/testsuite/20_util/tuple/cons/78302.cc >> >> b/libstdc++-v3/testsuite/20_util/tuple/cons/78302.cc >> >> new file mode 100644 >> >> index 000000000000..b3c6bd67fd27 >> >> --- /dev/null >> >> +++ b/libstdc++-v3/testsuite/20_util/tuple/cons/78302.cc >> >> @@ -0,0 +1,11 @@ >> >> +// { dg-do compile { target c++20 } } >> >> + >> >> +// Bug 78302 is_move_constructible_v<tuple<nonmovable>> should be false >> >> +// LWG 2899. is_(nothrow_)move_constructible and tuple, optional and >> >> unique_ptr >> >> + >> >> +#include <tuple> >> >> +#include <type_traits> >> >> + >> >> +struct NotMovable { NotMovable(NotMovable&&) = delete; }; >> >> +static_assert(!std::is_move_constructible_v<std::tuple<NotMovable>>); >> >> +static_assert(std::is_nothrow_move_constructible_v<std::tuple<int>>); >> >> Is this good enough? >> >> >> #include <tuple> >> #include <type_traits> >> >> struct NotMovable { NotMovable(NotMovable&&) = delete; }; >> static_assert(!std::is_move_constructible_v<std::tuple<NotMovable>>); >> static_assert(!std::is_move_constructible_v<std::tuple<int, NotMovable>>); >> static_assert(!std::is_move_constructible_v<std::tuple<int&, NotMovable>>); >> static_assert(!std::is_move_constructible_v<std::tuple<int&&, NotMovable>>); >> static_assert(std::is_nothrow_move_constructible_v<std::tuple<int>>); >> static_assert(std::is_nothrow_move_constructible_v<std::tuple<int&>>); >> static_assert(std::is_nothrow_move_constructible_v<std::tuple<int&&>>); >> static_assert(std::is_nothrow_move_constructible_v<std::tuple<int&&, int&>>); > > Add them to test file, so I do not need to check is_move_constructible_v on > reference,
Yes, what I pasted above is what is in the test file in my local tree. I've pushed it to trunk and will backport it after waiting a while. > when looking at it. LGTM with that. >> >> >> (It passes) >>
