This patch completes the implementation of P2321R2, giving tuple proper proxy
reference semantics.

The assignment operator is implemented as a template constrained to accept only
tuple<>. Consequently, the language does not consider it a copy assignment
operator, which prevents tuple<> from losing its trivially copyable status.

The _Tuple template parameter is defaulted, ensuring the constructor remains
a viable candidate for assignment with an empty brace-init list.

        PR libstdc++/119721

libstdc++-v3/ChangeLog:

        * include/std/tuple (tuple<>::operator=(const _Tuple&) const)
        [__cpp_lib_ranges_zip]: Define.
        * testsuite/23_containers/tuple/cons/119721.cc: Test assigment
        of empty braces.
---
This implements const copy-assigment operator in the way that does not
make tuple not trivially copyable.

Testing again on x86_64-linux. *tuple* tesst passed.

 libstdc++-v3/include/std/tuple                       |  5 +++++
 .../testsuite/23_containers/tuple/cons/119721.cc     | 12 +++++++++---
 2 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple
index 28a99ead499..c701164c84a 100644
--- a/libstdc++-v3/include/std/tuple
+++ b/libstdc++-v3/include/std/tuple
@@ -1996,6 +1996,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       void swap(tuple&) noexcept { /* no-op */ }
 
 #if __cpp_lib_ranges_zip // >= C++23
+      template<same_as<tuple> _Tuple = tuple>
+      constexpr const tuple&
+      operator=(const _Tuple&) const noexcept
+      { return *this; }
+
       constexpr void swap(const tuple&) const noexcept
       { /* no-op */ }
 #endif
diff --git a/libstdc++-v3/testsuite/23_containers/tuple/cons/119721.cc 
b/libstdc++-v3/testsuite/23_containers/tuple/cons/119721.cc
index e87845c6bda..3b1edb6bbda 100644
--- a/libstdc++-v3/testsuite/23_containers/tuple/cons/119721.cc
+++ b/libstdc++-v3/testsuite/23_containers/tuple/cons/119721.cc
@@ -54,12 +54,15 @@ test03()
 {
   // Test assignment return type (non-const assignment)
   std::tuple<> t, u;
-  std::tuple<>& r = (t = u);
+  std::tuple<>& r2 = (t = u);
   VERIFY( &r == &t );
-  
+
   std::array<int, 0> a{};
   std::tuple<>& r2 = (t = a);
   VERIFY( &r2 == &t );
+
+  std::tuple<>& r3 = (t = {});
+  VERIFY( &r3 == &t );
 }
 
 constexpr void
@@ -75,7 +78,10 @@ test04()
   // Const assignment from array
   t1 = a;
   t1 = std::move(a);
-  
+ 
+  // Const assigment from braces
+  t1 = {};
+
   VERIFY( t1 == t2 );
   VERIFY( t1 == a );
 }
-- 
2.51.0

Reply via email to