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

--- Comment #11 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Jonathan Wakely <[email protected]>:

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

commit r16-5968-gea42e28cbc3d4d579666582e8893e7629bf6a390
Author: Jonathan Wakely <[email protected]>
Date:   Fri Dec 5 20:54:32 2025 +0000

    libstdc++: Extend __is_standard_integer to cover extended integer types

    We have __is_signed_integer and __is_unsigned_integer traits which
    should have been updated by r16-2190-g4faa42ac0dee2c when making
    __int128 an extended integer type (for PR libstdc++/96710). Currently
    they check whether the type is a signed integer type or an unsigned
    integer type, or a cv-qualified version of one of those. This doesn't
    match the standard's definition, which does not include cv-qualified
    types. This change ensures that signed __int128 and unsigned __int128
    are included in those traits in strict -std modes, and it removes the
    use of remove_cv_t so that they are not true for cv-qualified types.
    This makes the traits match the meaning of "signed integer type" and
    "unsigned integer type" in the standard ([basic.fundamental]).

    We also have an __is_standard_integer trait, which is true if either
    __is_signed_integer or __is_unsigned_integer is true, but that's also
    not a match for the definition in the standard. The definitions of
    "signed integer type" and "unsigned integer type" include both standard
    and extended integer types, so only saying "standard" in the trait name
    is misleading (even before this change, because in non-strict -std modes
    the __GLIBCXX_TYPE_INT_N_0 .. __GLIBCXX_TYPE_INT_N_3 types were always
    included in the trait, and they aren't standard integer types).

    This change renames __is_standard_integer to the more accurate
    __is_signed_or_unsigned_integer. Because the set of signed and
    unsigned integer types is the same as the set of standard and extended
    integer types, the trait could instead have been renamed to
    __is_standard_or_extended_integer. I think it's clearer and more
    self-explanatory to avoid "standard and extended" and name it for the
    signed and unsigned integer types.

    N.B. we don't want to call it just __is_integer_type because the integer
    types includes cv-qualified types and also bool and the character types
    char, wchar_t, char16_t etc.

    The consequences of redefining and renaming these traits are small, and
    only positive.

    Apart from the uses in the __is_standard_integer trait, the only other
    uses of __is_signed_integer and __is_unsigned_integer are in <format>
    and those uses are unaffected by this change to add 128-bit integers to
    the traits. In both uses the type argument is already cv-unqualified,
    and there is already explicit handling for 128-bit integers where that
    is required.

    The existing uses of __is_standard_integer can simply be changed to use
    the new name. This does change the behaviour of those uses of the trait,
    because the __is_signed_or_unsigned_integer trait now includes
    128-bit integers in strict modes. However, that is a desirable change
    that fixes some bugs. Specifically, the [utility.intcmp] functions such
    as std::cmp_less and the [numeric.sat.arith] functions such as
    std::add_sat did not support 128-bit integers in strict modes. Since the
    standard says they should be enabled for all signed and unsigned integer
    types (or equivalently, for all standard and extended integer types),
    those functions should all support __int128 and unsigned __int128. That
    is fixed by this change.  Additionally, the same changes in <charconv>,
    <mdspan>, and <stdckdint.h> enable the use of 128-bit integers for those
    APIs in strict modes.

    Finally, this also make a drive-by fix to the enable_if constraints for
    the integer overloads of std::from_chars. That used remove_cv_t and so
    enabled the overload for lvalue arguments of type const char, which
    won't work and should not be enabled.

    libstdc++-v3/ChangeLog:

            * include/bits/intcmp.h: Replace all uses of
            __is_standard_integer with __is_signed_or_unsigned_integer.
            * include/bits/max_size_type.h: Fix outdated comment.
            * include/bits/sat_arith.h: Replace all uses of
            __is_standard_integer with __is_signed_or_unsigned_integer.
            * include/c_compatibility/stdckdint.h: Replace all uses of the
            __cv_unqual_signed_or_unsigned_integer_type concept with
            __is_signed_or_unsigned_integer.
            (__cv_unqual_signed_or_unsigned_integer_type): Remove.
            * include/ext/numeric_traits.h: Fix outdated comment.
            * include/std/charconv (from_chars): Replace use of
            __is_standard_integer with __is_signed_or_unsigned_integer.
            Do not enable for cv-qualified char.
            * include/std/mdspan: Likewise.
            * include/std/type_traits (__is_unsigned_integer): Include
            unsigned __int128 in type list.
            (__is_signed_integer): Include signed __int128 in type list.
            (__is_standard_integer): Rename to ...
            (__is_signed_or_unsigned_integer): ... this.
            * testsuite/23_containers/mdspan/extents/ctor_ints.cc: Test
            with 128-bit integers.
            * testsuite/23_containers/mdspan/submdspan/strided_slice.cc:
            Likewise.
            * testsuite/20_util/integer_comparisons/extended.cc: New test.
            * testsuite/26_numerics/saturation/extended.cc: New test.
            * testsuite/26_numerics/stdckdint/extended.cc: New test.

    Reviewed-by: Patrick Palka <[email protected]>

Reply via email to