]> git.ipfire.org Git - thirdparty/gcc.git/commit
libstdc++: implement tuple protocol for std::complex (P2819R2)
authorGiuseppe D'Angelo <giuseppe.dangelo@kdab.com>
Thu, 27 Feb 2025 21:47:27 +0000 (22:47 +0100)
committerGiuseppe D'Angelo <giuseppe.dangelo@kdab.com>
Thu, 6 Mar 2025 11:24:47 +0000 (12:24 +0100)
commitde231924b73bc120bf2b7ada4eeccd884c249ee1
treecadf4d023406d46b4bb1d55b2fef8d1f0d3595ee
parente836d80374aa03a5ea5bd6cca00d826020c461da
libstdc++: implement tuple protocol for std::complex (P2819R2)

This commit implements P2819R2 for C++26, making std::complex
destructurable and tuple-like (see [complex.tuple]).

std::get needs to get forward declared in stl_pair.h (following the
existing precedent for the implementation of P2165R4, cf.
r14-8710-g65b4cba9d6a9ff), and implemented in <complex>.

Also, std::get(complex<T>) needs to return *references* to the real and
imaginary parts of a std::complex object, honoring the value category
and constness of the argument. In principle a straightforward task, it
gets a bit convoluted by the fact that:

1) std::complex does not have existing getters that one can use for this
(real() and imag() return values, not references);

2) there are specializations for language/extended floating-point types,
which requires some duplication -- need to amend the primary and all
the specializations;

3) these specializations use a `__complex__ T`, but the primary template
uses two non-static data members, making generic code harder to write.

The implementation choice used here is to add the overloads of std::get
for complex as declared in [complex.tuple]. In turn they dispatch to a
newly added getter that extracts references to the real/imaginary parts
of a complex<T>. This getter is private API, and the implementation
depends on whether it's the primary (bind the data member) or a
specialization (use the GCC language extensions for __complex__).
To avoid duplication and minimize template instantiations, the getter
uses C++23's deducing this (this avoids const overloads). The value
category is dealt with by the std::get overloads.

Add a test that covers the aspects of the tuple protocol, as well as the
tuple-like interface. While at it, add a test for the existing
tuple-like feature-testing macro.

PR libstdc++/113310

libstdc++-v3/ChangeLog:

* include/bits/stl_pair.h (get): Forward-declare std::get for
std::complex.
* include/bits/version.def (tuple_like): Bump the value of
the feature-testing macro in C++26.
* include/bits/version.h: Regenerate.
* include/std/complex: Implement the tuple protocol for
std::complex.
(tuple_size): Specialize for std::complex.
(tuple_element): Ditto.
(__is_tuple_like_v): Ditto.
(complex): Add a private getter to obtain references to the real
and the imaginary part, on the primary class template and on its
specializations.
(get): Add overloads of std::get for std::complex.
* testsuite/20_util/tuple/tuple_like_ftm.cc: New test.
* testsuite/26_numerics/complex/tuple_like.cc: New test.
libstdc++-v3/include/bits/stl_pair.h
libstdc++-v3/include/bits/version.def
libstdc++-v3/include/bits/version.h
libstdc++-v3/include/std/complex
libstdc++-v3/testsuite/20_util/tuple/tuple_like_ftm.cc [new file with mode: 0644]
libstdc++-v3/testsuite/26_numerics/complex/tuple_like.cc [new file with mode: 0644]