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 operator 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 const
assignment.
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
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
{
std::array<int, 0> a{};
const std::tuple<> t1;
-
+
// Const assignment from array
- t1 = a;
- t1 = std::move(a);
-
- VERIFY( t1 == a );
+ std::tuple<> t2;
+ const std::tuple<>& r1 = (t1 = t2);
+ VERIFY( &r1 == &t1 );
+ const std::tuple<>& r2 = (t1 = std::move(t2));
+ VERIFY( &r2 == &t1 );
+
+ const std::tuple<>& r3 = (t1 = {});
+ VERIFY( &r3 == &t1 );
+
+ // Const assignment from array
+ const std::tuple<>& r4 = (t1 = a);
+ VERIFY( &r4 == &t1 );
+ const std::tuple<>& r5 = (t1 = std::move(a));
+ VERIFY( &r5 == &t1 );
}
void