diff options
Diffstat (limited to 'libstdc++-v3')
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 } } |