aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3
diff options
context:
space:
mode:
authorJerry DeLisle <jvdelisle@gcc.gnu.org>2025-09-02 15:58:26 -0700
committerJerry DeLisle <jvdelisle@gcc.gnu.org>2025-09-02 15:58:26 -0700
commit071b4126c613881f4cb25b4e5c39032964827f88 (patch)
tree7ed805786566918630d1d617b1ed8f7310f5fd8e /libstdc++-v3
parent845d23f3ea08ba873197c275a8857eee7edad996 (diff)
parentcaa1c2f42691d68af4d894a5c3e700ecd2dba080 (diff)
downloadgcc-devel/gfortran-test.zip
gcc-devel/gfortran-test.tar.gz
gcc-devel/gfortran-test.tar.bz2
Merge branch 'master' into gfortran-testdevel/gfortran-test
Diffstat (limited to 'libstdc++-v3')
-rw-r--r--libstdc++-v3/ChangeLog438
-rw-r--r--libstdc++-v3/acinclude.m438
-rw-r--r--libstdc++-v3/config.h.in12
-rw-r--r--libstdc++-v3/config/abi/pre/gnu.ver4
-rwxr-xr-xlibstdc++-v3/configure78
-rw-r--r--libstdc++-v3/configure.ac3
-rw-r--r--libstdc++-v3/doc/html/manual/appendix_porting.html2
-rw-r--r--libstdc++-v3/doc/html/manual/using_exceptions.html2
-rw-r--r--libstdc++-v3/doc/xml/manual/build_hacking.xml2
-rw-r--r--libstdc++-v3/doc/xml/manual/using_exceptions.xml2
-rw-r--r--libstdc++-v3/include/Makefile.am1
-rw-r--r--libstdc++-v3/include/Makefile.in1
-rw-r--r--libstdc++-v3/include/bits/align.h17
-rw-r--r--libstdc++-v3/include/bits/funcwrap.h14
-rw-r--r--libstdc++-v3/include/bits/indirect.h7
-rw-r--r--libstdc++-v3/include/bits/move.h2
-rw-r--r--libstdc++-v3/include/bits/ranges_algo.h118
-rw-r--r--libstdc++-v3/include/bits/ranges_algobase.h4
-rw-r--r--libstdc++-v3/include/bits/ranges_util.h29
-rw-r--r--libstdc++-v3/include/bits/stl_algo.h8
-rw-r--r--libstdc++-v3/include/bits/stl_iterator_base_funcs.h68
-rw-r--r--libstdc++-v3/include/bits/stl_vector.h9
-rw-r--r--libstdc++-v3/include/bits/utility.h20
-rw-r--r--libstdc++-v3/include/bits/vector.tcc69
-rw-r--r--libstdc++-v3/include/bits/version.def30
-rw-r--r--libstdc++-v3/include/bits/version.h37
-rw-r--r--libstdc++-v3/include/debug/bitset11
-rw-r--r--libstdc++-v3/include/precompiled/stdc++.h1
-rw-r--r--libstdc++-v3/include/std/bitset8
-rw-r--r--libstdc++-v3/include/std/chrono32
-rw-r--r--libstdc++-v3/include/std/complex15
-rw-r--r--libstdc++-v3/include/std/debugging77
-rw-r--r--libstdc++-v3/include/std/functional113
-rw-r--r--libstdc++-v3/include/std/inplace_vector2
-rw-r--r--libstdc++-v3/include/std/limits2
-rw-r--r--libstdc++-v3/include/std/mdspan359
-rw-r--r--libstdc++-v3/include/std/memory1
-rw-r--r--libstdc++-v3/include/std/mutex4
-rw-r--r--libstdc++-v3/include/std/ranges2
-rw-r--r--libstdc++-v3/include/std/stop_token19
-rw-r--r--libstdc++-v3/include/std/thread14
-rw-r--r--libstdc++-v3/include/std/type_traits22
-rw-r--r--libstdc++-v3/libsupc++/compare172
-rw-r--r--libstdc++-v3/python/libstdcxx/v6/printers.py6
-rw-r--r--libstdc++-v3/src/c++20/Makefile.am2
-rw-r--r--libstdc++-v3/src/c++20/Makefile.in4
-rw-r--r--libstdc++-v3/src/c++20/clock.cc52
-rw-r--r--libstdc++-v3/src/c++23/std.cc.in83
-rw-r--r--libstdc++-v3/src/c++26/Makefile.am4
-rw-r--r--libstdc++-v3/src/c++26/Makefile.in7
-rw-r--r--libstdc++-v3/src/c++26/debugging.cc176
-rw-r--r--libstdc++-v3/testsuite/18_support/comparisons/categories/zero_neg.cc16
-rw-r--r--libstdc++-v3/testsuite/18_support/numeric_limits/128bit.cc5
-rw-r--r--libstdc++-v3/testsuite/19_diagnostics/debugging/breakpoint.cc13
-rw-r--r--libstdc++-v3/testsuite/19_diagnostics/debugging/breakpoint_if_debugging.cc13
-rw-r--r--libstdc++-v3/testsuite/19_diagnostics/debugging/is_debugger_present-2.cc19
-rw-r--r--libstdc++-v3/testsuite/19_diagnostics/debugging/is_debugger_present.cc14
-rw-r--r--libstdc++-v3/testsuite/20_util/copyable_function/call.cc23
-rw-r--r--libstdc++-v3/testsuite/20_util/function_objects/bind_back/1.cc166
-rw-r--r--libstdc++-v3/testsuite/20_util/function_objects/bind_back/111327.cc11
-rw-r--r--libstdc++-v3/testsuite/20_util/function_objects/bind_front/1.cc164
-rw-r--r--libstdc++-v3/testsuite/20_util/function_objects/bind_front/111327.cc11
-rw-r--r--libstdc++-v3/testsuite/20_util/headers/memory/version.cc4
-rw-r--r--libstdc++-v3/testsuite/20_util/is_sufficiently_aligned/1.cc31
-rw-r--r--libstdc++-v3/testsuite/20_util/move_only_function/call.cc23
-rw-r--r--libstdc++-v3/testsuite/20_util/optional/cons/value_neg.cc1
-rw-r--r--libstdc++-v3/testsuite/20_util/scoped_allocator/69293_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/bitset/lwg4294.cc11
-rw-r--r--libstdc++-v3/testsuite/23_containers/inplace_vector/erasure.cc26
-rw-r--r--libstdc++-v3/testsuite/23_containers/mdspan/accessors/aligned_neg.cc33
-rw-r--r--libstdc++-v3/testsuite/23_containers/mdspan/accessors/debug/aligned_access_neg.cc23
-rw-r--r--libstdc++-v3/testsuite/23_containers/mdspan/accessors/debug/aligned_offset_neg.cc23
-rw-r--r--libstdc++-v3/testsuite/23_containers/mdspan/accessors/generic.cc90
-rw-r--r--libstdc++-v3/testsuite/23_containers/mdspan/extents/class_mandates_neg.cc3
-rw-r--r--libstdc++-v3/testsuite/23_containers/mdspan/extents/misc.cc7
-rw-r--r--libstdc++-v3/testsuite/23_containers/mdspan/version.cc17
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/modifiers/insert/insert_range.cc50
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/modifiers/moveable.cc6
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/modifiers/resize.cc69
-rw-r--r--libstdc++-v3/testsuite/24_iterators/operations/cxx20_iterators.cc60
-rw-r--r--libstdc++-v3/testsuite/24_iterators/random_access/string_vector_iterators.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/max/constrained.cc4
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/min/constrained.cc4
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/minmax/constrained.cc16
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/minmax_element/constrained.cc16
-rw-r--r--libstdc++-v3/testsuite/30_threads/timed_mutex/121496.cc14
-rw-r--r--libstdc++-v3/testsuite/backward/hash_set/check_construct_destroy.cc25
-rw-r--r--libstdc++-v3/testsuite/std/format/ranges/format_kind.cc4
-rw-r--r--libstdc++-v3/testsuite/std/memory/indirect/access.cc58
-rw-r--r--libstdc++-v3/testsuite/std/memory/polymorphic/access.cc53
-rw-r--r--libstdc++-v3/testsuite/std/time/format/data_not_present_neg.cc4
91 files changed, 2876 insertions, 460 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 9b6504b..3dc057e 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,441 @@
+2025-08-31 Gerald Pfeifer <gerald@pfeifer.com>
+
+ * doc/xml/manual/using_exceptions.xml: Update link to
+ Boost's "Exception-Safety"
+ * doc/html/manual/using_exceptions.html: Rebuild.
+
+2025-08-31 Jonathan Wakely <jwakely@redhat.com>
+
+ * src/c++26/debugging.cc [_GLIBCXX_HAVE_SYS_PTRACE_H]: Include
+ <sys/types.h>.
+ (breakpoint) [__i386__ || __x86_64__]: Use "int 0x03" instead of
+ "int3".
+
+2025-08-28 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/119670
+ * acinclude.m4 (GLIBCXX_CHECK_DEBUGGING): Check for facilities
+ needed by <debugging>.
+ * config.h.in: Regenerate.
+ * configure: Regenerate.
+ * configure.ac: Use GLIBCXX_CHECK_DEBUGGING.
+ * include/Makefile.am: Add new header.
+ * include/Makefile.in: Regenerate.
+ * include/bits/version.def (debugging): Add.
+ * include/bits/version.h: Regenerate.
+ * include/precompiled/stdc++.h: Add new header.
+ * src/c++26/Makefile.am: Add new file.
+ * src/c++26/Makefile.in: Regenerate.
+ * include/std/debugging: New file.
+ * src/c++26/debugging.cc: New file.
+ * testsuite/19_diagnostics/debugging/breakpoint.cc: New test.
+ * testsuite/19_diagnostics/debugging/breakpoint_if_debugging.cc:
+ New test.
+ * testsuite/19_diagnostics/debugging/is_debugger_present.cc: New
+ test.
+ * testsuite/19_diagnostics/debugging/is_debugger_present-2.cc:
+ New test.
+
+2025-08-28 Tomasz Kamiński <tkaminsk@redhat.com>
+
+ * testsuite/18_support/comparisons/categories/zero_neg.cc: New test.
+
+2025-08-28 Weslley da Silva Pereira <weslley.spereira@gmail.com>
+
+ * include/std/complex (polar, __complex_sqrt, pow)
+ (__complex_pow_unsigned): Use explicit conversions from int to
+ the complex value_type.
+
+2025-08-28 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/121046
+ * include/std/bitset (bitset(const CharT*, ...)): Add
+ constraints on CharT type.
+ * testsuite/23_containers/bitset/lwg4294.cc: New test.
+
+2025-08-28 Tomasz Kamiński <tkaminsk@redhat.com>
+
+ * libsupc++/compare (__cmp_cat::_Ord): Add unordered enumerator.
+ (__cmp_cat::_Ncmp): Remove.
+ (__cmp_cat::__ord, __cmp_cat::__make): Define.
+ (partial_ordering::partial_ordering(__cmp_cat::_Ncmp)): Remove.
+ (operator<=>(__cmp_cat::__unspec, partial_ordering))
+ (partial_ordering::unordered): Replace _Ncmp with _Ord.
+ (std::partial_ordering, std::weak_ordering, std::strong_ordering):
+ Befriend __ord and __make helpers, remove friend declartions for
+ other orderings.
+ (__compare::__fp_weak_ordering): Remove unused __cat variable.
+ Simplify ordering conversions.
+
+2025-08-27 Tomasz Kamiński <tkaminsk@redhat.com>
+
+ * libsupc++/compare
+ (operator<=>(__cmp_cat::__unspec, partial_ordering)):
+ Implement using _M_reverse.
+
+2025-08-27 Nathan Myers <ncm@cantrip.org>
+
+ * include/std/chrono (gps_clock::now, tai_clock::now): Remove
+ inline definitions.
+ * src/c++20/clock.cc (gps_clock::now, tai_clock::now): New file
+ for out-of-line now() impls.
+ * src/c++20/Makefile.am: Mention clock.cc.
+ * src/c++20/Makefile.in: Regenerate.
+ * config/abi/pre/gnu.ver: add mangled now() symbols.
+
+2025-08-27 Tomasz Kamiński <tkaminsk@redhat.com>
+
+ * libsupc++/compare (_Ncmp::_Unordered): Rename and change the value
+ to minimum value of signed char.
+ (_Ncomp::unordered): Renamed from _Unordered, the name is reserved
+ by partial_ordered::unordered.
+ (partial_ordering::_M_reverse()): Define.
+ (operator<=(partial_ordering, __cmp_cat::__unspec))
+ (operator>=(__cmp_cat::__unspec, partial_ordering)): Implemented
+ in terms of negated _M_value.
+ (operator>=(partial_ordering, __cmp_cat::__unspec))
+ (operator<=(__cmp_cat::__unspec, partial_ordering)): Directly
+ compare _M_value, as unordered value is negative.
+ (partial_ordering::unordered): Handle _Ncmp::unoredred rename.
+ * python/libstdcxx/v6/printers.py: Add -128 as integer value
+ for unordered, keeping 2 to preserve backward compatibility.
+
+2025-08-27 Tomasz Kamiński <tkaminsk@redhat.com>
+
+ * include/bits/funcwrap.h (__polyfunc::_Mo_base): Reorder _M_manage
+ and _M_storage members. Make _M_destroy protected and remove friend
+ declaration.
+ * testsuite/20_util/copyable_function/call.cc: Add test for aliasing
+ base class.
+ * testsuite/20_util/move_only_function/call.cc: Likewise.
+
+2025-08-26 Patrick Palka <ppalka@redhat.com>
+
+ * include/std/ranges (__detail::_CachedPosition): Remove
+ additional size constraint on the offset-based partial
+ specialization.
+
+2025-08-26 Tomasz Kamiński <tkaminsk@redhat.com>
+
+ PR libstdc++/90192
+ * include/bits/stl_vector.h (vector<T>::_M_fill_append): Declare.
+ (vector<T>::fill): Use _M_fill_append instead of _M_fill_insert.
+ * include/bits/vector.tcc (vector<T>::_M_fill_append): Define
+ (vector<T>::_M_fill_insert): Delegate to _M_fill_append when
+ elements are appended.
+ * testsuite/23_containers/vector/modifiers/moveable.cc: Updated
+ copycount for inserting at the end (appending).
+ * testsuite/23_containers/vector/modifiers/resize.cc: New test.
+ * testsuite/backward/hash_set/check_construct_destroy.cc: Updated
+ copycount, the hash_set constructor uses insert to fill buckets
+ with nullptrs.
+
+2025-08-26 Tomasz Kamiński <tkaminsk@redhat.com>
+
+ * include/bits/move.h (std::__like_impl, std::__like_t): Make
+ available in c++11.
+ * include/std/functional (std::_Indexed_bound_arg)
+ (std::_Bound_arg_storage, std::__make_bound_args): Define.
+ (std::_Bind_front, std::_Bind_back): Use _Bound_arg_storage.
+ * testsuite/20_util/function_objects/bind_back/1.cc: Expand
+ test to cover cases of 0, 1, many bound args.
+ * testsuite/20_util/function_objects/bind_back/111327.cc: Likewise.
+ * testsuite/20_util/function_objects/bind_front/1.cc: Likewise.
+ * testsuite/20_util/function_objects/bind_front/111327.cc: Likewise.
+
+2025-08-26 Tomasz Kamiński <tkaminsk@redhat.com>
+
+ * include/std/stop_token (__variant::_Never_valueless_alt): Declare.
+ (__variant::_Never_valueless_alt<std::stop_token>)
+ (__variant::_Never_valueless_alt<std::stop_source>): Define.
+ * include/std/thread: (__variant::_Never_valueless_alt): Declare.
+ (__variant::_Never_valueless_alt<std::jthread>): Define.
+
+2025-08-21 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/121496
+ * acinclude.m4 (GLIBCXX_CHECK_PTHREAD_MUTEX_CLOCKLOCK): Do not
+ use _GLIBCXX_TSAN in _GLIBCXX_USE_PTHREAD_MUTEX_CLOCKLOCK macro.
+ * configure: Regenerate.
+
+2025-08-21 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/121496
+ * include/std/mutex (__timed_mutex_impl::_M_try_wait_until):
+ Change preprocessor condition to use #if instead of #ifdef.
+ (recursive_timed_mutex::_M_clocklock): Likewise.
+ * testsuite/30_threads/timed_mutex/121496.cc: New test.
+
+2025-08-21 Luc Grosheintz <luc.grosheintz@gmail.com>
+
+ PR libstdc++/120994
+ * include/bits/version.def (aligned_accessor): Add.
+ * include/bits/version.h: Regenerate.
+ * include/std/mdspan (aligned_accessor): New class.
+ * src/c++23/std.cc.in (aligned_accessor): Add.
+ * testsuite/23_containers/mdspan/accessors/generic.cc: Add tests
+ for aligned_accessor.
+ * testsuite/23_containers/mdspan/accessors/aligned_neg.cc: New test.
+ * testsuite/23_containers/mdspan/version.cc: Add test for
+ __cpp_lib_aligned_accessor.
+ * testsuite/23_containers/mdspan/accessors/debug/aligned_access_neg.cc: New file.
+ * testsuite/23_containers/mdspan/accessors/debug/aligned_offset_neg.cc: New file.
+
+2025-08-21 Luc Grosheintz <luc.grosheintz@gmail.com>
+
+ PR libstdc++/120994
+ * include/bits/align.h (is_sufficiently_aligned): New function.
+ * include/bits/version.def (is_sufficiently_aligned): Add.
+ * include/bits/version.h: Regenerate.
+ * include/std/memory: Add __glibcxx_want_is_sufficiently_aligned.
+ * src/c++23/std.cc.in (is_sufficiently_aligned): Add.
+ * testsuite/20_util/headers/memory/version.cc: Add test for
+ __cpp_lib_is_sufficiently_aligned.
+ * testsuite/20_util/is_sufficiently_aligned/1.cc: New test.
+
+2025-08-21 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/121374
+ * include/std/limits (numeric_limits<__float128>::max_digits10):
+ Fix value.
+ * testsuite/18_support/numeric_limits/128bit.cc: Check value.
+
+2025-08-21 Jonathan Wakely <jwakely@redhat.com>
+
+ PR c++/117294
+ * testsuite/20_util/optional/cons/value_neg.cc: Prune additional
+ output for C++20 and later.
+ * testsuite/20_util/scoped_allocator/69293_neg.cc: Match
+ additional error for C++20 and later.
+
+2025-08-21 Luc Grosheintz <luc.grosheintz@gmail.com>
+
+ * include/bits/version.def (mdspan): Set value for C++26.
+ * include/bits/version.h: Regenerate.
+ * include/std/mdspan (dims): Add.
+ * src/c++23/std.cc.in (dims): Add.
+ * testsuite/23_containers/mdspan/extents/misc.cc: Add tests.
+ * testsuite/23_containers/mdspan/version.cc: Update test.
+
+2025-08-21 Luc Grosheintz <luc.grosheintz@gmail.com>
+
+ * include/std/mdspan (__static_prod): Delete.
+ (__fwd_partial_prods): Compute at compile-time in O(rank), not
+ O(rank**2).
+ (__rev_partial_prods): Ditto.
+ (__size): Inline __static_prod.
+
+2025-08-21 Luc Grosheintz <luc.grosheintz@gmail.com>
+
+ * include/std/mdspan (__fwd_partial_prods): Reduce size of the
+ array by 1 element.
+
+2025-08-21 Luc Grosheintz <luc.grosheintz@gmail.com>
+
+ * include/std/mdspan (__valid_static_extent): Replace
+ numeric_limits with __int_traits.
+ (extents::_S_ctor_explicit): Ditto.
+ (extents::__static_quotient): Ditto.
+ (layout_stride::mapping::mapping): Ditto.
+ (mdspan::size): Ditto.
+ * testsuite/23_containers/mdspan/extents/class_mandates_neg.cc:
+ Update test with additional diagnostics.
+
+2025-08-21 Luc Grosheintz <luc.grosheintz@gmail.com>
+
+ * include/std/mdspan (extents::operator==): Replace loop with
+ pack expansion.
+
+2025-08-21 Luc Grosheintz <luc.grosheintz@gmail.com>
+
+ * include/std/mdspan (__mdspan::__all_static): New function.
+ (__mdspan::_StaticExtents::_S_is_dyn): Inline and eliminate.
+ (__mdspan::_ExtentsStorage::_S_is_dynamic): New method.
+ (__mdspan::_ExtentsStorage::_M_extent): Use _S_is_dynamic.
+
+2025-08-21 Luc Grosheintz <luc.grosheintz@gmail.com>
+
+ * include/std/mdspan (__fwd_prods): Relax condition for fully-dynamic
+ extents to cover (dyn, ..., dyn, X).
+ (__rev_partial_prods): Analogous for (X, dyn, ..., dyn).
+
+2025-08-21 Luc Grosheintz <luc.grosheintz@gmail.com>
+
+ * include/std/mdspan (__mdspan::__all_dynamic): New function.
+ (__mdspan::_StaticExtents::_S_dynamic_index): Convert to method.
+ (__mdspan::_StaticExtents::_S_dynamic_index_inv): Ditto.
+ (__mdspan::_StaticExtents): New specialization for fully dynamic
+ extents.
+ (__mdspan::__fwd_prod): New constexpr if branch to avoid
+ instantiating __fwd_partial_prods.
+ (__mdspan::__rev_prod): Ditto.
+
+2025-08-21 Luc Grosheintz <luc.grosheintz@gmail.com>
+
+ * include/std/mdspan (__mdspan::__fwd_prod): Optimize
+ for rank <= 2.
+ (__mdspan::__rev_prod): Ditto.
+ (__mdspan::__size): Refactor to use a pre-computed product, not
+ a partial product.
+
+2025-08-21 Luc Grosheintz <luc.grosheintz@gmail.com>
+
+ * include/std/mdspan (__mdspan::__static_prod): New function.
+ (__mdspan::__fwd_partial_prods): Constexpr array of partial
+ forward products.
+ (__mdspan::__fwd_partial_prods): Same for reverse partial
+ products.
+ (__mdspan::__static_extents_prod): Delete function.
+ (__mdspan::__extents_prod): Renamed from __exts_prod and refactored.
+ include/std/mdspan (__mdspan::__fwd_prod): Compute as the
+ product of pre-computed static static and the product of dynamic
+ extents.
+ (__mdspan::__rev_prod): Ditto.
+
+2025-08-21 Luc Grosheintz <luc.grosheintz@gmail.com>
+
+ * include/std/mdspan (__mdspan::_StaticExtents): Extract non IndexType
+ related code from _ExtentsStorage.
+ (__mdspan::_ExtentsStorage): Use _StaticExtents.
+ (__mdspan::__static_extents): Return reference to NTTP of _StaticExtents.
+ (__mdspan::__contains_zero): New overload.
+ (__mdspan::__exts_prod, __mdspan::__static_quotient): Use span to avoid
+ copying __sta_exts.
+
+2025-08-19 Tomasz Kamiński <tkaminsk@redhat.com>
+
+ PR libstdc++/104874
+ * testsuite/24_iterators/random_access/string_vector_iterators.cc:
+ Call test6642.
+
+2025-08-18 Tomasz Kamiński <tkaminsk@redhat.com>
+
+ PR libstdc++/121476
+ * include/bits/ranges_algo.h (__all_of_fn::operator()):
+ (__any_of_fn::operator(), __none_of_fn::operator())
+ (__find_first_of_fn::operator(), __count_fn::operator())
+ (__find_end_fn::operator(), __remove_if_fn::operator())
+ (__remove_fn::operator(), __unique_fn::operator())
+ (__is_sorted_until_fn::operator(), __is_sorted_fn::operator())
+ (__lower_bound_fn::operator(), __upper_bound_fn::operator())
+ (__equal_range_fn::operator(), __binary_search_fn::operator())
+ (__is_partitioned_fn::operator(), __partition_point_fn::operator())
+ (__minmax_fn::operator(), __min_element_fn::operator())
+ (__includes_fn::operator(), __max_fn::operator())
+ (__lexicographical_compare_fn::operator(), __clamp__fn::operator())
+ (__find_last_fn::operator(), __find_last_if_fn::operator())
+ (__find_last_if_not_fn::operator()): Add [[nodiscard]] attribute.
+ * include/bits/ranges_algobase.h (__equal_fn::operator()):
+ Add [[nodiscard]] attribute.
+ * include/bits/ranges_util.h (__find_fn::operator())
+ (__find_if_fn::operator(), __find_if_not_fn::operator())
+ (__mismatch_fn::operator(), __search_fn::operator())
+ (__min_fn::operator(), __adjacent_find_fn::operator()):
+ Add [[nodiscard]] attribute.
+ * include/bits/stl_algo.h (std::min(initializer_list<T>))
+ (std::min(initializer_list<T>, _Compare))
+ (std::max(initializer_list<T>))
+ (std::mmax(initializer_list<T>, _Compare)): Add _GLIBCXX_NODISCARD.
+ * testsuite/25_algorithms/min/constrained.cc: Silence nodiscard
+ warning.
+ * testsuite/25_algorithms/max/constrained.cc: Likewise.
+ * testsuite/25_algorithms/minmax/constrained.cc: Likewise.
+ * testsuite/25_algorithms/minmax_element/constrained.cc: Likewise.
+
+2025-08-18 Tomasz Kamiński <tkaminsk@redhat.com>
+
+ PR libstdc++/121313
+ * include/bits/vector.tcc (vector::insert_range): Add check for
+ empty size.
+ * testsuite/23_containers/vector/modifiers/insert/insert_range.cc:
+ New tests.
+
+2025-08-10 H.J. Lu <hjl.tools@gmail.com>
+
+ * configure: Regenerated.
+
+2025-08-07 Gerald Pfeifer <gerald@pfeifer.com>
+
+ * doc/xml/manual/build_hacking.xml: Switch gcc.gnu.org installation
+ docs to https.
+ * doc/html/manual/appendix_porting.html: Regenerate.
+
+2025-08-05 Jakub Jelinek <jakub@redhat.com>
+
+ PR libstdc++/121373
+ * src/c++23/std.cc.in (std::ranges::iter_move, std::ranges::iter_swap):
+ Remove exports.
+
+2025-08-04 Jakub Jelinek <jakub@redhat.com>
+ hexne <printfne@gmail.com>
+
+ PR libstdc++/121373
+ * src/c++23/std.cc.in (std::ranges::shift_left,
+ std::ranges::shift_right): Only export for C++23 and later.
+ (std::ranges::fold_left_first_with_iter_result,
+ std::ranges::fold_left_with_iter_result): Export.
+ (std::byteswap): Export for C++23 and later.
+ (std::ranges::iter_move, std::ranges::iter_swap): Export.
+ (std::projected_value_t): Export for C++26 and later.
+ (std::out_ptr_t, std::inout_ptr_t): Export.
+ (std::ranges::iota_result): Export.
+ (std::regex_constants): Export a lot of constants.
+ (std::is_scoped_enum, std::is_scoped_enum_v): Export.
+
+2025-08-04 Tomasz Kamiński <tkaminsk@redhat.com>
+
+ PR libstdc++/121128
+ * include/bits/indirect.h (indirect::operator*):
+ Cast __self to approparietly qualified indirect.
+ * testsuite/std/memory/indirect/access.cc: New test.
+ * testsuite/std/memory/polymorphic/access.cc: New test.
+
+2025-08-03 Jakub Jelinek <jakub@redhat.com>
+
+ * src/c++23/std.cc.in (std::owner_equal, std::owner_hash): Export.
+
+2025-07-30 François Dumont <frs.dumont@gmail.com>
+
+ * testsuite/std/time/format/data_not_present_neg.cc: Remove _GLIBCXX_USE_DUAL_ABI
+ check.
+
+2025-07-29 Tomasz Kamiński <tkaminsk@redhat.com>
+
+ * testsuite/std/format/ranges/format_kind.cc: New test.
+
+2025-07-28 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/102181
+ * include/bits/stl_iterator_base_funcs.h (distance, advance):
+ Check C++20 iterator concepts and handle appropriately.
+ (__detail::__iter_category_converts_to_concept): New concept.
+ (__detail::__promotable_iterator): New concept.
+ * testsuite/24_iterators/operations/cxx20_iterators.cc: New
+ test.
+
+2025-07-28 Nathan Myers <ncm@cantrip.org>
+
+ PR libstdc++/119742
+ * include/debug/bitset: Add new ctor.
+
+2025-07-28 Luc Grosheintz <luc.grosheintz@gmail.com>
+
+ * include/std/mdspan: Small stylistic adjustments.
+
+2025-07-28 Luc Grosheintz <luc.grosheintz@gmail.com>
+
+ * testsuite/23_containers/mdspan/accessors/generic.cc: Refactor
+ test_ctor.
+
+2025-07-28 Tomasz Kamiński <tkaminsk@redhat.com>
+
+ PR libstdc++/121196
+ * include/std/inplace_vector (std::erase): Provide default argument
+ for _Up parameter.
+ * testsuite/23_containers/inplace_vector/erasure.cc: Add test for
+ using braces-init-list as arguments to erase_if and use function
+ to verify content of inplace_vector
+
2025-07-25 Tuur Martens <tuurmartens4@gmail.com>
* include/bits/unordered_map.h: Rectify referencing of
diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
index 080a4fc..eb2d262 100644
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -4511,7 +4511,7 @@ AC_DEFUN([GLIBCXX_CHECK_PTHREAD_MUTEX_CLOCKLOCK], [
[glibcxx_cv_PTHREAD_MUTEX_CLOCKLOCK=no])
])
if test $glibcxx_cv_PTHREAD_MUTEX_CLOCKLOCK = yes; then
- AC_DEFINE(_GLIBCXX_USE_PTHREAD_MUTEX_CLOCKLOCK, (_GLIBCXX_TSAN==0), [Define if pthread_mutex_clocklock is available in <pthread.h>.])
+ AC_DEFINE(_GLIBCXX_USE_PTHREAD_MUTEX_CLOCKLOCK, 1, [Define if pthread_mutex_clocklock is available in <pthread.h>.])
fi
CXXFLAGS="$ac_save_CXXFLAGS"
@@ -5769,6 +5769,42 @@ AC_LANG_SAVE
AC_LANG_RESTORE
])
+dnl
+dnl Check whether the dependencies for std::is_debugger_present are available.
+dnl
+dnl Defines:
+dnl _GLIBCXX_USE_PTRACE if ptrace(int, pid_t, int, int) is in <sys/ptrace.h>.
+dnl _GLIBCXX_USE_PROC_SELF_STATUS if /proc/self/status should be used.
+dnl
+AC_DEFUN([GLIBCXX_CHECK_DEBUGGING], [
+ AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+
+ AC_CHECK_HEADERS([sys/ptrace.h debugapi.h])
+
+ case "$target_os" in
+ linux*)
+ AC_DEFINE([_GLIBCXX_USE_PROC_SELF_STATUS],1,
+ [Define if /proc/self/status should be used for <debugging>.])
+ ;;
+ esac
+
+ AC_MSG_CHECKING([whether ptrace(int, pid_t, int, int) is in <sys/ptrace.h>])
+ AC_TRY_COMPILE([
+ #include <sys/ptrace.h>
+ ],[
+ int i = ptrace(PTRACE_TRACEME, (pid_t)0, 1, 0);
+ ], [ac_ptrace=yes], [ac_ptrace=no])
+ AC_MSG_RESULT($ac_ptrace)
+ if test "$ac_ptrace" = yes; then
+ AC_DEFINE_UNQUOTED(_GLIBCXX_USE_PTRACE, 1,
+ [Define if ptrace should be used for std::is_debugger_present.])
+ fi
+
+ AC_LANG_RESTORE
+])
+
+
# Macros from the top-level gcc directory.
m4_include([../config/gc++filt.m4])
m4_include([../config/tls.m4])
diff --git a/libstdc++-v3/config.h.in b/libstdc++-v3/config.h.in
index ffacdab..818117a 100644
--- a/libstdc++-v3/config.h.in
+++ b/libstdc++-v3/config.h.in
@@ -70,6 +70,9 @@
/* Define to 1 if you have the `cosl' function. */
#undef HAVE_COSL
+/* Define to 1 if you have the <debugapi.h> header file. */
+#undef HAVE_DEBUGAPI_H
+
/* Define to 1 if you have the declaration of `strnlen', and to 0 if you
don't. */
#undef HAVE_DECL_STRNLEN
@@ -435,6 +438,9 @@
/* Define to 1 if you have the <sys/param.h> header file. */
#undef HAVE_SYS_PARAM_H
+/* Define to 1 if you have the <sys/ptrace.h> header file. */
+#undef HAVE_SYS_PTRACE_H
+
/* Define to 1 if you have the <sys/resource.h> header file. */
#undef HAVE_SYS_RESOURCE_H
@@ -846,6 +852,9 @@
/* Define if nl_langinfo_l should be used for std::text_encoding. */
#undef _GLIBCXX_USE_NL_LANGINFO_L
+/* Define if /proc/self/status should be used for <debugging>. */
+#undef _GLIBCXX_USE_PROC_SELF_STATUS
+
/* Define if pthreads_num_processors_np is available in <pthread.h>. */
#undef _GLIBCXX_USE_PTHREADS_NUM_PROCESSORS_NP
@@ -862,6 +871,9 @@
/* Define if POSIX read/write locks are available in <gthr.h>. */
#undef _GLIBCXX_USE_PTHREAD_RWLOCK_T
+/* Define if ptrace should be used for std::is_debugger_present. */
+#undef _GLIBCXX_USE_PTRACE
+
/* Define if /dev/random and /dev/urandom are available for the random_device
of TR1 (Chapter 5.1). */
#undef _GLIBCXX_USE_RANDOM_TR1
diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver
index b5a89c3..e1601dc 100644
--- a/libstdc++-v3/config/abi/pre/gnu.ver
+++ b/libstdc++-v3/config/abi/pre/gnu.ver
@@ -2555,6 +2555,10 @@ GLIBCXX_3.4.35 {
_ZNSt8__detail17__wait_until_implEPKvRNS_16__wait_args_baseERKNSt6chrono8durationI[lx]St5ratioIL[lx]1EL[lx]1000000000EEEE;
_ZNSt8__detail11__wait_args22_M_load_proxy_wait_valEPKv;
+ # std::chrono::gps_clock::now, tai_clock::now
+ _ZNSt6chrono9gps_clock3nowEv;
+ _ZNSt6chrono9tai_clock3nowEv;
+
# __gnu_debug::_Safe_iterator_base and _Safe_sequence_base const
_ZN11__gnu_debug19_Safe_iterator_base9_M_attachEPKNS_19_Safe_sequence_baseEb;
_ZN11__gnu_debug19_Safe_iterator_base16_M_attach_singleEPKNS_19_Safe_sequence_baseEb;
diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
index 69aa246..c0eaeb9 100755
--- a/libstdc++-v3/configure
+++ b/libstdc++-v3/configure
@@ -21881,7 +21881,7 @@ fi
$as_echo "$glibcxx_cv_PTHREAD_MUTEX_CLOCKLOCK" >&6; }
if test $glibcxx_cv_PTHREAD_MUTEX_CLOCKLOCK = yes; then
-$as_echo "#define _GLIBCXX_USE_PTHREAD_MUTEX_CLOCKLOCK (_GLIBCXX_TSAN==0)" >>confdefs.h
+$as_echo "#define _GLIBCXX_USE_PTHREAD_MUTEX_CLOCKLOCK 1" >>confdefs.h
fi
@@ -26323,6 +26323,7 @@ fi
+
use_additional=yes
acl_save_prefix="$prefix"
@@ -53543,7 +53544,7 @@ $as_echo "$glibcxx_cv_libbacktrace_atomics" >&6; }
CXXFLAGS='-O0 -S'
cat > conftest.$ac_ext << EOF
-#line 53546 "configure"
+#line 53547 "configure"
#include <stddef.h>
int main()
{
@@ -54500,6 +54501,79 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
+# For std::is_debugger_present
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+ for ac_header in sys/ptrace.h debugapi.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_cxx_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+ case "$target_os" in
+ linux*)
+
+$as_echo "#define _GLIBCXX_USE_PROC_SELF_STATUS 1" >>confdefs.h
+
+ ;;
+ esac
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ptrace(int, pid_t, int, int) is in <sys/ptrace.h>" >&5
+$as_echo_n "checking whether ptrace(int, pid_t, int, int) is in <sys/ptrace.h>... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <sys/ptrace.h>
+
+int
+main ()
+{
+
+ int i = ptrace(PTRACE_TRACEME, (pid_t)0, 1, 0);
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_ptrace=yes
+else
+ ac_ptrace=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ptrace" >&5
+$as_echo "$ac_ptrace" >&6; }
+ if test "$ac_ptrace" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define _GLIBCXX_USE_PTRACE 1
+_ACEOF
+
+ fi
+
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
# Define documentation rules conditionally.
# See if makeinfo has been installed and is modern enough
diff --git a/libstdc++-v3/configure.ac b/libstdc++-v3/configure.ac
index a6c01b2..0bf2191 100644
--- a/libstdc++-v3/configure.ac
+++ b/libstdc++-v3/configure.ac
@@ -587,6 +587,9 @@ GLIBCXX_CHECK_FILEBUF_NATIVE_HANDLES
# For std::text_encoding
GLIBCXX_CHECK_TEXT_ENCODING
+# For std::is_debugger_present
+GLIBCXX_CHECK_DEBUGGING
+
# Define documentation rules conditionally.
# See if makeinfo has been installed and is modern enough
diff --git a/libstdc++-v3/doc/html/manual/appendix_porting.html b/libstdc++-v3/doc/html/manual/appendix_porting.html
index 887fa50..7b63613 100644
--- a/libstdc++-v3/doc/html/manual/appendix_porting.html
+++ b/libstdc++-v3/doc/html/manual/appendix_porting.html
@@ -26,7 +26,7 @@ Support for C++11 dialect.
</a></span></dt><dt><span class="section"><a href="backwards.html#backwards.third.iterator_type">
<code class="code">Container::iterator_type</code> is not necessarily <code class="code">Container::value_type*</code>
</a></span></dt></dl></dd></dl></dd></dl></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="appendix.porting.build_hacking"></a>Configure and Build Hacking</h2></div></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="build_hacking.prereq"></a>Prerequisites</h3></div></div></div><p>
- As noted <a class="link" href="http://gcc.gnu.org/install/prerequisites.html" target="_top">previously</a>,
+ As noted <a class="link" href="https://gcc.gnu.org/install/prerequisites.html" target="_top">previously</a>,
certain other tools are necessary for hacking on files that
control configure (<code class="code">configure.ac</code>,
<code class="code">acinclude.m4</code>) and make
diff --git a/libstdc++-v3/doc/html/manual/using_exceptions.html b/libstdc++-v3/doc/html/manual/using_exceptions.html
index eb4501b..2da86be 100644
--- a/libstdc++-v3/doc/html/manual/using_exceptions.html
+++ b/libstdc++-v3/doc/html/manual/using_exceptions.html
@@ -336,7 +336,7 @@ is called.
</em>. </span><span class="author"><span class="firstname">David</span> <span class="surname">Abrahams </span>. </span><span class="publisher"><span class="publishername">
Boost
. </span></span></p></div><div class="biblioentry"><a id="id-1.3.3.4.9.10.4"></a><p><span class="title"><em>
- <a class="link" href="https://www.boost.org/community/exception_safety.html" target="_top">
+ <a class="link" href="https://www.boost.org/doc/user-guide/exception-safety.html" target="_top">
Exception-Safety in Generic Components
</a>
</em>. </span><span class="author"><span class="firstname">David</span> <span class="surname">Abrahams</span>. </span><span class="publisher"><span class="publishername">
diff --git a/libstdc++-v3/doc/xml/manual/build_hacking.xml b/libstdc++-v3/doc/xml/manual/build_hacking.xml
index 20de49f..4c044d9 100644
--- a/libstdc++-v3/doc/xml/manual/build_hacking.xml
+++ b/libstdc++-v3/doc/xml/manual/build_hacking.xml
@@ -17,7 +17,7 @@
<section xml:id="build_hacking.prereq"><info><title>Prerequisites</title></info>
<para>
- As noted <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://gcc.gnu.org/install/prerequisites.html">previously</link>,
+ As noted <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://gcc.gnu.org/install/prerequisites.html">previously</link>,
certain other tools are necessary for hacking on files that
control configure (<code>configure.ac</code>,
<code>acinclude.m4</code>) and make
diff --git a/libstdc++-v3/doc/xml/manual/using_exceptions.xml b/libstdc++-v3/doc/xml/manual/using_exceptions.xml
index ac2ba9d..3b42802 100644
--- a/libstdc++-v3/doc/xml/manual/using_exceptions.xml
+++ b/libstdc++-v3/doc/xml/manual/using_exceptions.xml
@@ -545,7 +545,7 @@ is called.
<biblioentry>
<title>
<link xmlns:xlink="http://www.w3.org/1999/xlink"
- xlink:href="https://www.boost.org/community/exception_safety.html">
+ xlink:href="https://www.boost.org/doc/user-guide/exception-safety.html">
Exception-Safety in Generic Components
</link>
</title>
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index 6f248fe..6f59469 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -68,6 +68,7 @@ std_headers = \
${std_srcdir}/codecvt \
${std_srcdir}/complex \
${std_srcdir}/condition_variable \
+ ${std_srcdir}/debugging \
${std_srcdir}/deque \
${std_srcdir}/execution \
${std_srcdir}/filesystem \
diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in
index 014466f..4b5917e 100644
--- a/libstdc++-v3/include/Makefile.in
+++ b/libstdc++-v3/include/Makefile.in
@@ -424,6 +424,7 @@ std_freestanding = \
@GLIBCXX_HOSTED_TRUE@ ${std_srcdir}/codecvt \
@GLIBCXX_HOSTED_TRUE@ ${std_srcdir}/complex \
@GLIBCXX_HOSTED_TRUE@ ${std_srcdir}/condition_variable \
+@GLIBCXX_HOSTED_TRUE@ ${std_srcdir}/debugging \
@GLIBCXX_HOSTED_TRUE@ ${std_srcdir}/deque \
@GLIBCXX_HOSTED_TRUE@ ${std_srcdir}/execution \
@GLIBCXX_HOSTED_TRUE@ ${std_srcdir}/filesystem \
diff --git a/libstdc++-v3/include/bits/align.h b/libstdc++-v3/include/bits/align.h
index 2b40c37..6a85244 100644
--- a/libstdc++-v3/include/bits/align.h
+++ b/libstdc++-v3/include/bits/align.h
@@ -102,6 +102,23 @@ align(size_t __align, size_t __size, void*& __ptr, size_t& __space) noexcept
}
#endif // __glibcxx_assume_aligned
+#ifdef __glibcxx_is_sufficiently_aligned // C++ >= 26
+ /** @brief Is `__ptr` aligned to an _Align byte boundary?
+ *
+ * @tparam _Align An alignment value
+ * @tparam _Tp An object type
+ *
+ * C++26 20.2.5 [ptr.align]
+ *
+ * @ingroup memory
+ */
+ template<size_t _Align, class _Tp>
+ [[nodiscard,__gnu__::__always_inline__]]
+ inline bool
+ is_sufficiently_aligned(_Tp* __ptr)
+ { return reinterpret_cast<__UINTPTR_TYPE__>(__ptr) % _Align == 0; }
+#endif // __glibcxx_is_sufficiently_aligned
+
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
diff --git a/libstdc++-v3/include/bits/funcwrap.h b/libstdc++-v3/include/bits/funcwrap.h
index 9db4ab7..70ecfd9 100644
--- a/libstdc++-v3/include/bits/funcwrap.h
+++ b/libstdc++-v3/include/bits/funcwrap.h
@@ -419,6 +419,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_M_manage = _Manager::_S_empty;
}
+ void _M_destroy() noexcept
+ { _M_manage(_Manager::_Op::_Destroy, _M_storage, nullptr); }
+
~_Mo_base()
{ _M_destroy(); }
@@ -434,17 +437,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
std::swap(_M_manage, __x._M_manage);
}
- _Storage _M_storage;
-
- private:
- void _M_destroy() noexcept
- { _M_manage(_Manager::_Op::_Destroy, _M_storage, nullptr); }
-
_Manager::_Func _M_manage;
-
-#ifdef __glibcxx_copyable_function // C++ >= 26 && HOSTED
- friend class _Cpy_base;
-#endif // __glibcxx_copyable_function
+ _Storage _M_storage;
};
#endif // __glibcxx_copyable_function || __glibcxx_copyable_function
} // namespace __polyfunc
diff --git a/libstdc++-v3/include/bits/indirect.h b/libstdc++-v3/include/bits/indirect.h
index e8000d7..89fa8c8 100644
--- a/libstdc++-v3/include/bits/indirect.h
+++ b/libstdc++-v3/include/bits/indirect.h
@@ -286,8 +286,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
constexpr auto&&
operator*(this _Self&& __self) noexcept
{
- __glibcxx_assert(__self._M_objp != nullptr);
- return std::forward_like<_Self>(*((_Self)__self)._M_objp);
+ // n.b. [allocator.requirements.general] p22 implies
+ // dereferencing const pointer is same as pointer
+ const indirect& __iself = (const indirect&)__self;
+ __glibcxx_assert(__iself._M_objp != nullptr);
+ return std::forward_like<_Self>(*__iself._M_objp);
}
constexpr const_pointer
diff --git a/libstdc++-v3/include/bits/move.h b/libstdc++-v3/include/bits/move.h
index 061e6b4..8c4f461 100644
--- a/libstdc++-v3/include/bits/move.h
+++ b/libstdc++-v3/include/bits/move.h
@@ -89,7 +89,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return static_cast<_Tp&&>(__t);
}
-#if __glibcxx_forward_like // C++ >= 23
template<typename _Tp, typename _Up>
struct __like_impl; // _Tp must be a reference and _Up an lvalue reference
@@ -112,6 +111,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Tp, typename _Up>
using __like_t = typename __like_impl<_Tp&&, _Up&>::type;
+#if __glibcxx_forward_like // C++ >= 23
/** @brief Forward with the cv-qualifiers and value category of another type.
* @tparam _Tp An lvalue reference or rvalue reference.
* @tparam _Up An lvalue reference type deduced from the function argument.
diff --git a/libstdc++-v3/include/bits/ranges_algo.h b/libstdc++-v3/include/bits/ranges_algo.h
index 9f8945a..6e1e06c 100644
--- a/libstdc++-v3/include/bits/ranges_algo.h
+++ b/libstdc++-v3/include/bits/ranges_algo.h
@@ -109,7 +109,7 @@ namespace ranges
template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
typename _Proj = identity,
indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
- constexpr bool
+ [[nodiscard]] constexpr bool
operator()(_Iter __first, _Sent __last,
_Pred __pred, _Proj __proj = {}) const
{
@@ -122,7 +122,7 @@ namespace ranges
template<input_range _Range, typename _Proj = identity,
indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
_Pred>
- constexpr bool
+ [[nodiscard]] constexpr bool
operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const
{
return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -137,7 +137,7 @@ namespace ranges
template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
typename _Proj = identity,
indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
- constexpr bool
+ [[nodiscard]] constexpr bool
operator()(_Iter __first, _Sent __last,
_Pred __pred, _Proj __proj = {}) const
{
@@ -150,7 +150,7 @@ namespace ranges
template<input_range _Range, typename _Proj = identity,
indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
_Pred>
- constexpr bool
+ [[nodiscard]] constexpr bool
operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const
{
return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -165,7 +165,7 @@ namespace ranges
template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
typename _Proj = identity,
indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
- constexpr bool
+ [[nodiscard]] constexpr bool
operator()(_Iter __first, _Sent __last,
_Pred __pred, _Proj __proj = {}) const
{
@@ -178,7 +178,7 @@ namespace ranges
template<input_range _Range, typename _Proj = identity,
indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
_Pred>
- constexpr bool
+ [[nodiscard]] constexpr bool
operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const
{
return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -279,7 +279,7 @@ namespace ranges
typename _Pred = ranges::equal_to,
typename _Proj1 = identity, typename _Proj2 = identity>
requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>
- constexpr _Iter1
+ [[nodiscard]] constexpr _Iter1
operator()(_Iter1 __first1, _Sent1 __last1,
_Iter2 __first2, _Sent2 __last2, _Pred __pred = {},
_Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
@@ -298,7 +298,7 @@ namespace ranges
typename _Proj1 = identity, typename _Proj2 = identity>
requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>,
_Pred, _Proj1, _Proj2>
- constexpr borrowed_iterator_t<_Range1>
+ [[nodiscard]] constexpr borrowed_iterator_t<_Range1>
operator()(_Range1&& __r1, _Range2&& __r2, _Pred __pred = {},
_Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
{
@@ -319,7 +319,7 @@ namespace ranges
requires indirect_binary_predicate<ranges::equal_to,
projected<_Iter, _Proj>,
const _Tp*>
- constexpr iter_difference_t<_Iter>
+ [[nodiscard]] constexpr iter_difference_t<_Iter>
operator()(_Iter __first, _Sent __last,
const _Tp& __value, _Proj __proj = {}) const
{
@@ -336,7 +336,7 @@ namespace ranges
requires indirect_binary_predicate<ranges::equal_to,
projected<iterator_t<_Range>, _Proj>,
const _Tp*>
- constexpr range_difference_t<_Range>
+ [[nodiscard]] constexpr range_difference_t<_Range>
operator()(_Range&& __r, const _Tp& __value, _Proj __proj = {}) const
{
return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -726,7 +726,7 @@ namespace ranges
typename _Pred = ranges::equal_to,
typename _Proj1 = identity, typename _Proj2 = identity>
requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>
- constexpr subrange<_Iter1>
+ [[nodiscard]] constexpr subrange<_Iter1>
operator()(_Iter1 __first1, _Sent1 __last1,
_Iter2 __first2, _Sent2 __last2, _Pred __pred = {},
_Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
@@ -783,7 +783,7 @@ namespace ranges
typename _Proj1 = identity, typename _Proj2 = identity>
requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>,
_Pred, _Proj1, _Proj2>
- constexpr borrowed_subrange_t<_Range1>
+ [[nodiscard]] constexpr borrowed_subrange_t<_Range1>
operator()(_Range1&& __r1, _Range2&& __r2, _Pred __pred = {},
_Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
{
@@ -806,7 +806,7 @@ namespace ranges
indirect_equivalence_relation<projected<_Iter1, _Proj1>,
projected<_Iter2, _Proj2>> _Pred
= ranges::equal_to>
- constexpr bool
+ [[nodiscard]] constexpr bool
operator()(_Iter1 __first1, _Sent1 __last1,
_Iter2 __first2, _Sent2 __last2, _Pred __pred = {},
_Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
@@ -875,7 +875,7 @@ namespace ranges
indirect_equivalence_relation<
projected<iterator_t<_Range1>, _Proj1>,
projected<iterator_t<_Range2>, _Proj2>> _Pred = ranges::equal_to>
- constexpr bool
+ [[nodiscard]] constexpr bool
operator()(_Range1&& __r1, _Range2&& __r2, _Pred __pred = {},
_Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
{
@@ -1281,7 +1281,7 @@ namespace ranges
template<permutable _Iter, sentinel_for<_Iter> _Sent,
typename _Proj = identity,
indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
- constexpr subrange<_Iter>
+ [[nodiscard]] constexpr subrange<_Iter>
operator()(_Iter __first, _Sent __last,
_Pred __pred, _Proj __proj = {}) const
{
@@ -1305,7 +1305,7 @@ namespace ranges
indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
_Pred>
requires permutable<iterator_t<_Range>>
- constexpr borrowed_subrange_t<_Range>
+ [[nodiscard]] constexpr borrowed_subrange_t<_Range>
operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const
{
return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -1323,7 +1323,7 @@ namespace ranges
requires indirect_binary_predicate<ranges::equal_to,
projected<_Iter, _Proj>,
const _Tp*>
- constexpr subrange<_Iter>
+ [[nodiscard]] constexpr subrange<_Iter>
operator()(_Iter __first, _Sent __last,
const _Tp& __value, _Proj __proj = {}) const
{
@@ -1341,7 +1341,7 @@ namespace ranges
&& indirect_binary_predicate<ranges::equal_to,
projected<iterator_t<_Range>, _Proj>,
const _Tp*>
- constexpr borrowed_subrange_t<_Range>
+ [[nodiscard]] constexpr borrowed_subrange_t<_Range>
operator()(_Range&& __r, const _Tp& __value, _Proj __proj = {}) const
{
return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -1440,7 +1440,7 @@ namespace ranges
typename _Proj = identity,
indirect_equivalence_relation<
projected<_Iter, _Proj>> _Comp = ranges::equal_to>
- constexpr subrange<_Iter>
+ [[nodiscard]] constexpr subrange<_Iter>
operator()(_Iter __first, _Sent __last,
_Comp __comp = {}, _Proj __proj = {}) const
{
@@ -1462,7 +1462,7 @@ namespace ranges
indirect_equivalence_relation<
projected<iterator_t<_Range>, _Proj>> _Comp = ranges::equal_to>
requires permutable<iterator_t<_Range>>
- constexpr borrowed_subrange_t<_Range>
+ [[nodiscard]] constexpr borrowed_subrange_t<_Range>
operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
{
return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -2849,7 +2849,7 @@ namespace ranges
typename _Proj = identity,
indirect_strict_weak_order<projected<_Iter, _Proj>>
_Comp = ranges::less>
- constexpr _Iter
+ [[nodiscard]] constexpr _Iter
operator()(_Iter __first, _Sent __last,
_Comp __comp = {}, _Proj __proj = {}) const
{
@@ -2868,7 +2868,7 @@ namespace ranges
template<forward_range _Range, typename _Proj = identity,
indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>>
_Comp = ranges::less>
- constexpr borrowed_iterator_t<_Range>
+ [[nodiscard]] constexpr borrowed_iterator_t<_Range>
operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
{
return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -2884,7 +2884,7 @@ namespace ranges
typename _Proj = identity,
indirect_strict_weak_order<projected<_Iter, _Proj>>
_Comp = ranges::less>
- constexpr bool
+ [[nodiscard]] constexpr bool
operator()(_Iter __first, _Sent __last,
_Comp __comp = {}, _Proj __proj = {}) const
{
@@ -2903,7 +2903,7 @@ namespace ranges
template<forward_range _Range, typename _Proj = identity,
indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>>
_Comp = ranges::less>
- constexpr bool
+ [[nodiscard]] constexpr bool
operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
{
return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -2987,7 +2987,7 @@ namespace ranges
typename _Tp _GLIBCXX26_RANGE_ALGO_DEF_VAL_T(_Iter, _Proj),
indirect_strict_weak_order<const _Tp*, projected<_Iter, _Proj>>
_Comp = ranges::less>
- constexpr _Iter
+ [[nodiscard]] constexpr _Iter
operator()(_Iter __first, _Sent __last,
const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const
{
@@ -3017,7 +3017,7 @@ namespace ranges
indirect_strict_weak_order<const _Tp*,
projected<iterator_t<_Range>, _Proj>>
_Comp = ranges::less>
- constexpr borrowed_iterator_t<_Range>
+ [[nodiscard]] constexpr borrowed_iterator_t<_Range>
operator()(_Range&& __r,
const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const
{
@@ -3035,7 +3035,7 @@ namespace ranges
typename _Tp _GLIBCXX26_RANGE_ALGO_DEF_VAL_T(_Iter, _Proj),
indirect_strict_weak_order<const _Tp*, projected<_Iter, _Proj>>
_Comp = ranges::less>
- constexpr _Iter
+ [[nodiscard]] constexpr _Iter
operator()(_Iter __first, _Sent __last,
const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const
{
@@ -3065,7 +3065,7 @@ namespace ranges
indirect_strict_weak_order<const _Tp*,
projected<iterator_t<_Range>, _Proj>>
_Comp = ranges::less>
- constexpr borrowed_iterator_t<_Range>
+ [[nodiscard]] constexpr borrowed_iterator_t<_Range>
operator()(_Range&& __r,
const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const
{
@@ -3083,7 +3083,7 @@ namespace ranges
typename _Tp _GLIBCXX26_RANGE_ALGO_DEF_VAL_T(_Iter, _Proj),
indirect_strict_weak_order<const _Tp*, projected<_Iter, _Proj>>
_Comp = ranges::less>
- constexpr subrange<_Iter>
+ [[nodiscard]] constexpr subrange<_Iter>
operator()(_Iter __first, _Sent __last,
const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const
{
@@ -3128,7 +3128,7 @@ namespace ranges
indirect_strict_weak_order<const _Tp*,
projected<iterator_t<_Range>, _Proj>>
_Comp = ranges::less>
- constexpr borrowed_subrange_t<_Range>
+ [[nodiscard]] constexpr borrowed_subrange_t<_Range>
operator()(_Range&& __r, const _Tp& __value,
_Comp __comp = {}, _Proj __proj = {}) const
{
@@ -3146,7 +3146,7 @@ namespace ranges
typename _Tp _GLIBCXX26_RANGE_ALGO_DEF_VAL_T(_Iter, _Proj),
indirect_strict_weak_order<const _Tp*, projected<_Iter, _Proj>>
_Comp = ranges::less>
- constexpr bool
+ [[nodiscard]] constexpr bool
operator()(_Iter __first, _Sent __last,
const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const
{
@@ -3164,7 +3164,7 @@ namespace ranges
indirect_strict_weak_order<const _Tp*,
projected<iterator_t<_Range>, _Proj>>
_Comp = ranges::less>
- constexpr bool
+ [[nodiscard]] constexpr bool
operator()(_Range&& __r, const _Tp& __value, _Comp __comp = {},
_Proj __proj = {}) const
{
@@ -3180,7 +3180,7 @@ namespace ranges
template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
typename _Proj = identity,
indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
- constexpr bool
+ [[nodiscard]] constexpr bool
operator()(_Iter __first, _Sent __last,
_Pred __pred, _Proj __proj = {}) const
{
@@ -3196,7 +3196,7 @@ namespace ranges
template<input_range _Range, typename _Proj = identity,
indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
_Pred>
- constexpr bool
+ [[nodiscard]] constexpr bool
operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const
{
return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -3488,7 +3488,7 @@ namespace ranges
template<forward_iterator _Iter, sentinel_for<_Iter> _Sent,
typename _Proj = identity,
indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
- constexpr _Iter
+ [[nodiscard]] constexpr _Iter
operator()(_Iter __first, _Sent __last,
_Pred __pred, _Proj __proj = {}) const
{
@@ -3514,7 +3514,7 @@ namespace ranges
template<forward_range _Range, typename _Proj = identity,
indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
_Pred>
- constexpr borrowed_iterator_t<_Range>
+ [[nodiscard]] constexpr borrowed_iterator_t<_Range>
operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const
{
return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -3875,7 +3875,7 @@ namespace ranges
indirect_strict_weak_order<projected<_Iter1, _Proj1>,
projected<_Iter2, _Proj2>>
_Comp = ranges::less>
- constexpr bool
+ [[nodiscard]] constexpr bool
operator()(_Iter1 __first1, _Sent1 __last1,
_Iter2 __first2, _Sent2 __last2,
_Comp __comp = {},
@@ -3904,7 +3904,7 @@ namespace ranges
indirect_strict_weak_order<projected<iterator_t<_Range1>, _Proj1>,
projected<iterator_t<_Range2>, _Proj2>>
_Comp = ranges::less>
- constexpr bool
+ [[nodiscard]] constexpr bool
operator()(_Range1&& __r1, _Range2&& __r2, _Comp __comp = {},
_Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
{
@@ -4175,7 +4175,7 @@ namespace ranges
template<typename _Tp, typename _Proj = identity,
indirect_strict_weak_order<projected<const _Tp*, _Proj>>
_Comp = ranges::less>
- constexpr const _Tp&
+ [[nodiscard]] constexpr const _Tp&
operator()(const _Tp& __a, const _Tp& __b,
_Comp __comp = {}, _Proj __proj = {}) const
{
@@ -4192,7 +4192,7 @@ namespace ranges
_Comp = ranges::less>
requires indirectly_copyable_storable<iterator_t<_Range>,
range_value_t<_Range>*>
- constexpr range_value_t<_Range>
+ [[nodiscard]] constexpr range_value_t<_Range>
operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
{
auto __first = ranges::begin(__r);
@@ -4213,7 +4213,7 @@ namespace ranges
template<copyable _Tp, typename _Proj = identity,
indirect_strict_weak_order<projected<const _Tp*, _Proj>>
_Comp = ranges::less>
- constexpr _Tp
+ [[nodiscard]] constexpr _Tp
operator()(initializer_list<_Tp> __r,
_Comp __comp = {}, _Proj __proj = {}) const
{
@@ -4229,7 +4229,7 @@ namespace ranges
template<typename _Tp, typename _Proj = identity,
indirect_strict_weak_order<projected<const _Tp*, _Proj>> _Comp
= ranges::less>
- constexpr const _Tp&
+ [[nodiscard]] constexpr const _Tp&
operator()(const _Tp& __val, const _Tp& __lo, const _Tp& __hi,
_Comp __comp = {}, _Proj __proj = {}) const
{
@@ -4279,7 +4279,7 @@ namespace ranges
template<typename _Tp, typename _Proj = identity,
indirect_strict_weak_order<projected<const _Tp*, _Proj>>
_Comp = ranges::less>
- constexpr minmax_result<const _Tp&>
+ [[nodiscard]] constexpr minmax_result<const _Tp&>
operator()(const _Tp& __a, const _Tp& __b,
_Comp __comp = {}, _Proj __proj = {}) const
{
@@ -4295,7 +4295,7 @@ namespace ranges
indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>>
_Comp = ranges::less>
requires indirectly_copyable_storable<iterator_t<_Range>, range_value_t<_Range>*>
- constexpr minmax_result<range_value_t<_Range>>
+ [[nodiscard]] constexpr minmax_result<range_value_t<_Range>>
operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
{
auto __first = ranges::begin(__r);
@@ -4354,7 +4354,7 @@ namespace ranges
template<copyable _Tp, typename _Proj = identity,
indirect_strict_weak_order<projected<const _Tp*, _Proj>>
_Comp = ranges::less>
- constexpr minmax_result<_Tp>
+ [[nodiscard]] constexpr minmax_result<_Tp>
operator()(initializer_list<_Tp> __r,
_Comp __comp = {}, _Proj __proj = {}) const
{
@@ -4371,7 +4371,7 @@ namespace ranges
typename _Proj = identity,
indirect_strict_weak_order<projected<_Iter, _Proj>>
_Comp = ranges::less>
- constexpr _Iter
+ [[nodiscard]] constexpr _Iter
operator()(_Iter __first, _Sent __last,
_Comp __comp = {}, _Proj __proj = {}) const
{
@@ -4392,7 +4392,7 @@ namespace ranges
template<forward_range _Range, typename _Proj = identity,
indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>>
_Comp = ranges::less>
- constexpr borrowed_iterator_t<_Range>
+ [[nodiscard]] constexpr borrowed_iterator_t<_Range>
operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
{
return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -4408,7 +4408,7 @@ namespace ranges
typename _Proj = identity,
indirect_strict_weak_order<projected<_Iter, _Proj>>
_Comp = ranges::less>
- constexpr _Iter
+ [[nodiscard]] constexpr _Iter
operator()(_Iter __first, _Sent __last,
_Comp __comp = {}, _Proj __proj = {}) const
{
@@ -4429,7 +4429,7 @@ namespace ranges
template<forward_range _Range, typename _Proj = identity,
indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>>
_Comp = ranges::less>
- constexpr borrowed_iterator_t<_Range>
+ [[nodiscard]] constexpr borrowed_iterator_t<_Range>
operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
{
return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -4448,7 +4448,7 @@ namespace ranges
typename _Proj = identity,
indirect_strict_weak_order<projected<_Iter, _Proj>>
_Comp = ranges::less>
- constexpr minmax_element_result<_Iter>
+ [[nodiscard]] constexpr minmax_element_result<_Iter>
operator()(_Iter __first, _Sent __last,
_Comp __comp = {}, _Proj __proj = {}) const
{
@@ -4503,7 +4503,7 @@ namespace ranges
template<forward_range _Range, typename _Proj = identity,
indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>>
_Comp = ranges::less>
- constexpr minmax_element_result<borrowed_iterator_t<_Range>>
+ [[nodiscard]] constexpr minmax_element_result<borrowed_iterator_t<_Range>>
operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
{
return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -4521,7 +4521,7 @@ namespace ranges
indirect_strict_weak_order<projected<_Iter1, _Proj1>,
projected<_Iter2, _Proj2>>
_Comp = ranges::less>
- constexpr bool
+ [[nodiscard]] constexpr bool
operator()(_Iter1 __first1, _Sent1 __last1,
_Iter2 __first2, _Sent2 __last2,
_Comp __comp = {},
@@ -4607,7 +4607,7 @@ namespace ranges
indirect_strict_weak_order<projected<iterator_t<_Range1>, _Proj1>,
projected<iterator_t<_Range2>, _Proj2>>
_Comp = ranges::less>
- constexpr bool
+ [[nodiscard]] constexpr bool
operator()(_Range1&& __r1, _Range2&& __r2, _Comp __comp = {},
_Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
{
@@ -4836,7 +4836,7 @@ namespace ranges
typename _Proj = identity,
typename _Tp _GLIBCXX26_RANGE_ALGO_DEF_VAL_T(_Iter, _Proj)>
requires indirect_binary_predicate<ranges::equal_to, projected<_Iter, _Proj>, const _Tp*>
- constexpr subrange<_Iter>
+ [[nodiscard]] constexpr subrange<_Iter>
operator()(_Iter __first, _Sent __last, const _Tp& __value, _Proj __proj = {}) const
{
if constexpr (same_as<_Iter, _Sent> && bidirectional_iterator<_Iter>)
@@ -4869,7 +4869,7 @@ namespace ranges
typename _Tp
_GLIBCXX26_RANGE_ALGO_DEF_VAL_T(iterator_t<_Range>, _Proj)>
requires indirect_binary_predicate<ranges::equal_to, projected<iterator_t<_Range>, _Proj>, const _Tp*>
- constexpr borrowed_subrange_t<_Range>
+ [[nodiscard]] constexpr borrowed_subrange_t<_Range>
operator()(_Range&& __r, const _Tp& __value, _Proj __proj = {}) const
{ return (*this)(ranges::begin(__r), ranges::end(__r), __value, std::move(__proj)); }
};
@@ -4880,7 +4880,7 @@ namespace ranges
{
template<forward_iterator _Iter, sentinel_for<_Iter> _Sent, typename _Proj = identity,
indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
- constexpr subrange<_Iter>
+ [[nodiscard]] constexpr subrange<_Iter>
operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const
{
if constexpr (same_as<_Iter, _Sent> && bidirectional_iterator<_Iter>)
@@ -4911,7 +4911,7 @@ namespace ranges
template<forward_range _Range, typename _Proj = identity,
indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
- constexpr borrowed_subrange_t<_Range>
+ [[nodiscard]] constexpr borrowed_subrange_t<_Range>
operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const
{ return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__pred), std::move(__proj)); }
};
@@ -4922,7 +4922,7 @@ namespace ranges
{
template<forward_iterator _Iter, sentinel_for<_Iter> _Sent, typename _Proj = identity,
indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
- constexpr subrange<_Iter>
+ [[nodiscard]] constexpr subrange<_Iter>
operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const
{
if constexpr (same_as<_Iter, _Sent> && bidirectional_iterator<_Iter>)
@@ -4953,7 +4953,7 @@ namespace ranges
template<forward_range _Range, typename _Proj = identity,
indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
- constexpr borrowed_subrange_t<_Range>
+ [[nodiscard]] constexpr borrowed_subrange_t<_Range>
operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const
{ return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__pred), std::move(__proj)); }
};
diff --git a/libstdc++-v3/include/bits/ranges_algobase.h b/libstdc++-v3/include/bits/ranges_algobase.h
index a08f659b..45ed5b4 100644
--- a/libstdc++-v3/include/bits/ranges_algobase.h
+++ b/libstdc++-v3/include/bits/ranges_algobase.h
@@ -101,7 +101,7 @@ namespace ranges
typename _Pred = ranges::equal_to,
typename _Proj1 = identity, typename _Proj2 = identity>
requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>
- constexpr bool
+ [[nodiscard]] constexpr bool
operator()(_Iter1 __first1, _Sent1 __last1,
_Iter2 __first2, _Sent2 __last2, _Pred __pred = {},
_Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
@@ -168,7 +168,7 @@ namespace ranges
typename _Proj1 = identity, typename _Proj2 = identity>
requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>,
_Pred, _Proj1, _Proj2>
- constexpr bool
+ [[nodiscard]] constexpr bool
operator()(_Range1&& __r1, _Range2&& __r2, _Pred __pred = {},
_Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
{
diff --git a/libstdc++-v3/include/bits/ranges_util.h b/libstdc++-v3/include/bits/ranges_util.h
index 53b7f5c..84de258 100644
--- a/libstdc++-v3/include/bits/ranges_util.h
+++ b/libstdc++-v3/include/bits/ranges_util.h
@@ -501,7 +501,7 @@ namespace ranges
typename _Tp _GLIBCXX26_RANGE_ALGO_DEF_VAL_T(_Iter, _Proj)>
requires indirect_binary_predicate<ranges::equal_to,
projected<_Iter, _Proj>, const _Tp*>
- constexpr _Iter
+ [[nodiscard]] constexpr _Iter
operator()(_Iter __first, _Sent __last,
const _Tp& __value, _Proj __proj = {}) const
{
@@ -537,7 +537,7 @@ namespace ranges
requires indirect_binary_predicate<ranges::equal_to,
projected<iterator_t<_Range>, _Proj>,
const _Tp*>
- constexpr borrowed_iterator_t<_Range>
+ [[nodiscard]] constexpr borrowed_iterator_t<_Range>
operator()(_Range&& __r, const _Tp& __value, _Proj __proj = {}) const
{
return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -552,7 +552,7 @@ namespace ranges
template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
typename _Proj = identity,
indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
- constexpr _Iter
+ [[nodiscard]] constexpr _Iter
operator()(_Iter __first, _Sent __last,
_Pred __pred, _Proj __proj = {}) const
{
@@ -565,7 +565,7 @@ namespace ranges
template<input_range _Range, typename _Proj = identity,
indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
_Pred>
- constexpr borrowed_iterator_t<_Range>
+ [[nodiscard]] constexpr borrowed_iterator_t<_Range>
operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const
{
return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -580,7 +580,7 @@ namespace ranges
template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
typename _Proj = identity,
indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
- constexpr _Iter
+ [[nodiscard]] constexpr _Iter
operator()(_Iter __first, _Sent __last,
_Pred __pred, _Proj __proj = {}) const
{
@@ -593,7 +593,7 @@ namespace ranges
template<input_range _Range, typename _Proj = identity,
indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
_Pred>
- constexpr borrowed_iterator_t<_Range>
+ [[nodiscard]] constexpr borrowed_iterator_t<_Range>
operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const
{
return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -634,7 +634,7 @@ namespace ranges
typename _Pred = ranges::equal_to,
typename _Proj1 = identity, typename _Proj2 = identity>
requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>
- constexpr mismatch_result<_Iter1, _Iter2>
+ [[nodiscard]] constexpr mismatch_result<_Iter1, _Iter2>
operator()(_Iter1 __first1, _Sent1 __last1,
_Iter2 __first2, _Sent2 __last2, _Pred __pred = {},
_Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
@@ -655,6 +655,7 @@ namespace ranges
typename _Proj1 = identity, typename _Proj2 = identity>
requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>,
_Pred, _Proj1, _Proj2>
+ [[nodiscard]]
constexpr mismatch_result<iterator_t<_Range1>, iterator_t<_Range2>>
operator()(_Range1&& __r1, _Range2&& __r2, _Pred __pred = {},
_Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
@@ -675,7 +676,7 @@ namespace ranges
typename _Pred = ranges::equal_to,
typename _Proj1 = identity, typename _Proj2 = identity>
requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>
- constexpr subrange<_Iter1>
+ [[nodiscard]] constexpr subrange<_Iter1>
operator()(_Iter1 __first1, _Sent1 __last1,
_Iter2 __first2, _Sent2 __last2, _Pred __pred = {},
_Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
@@ -719,7 +720,7 @@ namespace ranges
typename _Proj1 = identity, typename _Proj2 = identity>
requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>,
_Pred, _Proj1, _Proj2>
- constexpr borrowed_subrange_t<_Range1>
+ [[nodiscard]] constexpr borrowed_subrange_t<_Range1>
operator()(_Range1&& __r1, _Range2&& __r2, _Pred __pred = {},
_Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
{
@@ -737,7 +738,7 @@ namespace ranges
template<typename _Tp, typename _Proj = identity,
indirect_strict_weak_order<projected<const _Tp*, _Proj>>
_Comp = ranges::less>
- constexpr const _Tp&
+ [[nodiscard]] constexpr const _Tp&
operator()(const _Tp& __a, const _Tp& __b,
_Comp __comp = {}, _Proj __proj = {}) const
{
@@ -754,7 +755,7 @@ namespace ranges
_Comp = ranges::less>
requires indirectly_copyable_storable<iterator_t<_Range>,
range_value_t<_Range>*>
- constexpr range_value_t<_Range>
+ [[nodiscard]] constexpr range_value_t<_Range>
operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
{
auto __first = ranges::begin(__r);
@@ -775,7 +776,7 @@ namespace ranges
template<copyable _Tp, typename _Proj = identity,
indirect_strict_weak_order<projected<const _Tp*, _Proj>>
_Comp = ranges::less>
- constexpr _Tp
+ [[nodiscard]] constexpr _Tp
operator()(initializer_list<_Tp> __r,
_Comp __comp = {}, _Proj __proj = {}) const
{
@@ -793,7 +794,7 @@ namespace ranges
indirect_binary_predicate<projected<_Iter, _Proj>,
projected<_Iter, _Proj>> _Pred
= ranges::equal_to>
- constexpr _Iter
+ [[nodiscard]] constexpr _Iter
operator()(_Iter __first, _Sent __last,
_Pred __pred = {}, _Proj __proj = {}) const
{
@@ -814,7 +815,7 @@ namespace ranges
indirect_binary_predicate<
projected<iterator_t<_Range>, _Proj>,
projected<iterator_t<_Range>, _Proj>> _Pred = ranges::equal_to>
- constexpr borrowed_iterator_t<_Range>
+ [[nodiscard]] constexpr borrowed_iterator_t<_Range>
operator()(_Range&& __r, _Pred __pred = {}, _Proj __proj = {}) const
{
return (*this)(ranges::begin(__r), ranges::end(__r),
diff --git a/libstdc++-v3/include/bits/stl_algo.h b/libstdc++-v3/include/bits/stl_algo.h
index 3f4674d..81a2457 100644
--- a/libstdc++-v3/include/bits/stl_algo.h
+++ b/libstdc++-v3/include/bits/stl_algo.h
@@ -5759,7 +5759,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
#if __cplusplus >= 201103L
// N2722 + DR 915.
template<typename _Tp>
- _GLIBCXX14_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX14_CONSTEXPR
inline _Tp
min(initializer_list<_Tp> __l)
{
@@ -5769,7 +5769,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
}
template<typename _Tp, typename _Compare>
- _GLIBCXX14_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX14_CONSTEXPR
inline _Tp
min(initializer_list<_Tp> __l, _Compare __comp)
{
@@ -5779,7 +5779,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
}
template<typename _Tp>
- _GLIBCXX14_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX14_CONSTEXPR
inline _Tp
max(initializer_list<_Tp> __l)
{
@@ -5789,7 +5789,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
}
template<typename _Tp, typename _Compare>
- _GLIBCXX14_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX14_CONSTEXPR
inline _Tp
max(initializer_list<_Tp> __l, _Compare __comp)
{
diff --git a/libstdc++-v3/include/bits/stl_iterator_base_funcs.h b/libstdc++-v3/include/bits/stl_iterator_base_funcs.h
index 637159f..f78e535 100644
--- a/libstdc++-v3/include/bits/stl_iterator_base_funcs.h
+++ b/libstdc++-v3/include/bits/stl_iterator_base_funcs.h
@@ -130,6 +130,28 @@ _GLIBCXX_END_NAMESPACE_CONTAINER
__distance(_OutputIterator, _OutputIterator, output_iterator_tag) = delete;
#endif
+#ifdef __glibcxx_concepts
+namespace __detail
+{
+ // Satisfied if ITER_TRAITS(Iter)::iterator_category is valid and is
+ // at least as strong as ITER_TRAITS(Iter)::iterator_concept.
+ template<typename _Iter>
+ concept __iter_category_converts_to_concept
+ = convertible_to<typename __iter_traits<_Iter>::iterator_category,
+ typename __iter_traits<_Iter>::iterator_concept>;
+
+ // Satisfied if the type is a C++20 iterator that defines iterator_concept,
+ // and its iterator_concept is stronger than its iterator_category (if any).
+ // Used by std::distance and std::advance to detect iterators which should
+ // dispatch based on their C++20 concept not their C++17 category.
+ template<typename _Iter>
+ concept __promotable_iterator
+ = input_iterator<_Iter>
+ && requires { typename __iter_traits<_Iter>::iterator_concept; }
+ && ! __iter_category_converts_to_concept<_Iter>;
+} // namespace __detail
+#endif
+
/**
* @brief A generalization of pointer arithmetic.
* @param __first An input iterator.
@@ -149,6 +171,24 @@ _GLIBCXX_END_NAMESPACE_CONTAINER
typename iterator_traits<_InputIterator>::difference_type
distance(_InputIterator __first, _InputIterator __last)
{
+#ifdef __glibcxx_concepts
+ // A type which satisfies the C++20 random_access_iterator concept might
+ // have input_iterator_tag as its iterator_category type, which would
+ // mean we select the O(n) __distance. Or a C++20 std::input_iterator
+ // that is not a Cpp17InputIterator might have output_iterator_tag as
+ // its iterator_category type and then calling __distance with
+ // std::__iterator_category(__first) would be ill-formed.
+ // So for C++20 iterator types we can just choose to do the right thing.
+ if constexpr (__detail::__promotable_iterator<_InputIterator>)
+ {
+ if constexpr (random_access_iterator<_InputIterator>)
+ return __last - __first;
+ else
+ return std::__distance(std::move(__first), std::move(__last),
+ input_iterator_tag());
+ }
+ else // assume it meets the Cpp17InputIterator requirements:
+#endif
// concept requirements -- taken care of in __distance
return std::__distance(__first, __last,
std::__iterator_category(__first));
@@ -221,9 +261,31 @@ _GLIBCXX_END_NAMESPACE_CONTAINER
inline _GLIBCXX17_CONSTEXPR void
advance(_InputIterator& __i, _Distance __n)
{
- // concept requirements -- taken care of in __advance
- typename iterator_traits<_InputIterator>::difference_type __d = __n;
- std::__advance(__i, __d, std::__iterator_category(__i));
+#ifdef __glibcxx_concepts
+ // A type which satisfies the C++20 bidirectional_iterator concept might
+ // have input_iterator_tag as its iterator_category type, which would
+ // mean we select the __advance overload which cannot move backwards.
+ // A C++20 random_access_iterator we might select the O(n) __advance
+ // if it doesn't meet the Cpp17RandomAccessIterator requirements.
+ // So for C++20 iterator types we can just choose to do the right thing.
+ if constexpr (__detail::__promotable_iterator<_InputIterator>
+ && ranges::__detail::__is_integer_like<_Distance>)
+ {
+ auto __d = static_cast<iter_difference_t<_InputIterator>>(__n);
+ if constexpr (random_access_iterator<_InputIterator>)
+ std::__advance(__i, __d, random_access_iterator_tag());
+ else if constexpr (bidirectional_iterator<_InputIterator>)
+ std::__advance(__i, __d, bidirectional_iterator_tag());
+ else
+ std::__advance(__i, __d, input_iterator_tag());
+ }
+ else // assume it meets the Cpp17InputIterator requirements:
+#endif
+ {
+ // concept requirements -- taken care of in __advance
+ typename iterator_traits<_InputIterator>::difference_type __d = __n;
+ std::__advance(__i, __d, std::__iterator_category(__i));
+ }
}
#if __cplusplus >= 201103L
diff --git a/libstdc++-v3/include/bits/stl_vector.h b/libstdc++-v3/include/bits/stl_vector.h
index f2c1bce..7625333 100644
--- a/libstdc++-v3/include/bits/stl_vector.h
+++ b/libstdc++-v3/include/bits/stl_vector.h
@@ -1154,7 +1154,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
resize(size_type __new_size, const value_type& __x)
{
if (__new_size > size())
- _M_fill_insert(end(), __new_size - size(), __x);
+ _M_fill_append(__new_size - size(), __x);
else if (__new_size < size())
_M_erase_at_end(this->_M_impl._M_start + __new_size);
}
@@ -1175,7 +1175,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
resize(size_type __new_size, value_type __x = value_type())
{
if (__new_size > size())
- _M_fill_insert(end(), __new_size - size(), __x);
+ _M_fill_append(__new_size - size(), __x);
else if (__new_size < size())
_M_erase_at_end(this->_M_impl._M_start + __new_size);
}
@@ -2088,6 +2088,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
void
_M_fill_insert(iterator __pos, size_type __n, const value_type& __x);
+ // Called by resize(n,x), and the _M_fill_insert(end(), n, x)
+ _GLIBCXX20_CONSTEXPR
+ void
+ _M_fill_append(size_type __n, const value_type& __x);
+
#if __cplusplus >= 201103L
// Called by resize(n).
_GLIBCXX20_CONSTEXPR
diff --git a/libstdc++-v3/include/bits/utility.h b/libstdc++-v3/include/bits/utility.h
index 84d25e0..4e57465 100644
--- a/libstdc++-v3/include/bits/utility.h
+++ b/libstdc++-v3/include/bits/utility.h
@@ -137,26 +137,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
using tuple_element_t = typename tuple_element<__i, _Tp>::type;
#endif
- // Stores a tuple of indices. Used by tuple and pair, and by bind() to
- // extract the elements in a tuple.
- template<size_t... _Indexes> struct _Index_tuple { };
-
- // Builds an _Index_tuple<0, 1, 2, ..., _Num-1>.
- template<size_t _Num>
- struct _Build_index_tuple
- {
-#if __has_builtin(__make_integer_seq)
- template<typename, size_t... _Indices>
- using _IdxTuple = _Index_tuple<_Indices...>;
-
- // Clang defines __make_integer_seq for this purpose.
- using __type = __make_integer_seq<_IdxTuple, size_t, _Num>;
-#else
- // For GCC and other compilers, use __integer_pack instead.
- using __type = _Index_tuple<__integer_pack(_Num)...>;
-#endif
- };
-
#ifdef __glibcxx_integer_sequence // C++ >= 14
/// Class template integer_sequence
diff --git a/libstdc++-v3/include/bits/vector.tcc b/libstdc++-v3/include/bits/vector.tcc
index 70ead1d..642edb5 100644
--- a/libstdc++-v3/include/bits/vector.tcc
+++ b/libstdc++-v3/include/bits/vector.tcc
@@ -664,8 +664,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{
if (__n != 0)
{
- if (size_type(this->_M_impl._M_end_of_storage
- - this->_M_impl._M_finish) >= __n)
+ if (__position.base() == this->_M_impl._M_finish)
+ _M_fill_append(__n, __x);
+ else if (size_type(this->_M_impl._M_end_of_storage
+ - this->_M_impl._M_finish) >= __n)
{
#if __cplusplus < 201103L
value_type __x_copy = __x;
@@ -760,6 +762,60 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
}
}
+ template<typename _Tp, typename _Alloc>
+ _GLIBCXX20_CONSTEXPR
+ void
+ vector<_Tp, _Alloc>::
+ _M_fill_append(size_type __n, const value_type& __x)
+ {
+ if (size_type(this->_M_impl._M_end_of_storage
+ - this->_M_impl._M_finish) >= __n)
+ {
+ _GLIBCXX_ASAN_ANNOTATE_GROW(__n);
+ this->_M_impl._M_finish =
+ std::__uninitialized_fill_n_a(this->_M_impl._M_finish, __n, __x,
+ _M_get_Tp_allocator());
+ _GLIBCXX_ASAN_ANNOTATE_GREW(__n);
+ }
+ else
+ {
+ // Make local copies of these members because the compiler thinks
+ // the allocator can alter them if 'this' is globally reachable.
+ pointer __old_start = this->_M_impl._M_start;
+ pointer __old_finish = this->_M_impl._M_finish;
+ const size_type __old_size = __old_finish - __old_start;
+
+ const size_type __len =
+ _M_check_len(__n, "vector::_M_fill_append");
+ pointer __new_start(this->_M_allocate(__len));
+ pointer __new_finish(__new_start + __old_size);
+ __try
+ {
+ // See _M_realloc_insert above.
+ __new_finish = std::__uninitialized_fill_n_a(
+ __new_finish, __n, __x,
+ _M_get_Tp_allocator());
+ std::__uninitialized_move_if_noexcept_a(
+ __old_start, __old_finish, __new_start,
+ _M_get_Tp_allocator());
+ }
+ __catch(...)
+ {
+ std::_Destroy(__new_start + __old_size, __new_finish,
+ _M_get_Tp_allocator());
+ _M_deallocate(__new_start, __len);
+ __throw_exception_again;
+ }
+ std::_Destroy(__old_start, __old_finish, _M_get_Tp_allocator());
+ _GLIBCXX_ASAN_ANNOTATE_REINIT;
+ _M_deallocate(__old_start,
+ this->_M_impl._M_end_of_storage - __old_start);
+ this->_M_impl._M_start = __new_start;
+ this->_M_impl._M_finish = __new_finish;
+ this->_M_impl._M_end_of_storage = __new_start + __len;
+ }
+ }
+
#if __cplusplus >= 201103L
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr
@@ -1007,15 +1063,18 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
if constexpr (ranges::forward_range<_Rg>)
{
+ const auto __ins_idx = __pos - cbegin();
+ // Number of new elements to insert:
+ const auto __n = size_type(ranges::distance(__rg));
+ if (__n == 0)
+ return begin() + __ins_idx;
+
// Start of existing elements:
pointer __old_start = this->_M_impl._M_start;
// End of existing elements:
pointer __old_finish = this->_M_impl._M_finish;
// Insertion point:
- const auto __ins_idx = __pos - cbegin();
pointer __ins = __old_start + __ins_idx;
- // Number of new elements to insert:
- const auto __n = size_type(ranges::distance(__rg));
// Number of elements that can fit in unused capacity:
const auto __cap = this->_M_impl._M_end_of_storage - __old_finish;
if (__cap >= __n)
diff --git a/libstdc++-v3/include/bits/version.def b/libstdc++-v3/include/bits/version.def
index dbe2cb8..84c755d 100644
--- a/libstdc++-v3/include/bits/version.def
+++ b/libstdc++-v3/include/bits/version.def
@@ -733,6 +733,14 @@ ftms = {
};
ftms = {
+ name = is_sufficiently_aligned;
+ values = {
+ v = 202411;
+ cxxmin = 26;
+ };
+};
+
+ftms = {
name = atomic_flag_test;
values = {
v = 201907;
@@ -1008,12 +1016,26 @@ ftms = {
ftms = {
name = mdspan;
values = {
+ v = 202406;
+ cxxmin = 26;
+ };
+ values = {
v = 202207;
cxxmin = 23;
};
};
ftms = {
+ name = aligned_accessor;
+ values = {
+ v = 202411;
+ cxxmin = 26;
+ extra_cond = "__glibcxx_assume_aligned "
+ "&& __glibcxx_is_sufficiently_aligned";
+ };
+};
+
+ftms = {
name = ssize;
values = {
v = 201902;
@@ -1885,6 +1907,14 @@ ftms = {
};
ftms = {
+ name = debugging;
+ values = {
+ v = 202403;
+ cxxmin = 26;
+ };
+};
+
+ftms = {
name = fstream_native_handle;
values = {
v = 202306;
diff --git a/libstdc++-v3/include/bits/version.h b/libstdc++-v3/include/bits/version.h
index 7bb6016..410e320 100644
--- a/libstdc++-v3/include/bits/version.h
+++ b/libstdc++-v3/include/bits/version.h
@@ -815,6 +815,16 @@
#endif /* !defined(__cpp_lib_assume_aligned) && defined(__glibcxx_want_assume_aligned) */
#undef __glibcxx_want_assume_aligned
+#if !defined(__cpp_lib_is_sufficiently_aligned)
+# if (__cplusplus > 202302L)
+# define __glibcxx_is_sufficiently_aligned 202411L
+# if defined(__glibcxx_want_all) || defined(__glibcxx_want_is_sufficiently_aligned)
+# define __cpp_lib_is_sufficiently_aligned 202411L
+# endif
+# endif
+#endif /* !defined(__cpp_lib_is_sufficiently_aligned) && defined(__glibcxx_want_is_sufficiently_aligned) */
+#undef __glibcxx_want_is_sufficiently_aligned
+
#if !defined(__cpp_lib_atomic_flag_test)
# if (__cplusplus >= 202002L)
# define __glibcxx_atomic_flag_test 201907L
@@ -1125,7 +1135,12 @@
#undef __glibcxx_want_span
#if !defined(__cpp_lib_mdspan)
-# if (__cplusplus >= 202100L)
+# if (__cplusplus > 202302L)
+# define __glibcxx_mdspan 202406L
+# if defined(__glibcxx_want_all) || defined(__glibcxx_want_mdspan)
+# define __cpp_lib_mdspan 202406L
+# endif
+# elif (__cplusplus >= 202100L)
# define __glibcxx_mdspan 202207L
# if defined(__glibcxx_want_all) || defined(__glibcxx_want_mdspan)
# define __cpp_lib_mdspan 202207L
@@ -1134,6 +1149,16 @@
#endif /* !defined(__cpp_lib_mdspan) && defined(__glibcxx_want_mdspan) */
#undef __glibcxx_want_mdspan
+#if !defined(__cpp_lib_aligned_accessor)
+# if (__cplusplus > 202302L) && (__glibcxx_assume_aligned && __glibcxx_is_sufficiently_aligned)
+# define __glibcxx_aligned_accessor 202411L
+# if defined(__glibcxx_want_all) || defined(__glibcxx_want_aligned_accessor)
+# define __cpp_lib_aligned_accessor 202411L
+# endif
+# endif
+#endif /* !defined(__cpp_lib_aligned_accessor) && defined(__glibcxx_want_aligned_accessor) */
+#undef __glibcxx_want_aligned_accessor
+
#if !defined(__cpp_lib_ssize)
# if (__cplusplus >= 202002L)
# define __glibcxx_ssize 201902L
@@ -2109,6 +2134,16 @@
#endif /* !defined(__cpp_lib_constexpr_new) && defined(__glibcxx_want_constexpr_new) */
#undef __glibcxx_want_constexpr_new
+#if !defined(__cpp_lib_debugging)
+# if (__cplusplus > 202302L)
+# define __glibcxx_debugging 202403L
+# if defined(__glibcxx_want_all) || defined(__glibcxx_want_debugging)
+# define __cpp_lib_debugging 202403L
+# endif
+# endif
+#endif /* !defined(__cpp_lib_debugging) && defined(__glibcxx_want_debugging) */
+#undef __glibcxx_want_debugging
+
#if !defined(__cpp_lib_fstream_native_handle)
# if (__cplusplus > 202302L) && _GLIBCXX_HOSTED
# define __glibcxx_fstream_native_handle 202306L
diff --git a/libstdc++-v3/include/debug/bitset b/libstdc++-v3/include/debug/bitset
index ad9b7b5..e4d3e66 100644
--- a/libstdc++-v3/include/debug/bitset
+++ b/libstdc++-v3/include/debug/bitset
@@ -164,6 +164,17 @@ namespace __debug
_CharT __zero, _CharT __one = _CharT('1'))
: _Base(__str, __pos, __n, __zero, __one) { }
+#ifdef __cpp_lib_bitset // ... from string_view
+ template<class _CharT, class _Traits>
+ constexpr explicit
+ bitset(std::basic_string_view<_CharT, _Traits> __s,
+ std::basic_string_view<_CharT, _Traits>::size_type __position = 0,
+ std::basic_string_view<_CharT, _Traits>::size_type __n =
+ std::basic_string_view<_CharT, _Traits>::npos,
+ _CharT __zero = _CharT('0'), _CharT __one = _CharT('1'))
+ : _Base(__s, __position, __n, __zero, __one) { }
+#endif
+
_GLIBCXX23_CONSTEXPR
bitset(const _Base& __x) : _Base(__x) { }
diff --git a/libstdc++-v3/include/precompiled/stdc++.h b/libstdc++-v3/include/precompiled/stdc++.h
index 733a5e5..636632a 100644
--- a/libstdc++-v3/include/precompiled/stdc++.h
+++ b/libstdc++-v3/include/precompiled/stdc++.h
@@ -237,6 +237,7 @@
#endif
#if __cplusplus > 202302L
+#include <debugging>
#include <inplace_vector>
#include <text_encoding>
#include <stdbit.h>
diff --git a/libstdc++-v3/include/std/bitset b/libstdc++-v3/include/std/bitset
index 93a03f6..92f11f1 100644
--- a/libstdc++-v3/include/std/bitset
+++ b/libstdc++-v3/include/std/bitset
@@ -1040,6 +1040,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
#endif
#if __cplusplus >= 201103L
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 4294. bitset(const CharT*) constructor needs to be constrained
/**
* Construct from a character %array.
* @param __str An %array of characters `__zero` and `__one`.
@@ -1049,7 +1051,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* @throw std::invalid_argument If a character appears in the string
* which is neither `__zero` nor `__one`.
*/
- template<typename _CharT>
+ template<typename _CharT,
+ typename = _Require<is_trivially_copyable<_CharT>,
+ is_standard_layout<_CharT>,
+ is_trivially_default_constructible<_CharT>,
+ __not_<is_array<_CharT>>>>
[[__gnu__::__nonnull__]]
_GLIBCXX23_CONSTEXPR
explicit
diff --git a/libstdc++-v3/include/std/chrono b/libstdc++-v3/include/std/chrono
index cb8213e..d1a01fb 100644
--- a/libstdc++-v3/include/std/chrono
+++ b/libstdc++-v3/include/std/chrono
@@ -22,6 +22,8 @@
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
+// [time]
+
/** @file include/chrono
* This is a Standard C++ Library header.
* @ingroup chrono
@@ -42,12 +44,16 @@
# include <bits/c++0x_warning.h>
#else
+#define __glibcxx_want_chrono
+#define __glibcxx_want_chrono_udls
+#include <bits/version.h>
+
#include <bits/chrono.h>
-#if __cplusplus >= 202002L
+#if __cpp_lib_bitops >= 201907L
# include <bit> // __countr_zero
#endif
-#if __cplusplus >= 202002L && _GLIBCXX_HOSTED
+#if __cpp_lib_chrono >= 201803L && _GLIBCXX_HOSTED
# include <sstream>
# include <string>
# include <vector>
@@ -56,10 +62,6 @@
# include <bits/unique_ptr.h>
#endif
-#define __glibcxx_want_chrono
-#define __glibcxx_want_chrono_udls
-#include <bits/version.h>
-
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -79,7 +81,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*/
namespace chrono
{
-#if __cplusplus >= 202002L
+#if __cpp_lib_chrono >= 201803L
/// @addtogroup chrono
/// @{
struct local_t { };
@@ -175,13 +177,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
using period = system_clock::period;
using duration = chrono::duration<rep, period>;
using time_point = chrono::time_point<tai_clock>;
- static constexpr bool is_steady = false; // XXX true for CLOCK_TAI?
+ static constexpr bool is_steady = false;
- // TODO move into lib, use CLOCK_TAI on linux, add extension point.
[[nodiscard]]
static time_point
- now()
- { return from_utc(utc_clock::now()); }
+ now(); // in src/c++20/clock.cc
template<typename _Duration>
[[nodiscard]]
@@ -215,13 +215,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
using period = system_clock::period;
using duration = chrono::duration<rep, period>;
using time_point = chrono::time_point<gps_clock>;
- static constexpr bool is_steady = false; // XXX
+ static constexpr bool is_steady = false;
- // TODO move into lib, add extension point.
[[nodiscard]]
static time_point
- now()
- { return from_utc(utc_clock::now()); }
+ now(); // in src/c++20/clock.cc
template<typename _Duration>
[[nodiscard]]
@@ -3321,7 +3319,7 @@ namespace __detail
#endif // C++20
} // namespace chrono
-#if __cplusplus >= 202002L
+#if __cpp_lib_chrono >= 201803L
inline namespace literals
{
inline namespace chrono_literals
@@ -3350,7 +3348,7 @@ namespace __detail
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
-#if __cplusplus >= 202002L && _GLIBCXX_HOSTED
+#if __cpp_lib_chrono >= 201803L && _GLIBCXX_HOSTED
# include <bits/chrono_io.h>
#endif
diff --git a/libstdc++-v3/include/std/complex b/libstdc++-v3/include/std/complex
index d9d2d8a..4765425 100644
--- a/libstdc++-v3/include/std/complex
+++ b/libstdc++-v3/include/std/complex
@@ -96,7 +96,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Tp>
_GLIBCXX20_CONSTEXPR complex<_Tp> conj(const complex<_Tp>&);
/// Return complex with magnitude @a rho and angle @a theta.
- template<typename _Tp> complex<_Tp> polar(const _Tp&, const _Tp& = 0);
+ template<typename _Tp> complex<_Tp> polar(const _Tp&, const _Tp& = _Tp(0));
// Transcendentals:
/// Return complex cosine of @a z.
@@ -1038,7 +1038,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
inline complex<_Tp>
polar(const _Tp& __rho, const _Tp& __theta)
{
- __glibcxx_assert( __rho >= 0 );
+ __glibcxx_assert( __rho >= _Tp(0) );
return complex<_Tp>(__rho * cos(__theta), __rho * sin(__theta));
}
@@ -1238,13 +1238,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
if (__x == _Tp())
{
- _Tp __t = sqrt(abs(__y) / 2);
+ _Tp __t = sqrt(abs(__y) / _Tp(2));
return complex<_Tp>(__t, __y < _Tp() ? -__t : __t);
}
else
{
- _Tp __t = sqrt(2 * (std::abs(__z) + abs(__x)));
- _Tp __u = __t / 2;
+ _Tp __t = sqrt(_Tp(2) * (std::abs(__z) + abs(__x)));
+ _Tp __u = __t / _Tp(2);
return __x > _Tp()
? complex<_Tp>(__u, __y / __t)
: complex<_Tp>(abs(__y) / __t, __y < _Tp() ? -__u : __u);
@@ -1334,7 +1334,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
complex<_Tp>
__complex_pow_unsigned(complex<_Tp> __x, unsigned __n)
{
- complex<_Tp> __y = __n % 2 ? __x : complex<_Tp>(1);
+ complex<_Tp> __y = __n % 2 ? __x : complex<_Tp>(_Tp(1));
while (__n >>= 1)
{
@@ -1357,7 +1357,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
pow(const complex<_Tp>& __z, int __n)
{
return __n < 0
- ? complex<_Tp>(1) / std::__complex_pow_unsigned(__z, -(unsigned)__n)
+ ? complex<_Tp>(_Tp(1)) / std::__complex_pow_unsigned(__z,
+ -(unsigned)__n)
: std::__complex_pow_unsigned(__z, __n);
}
diff --git a/libstdc++-v3/include/std/debugging b/libstdc++-v3/include/std/debugging
new file mode 100644
index 0000000..4cf7e4a
--- /dev/null
+++ b/libstdc++-v3/include/std/debugging
@@ -0,0 +1,77 @@
+// Debugging support -*- C++ -*-
+
+// Copyright The GNU Toolchain Authors.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file include/debugging
+ * This is a Standard C++ Library header.
+ */
+
+#ifndef _GLIBCXX_DEBUGGING
+#define _GLIBCXX_DEBUGGING 1
+
+#define __glibcxx_want_debugging
+#include <bits/version.h>
+
+#if __cpp_lib_debugging // C++ >= 26
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+// N.B. _GLIBCXX_BEGIN_NAMESPACE_VERSION is not used here.
+
+/** Try to determine if the program is running under control of a debugger.
+ *
+ * On GNU/Linux systems this function will only return true if the program
+ * is being traced by another program which is known to be a debugger.
+ * This is determined by checking the command name of the tracing program
+ * against a list of known debuggers, such as "gdb".
+ *
+ * On other POSIX-based systems, this function will return true if the
+ * program is being traced by any other process, which means it can return
+ * true for non-debugger utilities that use the ptrace system call.
+ *
+ * @since C++26
+ */
+bool
+is_debugger_present() noexcept;
+
+/** Stop the program with a breakpoint or debug trap.
+ *
+ * The details of how a breakpoint is implemented are platform-specific.
+ * Some systems provide a special instruction, such as `int3` in x86.
+ * When no more appropriate mechanism is available, this will stop the
+ * program using `__builtin_trap()`. It might not be possible for the
+ * program to continue after such a breakpoint.
+ *
+ * @since C++26
+ */
+void
+breakpoint() noexcept;
+
+/** Stop the program if it is running under control of a debugger.
+ *
+ * @since C++26
+ */
+void
+breakpoint_if_debugging() noexcept;
+
+} // namespace std
+#endif
+#endif // _GLIBCXX_DEBUGGING
diff --git a/libstdc++-v3/include/std/functional b/libstdc++-v3/include/std/functional
index 307bcb9..b1cda87 100644
--- a/libstdc++-v3/include/std/functional
+++ b/libstdc++-v3/include/std/functional
@@ -922,6 +922,53 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
#ifdef __cpp_lib_bind_front // C++ >= 20
+ template<size_t, typename _Tp>
+ struct _Indexed_bound_arg
+ {
+ [[no_unique_address]] _Tp _M_val;
+ };
+
+ template<typename... _IndexedArgs>
+ struct _Bound_arg_storage : _IndexedArgs...
+ {
+ template<typename _Fd, typename _Self, typename... _CallArgs>
+ static constexpr
+ decltype(auto)
+ _S_apply_front(_Fd&& __fd, _Self&& __self, _CallArgs&&... __call_args)
+ {
+ return std::invoke(std::forward<_Fd>(__fd),
+ __like_t<_Self, _IndexedArgs>(__self)._M_val...,
+ std::forward<_CallArgs>(__call_args)...);
+ }
+
+ template<typename _Fd, typename _Self, typename... _CallArgs>
+ static constexpr
+ decltype(auto)
+ _S_apply_back(_Fd&& __fd, _Self&& __self, _CallArgs&&... __call_args)
+ {
+ return std::invoke(std::forward<_Fd>(__fd),
+ std::forward<_CallArgs>(__call_args)...,
+ __like_t<_Self, _IndexedArgs>(__self)._M_val...);
+ }
+ };
+
+ template<typename... _BoundArgs, typename... _Args>
+ constexpr auto
+ __make_bound_args(_Args&&... __args)
+ {
+ if constexpr (sizeof...(_BoundArgs) == 1)
+ // pack has one element, so return copy of arg
+ return (_BoundArgs(std::forward<_Args>(__args)), ...);
+ else
+ {
+ auto __impl = [&]<size_t... _Inds>(index_sequence<_Inds...>)
+ {
+ return _Bound_arg_storage<_Indexed_bound_arg<_Inds, _BoundArgs>...>
+ { {_BoundArgs(std::forward<_Args>(__args))}... };
+ };
+ return __impl(index_sequence_for<_BoundArgs...>());
+ }
+ }
template<typename _Fd, typename... _BoundArgs>
struct _Bind_front
@@ -937,7 +984,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
noexcept(__and_<is_nothrow_constructible<_Fd, _Fn>,
is_nothrow_constructible<_BoundArgs, _Args>...>::value)
: _M_fd(std::forward<_Fn>(__fn)),
- _M_bound_args(std::forward<_Args>(__args)...)
+ _M_bound_args(__make_bound_args<_BoundArgs...>(std::forward<_Args>(__args)...))
{ static_assert(sizeof...(_Args) == sizeof...(_BoundArgs)); }
#if __cpp_explicit_this_parameter
@@ -948,7 +995,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
noexcept(is_nothrow_invocable_v<__like_t<_Self, _Fd>,
__like_t<_Self, _BoundArgs>..., _CallArgs...>)
{
- return _S_call(__like_t<_Self, _Bind_front>(__self), _BoundIndices(),
+ return _S_call(__like_t<_Self, _Bind_front>(__self),
std::forward<_CallArgs>(__call_args)...);
}
#else
@@ -959,8 +1006,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
operator()(_CallArgs&&... __call_args) &
noexcept(is_nothrow_invocable_v<_Fd&, _BoundArgs&..., _CallArgs...>)
{
- return _S_call(*this, _BoundIndices(),
- std::forward<_CallArgs>(__call_args)...);
+ return _S_call(*this, std::forward<_CallArgs>(__call_args)...);
}
template<typename... _CallArgs>
@@ -971,8 +1017,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
noexcept(is_nothrow_invocable_v<const _Fd&, const _BoundArgs&...,
_CallArgs...>)
{
- return _S_call(*this, _BoundIndices(),
- std::forward<_CallArgs>(__call_args)...);
+ return _S_call(*this, std::forward<_CallArgs>(__call_args)...);
}
template<typename... _CallArgs>
@@ -982,8 +1027,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
operator()(_CallArgs&&... __call_args) &&
noexcept(is_nothrow_invocable_v<_Fd, _BoundArgs..., _CallArgs...>)
{
- return _S_call(std::move(*this), _BoundIndices(),
- std::forward<_CallArgs>(__call_args)...);
+ return _S_call(std::move(*this),
+ std::forward<_CallArgs>(__call_args)...);
}
template<typename... _CallArgs>
@@ -994,8 +1039,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
noexcept(is_nothrow_invocable_v<const _Fd, const _BoundArgs...,
_CallArgs...>)
{
- return _S_call(std::move(*this), _BoundIndices(),
- std::forward<_CallArgs>(__call_args)...);
+ return _S_call(std::move(*this),
+ std::forward<_CallArgs>(__call_args)...);
}
template<typename... _CallArgs>
@@ -1012,20 +1057,28 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#endif
private:
- using _BoundIndices = index_sequence_for<_BoundArgs...>;
+ using _BoundArgsStorage
+ // _BoundArgs are required to be move-constructible, so this is valid.
+ = decltype(__make_bound_args<_BoundArgs...>(std::declval<_BoundArgs>()...));
- template<typename _Tp, size_t... _Ind, typename... _CallArgs>
+ template<typename _Tp, typename... _CallArgs>
static constexpr
decltype(auto)
- _S_call(_Tp&& __g, index_sequence<_Ind...>, _CallArgs&&... __call_args)
+ _S_call(_Tp&& __g, _CallArgs&&... __call_args)
{
- return std::invoke(std::forward<_Tp>(__g)._M_fd,
- std::get<_Ind>(std::forward<_Tp>(__g)._M_bound_args)...,
- std::forward<_CallArgs>(__call_args)...);
+ if constexpr (sizeof...(_BoundArgs) == 1)
+ return std::invoke(std::forward<_Tp>(__g)._M_fd,
+ std::forward<_Tp>(__g)._M_bound_args,
+ std::forward<_CallArgs>(__call_args)...);
+ else
+ return _BoundArgsStorage::_S_apply_front(
+ std::forward<_Tp>(__g)._M_fd,
+ std::forward<_Tp>(__g)._M_bound_args,
+ std::forward<_CallArgs>(__call_args)...);
}
[[no_unique_address]] _Fd _M_fd;
- [[no_unique_address]] std::tuple<_BoundArgs...> _M_bound_args;
+ [[no_unique_address]] _BoundArgsStorage _M_bound_args;
};
template<typename _Fn, typename... _Args>
@@ -1066,7 +1119,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
noexcept(__and_<is_nothrow_constructible<_Fd, _Fn>,
is_nothrow_constructible<_BoundArgs, _Args>...>::value)
: _M_fd(std::forward<_Fn>(__fn)),
- _M_bound_args(std::forward<_Args>(__args)...)
+ _M_bound_args(__make_bound_args<_BoundArgs...>(std::forward<_Args>(__args)...))
{ static_assert(sizeof...(_Args) == sizeof...(_BoundArgs)); }
template<typename _Self, typename... _CallArgs>
@@ -1076,25 +1129,33 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
noexcept(is_nothrow_invocable_v<__like_t<_Self, _Fd>,
_CallArgs..., __like_t<_Self, _BoundArgs>...>)
{
- return _S_call(__like_t<_Self, _Bind_back>(__self), _BoundIndices(),
+ return _S_call(__like_t<_Self, _Bind_back>(__self),
std::forward<_CallArgs>(__call_args)...);
}
private:
- using _BoundIndices = index_sequence_for<_BoundArgs...>;
+ using _BoundArgsStorage
+ // _BoundArgs are required to be move-constructible, so this is valid.
+ = decltype(__make_bound_args<_BoundArgs...>(std::declval<_BoundArgs>()...));
- template<typename _Tp, size_t... _Ind, typename... _CallArgs>
+ template<typename _Tp, typename... _CallArgs>
static constexpr
decltype(auto)
- _S_call(_Tp&& __g, index_sequence<_Ind...>, _CallArgs&&... __call_args)
+ _S_call(_Tp&& __g, _CallArgs&&... __call_args)
{
- return std::invoke(std::forward<_Tp>(__g)._M_fd,
- std::forward<_CallArgs>(__call_args)...,
- std::get<_Ind>(std::forward<_Tp>(__g)._M_bound_args)...);
+ if constexpr (sizeof...(_BoundArgs) == 1)
+ return std::invoke(std::forward<_Tp>(__g)._M_fd,
+ std::forward<_CallArgs>(__call_args)...,
+ std::forward<_Tp>(__g)._M_bound_args);
+ else
+ return _BoundArgsStorage::_S_apply_back(
+ std::forward<_Tp>(__g)._M_fd,
+ std::forward<_Tp>(__g)._M_bound_args,
+ std::forward<_CallArgs>(__call_args)...);
}
[[no_unique_address]] _Fd _M_fd;
- [[no_unique_address]] std::tuple<_BoundArgs...> _M_bound_args;
+ [[no_unique_address]] _BoundArgsStorage _M_bound_args;
};
template<typename _Fn, typename... _Args>
diff --git a/libstdc++-v3/include/std/inplace_vector b/libstdc++-v3/include/std/inplace_vector
index 290cf6e..b5a81be 100644
--- a/libstdc++-v3/include/std/inplace_vector
+++ b/libstdc++-v3/include/std/inplace_vector
@@ -1354,7 +1354,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
- template<typename _Tp, size_t _Nm, typename _Up>
+ template<typename _Tp, size_t _Nm, typename _Up = _Tp>
constexpr size_t
erase(inplace_vector<_Tp, _Nm>& __cont, const _Up& __value)
{
diff --git a/libstdc++-v3/include/std/limits b/libstdc++-v3/include/std/limits
index 3567a32..49ce7c9 100644
--- a/libstdc++-v3/include/std/limits
+++ b/libstdc++-v3/include/std/limits
@@ -2128,7 +2128,7 @@ __glibcxx_float_n(128)
static _GLIBCXX_USE_CONSTEXPR int digits = 113;
static _GLIBCXX_USE_CONSTEXPR int digits10 = 33;
#if __cplusplus >= 201103L
- static constexpr int max_digits10 = 35;
+ static constexpr int max_digits10 = 36;
#endif
static _GLIBCXX_USE_CONSTEXPR bool is_signed = true;
static _GLIBCXX_USE_CONSTEXPR bool is_integer = false;
diff --git a/libstdc++-v3/include/std/mdspan b/libstdc++-v3/include/std/mdspan
index 055778d..6c7469c 100644
--- a/libstdc++-v3/include/std/mdspan
+++ b/libstdc++-v3/include/std/mdspan
@@ -36,10 +36,14 @@
#include <span>
#include <array>
#include <type_traits>
-#include <limits>
#include <utility>
+#if __cplusplus > 202302L
+#include <bits/align.h>
+#endif
+
#define __glibcxx_want_mdspan
+#define __glibcxx_want_aligned_accessor
#include <bits/version.h>
#ifdef __glibcxx_mdspan
@@ -49,49 +53,66 @@ namespace std _GLIBCXX_VISIBILITY(default)
_GLIBCXX_BEGIN_NAMESPACE_VERSION
namespace __mdspan
{
- template<typename _IndexType, array _Extents>
- class _ExtentsStorage
- {
- public:
- static consteval bool
- _S_is_dyn(size_t __ext) noexcept
- { return __ext == dynamic_extent; }
+ consteval bool
+ __all_static(std::span<const size_t> __extents)
+ {
+ for(auto __ext : __extents)
+ if (__ext == dynamic_extent)
+ return false;
+ return true;
+ }
- template<typename _OIndexType>
- static constexpr _IndexType
- _S_int_cast(const _OIndexType& __other) noexcept
- { return _IndexType(__other); }
+ consteval bool
+ __all_dynamic(std::span<const size_t> __extents)
+ {
+ for(auto __ext : __extents)
+ if (__ext != dynamic_extent)
+ return false;
+ return true;
+ }
+ template<array _Extents>
+ class _StaticExtents
+ {
+ public:
static constexpr size_t _S_rank = _Extents.size();
- // For __r in [0, _S_rank], _S_dynamic_index[__r] is the number
+ // For __r in [0, _S_rank], _S_dynamic_index(__r) is the number
// of dynamic extents up to (and not including) __r.
//
// If __r is the index of a dynamic extent, then
// _S_dynamic_index[__r] is the index of that extent in
// _M_dyn_exts.
- static constexpr auto _S_dynamic_index = [] consteval
+ static constexpr size_t
+ _S_dynamic_index(size_t __r) noexcept
+ { return _S_dynamic_index_data[__r]; }
+
+ static constexpr auto _S_dynamic_index_data = [] consteval
{
array<size_t, _S_rank+1> __ret;
size_t __dyn = 0;
for (size_t __i = 0; __i < _S_rank; ++__i)
{
__ret[__i] = __dyn;
- __dyn += _S_is_dyn(_Extents[__i]);
+ __dyn += (_Extents[__i] == dynamic_extent);
}
__ret[_S_rank] = __dyn;
return __ret;
}();
- static constexpr size_t _S_rank_dynamic = _S_dynamic_index[_S_rank];
+ static constexpr size_t _S_rank_dynamic = _S_dynamic_index(_S_rank);
- // For __r in [0, _S_rank_dynamic), _S_dynamic_index_inv[__r] is the
+ // For __r in [0, _S_rank_dynamic), _S_dynamic_index_inv(__r) is the
// index of the __r-th dynamic extent in _Extents.
- static constexpr auto _S_dynamic_index_inv = [] consteval
+ static constexpr size_t
+ _S_dynamic_index_inv(size_t __r) noexcept
+ { return _S_dynamic_index_inv_data[__r]; }
+
+ static constexpr auto _S_dynamic_index_inv_data = [] consteval
{
array<size_t, _S_rank_dynamic> __ret;
for (size_t __i = 0, __r = 0; __i < _S_rank; ++__i)
- if (_S_is_dyn(_Extents[__i]))
+ if (_Extents[__i] == dynamic_extent)
__ret[__r++] = __i;
return __ret;
}();
@@ -99,15 +120,66 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
static constexpr size_t
_S_static_extent(size_t __r) noexcept
{ return _Extents[__r]; }
+ };
+
+ template<array _Extents>
+ requires (__all_dynamic<_Extents>())
+ class _StaticExtents<_Extents>
+ {
+ public:
+ static constexpr size_t _S_rank = _Extents.size();
+
+ static constexpr size_t
+ _S_dynamic_index(size_t __r) noexcept
+ { return __r; }
+
+ static constexpr size_t _S_rank_dynamic = _S_rank;
+
+ static constexpr size_t
+ _S_dynamic_index_inv(size_t __k) noexcept
+ { return __k; }
+
+ static constexpr size_t
+ _S_static_extent(size_t) noexcept
+ { return dynamic_extent; }
+ };
+
+ template<typename _IndexType, array _Extents>
+ class _ExtentsStorage : public _StaticExtents<_Extents>
+ {
+ private:
+ using _S_base = _StaticExtents<_Extents>;
+
+ public:
+ using _S_base::_S_rank;
+ using _S_base::_S_rank_dynamic;
+ using _S_base::_S_dynamic_index;
+ using _S_base::_S_dynamic_index_inv;
+ using _S_base::_S_static_extent;
+
+ static constexpr bool
+ _S_is_dynamic(size_t __r) noexcept
+ {
+ if constexpr (__all_static(_Extents))
+ return false;
+ else if constexpr (__all_dynamic(_Extents))
+ return true;
+ else
+ return _Extents[__r] == dynamic_extent;
+ }
+
+ template<typename _OIndexType>
+ static constexpr _IndexType
+ _S_int_cast(const _OIndexType& __other) noexcept
+ { return _IndexType(__other); }
constexpr _IndexType
_M_extent(size_t __r) const noexcept
{
- auto __se = _Extents[__r];
- if (__se == dynamic_extent)
- return _M_dyn_exts[_S_dynamic_index[__r]];
+ if (_S_is_dynamic(__r))
+ return _M_dyn_exts[_S_dynamic_index(__r)];
else
- return __se;
+ return _S_static_extent(__r);
}
template<size_t _OtherRank, typename _GetOtherExtent>
@@ -116,7 +188,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
if constexpr (_OtherRank == _S_rank)
for (size_t __i = 0; __i < _S_rank; ++__i)
- if (_Extents[__i] != dynamic_extent
+ if (!_S_is_dynamic(__i)
&& !cmp_equal(_Extents[__i], _S_int_cast(__get_extent(__i))))
return false;
return true;
@@ -131,7 +203,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
size_t __di = __i;
if constexpr (_OtherRank != _S_rank_dynamic)
- __di = _S_dynamic_index_inv[__i];
+ __di = _S_dynamic_index_inv(__i);
_M_dyn_exts[__i] = _S_int_cast(__get_extent(__di));
}
}
@@ -157,18 +229,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return __exts[__i]; });
}
- static constexpr span<const size_t>
- _S_static_extents(size_t __begin, size_t __end) noexcept
- {
- return {_Extents.data() + __begin, _Extents.data() + __end};
- }
+ static constexpr const array<size_t, _S_rank>&
+ _S_static_extents() noexcept
+ { return _Extents; }
constexpr span<const _IndexType>
_M_dynamic_extents(size_t __begin, size_t __end) const noexcept
requires (_Extents.size() > 0)
{
- return {_M_dyn_exts + _S_dynamic_index[__begin],
- _M_dyn_exts + _S_dynamic_index[__end]};
+ return {_M_dyn_exts + _S_dynamic_index(__begin),
+ _M_dyn_exts + _S_dynamic_index(__end)};
}
private:
@@ -184,24 +254,50 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<size_t _Extent, typename _IndexType>
concept
__valid_static_extent = _Extent == dynamic_extent
- || _Extent <= numeric_limits<_IndexType>::max();
- }
+ || _Extent <= __gnu_cxx::__int_traits<_IndexType>::__max;
- namespace __mdspan
- {
template<typename _Extents>
- constexpr span<const size_t>
- __static_extents(size_t __begin = 0, size_t __end = _Extents::rank())
- noexcept
- { return _Extents::_S_storage::_S_static_extents(__begin, __end); }
+ constexpr const array<size_t, _Extents::rank()>&
+ __static_extents() noexcept
+ { return _Extents::_S_storage::_S_static_extents(); }
+
+ // Pre-compute: \prod_{i = 0}^r _Extents[i], for r = 0,..., n (exclusive)
+ template<array _Extents>
+ constexpr auto __fwd_partial_prods = [] consteval
+ {
+ constexpr size_t __rank = _Extents.size();
+ std::array<size_t, __rank> __ret;
+ size_t __prod = 1;
+ for (size_t __r = 0; __r < __rank; ++__r)
+ {
+ __ret[__r] = __prod;
+ if (size_t __ext = _Extents[__r]; __ext != dynamic_extent)
+ __prod *= __ext;
+ }
+ return __ret;
+ }();
+
+ // Pre-compute: \prod_{i = r+1}^{n-1} _Extents[i]
+ template<array _Extents>
+ constexpr auto __rev_partial_prods = [] consteval
+ {
+ constexpr size_t __rank = _Extents.size();
+ std::array<size_t, __rank> __ret;
+ size_t __prod = 1;
+ for (size_t __r = __rank; __r > 0; --__r)
+ {
+ __ret[__r - 1] = __prod;
+ if (size_t __ext = _Extents[__r - 1]; __ext != dynamic_extent)
+ __prod *= __ext;
+ }
+ return __ret;
+ }();
template<typename _Extents>
constexpr span<const typename _Extents::index_type>
__dynamic_extents(const _Extents& __exts, size_t __begin = 0,
size_t __end = _Extents::rank()) noexcept
- {
- return __exts._M_exts._M_dynamic_extents(__begin, __end);
- }
+ { return __exts._M_exts._M_dynamic_extents(__begin, __end); }
}
template<typename _IndexType, size_t... _Extents>
@@ -212,7 +308,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
static_assert(
(__mdspan::__valid_static_extent<_Extents, _IndexType> && ...),
"Extents must either be dynamic or representable as IndexType");
-
public:
using index_type = _IndexType;
using size_type = make_unsigned_t<index_type>;
@@ -257,8 +352,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_S_ctor_explicit()
{
return (_S_is_less_dynamic(_Extents, _OExtents) || ...)
- || (numeric_limits<index_type>::max()
- < numeric_limits<_OIndexType>::max());
+ || (__gnu_cxx::__int_traits<index_type>::__max
+ < __gnu_cxx::__int_traits<_OIndexType>::__max);
}
template<size_t... _OExtents>
@@ -313,16 +408,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return false;
else
{
- for (size_t __i = 0; __i < __self.rank(); ++__i)
- if (!cmp_equal(__self.extent(__i), __other.extent(__i)))
- return false;
- return true;
+ auto __impl = [&__self, &__other]<size_t... _Counts>(
+ index_sequence<_Counts...>)
+ { return (cmp_equal(__self.extent(_Counts),
+ __other.extent(_Counts)) && ...); };
+ return __impl(make_index_sequence<__self.rank()>());
}
}
private:
- friend span<const size_t>
- __mdspan::__static_extents<extents>(size_t, size_t);
+ friend const array<size_t, rank()>&
+ __mdspan::__static_extents<extents>();
friend span<const index_type>
__mdspan::__dynamic_extents<extents>(const extents&, size_t, size_t);
@@ -347,6 +443,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return false;
}
+ template<typename _Tp, size_t _Nm>
+ consteval bool
+ __contains_zero(const array<_Tp, _Nm>& __exts) noexcept
+ { return __contains_zero(span<const _Tp>(__exts)); }
+
template<typename _Extents>
constexpr bool
__empty(const _Extents& __exts) noexcept
@@ -359,51 +460,75 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return false;
}
- constexpr size_t
- __static_extents_prod(const auto& __sta_exts) noexcept
- {
- size_t __ret = 1;
- for (auto __factor : __sta_exts)
- if (__factor != dynamic_extent)
- __ret *= __factor;
- return __ret;
- }
-
template<typename _Extents>
constexpr typename _Extents::index_type
- __exts_prod(const _Extents& __exts, size_t __begin, size_t __end) noexcept
+ __extents_prod(const _Extents& __exts, size_t __sta_prod, size_t __begin,
+ size_t __end) noexcept
{
- using _IndexType = typename _Extents::index_type;
-
- size_t __ret = 1;
- if constexpr (_Extents::rank_dynamic() != _Extents::rank())
- {
- auto __sta_exts = __static_extents<_Extents>(__begin, __end);
- __ret = __static_extents_prod(__sta_exts);
- if (__ret == 0)
- return 0;
- }
+ if (__sta_prod == 0)
+ return 0;
+ size_t __ret = __sta_prod;
if constexpr (_Extents::rank_dynamic() > 0)
for (auto __factor : __dynamic_extents(__exts, __begin, __end))
__ret *= size_t(__factor);
- return _IndexType(__ret);
+ return static_cast<typename _Extents::index_type>(__ret);
}
+ // Preconditions: _r < _Extents::rank()
template<typename _Extents>
constexpr typename _Extents::index_type
__fwd_prod(const _Extents& __exts, size_t __r) noexcept
- { return __exts_prod(__exts, 0, __r); }
+ {
+ constexpr size_t __rank = _Extents::rank();
+ constexpr auto& __sta_exts = __static_extents<_Extents>();
+ if constexpr (__rank == 1)
+ return 1;
+ else if constexpr (__rank == 2)
+ return __r == 0 ? 1 : __exts.extent(0);
+ else if constexpr (__all_dynamic(std::span(__sta_exts).first(__rank-1)))
+ return __extents_prod(__exts, 1, 0, __r);
+ else
+ {
+ size_t __sta_prod = __fwd_partial_prods<__sta_exts>[__r];
+ return __extents_prod(__exts, __sta_prod, 0, __r);
+ }
+ }
+ // Preconditions: _r < _Extents::rank()
template<typename _Extents>
constexpr typename _Extents::index_type
__rev_prod(const _Extents& __exts, size_t __r) noexcept
- { return __exts_prod(__exts, __r + 1, __exts.rank()); }
+ {
+ constexpr size_t __rank = _Extents::rank();
+ constexpr auto& __sta_exts = __static_extents<_Extents>();
+ if constexpr (__rank == 1)
+ return 1;
+ else if constexpr (__rank == 2)
+ return __r == 0 ? __exts.extent(1) : 1;
+ else if constexpr (__all_dynamic(std::span(__sta_exts).last(__rank-1)))
+ return __extents_prod(__exts, 1, __r + 1, __rank);
+ else
+ {
+ size_t __sta_prod = __rev_partial_prods<__sta_exts>[__r];
+ return __extents_prod(__exts, __sta_prod, __r + 1, __rank);
+ }
+ }
template<typename _Extents>
constexpr typename _Extents::index_type
__size(const _Extents& __exts) noexcept
- { return __fwd_prod(__exts, __exts.rank()); }
+ {
+ constexpr size_t __sta_prod = [] {
+ span<const size_t> __sta_exts = __static_extents<_Extents>();
+ size_t __ret = 1;
+ for(auto __ext : __sta_exts)
+ if (__ext != dynamic_extent)
+ __ret *= __ext;
+ return __ret;
+ }();
+ return __extents_prod(__exts, __sta_prod, 0, _Extents::rank());
+ }
template<typename _IndexType, size_t... _Counts>
auto __build_dextents_type(integer_sequence<size_t, _Counts...>)
@@ -414,6 +539,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
using dextents = decltype(__mdspan::__build_dextents_type<_IndexType>(
make_index_sequence<_Rank>()));
+#if __glibcxx_mdspan >= 202406L
+ template<size_t _Rank, typename _IndexType = size_t>
+ using dims = dextents<_IndexType, _Rank>;
+#endif
+
template<typename... _Integrals>
requires (is_convertible_v<_Integrals, size_t> && ...)
explicit extents(_Integrals...) ->
@@ -470,9 +600,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Extents,
typename _IndexType = typename _Extents::index_type>
consteval _IndexType
- __static_quotient(_IndexType __nom = numeric_limits<_IndexType>::max())
+ __static_quotient(_IndexType __nom = __gnu_cxx::__int_traits<_IndexType>
+ ::__max)
{
- auto __sta_exts = __static_extents<_Extents>();
+ std::span<const size_t> __sta_exts = __static_extents<_Extents>();
for (auto __factor : __sta_exts)
{
if (__factor != dynamic_extent)
@@ -919,12 +1050,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
static_assert(__mdspan::__representable_size<_OExtents, index_type>,
"The size of StridedMapping::extents_type must be representable as"
" index_type");
- if constexpr (cmp_greater(numeric_limits<_OIndexType>::max(),
- numeric_limits<index_type>::max()))
- __glibcxx_assert(!cmp_less(numeric_limits<index_type>::max(),
- __other.required_span_size())
- && "other.required_span_size() must be representable"
- " as index_type");
+ if constexpr (cmp_greater(__gnu_cxx::__int_traits<_OIndexType>::__max,
+ __gnu_cxx::__int_traits<index_type>::__max))
+ __glibcxx_assert(!cmp_less(
+ __gnu_cxx::__int_traits<index_type>::__max,
+ __other.required_span_size())
+ && "other.required_span_size() must be representable"
+ " as index_type");
if constexpr (extents_type::rank() > 0)
for (size_t __i = 0; __i < extents_type::rank(); ++__i)
_M_strides[__i] = index_type(__other.stride(__i));
@@ -1057,6 +1189,54 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return __p + __i; }
};
+#ifdef __glibcxx_aligned_accessor
+ template<typename _ElementType, size_t _ByteAlignment>
+ struct aligned_accessor
+ {
+ static_assert(has_single_bit(_ByteAlignment),
+ "ByteAlignment must be a power of two");
+ static_assert(_ByteAlignment >= alignof(_ElementType));
+
+ using offset_policy = default_accessor<_ElementType>;
+ using element_type = _ElementType;
+ using reference = element_type&;
+ using data_handle_type = element_type*;
+
+ static constexpr size_t byte_alignment = _ByteAlignment;
+
+ constexpr
+ aligned_accessor() noexcept = default;
+
+ template<typename _OElementType, size_t _OByteAlignment>
+ requires (_OByteAlignment >= byte_alignment)
+ && is_convertible_v<_OElementType(*)[], element_type(*)[]>
+ constexpr
+ aligned_accessor(aligned_accessor<_OElementType, _OByteAlignment>)
+ noexcept
+ { }
+
+ template<typename _OElementType>
+ requires is_convertible_v<_OElementType(*)[], element_type(*)[]>
+ constexpr explicit
+ aligned_accessor(default_accessor<_OElementType>) noexcept
+ { }
+
+ template<typename _OElementType>
+ requires is_convertible_v<element_type(*)[], _OElementType(*)[]>
+ constexpr
+ operator default_accessor<_OElementType>() const noexcept
+ { return {}; }
+
+ constexpr reference
+ access(data_handle_type __p, size_t __i) const noexcept
+ { return std::assume_aligned<byte_alignment>(__p)[__i]; }
+
+ constexpr typename offset_policy::data_handle_type
+ offset(data_handle_type __p, size_t __i) const noexcept
+ { return std::assume_aligned<byte_alignment>(__p) + __i; }
+ };
+#endif
+
namespace __mdspan
{
template<typename _Extents, typename _IndexType, size_t _Nm>
@@ -1241,16 +1421,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
size() const noexcept
{
__glibcxx_assert(cmp_less_equal(_M_mapping.required_span_size(),
- numeric_limits<size_t>::max()));
+ __gnu_cxx::__int_traits<size_t>
+ ::__max));
return size_type(__mdspan::__size(extents()));
}
[[nodiscard]]
constexpr bool
empty() const noexcept
- {
- return __mdspan::__empty(extents());
- }
+ { return __mdspan::__empty(extents()); }
friend constexpr void
swap(mdspan& __x, mdspan& __y) noexcept
@@ -1299,7 +1478,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
constexpr bool
is_strided() const noexcept(noexcept(_M_mapping.is_strided()))
- { return _M_mapping. is_strided(); }
+ { return _M_mapping.is_strided(); }
constexpr index_type
stride(rank_type __r) const { return _M_mapping.stride(__r); }
diff --git a/libstdc++-v3/include/std/memory b/libstdc++-v3/include/std/memory
index 763a57e..bc59622 100644
--- a/libstdc++-v3/include/std/memory
+++ b/libstdc++-v3/include/std/memory
@@ -110,6 +110,7 @@
#define __glibcxx_want_constexpr_memory
#define __glibcxx_want_enable_shared_from_this
#define __glibcxx_want_indirect
+#define __glibcxx_want_is_sufficiently_aligned
#define __glibcxx_want_make_unique
#define __glibcxx_want_out_ptr
#define __glibcxx_want_parallel_algorithm
diff --git a/libstdc++-v3/include/std/mutex b/libstdc++-v3/include/std/mutex
index e575a81..631c380 100644
--- a/libstdc++-v3/include/std/mutex
+++ b/libstdc++-v3/include/std/mutex
@@ -190,7 +190,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return static_cast<_Derived*>(this)->_M_timedlock(__ts);
}
-#ifdef _GLIBCXX_USE_PTHREAD_MUTEX_CLOCKLOCK
+#if _GLIBCXX_USE_PTHREAD_MUTEX_CLOCKLOCK
template<typename _Duration>
bool
_M_try_lock_until(const chrono::time_point<chrono::steady_clock,
@@ -377,7 +377,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_M_timedlock(const __gthread_time_t& __ts)
{ return !__gthread_recursive_mutex_timedlock(&_M_mutex, &__ts); }
-#ifdef _GLIBCXX_USE_PTHREAD_MUTEX_CLOCKLOCK
+#if _GLIBCXX_USE_PTHREAD_MUTEX_CLOCKLOCK
bool
_M_clocklock(clockid_t __clockid, const __gthread_time_t& __ts)
{ return !pthread_mutex_clocklock(&_M_mutex, __clockid, &__ts); }
diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
index efe6296..2970b2c 100644
--- a/libstdc++-v3/include/std/ranges
+++ b/libstdc++-v3/include/std/ranges
@@ -1585,8 +1585,6 @@ namespace views::__adaptor
};
template<random_access_range _Range>
- requires (sizeof(range_difference_t<_Range>)
- <= sizeof(iterator_t<_Range>))
struct _CachedPosition<_Range>
{
private:
diff --git a/libstdc++-v3/include/std/stop_token b/libstdc++-v3/include/std/stop_token
index 775ec6a..b593daf 100644
--- a/libstdc++-v3/include/std/stop_token
+++ b/libstdc++-v3/include/std/stop_token
@@ -648,6 +648,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Callback>
stop_callback(stop_token, _Callback) -> stop_callback<_Callback>;
+ /// @cond undocumented
+ namespace __detail::__variant
+ {
+ template<typename> struct _Never_valueless_alt; // see <variant>
+
+ // Provide the strong exception-safety guarantee when emplacing a
+ // stop_token or stop_source into a variant.
+ template<>
+ struct _Never_valueless_alt<std::stop_token>
+ : true_type
+ { };
+
+ template<>
+ struct _Never_valueless_alt<std::stop_source>
+ : true_type
+ { };
+ } // namespace __detail::__variant
+ /// @endcond
+
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif // __glibcxx_jthread
diff --git a/libstdc++-v3/include/std/thread b/libstdc++-v3/include/std/thread
index 0de08c0..94ded714 100644
--- a/libstdc++-v3/include/std/thread
+++ b/libstdc++-v3/include/std/thread
@@ -294,6 +294,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
stop_source _M_stop_source;
thread _M_thread;
};
+
+ /// @cond undocumented
+ namespace __detail::__variant
+ {
+ template<typename> struct _Never_valueless_alt; // see <variant>
+
+ // Provide the strong exception-safety guarantee when emplacing a
+ // jthread into a variant.
+ template<>
+ struct _Never_valueless_alt<std::jthread>
+ : true_type
+ { };
+ } // namespace __detail::__variant
+ /// @endcond
#endif // __cpp_lib_jthread
#ifdef __cpp_lib_formatters // C++ >= 23
diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
index ff23544..4636457 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -4280,6 +4280,28 @@ template<typename _Ret, typename _Fn, typename... _Args>
#endif // C++2a
+#if __cplusplus >= 201103L
+ // Stores a tuple of indices. Used by tuple and pair, and by bind() to
+ // extract the elements in a tuple.
+ template<size_t... _Indexes> struct _Index_tuple { };
+
+ // Builds an _Index_tuple<0, 1, 2, ..., _Num-1>.
+ template<size_t _Num>
+ struct _Build_index_tuple
+ {
+#if __has_builtin(__make_integer_seq)
+ template<typename, size_t... _Indices>
+ using _IdxTuple = _Index_tuple<_Indices...>;
+
+ // Clang defines __make_integer_seq for this purpose.
+ using __type = __make_integer_seq<_IdxTuple, size_t, _Num>;
+#else
+ // For GCC and other compilers, use __integer_pack instead.
+ using __type = _Index_tuple<__integer_pack(_Num)...>;
+#endif
+ };
+#endif // C++11
+
/// @} group metaprogramming
_GLIBCXX_END_NAMESPACE_VERSION
diff --git a/libstdc++-v3/libsupc++/compare b/libstdc++-v3/libsupc++/compare
index 82b5c53..7e3ad83 100644
--- a/libstdc++-v3/libsupc++/compare
+++ b/libstdc++-v3/libsupc++/compare
@@ -54,19 +54,34 @@ namespace std _GLIBCXX_VISIBILITY(default)
{
using type = signed char;
- enum class _Ord : type { equivalent = 0, less = -1, greater = 1 };
+ enum class _Ord : type
+ {
+ equivalent = 0, less = -1, greater = 1,
+ // value remains unchanged when negated
+ unordered = -__SCHAR_MAX__ - 1
+ };
+
+ template<typename _Ordering>
+ [[__gnu__::__always_inline__]]
+ constexpr _Ord
+ __ord(_Ordering __o) noexcept
+ { return _Ord(__o._M_value); }
- enum class _Ncmp : type { _Unordered = 2 };
+ template<typename _Ordering>
+ [[__gnu__::__always_inline__]]
+ constexpr _Ordering
+ __make(_Ord __o) noexcept
+ { return _Ordering(__o); }
- struct __unspec
+ struct __literal_zero
{
- consteval __unspec(__unspec*) noexcept { }
+ consteval __literal_zero(__literal_zero*) noexcept { }
};
}
class partial_ordering
{
- // less=0xff, equiv=0x00, greater=0x01, unordered=0x02
+ // less=0xff, equiv=0x00, greater=0x01, unordered=0x80
__cmp_cat::type _M_value;
constexpr explicit
@@ -74,13 +89,18 @@ namespace std _GLIBCXX_VISIBILITY(default)
: _M_value(__cmp_cat::type(__v))
{ }
- constexpr explicit
- partial_ordering(__cmp_cat::_Ncmp __v) noexcept
- : _M_value(__cmp_cat::type(__v))
- { }
+ [[__gnu__::__always_inline__]]
+ constexpr __cmp_cat::type
+ _M_reverse() const
+ {
+ // leaves _Ord::unordered unchanged
+ return static_cast<__cmp_cat::type>(-_M_value);
+ }
- friend class weak_ordering;
- friend class strong_ordering;
+ friend constexpr __cmp_cat::_Ord
+ __cmp_cat::__ord<partial_ordering>(partial_ordering) noexcept;
+ friend constexpr partial_ordering
+ __cmp_cat::__make<partial_ordering>(__cmp_cat::_Ord) noexcept;
public:
// valid values
@@ -92,7 +112,7 @@ namespace std _GLIBCXX_VISIBILITY(default)
// comparisons
[[nodiscard]]
friend constexpr bool
- operator==(partial_ordering __v, __cmp_cat::__unspec) noexcept
+ operator==(partial_ordering __v, __cmp_cat::__literal_zero) noexcept
{ return __v._M_value == 0; }
[[nodiscard]]
@@ -101,58 +121,53 @@ namespace std _GLIBCXX_VISIBILITY(default)
[[nodiscard]]
friend constexpr bool
- operator< (partial_ordering __v, __cmp_cat::__unspec) noexcept
+ operator< (partial_ordering __v, __cmp_cat::__literal_zero) noexcept
{ return __v._M_value == -1; }
[[nodiscard]]
friend constexpr bool
- operator> (partial_ordering __v, __cmp_cat::__unspec) noexcept
+ operator> (partial_ordering __v, __cmp_cat::__literal_zero) noexcept
{ return __v._M_value == 1; }
[[nodiscard]]
friend constexpr bool
- operator<=(partial_ordering __v, __cmp_cat::__unspec) noexcept
- { return __v._M_value <= 0; }
+ operator<=(partial_ordering __v, __cmp_cat::__literal_zero) noexcept
+ { return __v._M_reverse() >= 0; }
[[nodiscard]]
friend constexpr bool
- operator>=(partial_ordering __v, __cmp_cat::__unspec) noexcept
- { return __cmp_cat::type(__v._M_value & 1) == __v._M_value; }
+ operator>=(partial_ordering __v, __cmp_cat::__literal_zero) noexcept
+ { return __v._M_value >= 0; }
[[nodiscard]]
friend constexpr bool
- operator< (__cmp_cat::__unspec, partial_ordering __v) noexcept
+ operator< (__cmp_cat::__literal_zero, partial_ordering __v) noexcept
{ return __v._M_value == 1; }
[[nodiscard]]
friend constexpr bool
- operator> (__cmp_cat::__unspec, partial_ordering __v) noexcept
+ operator> (__cmp_cat::__literal_zero, partial_ordering __v) noexcept
{ return __v._M_value == -1; }
[[nodiscard]]
friend constexpr bool
- operator<=(__cmp_cat::__unspec, partial_ordering __v) noexcept
- { return __cmp_cat::type(__v._M_value & 1) == __v._M_value; }
+ operator<=(__cmp_cat::__literal_zero, partial_ordering __v) noexcept
+ { return 0 <= __v._M_value; }
[[nodiscard]]
friend constexpr bool
- operator>=(__cmp_cat::__unspec, partial_ordering __v) noexcept
- { return 0 >= __v._M_value; }
+ operator>=(__cmp_cat::__literal_zero, partial_ordering __v) noexcept
+ { return 0 <= __v._M_reverse(); }
[[nodiscard]]
friend constexpr partial_ordering
- operator<=>(partial_ordering __v, __cmp_cat::__unspec) noexcept
+ operator<=>(partial_ordering __v, __cmp_cat::__literal_zero) noexcept
{ return __v; }
[[nodiscard]]
friend constexpr partial_ordering
- operator<=>(__cmp_cat::__unspec, partial_ordering __v) noexcept
- {
- if (__v._M_value & 1)
- return partial_ordering(__cmp_cat::_Ord(-__v._M_value));
- else
- return __v;
- }
+ operator<=>(__cmp_cat::__literal_zero, partial_ordering __v) noexcept
+ { return partial_ordering(__cmp_cat::_Ord(__v._M_reverse())); }
};
// valid values' definitions
@@ -166,7 +181,7 @@ namespace std _GLIBCXX_VISIBILITY(default)
partial_ordering::greater(__cmp_cat::_Ord::greater);
inline constexpr partial_ordering
- partial_ordering::unordered(__cmp_cat::_Ncmp::_Unordered);
+ partial_ordering::unordered(__cmp_cat::_Ord::unordered);
class weak_ordering
{
@@ -176,7 +191,10 @@ namespace std _GLIBCXX_VISIBILITY(default)
weak_ordering(__cmp_cat::_Ord __v) noexcept : _M_value(__cmp_cat::type(__v))
{ }
- friend class strong_ordering;
+ friend constexpr __cmp_cat::_Ord
+ __cmp_cat::__ord<weak_ordering>(weak_ordering) noexcept;
+ friend constexpr weak_ordering
+ __cmp_cat::__make<weak_ordering>(__cmp_cat::_Ord) noexcept;
public:
// valid values
@@ -186,12 +204,12 @@ namespace std _GLIBCXX_VISIBILITY(default)
[[nodiscard]]
constexpr operator partial_ordering() const noexcept
- { return partial_ordering(__cmp_cat::_Ord(_M_value)); }
+ { return __cmp_cat::__make<partial_ordering>(__cmp_cat::_Ord(_M_value)); }
// comparisons
[[nodiscard]]
friend constexpr bool
- operator==(weak_ordering __v, __cmp_cat::__unspec) noexcept
+ operator==(weak_ordering __v, __cmp_cat::__literal_zero) noexcept
{ return __v._M_value == 0; }
[[nodiscard]]
@@ -200,52 +218,52 @@ namespace std _GLIBCXX_VISIBILITY(default)
[[nodiscard]]
friend constexpr bool
- operator< (weak_ordering __v, __cmp_cat::__unspec) noexcept
+ operator< (weak_ordering __v, __cmp_cat::__literal_zero) noexcept
{ return __v._M_value < 0; }
[[nodiscard]]
friend constexpr bool
- operator> (weak_ordering __v, __cmp_cat::__unspec) noexcept
+ operator> (weak_ordering __v, __cmp_cat::__literal_zero) noexcept
{ return __v._M_value > 0; }
[[nodiscard]]
friend constexpr bool
- operator<=(weak_ordering __v, __cmp_cat::__unspec) noexcept
+ operator<=(weak_ordering __v, __cmp_cat::__literal_zero) noexcept
{ return __v._M_value <= 0; }
[[nodiscard]]
friend constexpr bool
- operator>=(weak_ordering __v, __cmp_cat::__unspec) noexcept
+ operator>=(weak_ordering __v, __cmp_cat::__literal_zero) noexcept
{ return __v._M_value >= 0; }
[[nodiscard]]
friend constexpr bool
- operator< (__cmp_cat::__unspec, weak_ordering __v) noexcept
+ operator< (__cmp_cat::__literal_zero, weak_ordering __v) noexcept
{ return 0 < __v._M_value; }
[[nodiscard]]
friend constexpr bool
- operator> (__cmp_cat::__unspec, weak_ordering __v) noexcept
+ operator> (__cmp_cat::__literal_zero, weak_ordering __v) noexcept
{ return 0 > __v._M_value; }
[[nodiscard]]
friend constexpr bool
- operator<=(__cmp_cat::__unspec, weak_ordering __v) noexcept
+ operator<=(__cmp_cat::__literal_zero, weak_ordering __v) noexcept
{ return 0 <= __v._M_value; }
[[nodiscard]]
friend constexpr bool
- operator>=(__cmp_cat::__unspec, weak_ordering __v) noexcept
+ operator>=(__cmp_cat::__literal_zero, weak_ordering __v) noexcept
{ return 0 >= __v._M_value; }
[[nodiscard]]
friend constexpr weak_ordering
- operator<=>(weak_ordering __v, __cmp_cat::__unspec) noexcept
+ operator<=>(weak_ordering __v, __cmp_cat::__literal_zero) noexcept
{ return __v; }
[[nodiscard]]
friend constexpr weak_ordering
- operator<=>(__cmp_cat::__unspec, weak_ordering __v) noexcept
+ operator<=>(__cmp_cat::__literal_zero, weak_ordering __v) noexcept
{ return weak_ordering(__cmp_cat::_Ord(-__v._M_value)); }
};
@@ -268,6 +286,11 @@ namespace std _GLIBCXX_VISIBILITY(default)
: _M_value(__cmp_cat::type(__v))
{ }
+ friend constexpr __cmp_cat::_Ord
+ __cmp_cat::__ord<strong_ordering>(strong_ordering) noexcept;
+ friend constexpr strong_ordering
+ __cmp_cat::__make<strong_ordering>(__cmp_cat::_Ord) noexcept;
+
public:
// valid values
static const strong_ordering less;
@@ -277,16 +300,16 @@ namespace std _GLIBCXX_VISIBILITY(default)
[[nodiscard]]
constexpr operator partial_ordering() const noexcept
- { return partial_ordering(__cmp_cat::_Ord(_M_value)); }
+ { return __cmp_cat::__make<partial_ordering>(__cmp_cat::_Ord(_M_value)); }
[[nodiscard]]
constexpr operator weak_ordering() const noexcept
- { return weak_ordering(__cmp_cat::_Ord(_M_value)); }
+ { return __cmp_cat::__make<weak_ordering>(__cmp_cat::_Ord(_M_value)); }
// comparisons
[[nodiscard]]
friend constexpr bool
- operator==(strong_ordering __v, __cmp_cat::__unspec) noexcept
+ operator==(strong_ordering __v, __cmp_cat::__literal_zero) noexcept
{ return __v._M_value == 0; }
[[nodiscard]]
@@ -295,52 +318,52 @@ namespace std _GLIBCXX_VISIBILITY(default)
[[nodiscard]]
friend constexpr bool
- operator< (strong_ordering __v, __cmp_cat::__unspec) noexcept
+ operator< (strong_ordering __v, __cmp_cat::__literal_zero) noexcept
{ return __v._M_value < 0; }
[[nodiscard]]
friend constexpr bool
- operator> (strong_ordering __v, __cmp_cat::__unspec) noexcept
+ operator> (strong_ordering __v, __cmp_cat::__literal_zero) noexcept
{ return __v._M_value > 0; }
[[nodiscard]]
friend constexpr bool
- operator<=(strong_ordering __v, __cmp_cat::__unspec) noexcept
+ operator<=(strong_ordering __v, __cmp_cat::__literal_zero) noexcept
{ return __v._M_value <= 0; }
[[nodiscard]]
friend constexpr bool
- operator>=(strong_ordering __v, __cmp_cat::__unspec) noexcept
+ operator>=(strong_ordering __v, __cmp_cat::__literal_zero) noexcept
{ return __v._M_value >= 0; }
[[nodiscard]]
friend constexpr bool
- operator< (__cmp_cat::__unspec, strong_ordering __v) noexcept
+ operator< (__cmp_cat::__literal_zero, strong_ordering __v) noexcept
{ return 0 < __v._M_value; }
[[nodiscard]]
friend constexpr bool
- operator> (__cmp_cat::__unspec, strong_ordering __v) noexcept
+ operator> (__cmp_cat::__literal_zero, strong_ordering __v) noexcept
{ return 0 > __v._M_value; }
[[nodiscard]]
friend constexpr bool
- operator<=(__cmp_cat::__unspec, strong_ordering __v) noexcept
+ operator<=(__cmp_cat::__literal_zero, strong_ordering __v) noexcept
{ return 0 <= __v._M_value; }
[[nodiscard]]
friend constexpr bool
- operator>=(__cmp_cat::__unspec, strong_ordering __v) noexcept
+ operator>=(__cmp_cat::__literal_zero, strong_ordering __v) noexcept
{ return 0 >= __v._M_value; }
[[nodiscard]]
friend constexpr strong_ordering
- operator<=>(strong_ordering __v, __cmp_cat::__unspec) noexcept
+ operator<=>(strong_ordering __v, __cmp_cat::__literal_zero) noexcept
{ return __v; }
[[nodiscard]]
friend constexpr strong_ordering
- operator<=>(__cmp_cat::__unspec, strong_ordering __v) noexcept
+ operator<=>(__cmp_cat::__literal_zero, strong_ordering __v) noexcept
{ return strong_ordering(__cmp_cat::_Ord(-__v._M_value)); }
};
@@ -581,26 +604,9 @@ namespace std _GLIBCXX_VISIBILITY(default)
constexpr weak_ordering
__fp_weak_ordering(_Tp __e, _Tp __f)
{
- // Returns an integer with the same sign as the argument, and magnitude
- // indicating the classification: zero=1 subnorm=2 norm=3 inf=4 nan=5
- auto __cat = [](_Tp __fp) -> int {
- const int __sign = __builtin_signbit(__fp) ? -1 : 1;
- if (__builtin_isnormal(__fp))
- return (__fp == 0 ? 1 : 3) * __sign;
- if (__builtin_isnan(__fp))
- return 5 * __sign;
- if (int __inf = __builtin_isinf_sign(__fp))
- return 4 * __inf;
- return 2 * __sign;
- };
-
- auto __po = __e <=> __f;
- if (is_lt(__po))
- return weak_ordering::less;
- else if (is_gt(__po))
- return weak_ordering::greater;
- else if (__po == partial_ordering::equivalent)
- return weak_ordering::equivalent;
+ auto __po = __cmp_cat::__ord(__e <=> __f);
+ if (__po != __cmp_cat::_Ord::unordered)
+ return __cmp_cat::__make<weak_ordering>(__po);
else // unordered, at least one argument is NaN
{
// return -1 for negative nan, +1 for positive nan, 0 otherwise.
@@ -609,13 +615,7 @@ namespace std _GLIBCXX_VISIBILITY(default)
? __builtin_signbit(__fp) ? -1 : 1
: 0;
};
- auto __ord = __isnan_sign(__e) <=> __isnan_sign(__f);
- if (is_eq(__ord))
- return weak_ordering::equivalent;
- else if (is_lt(__ord))
- return weak_ordering::less;
- else
- return weak_ordering::greater;
+ return __isnan_sign(__e) <=> __isnan_sign(__f);
}
}
diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py
index 5f5963c..e5336b7 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -1749,7 +1749,11 @@ class StdCmpCatPrinter(printer_base):
if self._typename == 'strong_ordering' and self._val == 0:
name = 'equal'
else:
- names = {2: 'unordered', -1: 'less', 0: 'equivalent', 1: 'greater'}
+ names = {
+ -1: 'less', 0: 'equivalent', 1: 'greater',
+ # GCC 10-15 used 2 for unordered
+ -128: 'unordered', 2: 'unordered'
+ }
name = names[int(self._val)]
return 'std::{}::{}'.format(self._typename, name)
diff --git a/libstdc++-v3/src/c++20/Makefile.am b/libstdc++-v3/src/c++20/Makefile.am
index 15e6f34..736558f 100644
--- a/libstdc++-v3/src/c++20/Makefile.am
+++ b/libstdc++-v3/src/c++20/Makefile.am
@@ -36,7 +36,7 @@ else
inst_sources =
endif
-sources = tzdb.cc format.cc atomic.cc
+sources = tzdb.cc format.cc atomic.cc clock.cc
vpath % $(top_srcdir)/src/c++20
diff --git a/libstdc++-v3/src/c++20/Makefile.in b/libstdc++-v3/src/c++20/Makefile.in
index d9e1615..3cb6d6f 100644
--- a/libstdc++-v3/src/c++20/Makefile.in
+++ b/libstdc++-v3/src/c++20/Makefile.in
@@ -121,7 +121,7 @@ CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
LTLIBRARIES = $(noinst_LTLIBRARIES)
libc__20convenience_la_LIBADD =
-am__objects_1 = tzdb.lo format.lo atomic.lo
+am__objects_1 = tzdb.lo format.lo atomic.lo clock.lo
@ENABLE_EXTERN_TEMPLATE_TRUE@am__objects_2 = sstream-inst.lo
@GLIBCXX_HOSTED_TRUE@am_libc__20convenience_la_OBJECTS = \
@GLIBCXX_HOSTED_TRUE@ $(am__objects_1) $(am__objects_2)
@@ -432,7 +432,7 @@ headers =
@ENABLE_EXTERN_TEMPLATE_TRUE@inst_sources = \
@ENABLE_EXTERN_TEMPLATE_TRUE@ sstream-inst.cc
-sources = tzdb.cc format.cc atomic.cc
+sources = tzdb.cc format.cc atomic.cc clock.cc
@GLIBCXX_HOSTED_FALSE@libc__20convenience_la_SOURCES =
@GLIBCXX_HOSTED_TRUE@libc__20convenience_la_SOURCES = $(sources) $(inst_sources)
diff --git a/libstdc++-v3/src/c++20/clock.cc b/libstdc++-v3/src/c++20/clock.cc
new file mode 100644
index 0000000..9d674b0
--- /dev/null
+++ b/libstdc++-v3/src/c++20/clock.cc
@@ -0,0 +1,52 @@
+// std::chrono::tai_clock, gps_clock
+
+// Copyright (C) 2021-2025 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+// <http://www.gnu.org/licenses/>.
+
+//
+// ISO C++ 14882:2020
+// 27.7.4 [time.clock.tai], 27.7.5 [time.clock.gps]
+// P0355R7
+
+#include <chrono>
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+namespace chrono
+{
+#if __cpp_lib_chrono >= 201803L && _GLIBCXX_HOSTED
+ // TODO use CLOCK_TAI on linux, add extension point.
+ time_point<tai_clock>
+ tai_clock::now()
+ { return from_utc(utc_clock::now()); }
+
+ // TODO add extension point.
+ time_point<gps_clock>
+ gps_clock::now()
+ { return from_utc(utc_clock::now()); }
+#endif
+}
+
+_GLIBCXX_END_NAMESPACE_VERSION
+}
diff --git a/libstdc++-v3/src/c++23/std.cc.in b/libstdc++-v3/src/c++23/std.cc.in
index 9301ed9..4888b8b 100644
--- a/libstdc++-v3/src/c++23/std.cc.in
+++ b/libstdc++-v3/src/c++23/std.cc.in
@@ -277,15 +277,14 @@ export namespace std
using std::ranges::shuffle;
}
using std::shift_left;
- namespace ranges
- {
- using std::ranges::shift_left;
- }
using std::shift_right;
+#if __cpp_lib_shift >= 202202L // >= C++23
namespace ranges
{
+ using std::ranges::shift_left;
using std::ranges::shift_right;
}
+#endif
using std::sort;
namespace ranges
{
@@ -500,7 +499,9 @@ export namespace std
using ranges::fold_left;
using ranges::fold_left_first;
using ranges::fold_left_first_with_iter;
+ using ranges::fold_left_first_with_iter_result;
using ranges::fold_left_with_iter;
+ using ranges::fold_left_with_iter_result;
using ranges::fold_right;
using ranges::fold_right_last;
using ranges::in_value_result;
@@ -672,6 +673,9 @@ export namespace std
using std::popcount;
using std::rotl;
using std::rotr;
+#if __cpp_lib_byteswap // >= C++23
+ using std::byteswap;
+#endif
}
// 22.9 <bitset>
@@ -1747,6 +1751,9 @@ export namespace std
using std::make_const_iterator;
using std::make_const_sentinel;
#endif
+#if __glibcxx_algorithm_default_value_type // >= C++26
+ using std::projected_value_t;
+#endif
}
// <latch>
@@ -1851,14 +1858,20 @@ export namespace std
{
using std::extents;
using std::dextents;
+#if __glibcxx_mdspan >= 202406L
+ using std::dims;
+#endif
using std::layout_left;
using std::layout_right;
using std::layout_stride;
using std::default_accessor;
+#if __glibcxx_aligned_accessor
+ using std::aligned_accessor;
+#endif
using std::mdspan;
- // FIXME layout_left_padded, layout_right_padded, aligned_accessor,
- // strided_slice, submdspan_mapping_result, full_extent_t, full_extent,
- // submdspan_extents, mdsubspan
+ // FIXME layout_left_padded, layout_right_padded, strided_slice,
+ // submdspan_mapping_result, full_extent_t, full_extent, submdspan_extents,
+ // mdsubspan
}
#endif
@@ -1871,6 +1884,9 @@ export namespace std
using std::allocator_arg_t;
using std::allocator_traits;
using std::assume_aligned;
+#if __glibcxx_is_sufficiently_aligned
+ using std::is_sufficiently_aligned;
+#endif
using std::make_obj_using_allocator;
using std::pointer_traits;
using std::to_address;
@@ -1973,6 +1989,8 @@ export namespace std
#if __cpp_lib_out_ptr
using std::out_ptr;
using std::inout_ptr;
+ using std::out_ptr_t;
+ using std::inout_ptr_t;
#endif
#if __cpp_lib_indirect
using std::indirect;
@@ -1982,6 +2000,10 @@ export namespace std
using std::polymorphic;
namespace pmr { using std::pmr::polymorphic; }
#endif
+#if __cpp_lib_smart_ptr_owner_equality
+ using std::owner_equal;
+ using std::owner_hash;
+#endif
}
// 20.4 <memory_resource>
@@ -2097,7 +2119,11 @@ export namespace std
using std::lcm;
using std::midpoint;
#if __cpp_lib_ranges_iota
- namespace ranges { using ranges::iota; }
+ namespace ranges
+ {
+ using ranges::iota;
+ using ranges::iota_result;
+ }
#endif
#if __cpp_lib_saturation_arithmetic
using std::add_sat;
@@ -2508,6 +2534,43 @@ export namespace std
using std::regex_constants::operator|;
using std::regex_constants::operator|=;
using std::regex_constants::operator~;
+ using std::regex_constants::awk;
+ using std::regex_constants::basic;
+ using std::regex_constants::collate;
+ using std::regex_constants::ECMAScript;
+ using std::regex_constants::egrep;
+ using std::regex_constants::extended;
+ using std::regex_constants::grep;
+ using std::regex_constants::icase;
+ using std::regex_constants::multiline;
+ using std::regex_constants::nosubs;
+ using std::regex_constants::optimize;
+ using std::regex_constants::format_default;
+ using std::regex_constants::format_first_only;
+ using std::regex_constants::format_no_copy;
+ using std::regex_constants::format_sed;
+ using std::regex_constants::match_any;
+ using std::regex_constants::match_continuous;
+ using std::regex_constants::match_default;
+ using std::regex_constants::match_not_bol;
+ using std::regex_constants::match_not_bow;
+ using std::regex_constants::match_not_eol;
+ using std::regex_constants::match_not_eow;
+ using std::regex_constants::match_not_null;
+ using std::regex_constants::match_prev_avail;
+ using std::regex_constants::error_backref;
+ using std::regex_constants::error_badbrace;
+ using std::regex_constants::error_badrepeat;
+ using std::regex_constants::error_brace;
+ using std::regex_constants::error_brack;
+ using std::regex_constants::error_collate;
+ using std::regex_constants::error_complexity;
+ using std::regex_constants::error_ctype;
+ using std::regex_constants::error_escape;
+ using std::regex_constants::error_paren;
+ using std::regex_constants::error_range;
+ using std::regex_constants::error_space;
+ using std::regex_constants::error_stack;
}
using std::basic_regex;
using std::csub_match;
@@ -3149,6 +3212,10 @@ export namespace std
using std::is_pointer_interconvertible_base_of_v;
using std::is_pointer_interconvertible_with_class;
#endif
+#if __cpp_lib_is_scoped_enum
+ using std::is_scoped_enum;
+ using std::is_scoped_enum_v;
+#endif
}
// <typeindex>
diff --git a/libstdc++-v3/src/c++26/Makefile.am b/libstdc++-v3/src/c++26/Makefile.am
index 5defa4a..4123b7d 100644
--- a/libstdc++-v3/src/c++26/Makefile.am
+++ b/libstdc++-v3/src/c++26/Makefile.am
@@ -35,7 +35,9 @@ else
inst_sources =
endif
-sources = text_encoding.cc
+sources = \
+ debugging.cc \
+ text_encoding.cc
vpath % $(top_srcdir)/src/c++26
diff --git a/libstdc++-v3/src/c++26/Makefile.in b/libstdc++-v3/src/c++26/Makefile.in
index 77e73b2..1c317d6 100644
--- a/libstdc++-v3/src/c++26/Makefile.in
+++ b/libstdc++-v3/src/c++26/Makefile.in
@@ -121,7 +121,7 @@ CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
LTLIBRARIES = $(noinst_LTLIBRARIES)
libc__26convenience_la_LIBADD =
-am__objects_1 = text_encoding.lo
+am__objects_1 = debugging.lo text_encoding.lo
am__objects_2 =
@GLIBCXX_HOSTED_TRUE@am_libc__26convenience_la_OBJECTS = \
@GLIBCXX_HOSTED_TRUE@ $(am__objects_1) $(am__objects_2)
@@ -430,7 +430,10 @@ headers =
# XTEMPLATE_FLAGS = -fno-implicit-templates
@ENABLE_EXTERN_TEMPLATE_TRUE@inst_sources =
-sources = text_encoding.cc
+sources = \
+ debugging.cc \
+ text_encoding.cc
+
@GLIBCXX_HOSTED_FALSE@libc__26convenience_la_SOURCES =
@GLIBCXX_HOSTED_TRUE@libc__26convenience_la_SOURCES = $(sources) $(inst_sources)
diff --git a/libstdc++-v3/src/c++26/debugging.cc b/libstdc++-v3/src/c++26/debugging.cc
new file mode 100644
index 0000000..c6262db
--- /dev/null
+++ b/libstdc++-v3/src/c++26/debugging.cc
@@ -0,0 +1,176 @@
+// Implementation of <debugging> -*- C++ -*-
+
+// Copyright The GNU Toolchain Authors.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+// <http://www.gnu.org/licenses/>.
+
+#include <debugging>
+
+#if __cpp_lib_debugging
+
+#include <csignal> // std::raise
+
+#if _GLIBCXX_USE_PROC_SELF_STATUS
+# include <fstream>
+# include <string>
+#endif
+
+#if _GLIBCXX_HAVE_SYS_PTRACE_H
+# include <sys/types.h> // for darwin ptrace
+# include <sys/ptrace.h>
+# include <errno.h>
+#endif
+
+#if _GLIBCXX_HAVE_DEBUGAPI_H
+# include <debugapi.h>
+#endif
+
+#ifdef _GLIBCXX_HAVE_SYS_SDT_H
+# include <sys/sdt.h>
+/* We only want to use stap probes starting with v3. Earlier versions
+ added too much startup cost. */
+# if defined (STAP_PROBE) && _SDT_NOTE_TYPE >= 3
+# define PROBE(name) STAP_PROBE(libstdcxx, name)
+# endif
+#endif
+
+#ifndef PROBE
+# define PROBE(name)
+#endif
+
+namespace __gnu_cxx
+{
+ // This should be changed to non-zero by debuggers when they attach
+ // and back to zero when they detach.
+ // If the value is positive, std::breakpoint() will use it as the argument
+ // to std::raise, so it should be a valid signal number, e.g. SIGABRT or
+ // SIGTRAP.
+ // If the value is negative, std::breakpoint() will use a target-specific
+ // trap, e.g. asm("int3") or __builtin_trap().
+ volatile int debugger_signal_for_breakpoint = 0;
+}
+
+_GLIBCXX_WEAK_DEFINITION
+bool
+std::is_debugger_present() noexcept
+{
+ PROBE(std::is_debugger_present);
+
+ if (__gnu_cxx::debugger_signal_for_breakpoint != 0)
+ return true;
+
+#if _GLIBCXX_HOSTED
+# if _GLIBCXX_USE_PROC_SELF_STATUS
+ const string_view prefix = "TracerPid:\t"; // populated since Linux 2.6.0
+ ifstream in("/proc/self/status");
+ string line;
+ while (std::getline(in, line))
+ {
+ if (!line.starts_with(prefix))
+ continue;
+
+ string_view tracer = line;
+ tracer.remove_prefix(prefix.size());
+ if (tracer.size() == 1 && tracer[0] == '0') [[likely]]
+ return false; // Not being traced.
+
+ in.close();
+ string_view cmd;
+ string proc_dir = "/proc/" + string(tracer) + '/';
+ in.open(proc_dir + "comm"); // since Linux 2.6.33
+ if (std::getline(in, line)) [[likely]]
+ cmd = line;
+ else
+ {
+ in.close();
+ in.open(proc_dir + "cmdline");
+ if (std::getline(in, line))
+ cmd = line.c_str(); // Only up to first '\0'
+ else
+ return false;
+ }
+
+ for (auto i : {"gdb", "gdbserver", "lldb-server"}) // known debuggers
+ if (cmd.ends_with(i))
+ return true;
+
+ // We found the TracerPid line, no need to do any more work.
+ return false;
+ }
+# elif _GLIBCXX_USE_PTRACE
+ if (::ptrace(PTRACE_TRACEME, 0, 1, 0) == -1)
+ return errno == EPERM;
+# endif
+# if _GLIBCXX_HAVE_DEBUGAPI_H && defined(_WIN32) && !defined(__CYGWIN__)
+ return IsDebuggerPresent();
+# endif
+#endif // HOSTED
+ return false;
+}
+
+void
+std::breakpoint() noexcept
+{
+ PROBE(std::breakpoint);
+
+ if (__gnu_cxx::debugger_signal_for_breakpoint > 0)
+ std::raise(__gnu_cxx::debugger_signal_for_breakpoint);
+
+#if _GLIBCXX_HAVE_DEBUGAPI_H && defined(_WIN32) && !defined(__CYGWIN__)
+ DebugBreak();
+#elif __has_builtin(__builtin_debugtrap)
+ __builtin_debugtrap(); // Clang
+#elif defined(__i386__) || defined(__x86_64__)
+ // nop is for GDB, see https://sourceware.org/bugzilla/show_bug.cgi?id=31194
+ __asm__ volatile ("int $0x3\n\tnop");
+#elifdef __thumb__
+ __asm__ volatile (".inst 0xde01");
+#elifdef __aarch64__
+ __asm__ volatile (".inst 0xd4200000");
+#elifdef __arm__
+ __asm__ volatile (".inst 0xe7f001f0");
+#elifdef __riscv
+ /* section 2.8 in the RISC-V unprivileged ISA manual says for semi-hosted
+ * environments we want the sequence:
+ * slli x0, x0, 0x1f # Entry NOP
+ * ebreak # Break to debugger
+ * srai x0, x0, 7 # NOP encoding the semihosting call number 7
+ */
+ __asm__ volatile (".4byte 0x00100073");
+#elif defined __powerpc__ && ! defined _AIX
+ __asm__ volatile(".4byte 0x7d821008");
+#else
+ __builtin_trap();
+#endif
+} // If the debugger stops here, std::breakpoint() was called.
+
+// This is intentionally not defined inline. A non-inline definition allows
+// debuggers to insert a breakpoint on calls to the function, avoiding the
+// overhead of calling `is_debugger_present()`.
+void
+std::breakpoint_if_debugging() noexcept
+{
+ PROBE(std::breakpoint_if_debugging);
+
+ if (std::is_debugger_present()) [[unlikely]]
+ std::breakpoint();
+}
+
+#endif // __cpp_lib_debugging
diff --git a/libstdc++-v3/testsuite/18_support/comparisons/categories/zero_neg.cc b/libstdc++-v3/testsuite/18_support/comparisons/categories/zero_neg.cc
index 2e6b9c1..ce0ca8e 100644
--- a/libstdc++-v3/testsuite/18_support/comparisons/categories/zero_neg.cc
+++ b/libstdc++-v3/testsuite/18_support/comparisons/categories/zero_neg.cc
@@ -23,6 +23,16 @@
// C++20 [cmp.categories.pre]
// "an argument other than a literal 0 is undefined"
+struct PtrConv
+{
+ template<typename T>
+ consteval operator T*()
+ { return nullptr; }
+
+ consteval operator std::nullptr_t()
+ { return nullptr; }
+};
+
void
test01()
{
@@ -48,6 +58,12 @@ test01()
std::partial_ordering::equivalent == nullptr;
std::weak_ordering::equivalent == nullptr;
std::strong_ordering::equivalent == nullptr;
+
+ constexpr PtrConv c;
+ // requires two user-defined conversion
+ std::partial_ordering::equivalent == c; // { dg-error "no match for 'operator=='" }
+ std::weak_ordering::equivalent == c; // { dg-error "no match for 'operator=='" }
+ std::strong_ordering::equivalent == c; // { dg-error "no match for 'operator=='" }
}
// { dg-prune-output "reinterpret_cast.* is not a constant expression" }
diff --git a/libstdc++-v3/testsuite/18_support/numeric_limits/128bit.cc b/libstdc++-v3/testsuite/18_support/numeric_limits/128bit.cc
index b13d837..bf12b65 100644
--- a/libstdc++-v3/testsuite/18_support/numeric_limits/128bit.cc
+++ b/libstdc++-v3/testsuite/18_support/numeric_limits/128bit.cc
@@ -4,6 +4,11 @@
#if __SIZEOF_FLOAT128__
__extension__ template class std::numeric_limits<__float128>;
+
+# if __cplusplus >= 201103L
+static_assert( std::numeric_limits<__float128>::max_digits10 == 36,
+ "PR libstdc++/121374" );
+# endif
#endif
#if __SIZEOF_INT128__
diff --git a/libstdc++-v3/testsuite/19_diagnostics/debugging/breakpoint.cc b/libstdc++-v3/testsuite/19_diagnostics/debugging/breakpoint.cc
new file mode 100644
index 0000000..ad24177
--- /dev/null
+++ b/libstdc++-v3/testsuite/19_diagnostics/debugging/breakpoint.cc
@@ -0,0 +1,13 @@
+// { dg-do run { target c++26 xfail c++26 } }
+// { dg-options "-lstdc++exp" }
+// { dg-require-cpp-feature-test __cpp_lib_debugging }
+#include <debugging>
+#include <type_traits>
+
+static_assert( noexcept(std::breakpoint()) );
+static_assert( std::is_void_v<decltype(std::breakpoint())> );
+
+int main()
+{
+ std::breakpoint();
+}
diff --git a/libstdc++-v3/testsuite/19_diagnostics/debugging/breakpoint_if_debugging.cc b/libstdc++-v3/testsuite/19_diagnostics/debugging/breakpoint_if_debugging.cc
new file mode 100644
index 0000000..2646183
--- /dev/null
+++ b/libstdc++-v3/testsuite/19_diagnostics/debugging/breakpoint_if_debugging.cc
@@ -0,0 +1,13 @@
+// { dg-do run { target c++26 } }
+// { dg-options "-lstdc++exp" }
+// { dg-require-cpp-feature-test __cpp_lib_debugging }
+#include <debugging>
+#include <type_traits>
+
+static_assert( noexcept(std::breakpoint_if_debugging()) );
+static_assert( std::is_void_v<decltype(std::breakpoint_if_debugging())> );
+
+int main()
+{
+ std::breakpoint_if_debugging();
+}
diff --git a/libstdc++-v3/testsuite/19_diagnostics/debugging/is_debugger_present-2.cc b/libstdc++-v3/testsuite/19_diagnostics/debugging/is_debugger_present-2.cc
new file mode 100644
index 0000000..aa4690c
--- /dev/null
+++ b/libstdc++-v3/testsuite/19_diagnostics/debugging/is_debugger_present-2.cc
@@ -0,0 +1,19 @@
+// { dg-do run { target c++26 } }
+// { dg-options "-lstdc++exp" }
+// { dg-require-cpp-feature-test __cpp_lib_debugging }
+// { dg-xfail-run-if "no replaceable functions on AIX" { powerpc-ibm-aix* } }
+
+// P2810R4 is_debugger_present is_replaceable
+
+#include <debugging>
+#include <testsuite_hooks.h>
+
+bool called = false;
+
+bool std::is_debugger_present() noexcept { called = true; return true; }
+
+int main()
+{
+ VERIFY( std::is_debugger_present() );
+ VERIFY( called );
+}
diff --git a/libstdc++-v3/testsuite/19_diagnostics/debugging/is_debugger_present.cc b/libstdc++-v3/testsuite/19_diagnostics/debugging/is_debugger_present.cc
new file mode 100644
index 0000000..8dbfa69
--- /dev/null
+++ b/libstdc++-v3/testsuite/19_diagnostics/debugging/is_debugger_present.cc
@@ -0,0 +1,14 @@
+// { dg-do run { target c++26 } }
+// { dg-options "-lstdc++exp" }
+// { dg-require-cpp-feature-test __cpp_lib_debugging }
+#include <debugging>
+#include <type_traits>
+#include <testsuite_hooks.h>
+
+static_assert( noexcept(std::is_debugger_present()) );
+static_assert( std::is_same_v<decltype(std::is_debugger_present()), bool> );
+
+int main()
+{
+ VERIFY( ! std::is_debugger_present() );
+}
diff --git a/libstdc++-v3/testsuite/20_util/copyable_function/call.cc b/libstdc++-v3/testsuite/20_util/copyable_function/call.cc
index 0ac5348..605422d 100644
--- a/libstdc++-v3/testsuite/20_util/copyable_function/call.cc
+++ b/libstdc++-v3/testsuite/20_util/copyable_function/call.cc
@@ -214,6 +214,28 @@ test_params()
std::copyable_function<void(CompleteEnum)> f4;
}
+struct EmptyIdFunc
+{
+ EmptyIdFunc* operator()()
+ { return this; }
+};
+
+struct Composed : EmptyIdFunc
+{
+ std::move_only_function<EmptyIdFunc*()> nested;
+};
+
+void
+test_aliasing()
+{
+ Composed c;
+ c.nested = EmptyIdFunc{};
+
+ EmptyIdFunc* baseAddr = c();
+ EmptyIdFunc* nestedAddr = c.nested();
+ VERIFY( baseAddr != nestedAddr );
+};
+
int main()
{
test01();
@@ -222,4 +244,5 @@ int main()
test04();
test05();
test_params();
+ test_aliasing();
}
diff --git a/libstdc++-v3/testsuite/20_util/function_objects/bind_back/1.cc b/libstdc++-v3/testsuite/20_util/function_objects/bind_back/1.cc
index c31d322..a31528f 100644
--- a/libstdc++-v3/testsuite/20_util/function_objects/bind_back/1.cc
+++ b/libstdc++-v3/testsuite/20_util/function_objects/bind_back/1.cc
@@ -48,6 +48,16 @@ test01()
decltype(bind_back(std::declval<const F&>(), std::declval<const int&>()))
>);
+ static_assert(std::is_same_v<
+ decltype(bind_back(std::declval<F>(), std::declval<int>(), std::declval<float>())),
+ decltype(bind_back(std::declval<F&>(), std::declval<int&>(), std::declval<float&>()))
+ >);
+ static_assert(std::is_same_v<
+ decltype(bind_back(std::declval<F>(), std::declval<int>(), std::declval<float>())),
+ decltype(bind_back(std::declval<const F&>(), std::declval<const int&>(), std::declval<const float&>()))
+ >);
+
+
// Reference wrappers should be handled:
static_assert(!std::is_same_v<
decltype(bind_back(std::declval<F>(), std::declval<int&>())),
@@ -63,29 +73,58 @@ test01()
>);
}
+struct quals
+{
+ bool as_const;
+ bool as_lvalue;
+};
+
+template<typename... Args>
void
-test02()
+testTarget(Args... args)
{
- struct quals
+ struct F
{
- bool as_const;
- bool as_lvalue;
+ quals operator()(Args...) & { return { false, true }; }
+ quals operator()(Args...) const & { return { true, true }; }
+ quals operator()(Args...) && { return { false, false }; }
+ quals operator()(Args...) const && { return { true, false }; }
};
+ F f;
+ auto g = bind_back(f, args...);
+ const auto& cg = g;
+ quals q;
+
+ // constness and value category should be forwarded to the target object:
+ q = g();
+ VERIFY( ! q.as_const && q.as_lvalue );
+ q = std::move(g)();
+ VERIFY( ! q.as_const && ! q.as_lvalue );
+ q = cg();
+ VERIFY( q.as_const && q.as_lvalue );
+ q = std::move(cg)();
+ VERIFY( q.as_const && ! q.as_lvalue );
+}
+
+template<typename... Args>
+void
+testBoundArgs(Args... args)
+{
struct F
{
- quals operator()() & { return { false, true }; }
- quals operator()() const & { return { true, true }; }
- quals operator()() && { return { false, false }; }
- quals operator()() const && { return { true, false }; }
+ quals operator()(Args..., int&) const { return { false, true }; }
+ quals operator()(Args..., int const&) const { return { true, true }; }
+ quals operator()(Args..., int&&) const { return { false, false }; }
+ quals operator()(Args..., int const&&) const { return { true, false }; }
};
F f;
- auto g = bind_back(f);
+ auto g = bind_back(f, args..., 10);
const auto& cg = g;
quals q;
- // constness and value category should be forwarded to the target object:
+ // constness and value category should be forwarded to the bound objects:
q = g();
VERIFY( ! q.as_const && q.as_lvalue );
q = std::move(g)();
@@ -94,6 +133,70 @@ test02()
VERIFY( q.as_const && q.as_lvalue );
q = std::move(cg)();
VERIFY( q.as_const && ! q.as_lvalue );
+
+ int i = 0;
+ auto gr = bind_back(f, args..., std::ref(i));
+ const auto& cgr = gr;
+
+ // bound object is reference wrapper
+ q = gr();
+ VERIFY( ! q.as_const && q.as_lvalue );
+ q = std::move(gr)();
+ VERIFY( ! q.as_const && q.as_lvalue );
+ q = cgr();
+ VERIFY( ! q.as_const && q.as_lvalue );
+ q = std::move(cgr)();
+ VERIFY( ! q.as_const && q.as_lvalue );
+
+ auto gcr = bind_back(f, args..., std::cref(i));
+ const auto& cgcr = gcr;
+
+ q = gcr();
+ VERIFY( q.as_const && q.as_lvalue );
+ q = std::move(gcr)();
+ VERIFY( q.as_const && q.as_lvalue );
+ q = cgcr();
+ VERIFY( q.as_const && q.as_lvalue );
+ q = std::move(cgcr)();
+ VERIFY( q.as_const && q.as_lvalue );
+}
+
+template<typename... Args>
+void
+testCallArgs(Args... args)
+{
+ struct F
+ {
+ quals operator()(int&, Args...) const { return { false, true }; }
+ quals operator()(int const&, Args...) const { return { true, true }; }
+ quals operator()(int&&, Args...) const { return { false, false }; }
+ quals operator()(int const&&, Args...) const { return { true, false }; }
+ };
+
+ F f;
+ auto g = bind_back(f, args...);
+ const auto& cg = g;
+ quals q;
+ int i = 10;
+ const int ci = i;
+
+ q = g(i);
+ VERIFY( ! q.as_const && q.as_lvalue );
+ q = g(std::move(i));
+ VERIFY( ! q.as_const && ! q.as_lvalue );
+ q = g(ci);
+ VERIFY( q.as_const && q.as_lvalue );
+ q = g(std::move(ci));
+ VERIFY( q.as_const && ! q.as_lvalue );
+
+ q = cg(i);
+ VERIFY( ! q.as_const && q.as_lvalue );
+ q = cg(std::move(i));
+ VERIFY( ! q.as_const && ! q.as_lvalue );
+ q = cg(ci);
+ VERIFY( q.as_const && q.as_lvalue );
+ q = cg(std::move(ci));
+ VERIFY( q.as_const && ! q.as_lvalue );
}
void
@@ -168,11 +271,52 @@ test04()
return true;
}
+struct CountedArg
+{
+ CountedArg() = default;
+ CountedArg(CountedArg&& f) noexcept : counter(f.counter) { ++counter; }
+ CountedArg& operator=(CountedArg&&) = delete;
+
+ int counter = 0;
+};
+CountedArg const c;
+
+void
+testMaterialization()
+{
+ struct F
+ {
+ int operator()(CountedArg arg, int) const
+ { return arg.counter; };
+ };
+
+ // CountedArg is bound to rvalue-reference thus moved
+ auto f0 = std::bind_back(F{});
+ VERIFY( f0(CountedArg(), 10) == 1 );
+
+ auto f1 = std::bind_back(F{}, 10);
+ VERIFY( f1(CountedArg()) == 1 );
+}
+
int
main()
{
test01();
- test02();
test03();
+
+ testTarget();
+ testTarget(10);
+ testTarget(10, 20, 30);
+
+ testBoundArgs();
+ testBoundArgs(10);
+ testBoundArgs(10, 20, 30);
+
+ testCallArgs();
+ testCallArgs(10);
+ testCallArgs(10, 20, 30);
+
+ testMaterialization();
+
static_assert(test04());
}
diff --git a/libstdc++-v3/testsuite/20_util/function_objects/bind_back/111327.cc b/libstdc++-v3/testsuite/20_util/function_objects/bind_back/111327.cc
index d634db9..de3ae47 100644
--- a/libstdc++-v3/testsuite/20_util/function_objects/bind_back/111327.cc
+++ b/libstdc++-v3/testsuite/20_util/function_objects/bind_back/111327.cc
@@ -37,6 +37,17 @@ int main() {
g1(); // { dg-error "deleted|no match" }
std::move(g1)(); // { dg-error "deleted|no match" }
std::move(std::as_const(g1))();
+
+ auto f2 = std::bind_back(F{}, 42, 10);
+ f2(); // { dg-error "deleted|no match" }
+ std::move(f2)();
+ std::as_const(f2)();
+ std::move(std::as_const(f2))();
+
+ auto g2 = std::bind_back(G{}, 42, 10);
+ g2(); // { dg-error "deleted|no match" }
+ std::move(g2)(); // { dg-error "deleted|no match" }
+ std::move(std::as_const(g2))();
}
// { dg-error "no type named 'type' in 'struct std::invoke_result" "" { target c++23 } 0 }
diff --git a/libstdc++-v3/testsuite/20_util/function_objects/bind_front/1.cc b/libstdc++-v3/testsuite/20_util/function_objects/bind_front/1.cc
index 57482c5..ef28de8 100644
--- a/libstdc++-v3/testsuite/20_util/function_objects/bind_front/1.cc
+++ b/libstdc++-v3/testsuite/20_util/function_objects/bind_front/1.cc
@@ -48,6 +48,15 @@ test01()
decltype(bind_front(std::declval<const F&>(), std::declval<const int&>()))
>);
+ static_assert(std::is_same_v<
+ decltype(bind_front(std::declval<F>(), std::declval<int>(), std::declval<float>())),
+ decltype(bind_front(std::declval<F&>(), std::declval<int&>(), std::declval<float&>()))
+ >);
+ static_assert(std::is_same_v<
+ decltype(bind_front(std::declval<F>(), std::declval<int>(), std::declval<float>())),
+ decltype(bind_front(std::declval<const F&>(), std::declval<const int&>(), std::declval<const float&>()))
+ >);
+
// Reference wrappers should be handled:
static_assert(!std::is_same_v<
decltype(bind_front(std::declval<F>(), std::declval<int&>())),
@@ -63,29 +72,58 @@ test01()
>);
}
+struct quals
+{
+ bool as_const;
+ bool as_lvalue;
+};
+
+template<typename... Args>
void
-test02()
+testTarget(Args... args)
{
- struct quals
+ struct F
{
- bool as_const;
- bool as_lvalue;
+ quals operator()(Args...) & { return { false, true }; }
+ quals operator()(Args...) const & { return { true, true }; }
+ quals operator()(Args...) && { return { false, false }; }
+ quals operator()(Args...) const && { return { true, false }; }
};
+ F f;
+ auto g = bind_front(f, args...);
+ const auto& cg = g;
+ quals q;
+
+ // constness and value category should be forwarded to the target object:
+ q = g();
+ VERIFY( ! q.as_const && q.as_lvalue );
+ q = std::move(g)();
+ VERIFY( ! q.as_const && ! q.as_lvalue );
+ q = cg();
+ VERIFY( q.as_const && q.as_lvalue );
+ q = std::move(cg)();
+ VERIFY( q.as_const && ! q.as_lvalue );
+}
+
+template<typename... Args>
+void
+testBoundArgs(Args... args)
+{
struct F
{
- quals operator()() & { return { false, true }; }
- quals operator()() const & { return { true, true }; }
- quals operator()() && { return { false, false }; }
- quals operator()() const && { return { true, false }; }
+ quals operator()(Args..., int&) const { return { false, true }; }
+ quals operator()(Args..., int const&) const { return { true, true }; }
+ quals operator()(Args..., int&&) const { return { false, false }; }
+ quals operator()(Args..., int const&&) const { return { true, false }; }
};
F f;
- auto g = bind_front(f);
+ auto g = bind_front(f, args..., 10);
const auto& cg = g;
quals q;
- // constness and value category should be forwarded to the target object:
+ // constness and value category should be forwarded to the bound objects:
q = g();
VERIFY( ! q.as_const && q.as_lvalue );
q = std::move(g)();
@@ -94,6 +132,70 @@ test02()
VERIFY( q.as_const && q.as_lvalue );
q = std::move(cg)();
VERIFY( q.as_const && ! q.as_lvalue );
+
+ int i = 0;
+ auto gr = bind_front(f, args..., std::ref(i));
+ const auto& cgr = gr;
+
+ // bound object is reference wrapper, converts to same type of reference
+ q = gr();
+ VERIFY( ! q.as_const && q.as_lvalue );
+ q = std::move(gr)();
+ VERIFY( ! q.as_const && q.as_lvalue );
+ q = cgr();
+ VERIFY( ! q.as_const && q.as_lvalue );
+ q = std::move(cgr)();
+ VERIFY( ! q.as_const && q.as_lvalue );
+
+ auto gcr = bind_front(f, args..., std::cref(i));
+ const auto& cgcr = gcr;
+
+ q = gcr();
+ VERIFY( q.as_const && q.as_lvalue );
+ q = std::move(gcr)();
+ VERIFY( q.as_const && q.as_lvalue );
+ q = cgcr();
+ VERIFY( q.as_const && q.as_lvalue );
+ q = std::move(cgcr)();
+ VERIFY( q.as_const && q.as_lvalue );
+}
+
+template<typename... Args>
+void
+testCallArgs(Args... args)
+{
+ struct F
+ {
+ quals operator()(Args..., int&) const { return { false, true }; }
+ quals operator()(Args..., int const&) const { return { true, true }; }
+ quals operator()(Args..., int&&) const { return { false, false }; }
+ quals operator()(Args..., int const&&) const { return { true, false }; }
+ };
+
+ F f;
+ auto g = bind_front(f, args...);
+ const auto& cg = g;
+ quals q;
+ int i = 10;
+ const int ci = i;
+
+ q = g(i);
+ VERIFY( ! q.as_const && q.as_lvalue );
+ q = g(std::move(i));
+ VERIFY( ! q.as_const && ! q.as_lvalue );
+ q = g(ci);
+ VERIFY( q.as_const && q.as_lvalue );
+ q = g(std::move(ci));
+ VERIFY( q.as_const && ! q.as_lvalue );
+
+ q = cg(i);
+ VERIFY( ! q.as_const && q.as_lvalue );
+ q = cg(std::move(i));
+ VERIFY( ! q.as_const && ! q.as_lvalue );
+ q = cg(ci);
+ VERIFY( q.as_const && q.as_lvalue );
+ q = cg(std::move(ci));
+ VERIFY( q.as_const && ! q.as_lvalue );
}
void
@@ -167,11 +269,51 @@ test04()
VERIFY( bind_front(g2, 3)() == 6 );
}
+struct CountedArg
+{
+ CountedArg() = default;
+ CountedArg(CountedArg&& f) noexcept : counter(f.counter) { ++counter; }
+ CountedArg& operator=(CountedArg&&) = delete;
+
+ int counter = 0;
+};
+CountedArg const c;
+
+void
+testMaterialization()
+{
+ struct F
+ {
+ int operator()(int, CountedArg arg) const
+ { return arg.counter; };
+ };
+
+ // CountedArg is bound to rvalue-reference thus moved
+ auto f0 = std::bind_front(F{});
+ VERIFY( f0(10, CountedArg()) == 1 );
+
+ auto f1 = std::bind_front(F{}, 10);
+ VERIFY( f1(CountedArg()) == 1 );
+}
+
int
main()
{
test01();
- test02();
test03();
test04();
+
+ testTarget();
+ testTarget(10);
+ testTarget(10, 20, 30);
+
+ testBoundArgs();
+ testBoundArgs(10);
+ testBoundArgs(10, 20, 30);
+
+ testCallArgs();
+ testCallArgs(10);
+ testCallArgs(10, 20, 30);
+
+ testMaterialization();
}
diff --git a/libstdc++-v3/testsuite/20_util/function_objects/bind_front/111327.cc b/libstdc++-v3/testsuite/20_util/function_objects/bind_front/111327.cc
index 5fe0a83..6694322 100644
--- a/libstdc++-v3/testsuite/20_util/function_objects/bind_front/111327.cc
+++ b/libstdc++-v3/testsuite/20_util/function_objects/bind_front/111327.cc
@@ -37,6 +37,17 @@ int main() {
g1(); // { dg-error "deleted|no match" }
std::move(g1)(); // { dg-error "deleted|no match" }
std::move(std::as_const(g1))();
+
+ auto f2 = std::bind_front(F{}, 42, 10);
+ f2(); // { dg-error "deleted|no match" }
+ std::move(f2)();
+ std::as_const(f2)();
+ std::move(std::as_const(f2))();
+
+ auto g2 = std::bind_front(G{}, 42, 10);
+ g2(); // { dg-error "deleted|no match" }
+ std::move(g2)(); // { dg-error "deleted|no match" }
+ std::move(std::as_const(g2))();
}
// { dg-error "no type named 'type' in 'struct std::invoke_result" "" { target c++23 } 0 }
diff --git a/libstdc++-v3/testsuite/20_util/headers/memory/version.cc b/libstdc++-v3/testsuite/20_util/headers/memory/version.cc
index 946955d..5366a5d 100644
--- a/libstdc++-v3/testsuite/20_util/headers/memory/version.cc
+++ b/libstdc++-v3/testsuite/20_util/headers/memory/version.cc
@@ -10,3 +10,7 @@
#if __cpp_lib_addressof_constexpr != 201603L
# error "Feature-test macro __cpp_lib_addressof_constexpr has wrong value in <version>"
#endif
+
+#if __cplusplus > 202302L && __cpp_lib_is_sufficiently_aligned != 202411L
+# error "Feature-test macro __cpp_lib_is_sufficiently_aligned has wrong value in <version>"
+#endif
diff --git a/libstdc++-v3/testsuite/20_util/is_sufficiently_aligned/1.cc b/libstdc++-v3/testsuite/20_util/is_sufficiently_aligned/1.cc
new file mode 100644
index 0000000..4c2738b
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/is_sufficiently_aligned/1.cc
@@ -0,0 +1,31 @@
+// { dg-do run { target c++26 } }
+
+#include <memory>
+#include <array>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ constexpr size_t N = 4;
+ constexpr size_t M = 2*N + 1;
+ alignas(N) std::array<char, M> buffer{};
+
+ auto* ptr = buffer.data();
+ VERIFY(std::is_sufficiently_aligned<1>(ptr+0));
+ VERIFY(std::is_sufficiently_aligned<1>(ptr+1));
+
+ VERIFY(std::is_sufficiently_aligned<2>(ptr+0));
+ VERIFY(!std::is_sufficiently_aligned<2>(ptr+1));
+ VERIFY(std::is_sufficiently_aligned<2>(ptr+2));
+
+ for (size_t i = 0; i < M; ++i)
+ VERIFY(std::is_sufficiently_aligned<N>(ptr + i) == (i % N == 0));
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/20_util/move_only_function/call.cc b/libstdc++-v3/testsuite/20_util/move_only_function/call.cc
index 72c8118..34ca73b 100644
--- a/libstdc++-v3/testsuite/20_util/move_only_function/call.cc
+++ b/libstdc++-v3/testsuite/20_util/move_only_function/call.cc
@@ -214,6 +214,28 @@ test_params()
std::move_only_function<void(CompleteEnum)> f4;
}
+struct EmptyIdFunc
+{
+ EmptyIdFunc* operator()()
+ { return this; }
+};
+
+struct Composed : EmptyIdFunc
+{
+ std::move_only_function<EmptyIdFunc*()> nested;
+};
+
+void
+test_aliasing()
+{
+ Composed c;
+ c.nested = EmptyIdFunc{};
+
+ EmptyIdFunc* baseAddr = c();
+ EmptyIdFunc* nestedAddr = c.nested();
+ VERIFY( baseAddr != nestedAddr );
+};
+
int main()
{
test01();
@@ -222,4 +244,5 @@ int main()
test04();
test05();
test_params();
+ test_aliasing();
}
diff --git a/libstdc++-v3/testsuite/20_util/optional/cons/value_neg.cc b/libstdc++-v3/testsuite/20_util/optional/cons/value_neg.cc
index d3abd03..f6b1886 100644
--- a/libstdc++-v3/testsuite/20_util/optional/cons/value_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/optional/cons/value_neg.cc
@@ -37,3 +37,4 @@ int main()
}
}
// { dg-prune-output "no type .*enable_if" }
+// { dg-prune-output "no matching function for call to 'main..::U::U..'" }
diff --git a/libstdc++-v3/testsuite/20_util/scoped_allocator/69293_neg.cc b/libstdc++-v3/testsuite/20_util/scoped_allocator/69293_neg.cc
index d4be086..a3fbeba 100644
--- a/libstdc++-v3/testsuite/20_util/scoped_allocator/69293_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/scoped_allocator/69293_neg.cc
@@ -42,6 +42,8 @@ static_assert(uses_allocator<X, inner_alloc_type>{}, "");
static_assert(!is_constructible<X, allocator_arg_t, inner_alloc_type>{}, "");
static_assert(!is_constructible<X, inner_alloc_type>{}, "");
+// { dg-error "too many initializers" "" { target c++20 } 0 }
+
void
test01()
{
diff --git a/libstdc++-v3/testsuite/23_containers/bitset/lwg4294.cc b/libstdc++-v3/testsuite/23_containers/bitset/lwg4294.cc
new file mode 100644
index 0000000..977555f
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/bitset/lwg4294.cc
@@ -0,0 +1,11 @@
+// { dg-do compile { target c++11 } }
+
+// Bug 121046
+// Asking is_constructible_v<std::bitset<1>, NonTrivial*> is ill-formed
+
+// LWG 4294. bitset(const CharT*) constructor needs to be constrained
+
+#include <bitset>
+struct NonTrivial { ~NonTrivial() { } };
+static_assert( ! std::is_constructible<std::bitset<1>, NonTrivial*>::value,
+ "std::bitset cannot be constructed from this pointer" );
diff --git a/libstdc++-v3/testsuite/23_containers/inplace_vector/erasure.cc b/libstdc++-v3/testsuite/23_containers/inplace_vector/erasure.cc
index c7fda09..8fb56e9 100644
--- a/libstdc++-v3/testsuite/23_containers/inplace_vector/erasure.cc
+++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/erasure.cc
@@ -2,18 +2,38 @@
#include <inplace_vector>
#include <testsuite_hooks.h>
+#include <span>
+
+template<typename T, size_t N>
+constexpr bool
+eq(const std::inplace_vector<T, N>& l, std::span<const T> r) {
+ if (l.size() != r.size())
+ return false;
+ for (auto i = 0u; i < l.size(); ++i)
+ if (l[i] != r[i])
+ return false;
+ return true;
+};
constexpr void
test_erase()
{
- std::inplace_vector<int, 15> c{1, 2, 3, 4, 5, 6, 5, 4, 3, 2, 1, 4, 4, 9};
+ std::inplace_vector<int, 15> c{1, 0, 3, 4, 5, 6, 5, 4, 3, 0, 1, 4, 4, 9};
std::erase(c, 4);
VERIFY( c.size() == 10 );
std::erase(c, 1);
VERIFY( c.size() == 8 );
std::erase(c, 9);
VERIFY( c.size() == 7 );
- VERIFY( (c == std::inplace_vector<int, 15>{2, 3, 5, 6, 5, 3, 2}) );
+ VERIFY( eq(c, {0, 3, 5, 6, 5, 3, 0}) );
+
+ std::erase(c, {});
+ VERIFY( c.size() == 5 );
+ VERIFY( eq(c, {3, 5, 6, 5, 3}) );
+
+ std::erase(c, {5});
+ VERIFY( c.size() == 3 );
+ VERIFY( eq(c, {3, 6, 3}) );
std::inplace_vector<int, 0> e;
std::erase(e, 10);
@@ -29,7 +49,7 @@ test_erase_if()
std::erase_if(c, [](int i) { return i == 4; });
VERIFY( c.size() == 8 );
std::erase_if(c, [](int i) { return i & 1; });
- VERIFY( (c == std::inplace_vector<int, 15>{2, 2}) );
+ VERIFY( eq(c, {2, 2}) );
std::inplace_vector<int, 0> e;
std::erase_if(e, [](int i) { return i > 5; });
diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/accessors/aligned_neg.cc b/libstdc++-v3/testsuite/23_containers/mdspan/accessors/aligned_neg.cc
new file mode 100644
index 0000000..f36ebb1
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/mdspan/accessors/aligned_neg.cc
@@ -0,0 +1,33 @@
+// { dg-do compile { target c++26 } }
+#include<mdspan>
+
+#include <cstdint>
+
+std::aligned_accessor<uint32_t, 0> a; // { dg-error "required from here" }
+std::aligned_accessor<uint32_t, 7> b; // { dg-error "required from here" }
+std::aligned_accessor<uint32_t, size_t(-1)> c; // { dg-error "required from here" }
+
+std::aligned_accessor<uint32_t, 2> d; // { dg-error "required from here" }
+
+std::aligned_accessor<int[2], 32> e; // { dg-error "required from here" }
+
+class Abstract
+{
+ virtual void
+ foo() const = 0;
+};
+
+class Derived : public Abstract
+{
+ void
+ foo() const override
+ { }
+};
+
+std::aligned_accessor<Derived, alignof(int)> f_ok;
+std::aligned_accessor<Abstract, alignof(int)> f_err; // { dg-error "required from here" }
+
+// { dg-prune-output "ByteAlignment must be a power of two" }
+// { dg-prune-output "ElementType must not be an array type" }
+// { dg-prune-output "ElementType must not be an abstract" }
+// { dg-prune-output "static assertion failed" } // no message for alignment being too small
diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/accessors/debug/aligned_access_neg.cc b/libstdc++-v3/testsuite/23_containers/mdspan/accessors/debug/aligned_access_neg.cc
new file mode 100644
index 0000000..3511cef
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/mdspan/accessors/debug/aligned_access_neg.cc
@@ -0,0 +1,23 @@
+// { dg-do run { target c++26 xfail *-*-* } }
+// { dg-require-debug-mode "" }
+
+#include <mdspan>
+#include <array>
+
+void
+test_unaligned_access()
+{
+ constexpr size_t N = 4;
+ alignas(N) std::array<char, 128> buffer{};
+ auto* unaligned = buffer.data() + 1;
+ auto a = std::aligned_accessor<char, N>{};
+
+ [[maybe_unused]] char x = a.access(unaligned, 0);
+}
+
+int
+main()
+{
+ test_unaligned_access();
+ return 0;
+};
diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/accessors/debug/aligned_offset_neg.cc b/libstdc++-v3/testsuite/23_containers/mdspan/accessors/debug/aligned_offset_neg.cc
new file mode 100644
index 0000000..319da5f
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/mdspan/accessors/debug/aligned_offset_neg.cc
@@ -0,0 +1,23 @@
+// { dg-do run { target c++26 xfail *-*-* } }
+// { dg-require-debug-mode "" }
+
+#include <mdspan>
+#include <array>
+
+void
+test_unaligned_offset()
+{
+ constexpr size_t N = 4;
+ alignas(N) std::array<char, 128> buffer{};
+ auto* unaligned = buffer.data() + 1;
+ auto a = std::aligned_accessor<char, N>{};
+
+ [[maybe_unused]] char* x = a.offset(unaligned, 0);
+}
+
+int
+main()
+{
+ test_unaligned_offset();
+ return 0;
+};
diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/accessors/generic.cc b/libstdc++-v3/testsuite/23_containers/mdspan/accessors/generic.cc
index c335035..31cb13e 100644
--- a/libstdc++-v3/testsuite/23_containers/mdspan/accessors/generic.cc
+++ b/libstdc++-v3/testsuite/23_containers/mdspan/accessors/generic.cc
@@ -29,44 +29,59 @@ class Base
class Derived : public Base
{ };
-template<template<typename T> typename Accessor>
+template<typename RhsAccessor, typename LhsAccessor, bool ExpectConvertible>
+ constexpr void
+ check_convertible()
+ {
+ RhsAccessor rhs;
+ [[maybe_unused]] LhsAccessor lhs(rhs);
+ static_assert(std::is_nothrow_constructible_v<LhsAccessor, RhsAccessor>);
+ static_assert(std::is_convertible_v<RhsAccessor, LhsAccessor> == ExpectConvertible);
+ }
+
+template<template<typename T> typename LhsAccessor,
+ template<typename T> typename RhsAccessor = LhsAccessor,
+ bool ExpectConvertible = true>
constexpr bool
test_ctor()
{
// T -> T
- static_assert(std::is_nothrow_constructible_v<Accessor<double>,
- Accessor<double>>);
- static_assert(std::is_convertible_v<Accessor<double>, Accessor<double>>);
+ check_convertible<RhsAccessor<double>, LhsAccessor<double>,
+ ExpectConvertible>();
// T -> const T
- static_assert(std::is_convertible_v<Accessor<double>,
- Accessor<const double>>);
- static_assert(std::is_convertible_v<Accessor<Derived>,
- Accessor<const Derived>>);
+ check_convertible<RhsAccessor<double>, LhsAccessor<const double>,
+ ExpectConvertible>();
+ check_convertible<RhsAccessor<Derived>, LhsAccessor<const Derived>,
+ ExpectConvertible>();
// const T -> T
- static_assert(!std::is_constructible_v<Accessor<double>,
- Accessor<const double>>);
- static_assert(!std::is_constructible_v<Accessor<Derived>,
- Accessor<const Derived>>);
+ static_assert(!std::is_constructible_v<LhsAccessor<double>,
+ RhsAccessor<const double>>);
+ static_assert(!std::is_constructible_v<LhsAccessor<Derived>,
+ RhsAccessor<const Derived>>);
// T <-> volatile T
- static_assert(std::is_convertible_v<Accessor<int>, Accessor<volatile int>>);
- static_assert(!std::is_constructible_v<Accessor<int>,
- Accessor<volatile int>>);
+ check_convertible<RhsAccessor<int>, LhsAccessor<volatile int>,
+ ExpectConvertible>();
+ static_assert(!std::is_constructible_v<LhsAccessor<int>,
+ RhsAccessor<volatile int>>);
// size difference
- static_assert(!std::is_constructible_v<Accessor<char>, Accessor<int>>);
+ static_assert(!std::is_constructible_v<LhsAccessor<char>,
+ RhsAccessor<int>>);
// signedness
- static_assert(!std::is_constructible_v<Accessor<int>,
- Accessor<unsigned int>>);
- static_assert(!std::is_constructible_v<Accessor<unsigned int>,
- Accessor<int>>);
+ static_assert(!std::is_constructible_v<LhsAccessor<int>,
+ RhsAccessor<unsigned int>>);
+ static_assert(!std::is_constructible_v<LhsAccessor<unsigned int>,
+ RhsAccessor<int>>);
// Derived <-> Base
- static_assert(!std::is_constructible_v<Accessor<Base>, Accessor<Derived>>);
- static_assert(!std::is_constructible_v<Accessor<Derived>, Accessor<Base>>);
+ static_assert(!std::is_constructible_v<LhsAccessor<Base>,
+ RhsAccessor<Derived>>);
+ static_assert(!std::is_constructible_v<LhsAccessor<Derived>,
+ RhsAccessor<Base>>);
return true;
}
@@ -82,10 +97,36 @@ template<template<typename T> typename Accessor>
static_assert(test_properties<std::default_accessor>());
+#ifdef __glibcxx_aligned_accessor
+template<size_t Mult>
+struct OverAlignedAccessorTrait
+{
+ template<typename T>
+ using type = std::aligned_accessor<T, Mult*alignof(T)>;
+};
+
+static_assert(test_properties<OverAlignedAccessorTrait<1>::type>());
+static_assert(test_properties<OverAlignedAccessorTrait<2>::type>());
+static_assert(test_ctor<OverAlignedAccessorTrait<2>::type,
+ std::default_accessor, false>());
+static_assert(test_ctor<OverAlignedAccessorTrait<2>::type,
+ OverAlignedAccessorTrait<4>::type>());
+static_assert(test_ctor<std::default_accessor,
+ OverAlignedAccessorTrait<2>::type>());
+static_assert(!std::is_constructible_v<std::aligned_accessor<char, 4>,
+ std::aligned_accessor<char, 2>>);
+#endif
+
template<typename A>
constexpr size_t
accessor_alignment = alignof(typename A::element_type);
+#ifdef __glibcxx_aligned_accessor
+template<typename T, size_t N>
+ constexpr size_t
+ accessor_alignment<std::aligned_accessor<T, N>> = N;
+#endif
+
template<typename Accessor>
constexpr void
test_access(Accessor accessor)
@@ -121,5 +162,10 @@ main()
{
test_all<std::default_accessor<double>>();
static_assert(test_all<std::default_accessor<double>>());
+
+#ifdef __glibcxx_aligned_accessor
+ test_all<typename OverAlignedAccessorTrait<4>::type<double>>();
+ static_assert(test_all<typename OverAlignedAccessorTrait<4>::type<double>>());
+#endif
return 0;
}
diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/class_mandates_neg.cc b/libstdc++-v3/testsuite/23_containers/mdspan/extents/class_mandates_neg.cc
index 67d18fe..db5cad2 100644
--- a/libstdc++-v3/testsuite/23_containers/mdspan/extents/class_mandates_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/class_mandates_neg.cc
@@ -12,3 +12,6 @@ std::extents<double, 1> e4; // { dg-error "from here" }
// { dg-prune-output "signed or unsigned integer" }
// { dg-prune-output "invalid use of incomplete type" }
// { dg-prune-output "non-constant condition for static assertion" }
+// { dg-prune-output "integer constants in boolean context" }
+// { dg-prune-output "__gnu_cxx::__numeric_traits_integer" }
+// { dg-prune-output "static assertion failed" }
diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/misc.cc b/libstdc++-v3/testsuite/23_containers/mdspan/extents/misc.cc
index bca8901..8a43a68 100644
--- a/libstdc++-v3/testsuite/23_containers/mdspan/extents/misc.cc
+++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/misc.cc
@@ -159,6 +159,13 @@ static_assert(std::extents<int, 1, dyn>::static_extent(1) == dyn);
static_assert(std::extents<int, dyn, dyn>::static_extent(0) == dyn);
static_assert(std::extents<int, dyn, dyn>::static_extent(1) == dyn);
+// dims
+#if __glibcxx_mdspan >= 202406L
+static_assert(std::is_same_v<std::dims<0>, std::dextents<size_t, 0>>);
+static_assert(std::is_same_v<std::dims<3>, std::dextents<size_t, 3>>);
+static_assert(std::is_same_v<std::dims<3, int>, std::dextents<int, 3>>);
+#endif
+
// extent
template<typename Extent>
constexpr void
diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/version.cc b/libstdc++-v3/testsuite/23_containers/mdspan/version.cc
index 106ee40..1882600 100644
--- a/libstdc++-v3/testsuite/23_containers/mdspan/version.cc
+++ b/libstdc++-v3/testsuite/23_containers/mdspan/version.cc
@@ -1,9 +1,20 @@
-// { dg-do compile { target c++23 } }
+// { dg-do preprocess { target c++23 } }
+// { dg-add-options no_pch }
+
#include <mdspan>
#ifndef __cpp_lib_mdspan
#error "Feature test macro __cpp_lib_mdspan is missing for <mdspan>"
-#if __cpp_lib_mdspan < 202207
-#error "Feature test macro __cpp_lib_mdspan has the wrong value"
+#elif __cplusplus <= 202302L && __cpp_lib_mdspan != 202207L
+#error "Feature test macro __cpp_lib_mdspan has the wrong value for C++23"
+#elif __cplusplus > 202302L && __cpp_lib_mdspan != 202406L
+#error "Feature test macro __cpp_lib_mdspan has the wrong value for C++26"
+#endif
+
+#if __cplusplus > 202302L
+#ifndef __cpp_lib_aligned_accessor
+#error "Feature test macro __cpp_lib_aligned_accessor is missing for <mdspan>"
+#elif __cpp_lib_aligned_accessor != 202411L
+#error "Feature test macro __cpp_lib_aligned_accessor has the wrong value"
#endif
#endif
diff --git a/libstdc++-v3/testsuite/23_containers/vector/modifiers/insert/insert_range.cc b/libstdc++-v3/testsuite/23_containers/vector/modifiers/insert/insert_range.cc
index 506bebb..e4b5982 100644
--- a/libstdc++-v3/testsuite/23_containers/vector/modifiers/insert/insert_range.cc
+++ b/libstdc++-v3/testsuite/23_containers/vector/modifiers/insert/insert_range.cc
@@ -99,8 +99,58 @@ test_ranges()
return true;
}
+struct SelfAssignChecker {
+ static int moveCounter;
+ static int copyCounter;
+
+ SelfAssignChecker() = default;
+ constexpr SelfAssignChecker(int v) : val(v) { }
+ SelfAssignChecker(const SelfAssignChecker&) = default;
+ SelfAssignChecker(SelfAssignChecker&&) = default;
+
+ SelfAssignChecker operator=(const SelfAssignChecker& rhs)
+ {
+ if (this == &rhs)
+ ++copyCounter;
+ this->val = rhs.val;
+ return *this;
+ }
+
+ SelfAssignChecker operator=(SelfAssignChecker&& rhs)
+ {
+ if (this == &rhs)
+ ++moveCounter;
+ this->val = rhs.val;
+ return *this;
+ }
+
+ int val;
+
+ friend bool operator==(SelfAssignChecker, SelfAssignChecker) = default;
+};
+
+int SelfAssignChecker::moveCounter = 0;
+int SelfAssignChecker::copyCounter = 0;
+
+void
+test_pr121313()
+{
+ using namespace __gnu_test;
+
+ SelfAssignChecker::copyCounter = SelfAssignChecker::moveCounter = 0;
+ do_test<test_forward_range<int>, std::allocator<SelfAssignChecker>>();
+ VERIFY( SelfAssignChecker::moveCounter == 0 );
+ VERIFY( SelfAssignChecker::copyCounter == 0 );
+
+ SelfAssignChecker::copyCounter = SelfAssignChecker::moveCounter = 0;
+ do_test<test_input_range<int>, std::allocator<SelfAssignChecker>>();
+ VERIFY( SelfAssignChecker::moveCounter == 0 );
+ VERIFY( SelfAssignChecker::copyCounter == 0 );
+}
+
int main()
{
test_ranges();
+ test_pr121313();
static_assert( test_ranges() );
}
diff --git a/libstdc++-v3/testsuite/23_containers/vector/modifiers/moveable.cc b/libstdc++-v3/testsuite/23_containers/vector/modifiers/moveable.cc
index 8d0f9ae..343a298 100644
--- a/libstdc++-v3/testsuite/23_containers/vector/modifiers/moveable.cc
+++ b/libstdc++-v3/testsuite/23_containers/vector/modifiers/moveable.cc
@@ -109,9 +109,11 @@ test05()
// when it doesn't reallocate the buffer.
VERIFY(copycounter::copycount == 20 + 1);
a.insert(a.end(), 50, c);
- VERIFY(copycounter::copycount == 70 + 2);
+ // expect when inserting at the end (appending), where existing
+ // elements are not modified
+ VERIFY(copycounter::copycount == 70 + 1);
a.insert(a.begin() + 50, 100, c);
- VERIFY(copycounter::copycount == 170 + 3);
+ VERIFY(copycounter::copycount == 170 + 2);
}
diff --git a/libstdc++-v3/testsuite/23_containers/vector/modifiers/resize.cc b/libstdc++-v3/testsuite/23_containers/vector/modifiers/resize.cc
new file mode 100644
index 0000000..026b0f7
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/vector/modifiers/resize.cc
@@ -0,0 +1,69 @@
+// { dg-do run }
+
+#include <vector>
+#include <testsuite_hooks.h>
+
+struct NoAssign
+{
+ NoAssign(int p) : val(p) {}
+ const int val;
+};
+
+struct PrivateAssign
+{
+ PrivateAssign(int p) : val(p) {}
+ PrivateAssign(const PrivateAssign& rhs) : val(rhs.val) {}
+
+ int val;
+
+private:
+ PrivateAssign& operator=(const PrivateAssign&);
+};
+
+#if __cplusplus >= 201102L
+struct DeletedAssign
+{
+ DeletedAssign(int p) : val(p) {}
+ DeletedAssign(const DeletedAssign& rhs) : val(rhs.val) {}
+
+ DeletedAssign& operator=(const DeletedAssign&) = delete;
+
+ int val;
+};
+#endif
+
+template<typename T>
+void
+testPR90129()
+{
+ std::vector<T> v;
+ v.resize(5, T(5));
+ VERIFY( v.size() == 5 );
+ VERIFY( v.front().val == 5 );
+ VERIFY( v.back().val == 5 );
+
+ v.resize(10, T(10));
+ VERIFY( v.size() == 10 );
+ VERIFY( v.front().val == 5 );
+ VERIFY( v.back().val == 10 );
+
+ v.resize(7, T(7));
+ VERIFY( v.size() == 7 );
+ VERIFY( v.front().val == 5 );
+ VERIFY( v.back().val == 10 );
+
+ v.resize(3, T(3));
+ VERIFY( v.size() == 3 );
+ VERIFY( v.front().val == 5 );
+ VERIFY( v.back().val == 5 );
+}
+
+int main()
+{
+ testPR90129<NoAssign>();
+ testPR90129<PrivateAssign>();
+#if __cplusplus >= 201102L
+ testPR90129<DeletedAssign>();
+#endif
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/24_iterators/operations/cxx20_iterators.cc b/libstdc++-v3/testsuite/24_iterators/operations/cxx20_iterators.cc
new file mode 100644
index 0000000..b613c37
--- /dev/null
+++ b/libstdc++-v3/testsuite/24_iterators/operations/cxx20_iterators.cc
@@ -0,0 +1,60 @@
+// { dg-do run { target c++20 } }
+
+#include <ranges>
+#include <testsuite_iterators.h>
+#include <testsuite_hooks.h>
+
+// Bug 102181 std::advance and std::views::iota<std::int64_t> don't work
+void
+test_pr102181()
+{
+#ifdef __SIZEOF_INT128__
+ using type = unsigned __int128;
+#else
+ using type = unsigned long;
+#endif
+ auto v = std::ranges::iota_view(type(0), type(10));
+ auto b = v.begin();
+ VERIFY( std::distance(b, std::next(b)) == 1 );
+ std::advance(b, std::iter_difference_t<decltype(b)>(1));
+ VERIFY( *b == 1 );
+ VERIFY( std::distance(b, v.end()) == 9 );
+}
+
+// https://stackoverflow.com/questions/68100775/rangesviewtransform-produces-an-inputiterator-preventing-the-use-of-stdpre
+void
+test_transform_view_iterator()
+{
+ int a[] = {0, 1, 2, 3};
+ __gnu_test::random_access_container<int> rr(a);
+ auto rx = std::ranges::views::transform(rr, std::identity{});
+ auto re = rx.end();
+ VERIFY( *std::prev(re) == 3 );
+ VERIFY( std::distance(rx.begin(), re) == 4 );
+
+ __gnu_test::bidirectional_container<int> br(a);
+ auto bx = std::ranges::views::transform(br, std::identity{});
+ auto be = bx.end();
+ VERIFY( *std::prev(be) == 3 );
+ VERIFY( std::distance(bx.begin(), be) == 4 );
+
+ __gnu_test::forward_container<int> fr(a);
+ auto fx = std::ranges::views::transform(br, std::identity{});
+ auto fb = fx.begin();
+ VERIFY( *std::next(fb) == 1 );
+ VERIFY( std::distance(fb, fx.end()) == 4 );
+
+ __gnu_test::test_input_range<int> ir(a);
+ auto ix = std::ranges::views::transform(ir, std::identity{});
+ auto ii = ix.begin();
+ std::advance(ii, 1);
+ VERIFY( *ii == 1 );
+ // N.B. cannot use std::distance or std::next here because there is no
+ // iterator_traits<decltype(ii)>::difference_type for this iterator.
+}
+
+int main()
+{
+ test_pr102181();
+ test_transform_view_iterator();
+}
diff --git a/libstdc++-v3/testsuite/24_iterators/random_access/string_vector_iterators.cc b/libstdc++-v3/testsuite/24_iterators/random_access/string_vector_iterators.cc
index 22803e7..d6b95d6 100644
--- a/libstdc++-v3/testsuite/24_iterators/random_access/string_vector_iterators.cc
+++ b/libstdc++-v3/testsuite/24_iterators/random_access/string_vector_iterators.cc
@@ -370,5 +370,6 @@ main()
string_stuff();
vector_stuff();
reverse_stuff();
+ test6642();
return 0;
}
diff --git a/libstdc++-v3/testsuite/25_algorithms/max/constrained.cc b/libstdc++-v3/testsuite/25_algorithms/max/constrained.cc
index c3cd288..c6759f8 100644
--- a/libstdc++-v3/testsuite/25_algorithms/max/constrained.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/max/constrained.cc
@@ -87,12 +87,12 @@ test04()
int m;
};
A r[5] = {5, 4, 3, 2, 1};
- ranges::max(r, ranges::less{}, &A::m);
+ (void)ranges::max(r, ranges::less{}, &A::m);
VERIFY( copies == 1 );
VERIFY( moves == 0 );
copies = moves = 0;
A s[5] = {1, 2, 3, 4, 5};
- ranges::max(s, ranges::less{}, &A::m);
+ (void)ranges::max(s, ranges::less{}, &A::m);
VERIFY( copies == 5 );
VERIFY( moves == 0 );
}
diff --git a/libstdc++-v3/testsuite/25_algorithms/min/constrained.cc b/libstdc++-v3/testsuite/25_algorithms/min/constrained.cc
index d5de040..7d4fa58 100644
--- a/libstdc++-v3/testsuite/25_algorithms/min/constrained.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/min/constrained.cc
@@ -87,12 +87,12 @@ test04()
int m;
};
A r[5] = {5, 4, 3, 2, 1};
- ranges::min(r, ranges::less{}, &A::m);
+ (void)ranges::min(r, ranges::less{}, &A::m);
VERIFY( copies == 5 );
VERIFY( moves == 0 );
copies = moves = 0;
A s[5] = {1, 2, 3, 4, 5};
- ranges::min(s, ranges::less{}, &A::m);
+ (void)ranges::min(s, ranges::less{}, &A::m);
VERIFY( copies == 1 );
VERIFY( moves == 0 );
}
diff --git a/libstdc++-v3/testsuite/25_algorithms/minmax/constrained.cc b/libstdc++-v3/testsuite/25_algorithms/minmax/constrained.cc
index 5a5d341..270fd45 100644
--- a/libstdc++-v3/testsuite/25_algorithms/minmax/constrained.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/minmax/constrained.cc
@@ -99,20 +99,28 @@ test04()
struct counted_less
{ bool operator()(int a, int b) { ++counter; return a < b; } };
- ranges::minmax({1,2}, counted_less{});
+ auto p = ranges::minmax({1,2}, counted_less{});
VERIFY( counter == 1 );
+ VERIFY( p.min = 1 );
+ VERIFY( p.max = 2 );
counter = 0;
- ranges::minmax({1,2,3}, counted_less{});
+ p = ranges::minmax({1,2,3}, counted_less{});
VERIFY( counter == 3 );
+ VERIFY( p.min = 1 );
+ VERIFY( p.max = 3 );
counter = 0;
- ranges::minmax({1,2,3,4,5,6,7,8,9,10}, counted_less{});
+ p = ranges::minmax({1,2,3,4,5,6,7,8,9,10}, counted_less{});
VERIFY( counter <= 15 );
+ VERIFY( p.min = 1 );
+ VERIFY( p.max = 10 );
counter = 0;
- ranges::minmax({10,9,8,7,6,5,4,3,2,1}, counted_less{});
+ p = ranges::minmax({10,9,8,7,6,5,4,3,2,1}, counted_less{});
VERIFY( counter <= 15 );
+ VERIFY( p.min = 1 );
+ VERIFY( p.max = 10 );
}
void
diff --git a/libstdc++-v3/testsuite/25_algorithms/minmax_element/constrained.cc b/libstdc++-v3/testsuite/25_algorithms/minmax_element/constrained.cc
index 99ebf03..1eaaf07 100644
--- a/libstdc++-v3/testsuite/25_algorithms/minmax_element/constrained.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/minmax_element/constrained.cc
@@ -70,21 +70,29 @@ test02()
{ bool operator()(int a, int b) { ++counter; return a < b; } };
int x[] = {1,2,3,4,5,6,7,8,9,10};
- ranges::minmax_element(x, x+2, counted_less{});
+ auto p = ranges::minmax_element(x, x+2, counted_less{});
VERIFY( counter == 1 );
+ VERIFY( p.min == x+0 );
+ VERIFY( p.max == x+1 );
counter = 0;
- ranges::minmax_element(x, x+3, counted_less{});
+ p = ranges::minmax_element(x, x+3, counted_less{});
VERIFY( counter == 3 );
+ VERIFY( p.min == x+0 );
+ VERIFY( p.max == x+2 );
counter = 0;
- ranges::minmax_element(x, counted_less{});
+ p = ranges::minmax_element(x, counted_less{});
VERIFY( counter <= 15 );
+ VERIFY( p.min == x+0 );
+ VERIFY( p.max == x+9 );
ranges::reverse(x);
counter = 0;
- ranges::minmax_element(x, counted_less{});
+ p = ranges::minmax_element(x, counted_less{});
VERIFY( counter <= 15 );
+ VERIFY( p.min == x+9 );
+ VERIFY( p.max == x+0 );
}
int
diff --git a/libstdc++-v3/testsuite/30_threads/timed_mutex/121496.cc b/libstdc++-v3/testsuite/30_threads/timed_mutex/121496.cc
new file mode 100644
index 0000000..d919704
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/timed_mutex/121496.cc
@@ -0,0 +1,14 @@
+// { dg-do compile { target { { i?86-*-linux* x86_64-*-linux* } && lp64 } } }
+// { dg-require-effective-target c++11 }
+// { dg-options "-fsanitize=thread" }
+
+// PR libstdc++/121496 no member named '_M_clocklock' with -fsanitize=thread
+
+#include <mutex>
+#include <chrono>
+
+void
+test_pr121496(std::timed_mutex& m)
+{
+ (void) m.try_lock_until(std::chrono::steady_clock::time_point{});
+}
diff --git a/libstdc++-v3/testsuite/backward/hash_set/check_construct_destroy.cc b/libstdc++-v3/testsuite/backward/hash_set/check_construct_destroy.cc
index 042de4e..aca296d 100644
--- a/libstdc++-v3/testsuite/backward/hash_set/check_construct_destroy.cc
+++ b/libstdc++-v3/testsuite/backward/hash_set/check_construct_destroy.cc
@@ -39,50 +39,45 @@ int main()
int buckets;
- // For C++11 and later add 1 to all counts, because the std::vector used
- // internally by the hashtable creates and destroys a temporary object
- // using its allocator.
- const int extra = __cplusplus >= 201102L ? 1 : 0;
-
tracker_allocator_counter::reset();
{
Container c;
buckets = c.bucket_count();
- ok = check_construct_destroy("empty container", buckets+extra, extra) && ok;
+ ok = check_construct_destroy("empty container", buckets, 0) && ok;
}
- ok = check_construct_destroy("empty container", buckets+extra, buckets+extra) && ok;
+ ok = check_construct_destroy("empty container", buckets, buckets) && ok;
tracker_allocator_counter::reset();
{
Container c(arr10, arr10 + 10);
- ok = check_construct_destroy("Construct from range", buckets+10+extra, extra) && ok;
+ ok = check_construct_destroy("Construct from range", buckets+10, 0) && ok;
}
- ok = check_construct_destroy("Construct from range", buckets+10+extra, buckets+10+extra) && ok;
+ ok = check_construct_destroy("Construct from range", buckets+10, buckets+10) && ok;
tracker_allocator_counter::reset();
{
Container c(arr10, arr10 + 10);
c.insert(arr10a[0]);
- ok = check_construct_destroy("Insert element", buckets+11+extra, extra) && ok;
+ ok = check_construct_destroy("Insert element", buckets+11, 0) && ok;
}
- ok = check_construct_destroy("Insert element", buckets+11+extra, buckets+11+extra) && ok;
+ ok = check_construct_destroy("Insert element", buckets+11, buckets+11) && ok;
tracker_allocator_counter::reset();
{
Container c(arr10, arr10 + 10);
c.insert(arr10a, arr10a+3);
- ok = check_construct_destroy("Insert short range", buckets+13+extra, extra) && ok;
+ ok = check_construct_destroy("Insert short range", buckets+13, 0) && ok;
}
- ok = check_construct_destroy("Insert short range", buckets+13+extra, buckets+13+extra) && ok;
+ ok = check_construct_destroy("Insert short range", buckets+13, buckets+13) && ok;
tracker_allocator_counter::reset();
{
Container c(arr10, arr10 + 10);
c.insert(arr10a, arr10a+10);
- ok = check_construct_destroy("Insert long range", buckets+20+extra, extra) && ok;
+ ok = check_construct_destroy("Insert long range", buckets+20, 0) && ok;
}
- ok = check_construct_destroy("Insert long range", buckets+20+extra, buckets+20+extra) && ok;
+ ok = check_construct_destroy("Insert long range", buckets+20, buckets+20) && ok;
return ok ? 0 : 1;
}
diff --git a/libstdc++-v3/testsuite/std/format/ranges/format_kind.cc b/libstdc++-v3/testsuite/std/format/ranges/format_kind.cc
index 14b9ff2..1450fba 100644
--- a/libstdc++-v3/testsuite/std/format/ranges/format_kind.cc
+++ b/libstdc++-v3/testsuite/std/format/ranges/format_kind.cc
@@ -75,7 +75,9 @@ void test_override()
CustFormat<int, std::range_format::set> setf{1, 2, 3};
VERIFY( std::format("{}", setf) == "{1, 2, 3}" );
- // TODO test map once formatter for pair is implenented
+ CustFormat<std::pair<int, int>, std::range_format::map> mapf
+ {{1, 11}, {2, 22}, {3, 33}};
+ VERIFY( std::format("{}", mapf) == "{1: 11, 2: 22, 3: 33}" );
CustFormat<char, std::range_format::string> stringf{'a', 'b', 'c', 'd'};
VERIFY( std::format("{}", stringf) == "abcd" );
diff --git a/libstdc++-v3/testsuite/std/memory/indirect/access.cc b/libstdc++-v3/testsuite/std/memory/indirect/access.cc
new file mode 100644
index 0000000..cf21275
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/memory/indirect/access.cc
@@ -0,0 +1,58 @@
+// { dg-do run { target c++26 } }
+
+#include <memory>
+#include <vector>
+
+#include <testsuite_hooks.h>
+
+template<template<typename> class Indirect>
+constexpr void
+test_access()
+{
+ const std::vector<int> src{1, 2, 3, 4, 5};
+ Indirect<std::vector<int>> i(src);
+ auto const& ci = i;
+ VERIFY( *i == src );
+ VERIFY( *ci == src );
+ VERIFY( *std::move(ci) == src );
+
+ std::vector<int>&& vr = *std::move(i);
+ VERIFY( vr == src );
+ VERIFY( *i == src );
+
+ std::vector<int> vc = *std::move(i);
+ VERIFY( vc == src );
+ VERIFY( vr.empty() );
+ VERIFY( i->empty() );
+ VERIFY( ci->empty() );
+}
+
+template<typename T>
+struct PublicBase : std::indirect<T>
+{
+ using std::indirect<T>::indirect;
+};
+
+template<typename T>
+class PrivateBase : std::indirect<T>
+{
+public:
+ using std::indirect<T>::indirect;
+ using std::indirect<T>::operator*;
+ using std::indirect<T>::operator->;
+};
+
+constexpr bool
+test_all()
+{
+ test_access<std::indirect>();
+ test_access<PublicBase>();
+ test_access<PrivateBase>();
+ return true;
+}
+
+int main()
+{
+ test_all();
+ static_assert(test_all());
+}
diff --git a/libstdc++-v3/testsuite/std/memory/polymorphic/access.cc b/libstdc++-v3/testsuite/std/memory/polymorphic/access.cc
new file mode 100644
index 0000000..7b95bb1
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/memory/polymorphic/access.cc
@@ -0,0 +1,53 @@
+// { dg-do run { target c++26 } }
+
+#include <memory>
+#include <vector>
+
+#include <testsuite_hooks.h>
+
+template<template<typename> class Polymorhpic>
+constexpr void
+test_access()
+{
+ const std::vector<int> src{1, 2, 3, 4, 5};
+ Polymorhpic<std::vector<int>> i(src);
+ auto const& ci = i;
+ VERIFY( *i == src );
+ VERIFY( *ci == src );
+ VERIFY( *std::move(ci) == src );
+
+ auto&& vr = *std::move(i);
+ static_assert( std::is_same_v<decltype(vr), std::vector<int>&> );
+ VERIFY( vr == src );
+ VERIFY( *i == src );
+}
+
+template<typename T>
+struct PublicBase : std::polymorphic<T>
+{
+ using std::polymorphic<T>::polymorphic;
+};
+
+template<typename T>
+class PrivateBase : std::polymorphic<T>
+{
+public:
+ using std::polymorphic<T>::polymorphic;
+ using std::polymorphic<T>::operator*;
+ using std::polymorphic<T>::operator->;
+};
+
+constexpr bool
+test_all()
+{
+ test_access<std::polymorphic>();
+ test_access<PublicBase>();
+ test_access<PrivateBase>();
+ return true;
+}
+
+int main()
+{
+ test_all();
+// static_assert(test_all());
+}
diff --git a/libstdc++-v3/testsuite/std/time/format/data_not_present_neg.cc b/libstdc++-v3/testsuite/std/time/format/data_not_present_neg.cc
index bb09451..cb8f916 100644
--- a/libstdc++-v3/testsuite/std/time/format/data_not_present_neg.cc
+++ b/libstdc++-v3/testsuite/std/time/format/data_not_present_neg.cc
@@ -119,7 +119,7 @@ auto tai = std::format("{:%Q}", tai_clock::now()); // { dg-error "call to conste
auto file = std::format("{:%Q}", file_clock::now()); // { dg-error "call to consteval function" }
const auto ltc = local_seconds(10s);
-#if _GLIBCXX_USE_CXX11_ABI || !_GLIBCXX_USE_DUAL_ABI
+#if _GLIBCXX_USE_CXX11_ABI
const auto zt = zoned_time<seconds>("Europe/Sofia", local_seconds(10s));
auto zt1 = std::format("{:%Q}", zt); // { dg-error "call to consteval function" "" { target cxx11_abi } }
#endif
@@ -141,7 +141,7 @@ auto hms5 = std::format("{:%F}", HMS(1255s)); // { dg-error "call to consteval f
auto hms6 = std::format("{:%Q}", HMS(1255s)); // { dg-error "call to consteval function" }
auto hms7 = std::format("{:%Z}", HMS(1255s)); // { dg-error "call to consteval function" }
-#if _GLIBCXX_USE_CXX11_ABI || !_GLIBCXX_USE_DUAL_ABI
+#if _GLIBCXX_USE_CXX11_ABI
auto li1 = std::format("{:%d}", local_info()); // { dg-error "call to consteval function" "" { target cxx11_abi } }
auto li2 = std::format("{:%w}", local_info()); // { dg-error "call to consteval function" "" { target cxx11_abi } }
auto li3 = std::format("{:%m}", local_info()); // { dg-error "call to consteval function" "" { target cxx11_abi } }