https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113310

--- Comment #1 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The trunk branch has been updated by Giuseppe D'Angelo <pe...@gcc.gnu.org>:

https://gcc.gnu.org/g:de231924b73bc120bf2b7ada4eeccd884c249ee1

commit r15-7853-gde231924b73bc120bf2b7ada4eeccd884c249ee1
Author: Giuseppe D'Angelo <giuseppe.dang...@kdab.com>
Date:   Thu Feb 27 22:47:27 2025 +0100

    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.

Reply via email to