On Mon, Jul 14, 2025 at 10:58 PM Jonathan Wakely <jwak...@redhat.com> wrote:
> We pre-emptively implemented part of LWG 2766, which still hasn't been > approved. Add comments to the deleted swap overloads saying why they're > there, because the standard doesn't require them. > > libstdc++-v3/ChangeLog: > > * include/bits/stl_pair.h (swap): Add comment to deleted > overload. > * include/bits/unique_ptr.h (swap): Likewise. > * include/std/array (swap): Likewise. > * include/std/optional (swap): Likewise. > * include/std/tuple (swap): Likewise. > * include/std/variant (swap): Likewise. > * testsuite/23_containers/array/tuple_interface/get_neg.cc: > Adjust dg-error line numbers. > --- > > Tested powerpc64le-linux, pushed to trunk. > Only tangentially related, but it looks like we are adding more and more use cases for having a conditional = delete(expr), than can be followed by body. > > libstdc++-v3/include/bits/stl_pair.h | 2 ++ > libstdc++-v3/include/bits/unique_ptr.h | 2 ++ > libstdc++-v3/include/std/array | 2 ++ > libstdc++-v3/include/std/optional | 2 ++ > libstdc++-v3/include/std/tuple | 4 +++- > libstdc++-v3/include/std/variant | 2 ++ > .../23_containers/array/tuple_interface/get_neg.cc | 6 +++--- > 7 files changed, 16 insertions(+), 4 deletions(-) > > diff --git a/libstdc++-v3/include/bits/stl_pair.h > b/libstdc++-v3/include/bits/stl_pair.h > index 8c57712b4617..393f6a016196 100644 > --- a/libstdc++-v3/include/bits/stl_pair.h > +++ b/libstdc++-v3/include/bits/stl_pair.h > @@ -1132,6 +1132,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > #endif // C++23 > > #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 > + // _GLIBCXX_RESOLVE_LIB_DEFECTS > + // 2766. Swapping non-swappable types > template<typename _T1, typename _T2> > typename enable_if<!__and_<__is_swappable<_T1>, > __is_swappable<_T2>>::value>::type > diff --git a/libstdc++-v3/include/bits/unique_ptr.h > b/libstdc++-v3/include/bits/unique_ptr.h > index 6ae46a93800c..d76ad63ba7bf 100644 > --- a/libstdc++-v3/include/bits/unique_ptr.h > +++ b/libstdc++-v3/include/bits/unique_ptr.h > @@ -832,6 +832,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > { __x.swap(__y); } > > #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 > + // _GLIBCXX_RESOLVE_LIB_DEFECTS > + // 2766. Swapping non-swappable types > template<typename _Tp, typename _Dp> > typename enable_if<!__is_swappable<_Dp>::value>::type > swap(unique_ptr<_Tp, _Dp>&, > diff --git a/libstdc++-v3/include/std/array > b/libstdc++-v3/include/std/array > index fdcf0b073762..12f010921db1 100644 > --- a/libstdc++-v3/include/std/array > +++ b/libstdc++-v3/include/std/array > @@ -381,6 +381,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > { __one.swap(__two); } > > #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 > + // _GLIBCXX_RESOLVE_LIB_DEFECTS > + // 2766. Swapping non-swappable types > template<typename _Tp, std::size_t _Nm> > __enable_if_t<!__array_traits<_Tp, _Nm>::_Is_swappable::value> > swap(array<_Tp, _Nm>&, array<_Tp, _Nm>&) = delete; > diff --git a/libstdc++-v3/include/std/optional > b/libstdc++-v3/include/std/optional > index cc7af5bbd7d2..e5051d72c828 100644 > --- a/libstdc++-v3/include/std/optional > +++ b/libstdc++-v3/include/std/optional > @@ -1740,6 +1740,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > noexcept(noexcept(__lhs.swap(__rhs))) > { __lhs.swap(__rhs); } > > + // _GLIBCXX_RESOLVE_LIB_DEFECTS > + // 2766. Swapping non-swappable types > template<typename _Tp> > enable_if_t<!(is_move_constructible_v<_Tp> && is_swappable_v<_Tp>)> > swap(optional<_Tp>&, optional<_Tp>&) = delete; > diff --git a/libstdc++-v3/include/std/tuple > b/libstdc++-v3/include/std/tuple > index b39ce710984c..2e6499eab22d 100644 > --- a/libstdc++-v3/include/std/tuple > +++ b/libstdc++-v3/include/std/tuple > @@ -2835,6 +2835,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > { __x.swap(__y); } > > #if __cpp_lib_ranges_zip // >= C++23 > + /// Exchange the values of two const tuples (if const elements can be > swapped) > template<typename... _Elements> > requires (is_swappable_v<const _Elements> && ...) > constexpr void > @@ -2844,7 +2845,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > #endif // C++23 > > #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 > - /// Exchange the values of two const tuples (if const elements can be > swapped) > + // _GLIBCXX_RESOLVE_LIB_DEFECTS > + // 2766. Swapping non-swappable types > template<typename... _Elements> > _GLIBCXX20_CONSTEXPR > typename enable_if<!__and_<__is_swappable<_Elements>...>::value>::type > diff --git a/libstdc++-v3/include/std/variant > b/libstdc++-v3/include/std/variant > index ec46ff1dabb5..2f44f9700283 100644 > --- a/libstdc++-v3/include/std/variant > +++ b/libstdc++-v3/include/std/variant > @@ -1387,6 +1387,8 @@ namespace __detail::__variant > noexcept(noexcept(__lhs.swap(__rhs))) > { __lhs.swap(__rhs); } > > + // _GLIBCXX_RESOLVE_LIB_DEFECTS > + // 2766. Swapping non-swappable types > template<typename... _Types> > enable_if_t<!((is_move_constructible_v<_Types> && ...) > && (is_swappable_v<_Types> && ...))> > diff --git > a/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc > b/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc > index 25511e79941d..e1e9ce9bdac1 100644 > --- a/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc > +++ b/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc > @@ -26,6 +26,6 @@ int n1 = std::get<1>(a); > int n2 = std::get<1>(std::move(a)); > int n3 = std::get<1>(ca); > > -// { dg-error "static assertion failed" "" { target *-*-* } 394 } > -// { dg-error "static assertion failed" "" { target *-*-* } 403 } > -// { dg-error "static assertion failed" "" { target *-*-* } 412 } > +// { dg-error "static assertion failed" "" { target *-*-* } 396 } > +// { dg-error "static assertion failed" "" { target *-*-* } 405 } > +// { dg-error "static assertion failed" "" { target *-*-* } 414 } > -- > 2.50.1 > >