Commit Graph

6814 Commits

Author SHA1 Message Date
Jakub Jelinek 62c126db6b libstdc++: Implement C++26 P3378R2 - constexpr exception types
The following patch attempts to implement the C++26 P3378R2 - constexpr
exception types paper.

This is quite complicated, because most of these classes which should
be constexpr-ized use solely or mostly out of line definitions in
libstdc++, both for historical, code size and dual ABI reasons, so that
one can throw these as exceptions between TUs with old vs. new (or vice
versa) ABIs.
For this reason, logic_error/runtime_error and classes derived from it
have the old ABI std::string object inside of them and the exported
APIs from libstdc++.so.6 ensure the right thing.

Now, because new invoked during constant evaluation needs to be deleted
during the same constant evaluation and can't leak into the constant
expressions, I think we don't have to use COW strings under the hood
(which aren't constexpr I guess because of reference counting/COW) and
we can use something else, the patch uses heap allocated std::string
object (where __cow_constexpr_string class has just a pointer to that).
As I think we still want to hide the ugly details if !consteval in the
library, the patch exports 8 __cow_string class symbols (6 existing which
were previously just not exported and 2 new ones) and if !consteval
calls those through extern "C" _Zmangled_name symbols.  The functions
are always_inline.

And then logic_error etc. have for C++26 (precisely for
__cpp_lib_constexpr_exceptions >= 202502L) constexpr definitions of
cdtors/methods.  This results in slightly larger code (a few insns at most)
at runtime for C++26, e.g. instead of calling say some logic error
cdtor/method with 2 arguments it calls some __cow_string one with 2
arguments but + 8 bytes pointer additions on both.

The patch also removes the __throw_format_error forward declaration
which apparently wasn't needed for anything as all __throw_format_error
users were either in <format> or included <format> before the uses,
reverts the
https://gcc.gnu.org/pipermail/libstdc++/2025-July/062598.html
patch and makes sure __throw_* functions (only those for exception types
which the P3378R2 or P3068R5 papers made constexpr usable and there are
actually constexpr/consteval uses of those) are constexpr for C++26
constexpr exceptions.

The patch does that by splitting the bits/functexcept.h header:
1) bits/functexcept.h stays for the __throw_* functions which are (at
least for now) never constexpr (the <ios>, <system_error>, <future>
and <functional> std::exception derived classes) or are never used
or never used in constexpr/consteval contexts (<exception>, <typeinfo>
std::exception derived classes and std::range_error).
2) bits/new_{throw,except}.h for __throw_bad_alloc/__throw_bad_array_new_length
and std::bad_alloc/std::bad_array_new_length (where <new> includes
<bits/new_except.h> and <bits/new_throw.h> as well for the C++26 constexpr
exceptions case)
3) for the most complicated <stdexcept> stuff, one header
addition to bits/stdexcept.h one header for the __throw_logic_error etc.
forward declarations, one header for the __throw_logic_error etc.
definitions and one header without header guards which will
depending on __glibcxx_exc_in_string include one or the other because
<string> vs. <string_view> vs. <stdexcept> have heavy interdependencies

2025-12-11  Jakub Jelinek  <jakub@redhat.com>

	PR libstdc++/121114
libstdc++-v3/
	* include/bits/version.def: Implement C++26 P3378R2 - constexpr
	exception types.
	(constexpr_exceptions): Change value from 1 to 202502, remove
	no_stdname and TODO comments.
	* include/bits/version.h: Regenerate.
	* src/c++11/cow-stdexcept.cc (__cow_string(const char*)): New
	ctor.
	(__cow_string::c_str()): New method.
	* config/abi/pre/gnu.ver (GLIBCXX_3.4.35): Export 8 __cow_string
	symbols.
	* include/bits/new_except.h: New file.
	* include/bits/new_throw.h: New file.
	* include/bits/stdexcept_throw.h: New file.
	* include/bits/stdexcept_throwdef.h: New file.
	* include/bits/stdexcept_throwfwd.h: New file.
	* include/std/stdexcept: Include bits/stdexcept_except.h and move
	everything after <string> include except for std::range_error into
	include/bits/stdexcept_except.h.
	(std::range_error): If __cpp_lib_constexpr_exceptions >= 202502L
	make all cdtors and methods constexpr.
	* include/bits/stdexcept_except.h: New file.
	* include/std/optional (__glibcxx_want_constexpr_exceptions): Define
	before including bits/version.h.
	(bad_optional_access::what): Make constexpr for
	__cpp_lib_constexpr_exceptions >= 202502L.
	(__throw_bad_optional_access): Likewise.
	* include/std/expected (__glibcxx_want_constexpr_exceptions): Define
	before including bits/version.h.
	(bad_expected_access): Make cdtors and all methods constexpr for
	__cpp_lib_constexpr_exceptions >= 202502L.
	* include/std/format (__glibcxx_want_constexpr_exceptions): Define
	before including bits/version.h.
	(_GLIBCXX_CONSTEXPR_FORMAT_ERROR): Define and undef later.
	(format_error): Use _GLIBCXX_CONSTEXPR_FORMAT_ERROR on ctors.
	* include/std/variant (__glibcxx_want_constexpr_exceptions): Define
	before including bits/version.h.
	(_GLIBCXX_CONSTEXPR_BAD_VARIANT_ACCESS): Define and undef later.
	(bad_variant_access): Use it on ctors and what() method.
	(__throw_bad_variant_access): Use it here too.
	* testsuite/18_support/exception/version.cc: Adjust expected
	__cpp_lib_constexpr_exceptions value.
	* testsuite/19_diagnostics/runtime_error/constexpr.cc: New test.
	* testsuite/19_diagnostics/headers/stdexcept/version.cc: New test.
	* testsuite/19_diagnostics/logic_error/constexpr.cc: New test.
	* testsuite/20_util/expected/observers.cc (test_value_throw): Change
	return type to bool from void, return true at the end, add test
	to dereference what() first character.  Make it constexpr for
	__cpp_lib_constexpr_exceptions >= 202502L and add static_assert.
	* testsuite/20_util/expected/version.cc: Add tests for
	__cpp_lib_constexpr_exceptions value.
	* testsuite/20_util/variant/constexpr.cc: For
	__cpp_lib_constexpr_exceptions >= 202502L include <string>.
	(test_get): New function if __cpp_lib_constexpr_exceptions >= 202502L,
	assert calling it is true.
	* testsuite/20_util/variant/version.cc: Add tests for
	__cpp_lib_constexpr_exceptions value.
	* testsuite/20_util/optional/constexpr/observers/3.cc: Include
	testsuite_hooks.h.
	(eat, test01): New functions.  Assert test01() is true.
	* testsuite/20_util/optional/version.cc: Add tests for
	__cpp_lib_constexpr_exceptions value.
	* include/std/future: Add #include <bits/functexcept.h>.
	* include/std/shared_mutex: Include <bits/new_throw.h>.
	* include/std/flat_map: Include <bits/stdexcept_throw.h> instead of
	<bits/functexcept.h>.
	* include/std/syncstream: Remove <bits/functexcept.h> include.
	* include/std/flat_set: Likewise.
	* include/std/bitset: Include <bits/stdexcept_throw.h> instead of
	<bits/functexcept.h>.
	* include/std/string_view: Don't include <bits/functexcept.h>, include
	<bits/stdexcept_throw.h> early if __glibcxx_exc_in_string is not
	defined and include <bits/stdexcept_throw.h> at the end of
	the header again if __glibcxx_exc_in_string is 2 and C++26 constexpr
	exceptions are enabled.
	(__glibcxx_exc_in_string): Define if __glibcxx_exc_in_string wasn't
	defined before including <bits/stdexcept_throw.h>.
	* include/std/array: Include <bits/stdexcept_throw.h> instead of
	<bits/functexcept.h>.
	* include/std/inplace_vector: Likewise.
	* include/std/string: Include <bits/stdexcept_except.h> and
	<bits/stdexcept_throw.h> after bits/basic_string.tcc include if
	C++26 constexpr exceptions are enabled and include
	<bits/stdexcept_throw.h> instead of <bits/functexcept.h> early.
	(__glibcxx_exc_in_string): Define early to 1, undefine at the end.
	* include/std/deque: Include <bits/stdexcept_throw.h>.
	* include/bits/new_allocator.h: Include <bits/new_throw.h> instead
	of <bits/functexcept.h>.
	* include/bits/stl_algobase.h: Remove <bits/functexcept.h> include.
	* include/bits/stl_vector.h: Include <bits/stdexcept_throw.h> instead
	of <bits/functexcept.h>.
	* include/bits/memory_resource.h: Include <bits/new_throw.h> instead
	of <bits/functexcept.h>.
	* include/bits/functexcept.h: Guard everything after includes with
	#if _GLIBCXX_HOSTED.
	(__throw_bad_alloc, __throw_bad_array_new_length,  __throw_logic_error,
	__throw_domain_error, __throw_invalid_argument, __throw_length_error,
	__throw_out_of_range, __throw_out_of_range_fmt, __throw_runtime_error,
	__throw_overflow_error, __throw_underflow_error): Move declarations to
	other headers - <bits/new_throw.h> and <bits/stdexcept_throwfwd.h>.
	* include/bits/stl_map.h: Include <bits/stdexcept_throw.h> instead
	of <bits/functexcept.h>.
	* include/bits/hashtable_policy.h: Include <bits/stdexcept_throw.h>
	instead of <bits/functexcept.h>.
	* include/bits/formatfwd.h (std::__throw_format_error): Remove
	declaration.
	* include/bits/specfun.h: Include <bits/stdexcept_throw.h> instead of
	<bits/functexcept.h>.
	* include/bits/basic_ios.h: Include <bits/functexcept.h>.
	* include/bits/locale_classes.h: Likewise.
	* include/tr1/cmath: Include <bits/stdexcept_throw.h> instead of
	<bits/functexcept.h>.
	* include/tr1/memory: Remove <bits/functexcept.h> include.
	* include/tr1/array: Include <bits/stdexcept_throw.h>.
	* include/ext/vstring_util.h: Include <bits/stdexcept_throw.h> instead
	of <bits/functexcept.h>.
	* include/ext/bitmap_allocator.h: Include <bits/new_throw.h> instead
	of <bits/functexcept.h>.
	* include/ext/mt_allocator.h: Likewise.
	* include/ext/malloc_allocator.h: Likewise.
	* include/ext/debug_allocator.h: Include <bits/stdexcept_throw.h>
	instead of <bits/functexcept.h>.
	* include/ext/concurrence.h: Include <bits/exception_defines.h>
	instead of <bits/functexcept.h>.
	* include/ext/throw_allocator.h: Include <bits/new_throw.h> and
	<bits/stdexcept_throw.h> instead of <bits/functexcept.h>.
	* include/ext/string_conversions.h: Include <bits/stdexcept_throw.h>
	instead of <bits/functexcept.h>.
	* include/ext/pool_allocator.h: Include <bits/new_throw.h> instead
	of <bits/functexcept.h>.
	* include/ext/ropeimpl.h: Include <bits/stdexcept_throw.h> instead of
	<bits/functexcept.h>.
	* include/tr2/dynamic_bitset: Likewise.
	* include/experimental/optional: Include <bits/exception_defines.h>
	instead of <bits/functexcept.h>.
	* include/Makefile.am (bits_freestanding): Add
	${bits_srcdir}/{new,stdexcept}_{except,throw}.h
	and ${bits_srcdir}/stdexcept_throw{fwd,def}.h.
	* include/Makefile.in: Regenerate.
	* src/c++17/floating_from_chars.cc: Remove <bits/functexcept.h>
	include.
	* src/c++11/regex.cc: Likewise.
	* src/c++11/functexcept.cc: Likewise.
	* src/c++11/snprintf_lite.cc: Include <bits/stdexcept_throw.h> instead
	of <bits/functexcept.h>.
	* src/c++11/thread.cc: Include <bits/functexcept.h>.
	* testsuite/util/testsuite_hooks.h: Include <bits/stdexcept_throw.h>
	instead of <bits/functexcept.h>.
	* testsuite/util/io/verified_cmd_line_input.cc: Include
	<bits/exception_defines.h> instead of <bits/functexcept.h>.
	* testsuite/20_util/allocator/105975.cc: Expect different diagnostics
	for C++26.
	* testsuite/23_containers/inplace_vector/access/capacity.cc: Remove
	#error, guard if consteval { return; } with
	#ifndef __cpp_lib_constexpr_exceptions.
	* testsuite/23_containers/inplace_vector/access/elem.cc: Likewise.
	* testsuite/23_containers/inplace_vector/cons/1.cc: Likewise.
	* testsuite/23_containers/inplace_vector/cons/from_range.cc: Likewise.
	* testsuite/23_containers/inplace_vector/modifiers/single_insert.cc:
	Likewise.
	* testsuite/23_containers/inplace_vector/modifiers/assign.cc:
	Likewise.
	* testsuite/23_containers/inplace_vector/modifiers/multi_insert.cc:
	Likewise.
	* libsupc++/new: Include <bits/new_except.h>.
	(std::bad_alloc, std::bad_array_new_length): Move defintion to
	<bits/new_except.h>.
libgomp/
	* omp.h.in: Include <bits/new_throw.h> instead of
	<bits/functexcept.h>.
gcc/testsuite/
	* g++.dg/tree-ssa/pr110819.C: Guard scan-tree-dump-not delete on
	c++23_down and add comment explaining why C++26 fails that.
	* g++.dg/tree-ssa/pr96945.C: Likewise.
	* g++.dg/tree-ssa/pr109442.C: Likewise.
	* g++.dg/tree-ssa/pr116868.C: Likewise.
	* g++.dg/tree-ssa/pr58483.C: Likewise.
2025-12-11 19:54:44 +01:00
Jason Merrill 6fb589cd4b c++, libstdc++: add "modules" std to testsuite
Since modules aren't enabled by default at any -std= yet, let's add a
pseudo-std for them, like we already have for -fimplicit-constexpr.  And
also add to target-supports so dg lines can check { target modules }.

To run library tests with modules we need to compile them; this patch makes
us build a header unit for bits/stdc++.h and module interface units for std
and std.compat, if v3_std_list includes "modules".  So this doesn't happen
by default without a further change.

libstdc++-v3/ChangeLog:

	* testsuite/Makefile.am (CLEANFILES): Add gcm.cache.
	* testsuite/Makefile.in: Regenerate.
	* testsuite/lib/dg-options.exp (add_options_for_no_pch): Also add
	-fno-modules.
	* testsuite/lib/libstdc++.exp (v3_std_list): Handle "modules" std.
	(v3_modules_std): New global.
	(v3-build_support): Build gcms for bits/stdc++.h, std, and
	std.compat.

gcc/testsuite/ChangeLog:

	* lib/g++-dg.exp: Handle "modules" std.
	* lib/target-supports.exp (check_effective_target_modules): New.
2025-12-11 23:31:18 +07:00
Yuao Ma bf9dd44a97 libstdc++: constexpr flat_set and flat_multiset
This patch makes flat_set and flat_multiset constexpr as part of P3372R3.

libstdc++-v3/ChangeLog:

	* include/bits/version.def: Add FTM.
	* include/bits/version.h: Regenerate.
	* include/std/flat_set: Add constexpr.
	* testsuite/23_containers/flat_multiset/1.cc: Add constexpr test.
	* testsuite/23_containers/flat_set/1.cc: Add constexpr test.
2025-12-11 22:24:42 +08:00
Luc Grosheintz f5d72af36d libstdc++: Implement submdspan_mapping for layout_right_padded. [PR110352]
Implements submdspan for layout_right_padded as described in P3663.

	PR libstdc++/110352

libstdc++-v3/ChangeLog:

	* include/std/mdspan
	(__mdspan::_SubMdspanMapping<_LayoutSide::__right, true>): Define.
	(layout_right_padded::submdspan_mapping): New friend function.
	* testsuite/23_containers/mdspan/submdspan/selections/right_padded.cc:
	Instantiate tests for layout_right_padded.
	* testsuite/23_containers/mdspan/submdspan/submdspan_mapping.cc:
	Ditto.

Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
Signed-off-by: Luc Grosheintz <luc.grosheintz@gmail.com>
2025-12-09 17:12:58 +01:00
Luc Grosheintz 558ab7b638 libstdc++: Implement submdspan_mapping for layout_left_padded. [PR110352]
Implements submdspan for layout_left_padded as described in P3663.

	PR libstdc++/110352

libstdc++-v3/ChangeLog:

	* include/std/mdspan (__mdspan::__is_padded_mapping): Define.
	(__mdspan::_SubMdspanMapping): Add _Padded template parameter.
	(__mdspan::_SubMdspanMapping<_LayoutSide::__left, true>): Define.
	(__mdspan::__submdspan_mapping_impl): Updated _Trait alias.
	(layout_left_padded::submdspan_mapping): New friend method.
	* testsuite/23_containers/mdspan/layout_traits.h
	(LayoutTraits::layout_same_padded): New template type alias.
	* testsuite/23_containers/mdspan/submdspan/selections/left_padded.cc:
	Instantiate tests for layout_left_padded.
	* testsuite/23_containers/mdspan/submdspan/submdspan_mapping.cc:
	Ditto.

Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
Signed-off-by: Luc Grosheintz <luc.grosheintz@gmail.com>
2025-12-09 17:08:01 +01:00
Luc Grosheintz 57d53be024 libstdc++: Implement submdspan_mapping for layout_stride. [PR110352]
Add submdspan_mapping for layout_stride as in P3663.

	PR libstdc++/110352

libstdc++-v3/ChangeLog:

	* include/std/mdspan (layout_stride::mapping::submdspan_mapping): New
	friend function.
	* testsuite/23_containers/mdspan/submdspan/selections/stride.cc:
	Instantiate tests for layout_stride.
	* testsuite/23_containers/mdspan/submdspan/submdspan_neg.cc:
	Ditto.
	* testsuite/23_containers/mdspan/submdspan/submdspan_mapping.cc:
	Add tests for layout_stride.

Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
Signed-off-by: Luc Grosheintz <luc.grosheintz@gmail.com>
2025-12-09 13:49:32 +01:00
Luc Grosheintz c1c5ada671 libstdc++: Implement submdspan_mapping for layout_right. [PR110352]
Adds submdspan_mapping for layout_right as described in P3663.

	PR libstdc++/110352

libstdc++-v3/ChangeLog:

	* include/std/mdspan
	(__mdspan::_SubMdspanMapping<_LayoutSide::__right>): Define.
	(layout_right::mapping::submdspan_mapping): New friend function.
	* testsuite/23_containers/mdspan/submdspan/selections/right.cc:
	Instantiate tests for layout_right.
	* testsuite/23_containers/mdspan/submdspan/submdspan_mapping.cc:
	Ditto.
	* testsuite/23_containers/mdspan/submdspan/submdspan_neg.cc:
	Ditto.

Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
Signed-off-by: Luc Grosheintz <luc.grosheintz@gmail.com>
2025-12-09 13:46:36 +01:00
Luc Grosheintz ead579d3c5 libstdc++: Implement submdspan and submdspan_mapping for layout_left. [PR110352]
Implements `submdspan` and `submdspan_mapping` for layout_left as
described in P3663 (Future proofing mdspan).

When computing the offset of the submdspan, one must check that the
lower bound of the slice range isn't out-of-range. There's a few
cases when the lower bound is never out-of-range:

  - full_extent and exts.extent(k) != 0,
  - collapsing slice types.

If those conditions are known to hold, no checks are generated.

Similarly, if all slices are full_extent, there's no need to call
mapping(0,...,0) for standardized mappings.

The implementation prepares to use the symmetry between layout_left and
layout_right and introduces concepts like a "layout side", i.e. left,
right or unknown/strided.

The tests use an iterator to replace nested for-loops. Which also makes
it easier to write the core test logic in a rank-independent manner.

	PR libstdc++/110352

libstdc++-v3/ChangeLog:

	* include/std/mdspan (__mdspan::__is_submdspan_mapping_result)
	(__mdspan::__submdspan_mapping_result, __mdspan::__fwd_prod)
	(__mdspan::__acceptable_slice_type, __mdspan::__slice_begin)
	(__mdspan::__suboffset, __mdspan::_LayoutSide, __mdspan::__mapping_side)
	(__mdspan::_StridesTrait, __mdspan::__substrides_generic)
	(__mdspan::__substrides_standardized, __mdspan::__substrides)
	(__mdspan::__is_unit_stride_slice, __mdspan::_SliceKind)
	(__mdspan::__make_slice_kind, __mdspan::__make_slice_kind_array)
	(__mdspan::__is_block, __mdspan::__padded_block_begin_generic)
	(__mdspan::__padded_block_begin, __mpdspan::_SubMdspanMapping)
	(__mdspan::__submdspan_mapping_impl): Define.
	(__mdspan::__dynamic_slice_extent, __mdspan::__static_slice_extent)
	(__mdspan::__subextents): Move earlier in the file.
	(layout_left::mapping::submdspan_mapping, __mdspan::__sliceable_mapping)
	(__mdspan::__submapping, submdspan): Define.
	* src/c++23/std.cc.in: Add submdspan.
	* testsuite/23_containers/mdspan/submdspan/generic.cc: New test.
	* testsuite/23_containers/mdspan/submdspan/selections/left.cc:
	Instantiate selection tests for layout_left.
	* testsuite/23_containers/mdspan/submdspan/selections/testcases.h: Generic
	tests different selections.
	* testsuite/23_containers/mdspan/submdspan/submdspan_mapping.cc: New test.
	* testsuite/23_containers/mdspan/submdspan/submdspan_neg.cc: New test.

Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
Signed-off-by: Luc Grosheintz <luc.grosheintz@gmail.com>
2025-12-09 13:44:06 +01:00
Jonathan Wakely 03562c1e02
libstdc++: Implement P2404R3 relaxations to comparable_with concepts [PR122946]
This implements the C++23 proposal P2404R3 "Move-only types for
equality_comparable_with, totally_ordered_with, and
three_way_comparable_with". As agreed with the maintainers of libc++ and
MSVC STL, we treat this as a DR for C++20. It allows reasonable code to
compile which wasn't originally allowed in C++20, and only affects some
obscure subsumption cases for valid C++20 code.

libstdc++-v3/ChangeLog:

	PR libstdc++/122946
	* include/bits/version.def (concepts): Set value to 202207.
	* include/bits/version.h: Regenerate.
	* include/std/concepts (__comparison_common_type_with_impl)
	(__comparison_common_type_with): New helper concepts.
	(equality_comparable_with): Use __comparison_common_type_with.
	* libsupc++/compare (three_way_comparable_with): Likewise.
	(__glibcxx_want_concepts): Define to get __cpp_lib_concepts
	here.
	* testsuite/std/concepts/concepts.compare/move_only.cc: New
	test.

Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-12-08 18:55:02 +00:00
Jonathan Wakely ea42e28cbc
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 <ppalka@redhat.com>
2025-12-08 18:55:02 +00:00
Tomasz Kamiński 09bece00d0 libstdc++: Refactor _Variadic_union so _Unitialized<T, false> is not needed [PR112591].
The changes the _Variadic_union implementation, in a way that the
_Unitialized<T, false> partial specialization for non-trivial types is not
necessary.

This is simply done by separating the specialization for __trivially_destructible
being true and false, and for the later defining an empty destructor (similarly
as it was done using concepts).

We also reduce the number of specialization of _Variadic_union, so specialization
(int, int) is reused by (string, int, int) and (int, int). This is done by
initialization __trivially_destructible with conjunction of
is_trivially_destructible_v for remaining components. This is only necessary
for non-trivial (false) specialization, as if both _First and _Rest... are
trivially destructible, then _Rest must also be.

The above change does not regress the fix r14-7259-g2d55d94e5df389 for
template depth, and both before and after the change template depth is 266.
I have added dg-options to the 87619.cc to catch future regressions.

This also add test for PR112591.

	PR libstdc++/112591

libstdc++-v3/ChangeLog:

	* include/std/variant (_Variadic_union): Separate specializations for
	for union of only trivially destructible types (true as first template
	argument). Unconditionally define destructor for _Variadic_union<false,
	_First, _Rest...>.
	* testsuite/20_util/variant/87619.cc: Add limit for the template depth.
	* testsuite/20_util/variant/112591.cc: New test.

Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-12-08 13:20:35 +01:00
Patrick Palka 83aab2f736 libstdc++: Use deducing this in std::bind when available [PR80564]
Implement the forwarding performed by std::bind via deducing this when
available, instead of needing 4 operator() overloads.  Using deducing
this here is more complicated than in other standard call wrappers
because std::bind is not really "perfect forwarding": it doesn't
consider value category, and along with const-ness it also forwards
volatile-ness (until C++20).

The old implementation suffers from the same problem that other
pre-C++23 SFINAE-friendly call wrappers have which is solved by using
deducing this (see p5.5 of the deducing this paper P0847R7).

	PR libstdc++/80564

libstdc++-v3/ChangeLog:

	* include/std/functional (__cv_like): New.
	(_Bind::_Res_type): Don't define when not needed.
	(_Bind::__dependent): Likewise.
	(_Bind::_Res_type_cv): Likewise.
	(_Bind::operator()) [_GLIBCXX_EXPLICIT_THIS_PARAMETER]:
	Define as two instead of four overloads using deducing
	this.
	* testsuite/20_util/bind/cv_quals_2.cc: Ignore SFINAE
	diagnostics inside headers.
	* testsuite/20_util/bind/ref_neg.cc: Likewise.
	* testsuite/20_util/bind/80564.cc: New test.

Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
2025-12-05 21:09:34 -05:00
Patrick Palka d1ac432c5a libstdc++: Implement rest of P2655R3 common_reference of reference_wrapper
PR libstdc++/120446

libstdc++-v3/ChangeLog:

	* include/bits/refwrap.h (__detail::__is_ref_wrapper):
	Define as per P2655R3 for C++20.
	(__detail::__ref_wrap_common_reference_exists_with): Likewise.
	(basic_common_reference): Define partial specializations using
	the above as per P2655R3 for C++20.
	* include/bits/version.def (common_reference_wrapper): New.
	* include/bits/version.h: Regenerate.
	* include/std/functional (__glibcxx_want_common_reference_wrapper):
	Define.
	* testsuite/20_util/reference_wrapper/p2655r3.cc: New test.

Co-authored-by: Tomasz Kamiński <tkaminsk@redhat.com>
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
2025-12-05 13:43:40 -05:00
Patrick Palka a9fd651fbb libstdc++: Implement P2655R3 changes to common_reference bullet 1
We implement this paper as a DR against C++20 (as do MSVC and libc++).

	PR libstdc++/120446

libstdc++-v3/ChangeLog:

	* include/bits/version.def (common_reference): New.
	* include/bits/version.h: Regenerate.
	* include/std/type_traits (__glibcxx_want_common_reference):
	Define.
	(__common_reference_impl<T1, T2, 1>): Add pointer convertibility
	constraints as per P2655R3.
	* testsuite/20_util/common_reference/p2655r3.cc: New test.

Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
2025-12-05 13:43:29 -05:00
Patrick Palka 5d5eeb3709 libstdc++/testsuite: Fix malformed dg-error directive
libstdc++-v3/ChangeLog:

	* testsuite/20_util/function_objects/bind_front/111327.cc:
	Add missing space before } ending a dg-error directive.
2025-12-05 12:48:44 -05:00
Patrick Palka 5a2a527b26 libstdc++: Use deducing this in range adaptors even in C++20 [PR111550]
Use deducing this to implement perfect forwarding even in C++20 mode
by using the _GLIBCXX_EXPLICIT_THIS_PARAMETER internal FTM instead of
the standard __cpp_explicit_this_parameter.  This fixes the original
testcase from this PR even in C++20 mode.

	PR libstdc++/111550

libstdc++-v3/ChangeLog:

	* include/std/ranges (views::__adaptor::_Partial::operator())
	[_GLIBCXX_EXPLICIT_THIS_PARAMETER]: Also use deducing this
	in C++20 mode when possible.
	(views::__adaptor::_Pipe::Operator())
	[_GLIBCXX_EXPLICIT_THIS_PARAMETER]: Likewise.
	* testsuite/std/ranges/adaptors/take.cc (test07): New test.

Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
2025-12-05 12:16:30 -05:00
Patrick Palka b212314667 libstdc++: Use deducing this in std::bind_front even in C++20 [PR111327]
PR libstdc++/111327

libstdc++-v3/ChangeLog:

	* include/bits/binders.h (_Binder::operator())
	[_GLIBCXX_EXPLICIT_THIS_PARAMETER]: Also use deducing this in
	C++20 mode when possible.
	* testsuite/20_util/function_objects/bind_front/111327.cc:
	Expect error inside header even in C++20 mode.

Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
2025-12-05 12:15:08 -05:00
Patrick Palka 756e32a160 libstdc++: Use deducing this in std::not_fn when available [PR111327]
Implement the perfect forwarding required by std::not_fn using deducing
this when available, instead of needing 8 operator() overloads.  This
also fixes Jiang An's test from this PR which would be messy to fix in
the old implementation.

	PR libstdc++/111327

libstdc++-v3/ChangeLog:

	* include/std/functional (_Not_fn::operator())
	[_GLIBCXX_EXPLICIT_THIS_PARAMETER]: Define as a single
	overload using deducing this.
	* testsuite/20_util/function_objects/not_fn/111327.cc: Extend test.

Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
2025-12-05 12:14:23 -05:00
François Dumont bbe0599297
libstdc++: Fix std::erase_if behavior for std::__debug::deque
std::erase and std::erase_if are broken for users directly referencing
__gnu_debug::deque in their code that is to say without activating the
_GLIBCXX_DEBUG mode. The iterators potentially invalidated by the erase
operations are not detected by the __gnu_debug::deque container and so
won't be reported as invalidated.

We need explicit std::erase and std::erase_if implementations for
std::__debug::deque which will work also when _GLIBCXX_DEBUG mode is
activated.

libstdc++-v3/ChangeLog:

	* include/debug/deque
	(std::erase_if<>(std::__debug::deque<>&, _Pred)): New.
	(std::erase<>(std::__debug::deque<>&, const _Up&)): New.
	* include/std/deque (std::erase_if(std::deque<>&, _Pred)): Remove
	_GLIBCXX_DEBUG code.
	* testsuite/23_containers/deque/debug/erase.cc: New test case.
	* testsuite/23_containers/deque/debug/invalidation/erase.cc: New test case.
2025-12-04 22:04:00 +01:00
Luc Grosheintz e0dd9c0a60 libstdc++: Convertibility of rank == 0 layouts, LWG4272.
LWG4272 proposes to add a condition for convertibility from
layout_stride::mapping to other mappings. New conversion requires
both that rank == 0 and that the extent types are convertible.

LWG4272 also proposes to add the same condition for conversion of
padded layouts, i.e. in addition to the condition on the padding
value, the extent types must be convertible.

libstdc++-v3/ChangeLog:

	* include/std/mdspan (layout_left): Apply LWG4272.
	(layout_right, layout_left_padded, layout_right_padded): Ditto.
	* testsuite/23_containers/mdspan/layouts/ctors.cc: Add
	test to check ctor uniformity at rank == 0. Update test
	for new behavior.
	* testsuite/23_containers/mdspan/layouts/padded.cc: Update test
	for new behavior.

Co-authored-by: Tomasz Kamiński <tkaminsk@redhat.com>
Signed-off-by: Luc Grosheintz <luc.grosheintz@gmail.com>
Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-12-04 13:57:38 +01:00
Yuao Ma 6123cb8bfc libstdc++: implement P3044R2 - sub-string_view from string (string part)
libstdc++-v3/ChangeLog:

	* include/bits/basic_string.h: Add subview.
	* include/bits/cow_string.h: Add subview.
	* include/std/string: Add FTM.
	* testsuite/21_strings/basic_string/operations/subview/char.cc: New test.
	* testsuite/21_strings/basic_string/operations/subview/wchar_t.cc: New test.
2025-12-03 23:56:32 +08:00
Yuao Ma 475933164f libstdc++: implement P3044R2 - sub-string_view from string (string_view part)
libstdc++-v3/ChangeLog:

	* include/bits/version.def: Add string_subview FTM.
	* include/bits/version.h: Regenerate.
	* include/std/string_view: Add subview.
	* testsuite/21_strings/basic_string_view/operations/subview/char.cc: New test.
	* testsuite/21_strings/basic_string_view/operations/subview/wchar_t.cc: New test.
2025-12-03 23:55:06 +08:00
François Dumont 8a2e6590cc
libstdc++: [_GLIBCXX_DEBUG] Implement std::__debug::inplace_vector
Add _GLIBCXX_DEBUG std::inplace_vector implementation.

libstdc++-v3/ChangeLog:

	* include/Makefile.am (debug_headers): Add inplace_vector.
	* include/Makefile.in: Regenerate.
	* include/debug/functions.h (__check_valid_range): Add C++20 constexpr.
	* include/debug/helper_functions.h (__valid_range): Likewise.
	* include/debug/inplace_vector: New.
	* include/debug/safe_base.h (~_Safe_sequence_base()): Add C++11 noexcept.
	(_Safe_sequence_base::operator=(const _Safe_sequence_base&)): New.
	(_Safe_sequence_base::operator=(_Safe_sequence_base&&)): New.
	(_Safe_sequence_base::_M_invalidate_all): Add C++20 constexpr.
	* include/debug/safe_container.h
	(_Safe_container<>::operator=(const _Safe_container<>&)): Implement using
	_Safe_sequence_base same operator.
	* include/debug/safe_iterator.h (__valid_range): Add C++20 constexpr.
	* include/debug/safe_sequence.h
	(_Not_equal_to(const _Type&)): Add C++20 constexpr.
	(_Equal_to(const _Type&)): Add C++20 constexpr.
	(_After_nth_from(const difference_type&, const _Iterator&)): Add C++20 constexpr.
	(_Safe_sequence<>::_M_invalidate_if): Add C++20 constexpr.
	(_Safe_node_sequence::operator=(const _Safe_node_sequence&)): New.
	(_Safe_node_sequence::operator=(_Safe_node_sequence&&)): New.
	(_Safe_node_sequence<>::_M_invalidate_all()): Add C++20 constexpr.
	* include/debug/safe_sequence.tcc
	(_Safe_sequence<>::_M_invalidate_if): Add C++20 constexpr.
	* include/std/inplace_vector [_GLIBCXX_DEBUG](std::inplace_vector<>): Move
	implementation into __cxx1998 namespace.
	(erase, erase_if): Limit to non-debug inplace_vector<>, cleanup code.
	[_GLIBCXX_DEBUG]: Add include <debug/inplace_vector>.
	* testsuite/23_containers/inplace_vector/cons/1.cc: Adapt, skip several
	is_trivially_xxx checks when in _GLIBCXX_DEBUG mode.
	* testsuite/23_containers/inplace_vector/copy.cc: Likewise.
	* testsuite/23_containers/inplace_vector/move.cc: Likewise.
	* testsuite/23_containers/inplace_vector/debug/assign1_neg.cc: New test case.
	* testsuite/23_containers/inplace_vector/debug/assign2_neg.cc: New test case.
	* testsuite/23_containers/inplace_vector/debug/assign3_neg.cc: New test case.
	* testsuite/23_containers/inplace_vector/debug/assign4_backtrace_neg.cc: New test case.
	* testsuite/23_containers/inplace_vector/debug/assign4_neg.cc: New test case.
	* testsuite/23_containers/inplace_vector/debug/construct1_neg.cc: New test case.
	* testsuite/23_containers/inplace_vector/debug/construct2_neg.cc: New test case.
	* testsuite/23_containers/inplace_vector/debug/construct3_neg.cc: New test case.
	* testsuite/23_containers/inplace_vector/debug/construct4_neg.cc: New test case.
	* testsuite/23_containers/inplace_vector/debug/debug_functions.cc: New test case.
	* testsuite/23_containers/inplace_vector/debug/erase.cc: New test case.
	* testsuite/23_containers/inplace_vector/debug/insert1_neg.cc: New test case.
	* testsuite/23_containers/inplace_vector/debug/insert2_neg.cc: New test case.
	* testsuite/23_containers/inplace_vector/debug/insert3_neg.cc: New test case.
	* testsuite/23_containers/inplace_vector/debug/insert4_neg.cc: New test case.
	* testsuite/23_containers/inplace_vector/debug/insert5_neg.cc: New test case.
	* testsuite/23_containers/inplace_vector/debug/insert7_neg.cc: New test case.
	* testsuite/23_containers/inplace_vector/debug/invalidation/1.cc: New test case.
	* testsuite/23_containers/inplace_vector/debug/invalidation/2.cc: New test case.
	* testsuite/23_containers/inplace_vector/debug/invalidation/3.cc: New test case.
	* testsuite/23_containers/inplace_vector/debug/invalidation/4.cc: New test case.
	* testsuite/23_containers/inplace_vector/debug/invalidation/append_range.cc:
	New test case.
	* testsuite/23_containers/inplace_vector/debug/invalidation/erase.cc:
	New test case.
	* testsuite/23_containers/inplace_vector/debug/invalidation/pop_back.cc:
	New test case.
	* testsuite/23_containers/inplace_vector/debug/invalidation/push_back.cc:
	New test case.
	* testsuite/23_containers/inplace_vector/debug/invalidation/swap.cc:
	New test case.
	* testsuite/23_containers/inplace_vector/debug/invalidation/try_append_range.cc:
	New test case.
	* testsuite/23_containers/inplace_vector/debug/invalidation/try_emplace_back.cc:
	New test case.
	* testsuite/23_containers/inplace_vector/debug/invalidation/try_push_back.cc:
	New test case.
	* testsuite/23_containers/inplace_vector/debug/invalidation/unchecked_emplace_back.cc:
	New test case.
	* testsuite/util/debug/checks.h: Avoid using _GLIBCXX_DEBUG containers in test
	implementations.
2025-12-03 06:56:27 +01:00
Luc Grosheintz c915bfc0f7 libstdc++: Implement submdspan_extents. [PR110352]
Implement submdspan_extents as described in P3663 and adds it to the std
module.

	PR libstdc++/110352

libstdc++-v3/ChangeLog:

	* include/std/mdspan (submdspan_extents): New function.
	* src/c++23/std.cc.in: Add submdspan_extents.
	* testsuite/23_containers/mdspan/int_like.h: Add StructuralInt.
	* testsuite/23_containers/mdspan/submdspan/submdspan_extents.cc: New test.
	* testsuite/23_containers/mdspan/submdspan/submdspan_extents_neg.cc: New test.

Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
Signed-off-by: Luc Grosheintz <luc.grosheintz@gmail.com>
2025-12-02 15:40:59 +01:00
Luc Grosheintz f6f9aec0c6 libstdc++: Implement submdspan_canonicalize_slices. [PR110352]
Implements submdspan_canonicalize_slices as described in P3663 and adds
it to the std module.

There's one deviation from the standard. Doesn't (under all
circumstances) require:

  0 <= begin[k] <= end[k] <= exts.extent(k)

where the k-th slice range is [begin[k], end[k]). Instead, it requires
that the k-th slice ranges is contained in the k-th extent interval. If
the slice range is empty, then that condition is always satisfied, even if

  begin[k] == end[k] > exts.extent(k)

The deviation is that we enforce the above inequality through
preconditions. This is analogous to what the standard requires if
begin[k] is a constant wrapper.

	PR libstdc++/110352

libstdc++-v3/ChangeLog:

	* include/std/mdspan (submdspan_canonicalize_slices): New
	function.
	* src/c++23/std.cc.in (submdspan_canonicalize_slices): Add.
	* testsuite/23_containers/mdspan/submdspan/submdspan_canonicalize_slices.cc: New test.
	* testsuite/23_containers/mdspan/submdspan/submdspan_canonicalize_slices_neg.cc: New test.

Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
Signed-off-by: Luc Grosheintz <luc.grosheintz@gmail.com>
2025-12-02 15:39:23 +01:00
Patrick Palka 3e02f86cd1 libstdc++: Inconsistent const in flat_map's value_type [PR122921]
flat_map's value_type is pair<key_type, mapped_type>, which we correctly
define within the container but incorrectly within the iterator.

	PR libstdc++/122921

libstdc++-v3/ChangeLog:

	* include/std/flat_map (_Flat_map_impl::_Iterator::value_type):
	Remove const from key_type to make consistent with the
	container's value_type.
	* testsuite/23_containers/flat_map/1.cc (test09): New test.
	* testsuite/23_containers/flat_multimap/1.cc (test09): New test.

Reported-by: Vincent X
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
2025-12-01 17:08:01 -05:00
Patrick Palka 2d3142c009 libstdc++: Correctly implement LWG 3946 changes to const_iterator_t [PR122842]
LWG 3946 made const_iterator_t/sentinel_t agree with ranges::cbegin/cend
by defining the aliases in terms of the CPOs, but I defined it the other
way around in an incorrect way that made the aliases not consider
range-ness of const T via __possibly_const_range.  This patch
reimplements the proposed resolution in a more obviously correct way,
mirroring the wording.

	PR libstdc++/122842

libstdc++-v3/ChangeLog:

	* include/bits/ranges_base.h (__access:_CBegin): Define in
	terms of const_iterator directly, not const_iterator_t.
	(__access::_CEnd): Likewise in terms of const_sentinel vs
	const_sentinel_t.
	(const_iterator_t): Move down definition and define in terms
	of ranges::cbegin as per LWG 3946.
	(const_sentinel_t): Likewise in terms of ranges::cend.
	* testsuite/24_iterators/const_iterator/1.cc (test02): Correct
	test for int[], std::array and std::vector.  Also test
	std::string.

Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
2025-11-28 15:38:04 -05:00
Jonathan Wakely 7f355b11db
libstdc++: Fix nodiscard warnings in performance tests
libstdc++-v3/ChangeLog:

	* testsuite/performance/23_containers/sort_search/list.cc: Cast
	results to void to suppress -Wunused-result warnings from
	nodiscard functions.
	* testsuite/performance/25_algorithms/equal_deque_iterators.cc:
	Likewise.
	* testsuite/performance/25_algorithms/search_n.cc: Likewise.
2025-11-27 15:55:52 +00:00
Jonathan Wakely 37e881b316
libstdc++: Fix comment typo in testsuite/Makefile
libstdc++-v3/ChangeLog:

	* testsuite/Makefile.am: Fix typo in comment.
	* testsuite/Makefile.in: Regenerate.
2025-11-27 15:55:52 +00:00
Jonathan Wakely 89552346e3
libstdc++: Fix std::counting_semaphore<> default max value
My recent (uncommitted) changes to support a 64-bit __platform_wait_t
for FreeBSD and Darwin revealed a problem in std::counting_semaphore.
When the default template argument is used and __platform_wait_t is a
64-bit type, the numeric_limits<__platform_wait_t>::max() value doesn't
fit in ptrdiff_t and so we get ptrdiff_t(-1), which fails a
static_assert in the class body.

The solution is to cap the value to PTRDIFF_MAX instead of allowing it
to go negative.

libstdc++-v3/ChangeLog:

	* include/bits/semaphore_base.h (__platform_semaphore::_S_max):
	Limit to PTRDIFF_MAX to avoid negative values.
	* testsuite/30_threads/semaphore/least_max_value.cc: New test.

Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-11-27 09:43:24 +00:00
Tomasz Kamiński 9ed821d107 libstdc++: Optimize functor storage for transform views iterators.
The iterators for transform views (views::transform, views::zip_transform,
and views::adjacent_transform) now store a function handle from (from
__detail::__func_handle namespace) instead of a pointer to the view object
(_M_parent).

The following handle templates are defined in __func_handle namespace:
* _Inplace: Used if the functor is a function pointer or standard operator
  wrapper (std::less<>, etc). The functor is  stored directly in __func_handle
  and the iterator. This avoid double indirection through a pointer to the
  function pointer, and reduce the size of iterator for std wrappers.
* _InplaceMemPtr: Used for data or function member pointers. This behaves
  similarly to _Inplace, but uses __invoke for invocations.
* _StaticCall: Used if the operator() selected by overload resolution
  for the iterator reference is static. In this case, __func_handle is empty,
  reducing the iterator size.
* _ViaPointer: Used for all remaining cases. __func_handle stores a pointer
  to the functor object stored within the view. Only for this template the
  cv-qualification of the functor template parameter (_Fn) relevant, and
  specialization for both const and mutable types are generated.

As a consequence of these changes, the iterators of transform views no longer
depend on the view object when handle other than __func_handle::_ViaPointer
is used. The corresponding views are not marked as borrowed_range, as they
are not marked as such in the standard.

The use of _Inplace is limited to only set of pre-C++20 standard functors,
as for once introduced later operator() was retroactively made static.
We do not extent to to any empty fuctor, as it's oprator may still depend on
value of this pointer as illustrated by test12 in
std/ranges/adaptors/transform.cc test file.

Storing function member pointers directly increases the iterator size in that
specific case, but this is deemed beneficial for consistent treatment of
function and data member pointers.

To avoid materializing temporaries when the underlying iterator(s) return a
prvalue, the _M_call_deref and _M_call_subscript methods of handles are
defined to accept the iterator(s), which are then dereferenced as arguments
of the functor.

Using _Fd::operator()(*__iters...) inside requires expression is only
supported since clang-20, however at the point of GCC-16 release, clang-22
should be already available.

libstdc++-v3/ChangeLog:

	* include/std/ranges (__detail::__is_std_op_template)
	(__detail::__is_std_op_wrapper, __func_handle::_Inplace)
	(__func_handle::_InplaceMemPtr, __func_handle::_ViaPointer)
	(__func_handle::_StaticCall, __detail::__func_handle_t): Define.
	(transform_view::_Iterator, zip_transform_view::_Iterator)
	(adjacent_tranform_view::_Iterator): Replace pointer to view
	(_M_parent) with pointer to functor (_M_fun). Update constructors
	to construct _M_fun from *__parent->_M_fun. Define operator* and
	operator[] in terms of _M_call_deref and _M_call_subscript.
	* testsuite/std/ranges/adaptors/adjacent_transform/1.cc: New tests.
	* testsuite/std/ranges/adaptors/transform.cc: New tests.
	* testsuite/std/ranges/zip_transform/1.cc: New tests.

Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
Reviewed-by: Patrick Palka <ppalka@redhat.com>
Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-11-26 12:06:50 +01:00
Tomasz Kamiński 1c9d93bfcd libstdc++: Hashing support for chrono value classes [PR110357]
This patch implements P2592R3 Hashing support for std::chrono value classes.

To avoid the know issues with current hashing of integer types (see PR104945),
we use chrono::__int_hash function that hash the bytes of representation,
instead of hash<T>, as the later simply cast to value. Currently _Hash_impl
it used, but we should consider replacing it (see PR55815) before C++26 ABI
is made stable. The function is declared inside <chrono> header and chrono
namespace, to make sure that only chrono components would be affected by
such change. Finally, chrono::__int_hash is made variadic, to support
combining hashes of multiple integers.

To reduce the number of calls to hasher (defined out of line), the calendar
types are packed into single unsigned integer value. This is done by
chrono::__hash helper, that calls:
* chrono::__as_int to cast the value of single component, to unsigned integer
  with size matching the one used by internal representation: unsigned short
  for year/weekday_indexed, and unsigned char in all other cases,
* chrono::__pack_ints to pack integers (if more than one) into single integer
  by performing bit shift operations,
* chrono::__int_hash to hash the value produced by above.

Hashing of duration, time_point, and zoned_time only hashes the value and
ignores any difference in the period, i.e. hashes of nanoseconds(2) and
seconds(2) are the same. This does not affect the usages inside unordered
containers, as the arguments are converted to key type first. To address
that period::num and period::den could be included in the hash, however
such approach will not make hashes of equal durations (2000ms, 2s) equal,
so they would remain unusable for precomputed hashes. In consequence,
including period in hash, would only increase runtime cost, withou any
clear benefits.

Futhermore,  chrono::__int_hash is used when the duration representation
is integral type, and for other types (floating point due special handling
of +/-0.0 and user defined types) we delegate to hash specialization.
This is automatically picked up by time_point, that delegates to hasher
of duration. Similarly for leap_second that is specified to use integer
durations, we simply hash representations of date() and value(). Finally
zoned_time in addition to handling integer durations as described above,
we also use __int_hash for const time_zone* (if used), as hash<T*> have
similar problems as hash specialization for integers. This is limited
only to _TimeZonePtr being const time_zone* (default), as user can define
hash specializations for raw pointers to they zones.

As accessing the representation for duration requires calling count()
method that returns a copy of representation by value, the noexcept
specification of the hasher needs to take into consideration copy
constructor of duration. Similar reasoning applies for time_since_epoch
for time_points, and get_sys_time, get_time_zone for zoned_time.
For all this cases we use internal __is_nothrow_copy_hashable concept.

Finally support for zoned_time is provided only for CXX11 string ABI,
__cpp_lib_chrono feature test macro cannot be bumped if COW string are used.
To indicate presence of hasher for remaining types this patch also bumps
the internal __glibcxx_chrono_cxx20 macro, and uses it as guard to new
features.

	PR libstdc++/110357

libstdc++-v3/ChangeLog:

	* include/bits/version.def (chrono, chrono_cxx20): Bump values.
	* include/bits/version.h: Regenerate.
	* include/std/chrono (__is_nothrow_copy_hashable)
	(chrono::__pack_ints, chrono::__as_int, chrono::__int_hash)
	(chrono::__hash): Define.
	(std::hash): Define partial specialization for duration, time_point,
	and zoned_time, and full specializations for calendar types and
	leap_second.
	(std::__is_fast_hash): Define partial specializations for duration,
	time_point, zoned_time.
	* testsuite/std/time/hash.cc: New test.

Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
Co-authored-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
Signed-off-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
2025-11-26 08:35:48 +01:00
Jonathan Wakely 230dc6e74f
libstdc++: Implement LWG 4370 for std::optional comparisons
This modifies the relational comparisons for std::optional so that they
do not use logical expressions with && or || that involve the
comparisons on the contained values, because x && (*y == *z) might do
the wrong thing if *y == *z does not return bool.

libstdc++-v3/ChangeLog:

	* include/std/optional (operator==, operator!=, operator>)
	(operator>, operator<=, operator>=): Do not use logical
	&& and || with operands of unknown types.
	* testsuite/20_util/optional/relops/lwg4370.cc: New test.

Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-11-24 14:59:07 +00:00
Jonathan Wakely 2ef6875115
libstdc++: Implement LWG 4366 for std::expected comparisons
This modifies the equality comparisons for std::expected so that they do
not use explicit conversions to bool, to match the constraints which are
specified in terms of "convertible to" which implies implicitly
convertible. As a result of those changes, we cannot use logical
expressions with && or || that involve comparisons of the contained
values, because x && (*y == *z) might do the wrong thing if *y == *z
does not return bool.

Also add [[nodiscard]] attributes which were missing.

The new lwg4366.cc testcase is a dg-do run test not dg-do compile,
because the original example won't compile with libstdc++ even after
these fixes. We constrain the std::expected comparison operators with
std::convertible_to<bool> and the pathological Bool type in the issue
doesn't satisfy that concept. So the new test replaces the deleted
explicit conversion oeprator in the issue with one that isn't deleted
but terminates if called. This ensures we don't call it, thus ensuring
that std::expected's comparisons do implicit conversions only.

It's unclear to me whether using the convertible_to concept in
std::expected comparisons is conforming, or if we should switch to an
__implicitly_convertible_to<bool> concept which only uses
std::is_convertible_v<T, bool> and doesn't check for explicit
conversions. That can be addressed separately from this change.

libstdc++-v3/ChangeLog:

	* include/std/expected (operator==): Use implicit conversion to
	bool and do not use logical && and || with operands of unknown
	types. Add nodiscard attributes.
	* testsuite/20_util/expected/equality.cc: Test some missing
	cases which were not covered previously.
	* testsuite/20_util/expected/lwg4366.cc: New test.

Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-11-24 14:59:05 +00:00
Yuao Ma 0d4ab66aaf
libstdc++: Implement P3223R2 Making std::istream::ignore less surprising
libstdc++-v3/ChangeLog:

	* include/std/istream (ignore): Add an overload for char.
	* testsuite/27_io/basic_istream/ignore/char/93672.cc: Adjust
	expected behaviour for C++26 mode.
	* testsuite/27_io/basic_istream/ignore/char/4.cc: New test.

Co-authored-by: Jonathan Wakely <jwakely@redhat.com>
2025-11-21 15:30:50 +00:00
Jonathan Wakely 72afe64d34
libstdc++: Remove no_pch from tests that shouldn't depend on PCH
libstdc++-v3/ChangeLog:

	* testsuite/23_containers/vector/debug/erase.cc: Remove no_pch
	option.
	* testsuite/23_containers/vector/debug/invalidation/erase.cc:
	Likewise.
2025-11-21 15:30:49 +00:00
François Dumont e166a0f5ee
libstdc++: [_GLIBCXX_DEBUG] Fix std::erase_if behavior for __gnu_debug::vector
When using directly __gnu_debug::vector the std::erase_if is called with a
reference to the std::vector base class and so is missing the invalidation
of the iterators implied by this operation.

To fix this provide a std::erase_if overload dedicated to __gnu_debug::vector.
Doing so we can cleanup the implementation dedicated to std::vector from any
_GLIBCXX_DEBUG consideration.

libstdc++-v3/ChangeLog:

	* include/debug/vector (std::erase_if, std::erase): New overloads for
	std::__debug::vector instances.
	* include/std/vector (std::erase_if, std::erase): Make overloads specific
	to normal std::vector implementation.
	* testsuite/23_containers/vector/debug/erase.cc: New test case.
	* testsuite/23_containers/vector/debug/invalidation/erase.cc: New test case.
2025-11-20 19:10:20 +01:00
Luc Grosheintz 828ac566b7 libstdc++: Prepare mdspan-related code for submdspan.
The changes needed for submdspan are:

  * In submdspan related code the user-defined integer-like
    types need to be copy- and move-constructable.

  * The traits for writing tests that work with both left- and right,
    possibly padded, layouts will also be useful for submdspan.
    Therefore, this code is moved up and generalized.

  * Move __offset further up in <mdspan> and fix some formatting
    mistakes.

libstdc++-v3/ChangeLog:

	* include/std/mdspan: Improve formatting and placement.
	* testsuite/23_containers/mdspan/int_like.h: Optionally,
	add move- and copy-ctors.
	* testsuite/23_containers/mdspan/layouts/padded_traits.h: Move to...
	* testsuite/23_containers/mdspan/layout_traits.h: ...here.
	* testsuite/23_containers/mdspan/layouts/ctors.cc: Fix include.
	* testsuite/23_containers/mdspan/layouts/mapping.cc: Ditto.
	* testsuite/23_containers/mdspan/layouts/padded.cc: Ditto.
	* testsuite/23_containers/mdspan/layouts/padded_neg.cc: Ditto.

Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
Signed-off-by: Luc Grosheintz <luc.grosheintz@gmail.com>
2025-11-20 17:21:05 +01:00
Jonathan Wakely ba1e169072
libstdc++: Add constexpr to operator delete in 18_support/headers/new/synopsis.cc
r16-5411-g5294e0a0b40674 made the "placement delete" functions noexcept,
so adjust the header synopsis test.

libstdc++-v3/ChangeLog:

	* testsuite/18_support/headers/new/synopsis.cc: Add constexpr to
	placement delete for C++26 and up.
2025-11-20 16:14:36 +00:00
Mike Crowe a39fec8c74
libstdc++: shared_mutex: Respond consistently to errors and deadlock
Make the shared_mutex::try_lock(), shared_timed_mutex::try_lock_until()
and shared_timed_mutex::try_lock_shared_until() all handle errors from
pthread functions consistently by returning false to indicate that the
lock could not be taken. If _GLIBCXX_ASSERTIONS is defined then
unexpected errors, such as EDEADLK and EINVAL will cause an assertion
failure. If _GLIBCXX_ASSERTIONS is not defined then these functions no
longer ever return true incorrectly indicating that they have taken the
lock.

This removes the previous behaviour of looping on EDEADLK in
try_lock_shared_until() and no longer returns true on EINVAL in all of
these functions. (In theory at least it should not be possible to
trigger EINVAL since 5dba17a3e709859968f939354e6e5e8d796012d3.)

Unfortunately my reading of POSIX is that pthread_rwlock_clockrdlock[1],
pthread_rwlock_timedrdlock pthread_rwlock_clockwrlock[2] and
pthread_rwlock_timedwrlock are allowed to deadlock rather than return
EDEADLK when trying to take a lock a second time from the same
thread. This means that the deadlock tests cannot be enabled by
default. I believe that the tests do work with glibc (2.31 & 2.36) and
with the __shared_mutex_cv implementation though.

[1] https://pubs.opengroup.org/onlinepubs/9799919799/functions/pthread_rwlock_clockrdlock.html
[2] https://pubs.opengroup.org/onlinepubs/9799919799/functions/pthread_rwlock_clockwrlock.html

libstdc++-v3/ChangeLog:

	* include/std/shared_mutex (try_lock, try_lock_until)
	(try_lock_shared_until): Respond consistently to errors and
	deadlocks.
	* testsuite/30_threads/shared_timed_mutex/try_lock_until/116586.cc:
	Test deadlock behaviour if possible.

Signed-off-by: Mike Crowe <mac@mcrowe.com>
2025-11-18 17:13:44 +00:00
Tomasz Kamiński ac45382d0c libstdc++: Fix construction function_ref from nontype<&S::x> and reference_wrapper [PR121858]
To reduce instantiation count, function_ref(nontype<&S::x>, r) previously
reused the invoker from function_ref(nontype<&S::x>, &r). This assumed r was
always a reference to S or a derived class. However, this constructor is also
valid for lvalues (but not rvalues) of reference_wrapper specializations.

This patch fixes this by limiting above optimization only to situations,
when argument is not specialization of reference_wrapper. This is achieved
bu comparing __inv_unwrap<_Td>::type with _Td. We use __inv_unwrap because
unwrap_reference_t does not handle cv-qualified types.

	PR libstdc++/121858

libstdc++-v3/ChangeLog:

	* include/bits/funcref_impl.h
	(function_ref::function_ref(nontype<__fn>, _Up&&)): Handle.
	reference_wrapper.
	* testsuite/20_util/function_ref/call.cc: Call and update
	test05(). Add new test06() for reference_wrapper.

Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-11-18 11:51:16 +01:00
Jonathan Wakely 77278e0292 libstdc++: Fix error reporting for filesystem::rename on Windows [PR122726]
Use the __last_system_error() function and the system_category to
convert the Windows error to a generic one.

libstdc++-v3/ChangeLog:

	PR libstdc++/122726
	* src/filesystem/ops-common.h [_GLIBCXX_FILESYSTEM_IS_WINDOWS]
	(rename): Use __last_system_error to set errno accurately.
	* testsuite/27_io/filesystem/operations/rename.cc: Test
	error_code matches errc::no_such_file_or_directory.
2025-11-17 21:18:24 +00:00
Jason Merrill 359d48af20 libstdc++: testsuite/util adjustments for import std
In my import std testing patch, to work around c++/99000 (include after
import) I move #includes of the util/ headers above the import.  And so I
made some adjustments to those headers to support this: adding some missing
dependencies, making sure that in headers that include both importable and
non-importable headers, at least one importable header comes first to work
with my patch to translate e.g. #include <vector> to import <bits/stdc++.h>.

The testsuite_iterators.h avoids a failure in
20_util/specialized_algorithms/uninitialized_copy/constrained.cc from
including <memory> after this header, with a mysterious "no match for
operator<" between long and difference_type.

libstdc++-v3/ChangeLog:

	* testsuite/util/testsuite_allocator.h: Move importable headers up.
	* testsuite/util/testsuite_common_types.h: Likewise.
	* testsuite/util/testsuite_containers.h: Likewise.
	* testsuite/util/testsuite_error.h: Move includes inside
	include guard.
	* testsuite/util/testsuite_greedy_ops.h: #include <cstddef>.
	* testsuite/util/testsuite_iterators.h: #include <utility>.
	* testsuite/util/testsuite_new_operators.h: #include <cstdlib>.
	* testsuite/util/testsuite_random.h: #include <random>.
2025-11-17 21:26:40 +05:30
Tomasz Kamiński f94a73e0fc libstdc++: Ensure that _Utf_view is always a view.
Previously, _Utf_view accepted any input_range, including reference-to-array
types like char(&)[2], and stored it as the _M_base member. In such cases,
_Utf_view was not assignable, failing the requirements of view concept.

This patch addresses the issue by adding the ranges::view constraint to the
second template parameter of _Utf_view, and for clarity renaming it from
_Range to _View. The constructor is also adjusted to accept its argument
by value (views must be O(1) move-constructible). This prevents implicitly
generated CTAD from deducing a reference type.

This makes _Utf_view consistent with both other standard views and the
wording from P2728R8: Unicode in the Library, Part 1: UTF Transcoding [1].

The explicit CTAD from viewable_range is not defined for _Utf_view because
it depends on views::all_t, views::ref_view, and views::owning_view,
which are declared in <ranges>. Consequently, users must explicitly cast
the argument to a view or specify it as a template parameter.

[1] https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p2728r8.html

libstdc++-v3/ChangeLog:

	* include/bits/unicode.h (_Utf_view): Rename the template parameter
	from _Range to _View and constrain it with ranges::view.
	(_Utf_view::_Utf_view): Accept by value instead of rvalue reference.
	* include/std/format (__format::__write_padded): Replace _Utf_view
	over const char32_t(&)[1] with span<const char32_t, 1>.
	* testsuite/ext/unicode/view.cc: Add checks if specialization
	of _Utf_view satisfy view. Wrap arrays into std::span before
	constructing _Utf_view.

Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-11-14 18:27:01 +01:00
Karpalo Toivonen e7ba197b19
libstdc++: std::bitset<0>("zero") should throw std::invalid_argument [PR121054]
According to the standard the first n characters of a bitset constructor
string need to be checked instead of only N.

libstdc++-v3/ChangeLog:

	PR libstdc++/121054
	* include/std/bitset: Add string check to constructor.
	* testsuite/20_util/bitset/121054.cc: New test.
	* testsuite/20_util/bitset/cons/constexpr_c++23.cc: Fix.

Co-authored-by: Jonathan Wakely <jwakely@redhat.com>
2025-11-14 13:08:52 +00:00
Tomasz Kamiński 71004c2414 libstdc++: Use _Bind_front_t/_Bind_back_t in bind_front<f>/bind_back<f> [PR122032]
This patch changes the implementation of bind_front<f> and bind_back<f> to
return a _Bind_front_t<_Bind_fn_t<f>, ...> and _Bind_back_t<_Bind_fn_t<f>, ...>
respectively, replacing the previous lambda-based implementation. The prior use
of a lambda caused non-conforming behavior with respect to C++23 [func.require]
p8, which requires that bind_front<f>(s), bind_front<f>(move(s)), and
bind_front<f>(as_const(s)) produce the same type.

Additionally, using specialized structs reduces the size of the resulting functor
in certain scenarios (see PR).

For the zero-argument case, the function still returns a _Bind_fn_t<f>. Since this
type is already a perfect forwarding call wrapper, it yields the same result as
_Bind_front_t<_Bind_fn_t<f>>.

A consequence of this change is that the types returned by bind_front<f>(args...)
and bind_back<f>(args...) are no longer structural - they are not required to be
structural by the standard.

	PR libstdc++/122032

libstdc++-v3/ChangeLog:

	* include/std/functional (std::bind_front<f>, std::bind_back<f>):
	Define in terms of _Bind_front_t/_Bind_back_t.
	* testsuite/20_util/function_objects/bind_back/nttp.cc: New tests.
	* testsuite/20_util/function_objects/bind_front/nttp.cc: New tests.

Reviewed-by: Patrick Palka <ppalka@redhat.com>
Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-11-14 12:38:27 +01:00
Jonathan Wakely 9332dfd452
libstdc++: Fix std::forward_list::assign assignable check [PR122661]
The std::is_assignable check should test for assignment to an lvalue,
not an rvalue.

libstdc++-v3/ChangeLog:

	PR libstdc++/122661
	* include/bits/forward_list.h (forward_list::assign(I, I)): Fix
	value category in is_assignable check.
	* testsuite/23_containers/forward_list/modifiers/122661.cc:
	New test.
2025-11-13 14:29:15 +00:00
Xavier Bonaventura bc7a89048e
libstdc++: testsuite: Add csignal missing test for SIG_IGN
SIG_IGN also needs to be defined according to the C++ standard.
This was missing in the test.

	* testsuite/18_support/headers/csignal/macros.cc: Check for
	SIG_IGN.

Signed-off-by: Xavier Bonaventura <xavibonaventura@gmail.com>
2025-11-13 14:29:08 +00:00
Xavier Bonaventura 228433365c
libstdc++: testsuite: Add climits missing LL tests
"long long" and "unsigned long long" min and max macros were added in
C++11, but they were not present in the climits test.

libstdc++-v3/ChangeLog:

	* testsuite/18_support/headers/climits/values.cc: Check for
	LLONG_MIN, LLONG_MAX, and ULLONG_MAX.

Signed-off-by: Xavier Bonaventura <xavibonaventura@gmail.com>
2025-11-13 14:28:53 +00:00
Tomasz Kamiński 35f05d04f3 libstdc++: Optimize handling of optional for views: take, drop, reverse and as_const.
This implements P3913R1: Optimize for std::optional in range adaptors.

Specifically, for an opt of type optional<T> that is a view:
* views::reverse(opt), views::take(opt, n), and views::drop(opt, n) returns
   optional<T>.
* views::as_const(opt), optional<T&> is converted into optional<const T&>.
  optional<T const> is not used in the non-reference case because, such
  type is not move assignable, and thus not a view.

libstdc++-v3/ChangeLog:

	* include/std/optional (__is_optional_ref): Define.
	* include/std/ranges (_Take::operator(), _Drop::operator())
	(_Reverse::operator()):	Handle optional<T> that are view.
	(_AsConst::operator()): Handle optional<T&>.
	* testsuite/20_util/optional/range.cc: New tests.

Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-11-13 14:35:11 +01:00