aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/include
AgeCommit message (Collapse)AuthorFilesLines
2025-05-30libstdc++: Define __wait_result_type for atomic waitingJonathan Wakely2-29/+44
libstdc++-v3/ChangeLog: * include/bits/atomic_timed_wait.h: Use __wait_result_type. * include/bits/atomic_wait.h (__wait_result_type): New struct. (__wait_args::_M_prep_for_wait_on): Rename to _M_setup_wait, use __wait_result_type. (__atomic_wait_address): Adjust to call _M_setup_wait. * src/c++20/atomic.cc (__spin_impl): Use __wait_result_type. (__wait_impl): Likewise. (__spin_until_impl): Likewise. (__wait_until_impl): Likewise.
2025-05-30libstdc++: Rewrite std::counting_semaphore base class [PR118494]Jonathan Wakely4-187/+73
Remove __platform_semaphore. Replace __atomic_semaphore with __semaphore_base<bool> and change its counter to be ptrdiff_t when the count doesn't fit in __platform_wait_t (PR 118494). Make the std::counting_semaphore constructor constexpr to support constant initialization (PR 110854). Add precondition checks to the constructor and release member functions (PR 98749). libstdc++-v3/ChangeLog: PR libstdc++/118494 PR libstdc++/110854 PR libstdc++/98749 * acinclude.m4 (GLIBCXX_CHECK_GTHREADS): Remove checks for sem_timedwait. Do not define _GLIBCXX_HAVE_POSIX_SEMAPHORE. * config.h.in: Regenerate. * configure: Regenerate. * include/bits/semaphore_base.h (__platform_semaphore): Remove. (__atomic_semaphore): Replace with __semaphore_base<bool> and make type of _M_count depend on template parameter. Fix _S_max constant to use correct type. (__semaphore_base::_M_try_acquire): Qualify to avoid ADL. (__semaphore_base::_M_release): Return old value. Remove FIXME comment. (__semaphore_impl): Replace typedef with alias template. * include/bits/version.def (semaphore): Do not depend on _GLIBCXX_HAVE_POSIX_SEMAPHORE. * include/bits/version.h: Regenerate. * include/std/semaphore (semaphore): Adjust type of _M_sem member. Add constexpr to constructor. Add assertions to (semaphore::semaphore(ptrdiff_t)): Add constexpr. Add assertion for precondition. (semaphore::release): Add assertion using value returned from _M_release. * testsuite/30_threads/semaphore/100806.cc: Increase template argument for std::counting_semaphore, so constructor precondition is met. * testsuite/30_threads/semaphore/cons.cc: New test. * testsuite/30_threads/semaphore/try_acquire_posix.cc: Remove. * testsuite/30_threads/semaphore/platform_try_acquire_for.cc: Removed.
2025-05-30libstdc++: Create new base class of std::barrier<C> for non-dependent codeJonathan Wakely1-79/+91
This moves all non-dependent state and logic for std::barrier<C> into a new non-template base class, to avoid template bloat. This would permit moving the _M_arrive function into the library instead of the header. libstdc++-v3/ChangeLog: * include/std/barrier (__tree_barrier_base): New class. (__tree_barrier): Move non-dependent code into __tree_barrier_base and derive from it.
2025-05-30libstdc++: Fix std::barrier for constant initialization [PR118395]Jonathan Wakely1-15/+42
The std::barrier constructor should be constexpr, which means we need to defer the dynamic allocation if the constructor is called during constant-initialization. We can defer it to the first call to barrier::arrive, using compare-and-swap on an atomic<T*> (instead of the unique_ptr<T[]> currently used). Also add precondition checks to the constructor and arrive member function. Also implement the proposed resolution of LWG 3898. libstdc++-v3/ChangeLog: PR libstdc++/118395 PR libstdc++/108974 PR libstdc++/98749 * include/std/barrier (__tree_barrier): Use default member-initializers. Change _M_state member from unique_ptr<__state_t[]> to atomic<__state_t*>. Add no_unique_address attribute to _M_completion. (__tree_barrier::_M_arrive): Load value from _M_state. (__tree_barrier::_M_invoke_completion): New member function to ensure a throwing completion function will terminate, as proposed in LWG 3898. (__tree_barrier::max): Reduce by one to avoid overflow. (__tree_barrier::__tree_barrier): Add constexpr. Qualify call to std::move. Remove mem-initializers made unnecessary by default member-initializers. Add precondition check. Only allocate state array if not constant evaluated. (__tree_barrier::arrive): Add precondition check. Do deferred initialization of _M_state if needed. (barrier): Add static_assert, as proposed in LWG 3898. (barrier::barrier): Add constexpr. * testsuite/30_threads/barrier/cons.cc: New test. * testsuite/30_threads/barrier/lwg3898.cc: New test.
2025-05-30libstdc++: Optimise std::latch::arrive_and_waitJonathan Wakely1-2/+15
We don't need to wait if we know the counter has reached zero. libstdc++-v3/ChangeLog: * include/std/latch (latch::arrive_and_wait): Optimise.
2025-05-30libstdc++: Move atomic wait/notify entry points into the libraryJonathan Wakely2-423/+53
This moves the implementation details of atomic wait/notify functions into the library, so that only a small API surface is exposed to users. This also fixes some race conditions present in the design for proxied waits: - The stores to _M_ver in __notify_impl must be protected by the mutex, and the loads from _M_ver in __wait_impl and __wait_until_impl to check for changes must also be protected by the mutex. This ensures that checking _M_ver for updates and waiting on the condition_variable happens atomically. Otherwise it's possible to have: _M_ver == old happens-before {++_M_ver; cv.notify;} which happens-before cv.wait. That scenario results in a missed notification, and so the waiting function never wakes. This wasn't a problem for Linux, because the futex wait call re-checks the _M_ver value before sleeping, so the increment cannot interleave between the check and the wait. - The initial load from _M_ver that reads the 'old' value used for the _M_ver == old checks must be done before loading and checking the value of the atomic variable. Otherwise it's possible to have: var.load() == val happens-before {++_M_ver; _M_cv.notify_all();} happens-before {old = _M_ver; lock mutex; if (_M_ver == old) cv.wait}. This results in the waiting thread seeing the already-incremented value of _M_ver and then waiting for it to change again, which doesn't happen. This race was present even for Linux, because using a futex instead of mutex+condvar doesn't prevent the increment from happening before the waiting threads checks for the increment. The first race can be solved locally in the waiting and notifying functions, by acquiring the mutex lock earlier in the function. The second race cannot be fixed locally, because the load of the atomic variable and the check for updates to _M_ver happen in different functions (one in a function template in the headers and one in the library). We do have an _M_old data member in the __wait_args_base struct which was previously only used for non-proxy waits using a futex. We can add a new entry point into the library to look up the waitable state for the address and then load its _M_ver into the _M_old member. This allows the inline function template to ensure that loading _M_ver happens-before testing whether the atomic variable has been changed, so that we can reliably tell if _M_ver changes after we've already tested the atomic variable. This isn't 100% reliable, because _M_ver could be incremented 2^32 times and wrap back to the same value, but that seems unlikely in practice. If/when we support waiting on user-defined predicates (which could execute long enough for _M_ver to wrap) we might want to always wait with a timeout, so that we get a chance to re-check the predicate even in the rare case that _M_ver wraps. Another change is to make the __wait_until_impl function take a __wait_clock_t::duration instead of a __wait_clock_t::time_point, so that the __wait_until_impl function doesn't depend on the symbol name of chrono::steady_clock. Inside the library it can be converted back to a time_point for the clock. This would potentially allow using a different clock, if we made a different __abi_version in the __wait_args imply waiting with a different clock. This also adds a void* to the __wait_args_base structure, so that __wait_impl can store the __waitable_state* in there the first time it's looked up for a given wait, so that it doesn't need to be retrieved again on each loop. This requires passing the __wait_args_base structure by non-const reference. The __waitable_state::_S_track function can be removed now that it's all internal to the library, and namespace-scope RAII types added for locking and tracking contention. libstdc++-v3/ChangeLog: * config/abi/pre/gnu.ver: Add new symbol version and exports. * include/bits/atomic_timed_wait.h (__platform_wait_until): Move to atomic.cc. (__cond_wait_until, __spin_until_impl): Likewise. (__wait_until_impl): Likewise. Change __wait_args_base parameter to non-const reference and change third parameter to __wait_clock_t::duration. (__wait_until): Change __wait_args_base parameter to non-const reference. Change Call time_since_epoch() to get duration from time_point. (__wait_for): Change __wait_args_base parameter to non-const reference. (__atomic_wait_address_until): Call _M_prep_for_wait_on on args. (__atomic_wait_address_for): Likewise. (__atomic_wait_address_until_v): Qualify call to avoid ADL. Do not forward __vfn. * include/bits/atomic_wait.h (__platform_wait_uses_type): Use alignof(T) not alignof(T*). (__futex_wait_flags, __platform_wait, __platform_notify) (__waitable_state, __spin_impl, __notify_impl): Move to atomic.cc. (__wait_impl): Likewise. Change __wait_args_base parameter to non-const reference. (__wait_args_base::_M_wait_state): New data member. (__wait_args_base::_M_prep_for_wait_on): New member function. (__wait_args_base::_M_load_proxy_wait_val): New member function. (__wait_args_base::_S_memory_order_for): Remove member function. (__atomic_wait_address): Call _M_prep_for_wait_on on args. (__atomic_wait_address_v): Qualify call to avoid ADL. * src/c++20/Makefile.am: Add new file. * src/c++20/Makefile.in: Regenerate. * src/c++20/atomic.cc: New file. * testsuite/17_intro/headers/c++1998/49745.cc: Remove XFAIL for C++20 and later. * testsuite/29_atomics/atomic/wait_notify/100334.cc: Remove use of internal implementation details. * testsuite/util/testsuite_abi.cc: Add GLIBCXX_3.4.35 version.
2025-05-30libstdc++: Rename __waiter_pool_impl to __waitable_stateJonathan Wakely2-46/+51
The name __waiter_pool_impl is misleading. An object of that type is a member of the pool, not the pool itself, and it's not an "impl" of any abstract base class or generic concept. Just call it __waitable_state since it maintains the state used for waiting/notifying a waitable atomic object. Similarly, rename _S_impl_for to _S_state_for. Once these functions move into the shared library they won't be exported and so the naming won't matter much anyway. libstdc++-v3/ChangeLog: * include/bits/atomic_timed_wait.h (__wait_until_impl): Adjust to use new naming. * include/bits/atomic_wait.h (__waiter_pool_impl): Rename to __waitable_state. (__waiter_pool_impl::_S_wait): Rename to _M_waiters. (__waiter_pool_impl::_S_impl_for): Rename to _S_state_for. (__waiter_pool_impl::_S_track): Adjust to use new naming. (__wait_impl, __notify_impl): Likewise. * testsuite/29_atomics/atomic/wait_notify/100334.cc: Adjust to use new naming.
2025-05-30libstdc++: Rename __atomic_compare to __atomic_eqJonathan Wakely2-6/+9
This is an equality comparison rather than a three-way comparison like memcmp and <=>, so name it more precisely. libstdc++-v3/ChangeLog: * include/bits/atomic_timed_wait.h (__atomic_wait_address_until_v): Replace __atomic_compare with __atomic_eq. (__atomic_wait_address_for_v): Likewise. * include/bits/atomic_wait.h (__atomic_compare): Rename to __atomic_eq. (__atomic_wait_address_v): Replace __atomic_compare with __atomic_eq.
2025-05-30libstdc++: Remove reinterpret_cast uses in atomic wait/notifyJonathan Wakely2-21/+12
We can pass around void* instead of casting incompatible pointers to __platform_wait_t*, and then only static_cast to __platform_wait_t* when we know that's valid. libstdc++-v3/ChangeLog: * include/bits/atomic_timed_wait.h (__wait_until_impl): Change first parameter to const void* and then static_cast to const __platform_wait_t* when not using proxied wait. (__wait_until): Change first parameter to const void*. (__wait_for): Likewise. (__atomic_wait_address_until): Remove reinterpret_cast and allow address to implicitly convert to const void* instead. (__atomic_wait_address_for): Likewise. * include/bits/atomic_wait.h: (__wait_impl, __notify_impl): Change first parameter to const void* and then static_cast to const __platform_wait_t* when not using proxied wait. (__atomic_wait_address, __atomic_notify_address) Remove reinterpret_cast and allow address to implicitly convert to const void* instead.
2025-05-30libstdc++: Simplify futex wrapper functions for atomic wait/notifyJonathan Wakely1-20/+20
libstdc++-v3/ChangeLog: * include/bits/atomic_wait.h (__platform_wait): Change function template to a normal function. The parameter is always __platform_wait_t* which is just int* for this implementation of the function. (__platform_notify): Likewise.
2025-05-30libstdc++: Fix time_point conversion in atomic timed waitsJonathan Wakely1-17/+17
Even if a time_point already uses the right clock, we might still need to convert it to use the expected duration. Calling __to_wait_clock will perform that conversion, so use that even when the clock is correct. libstdc++-v3/ChangeLog: * include/bits/atomic_timed_wait.h (__to_wait_clock): Do not use chrono::ceil if clock and duration are already correct type. (__wait_until): Always call __to_wait_clock.
2025-05-30libstdc++: Fix race condition in new atomic notify codeJonathan Wakely1-9/+9
When using a proxy object for atomic waiting and notifying operations, we need to ensure that the _M_ver value is always incremented by a notifying operation, even if we return early without doing the futex wake syscall. Otherwise we get missed wake-ups because the notifying thread doesn't modify the value that other threads are doing a futex wait on. libstdc++-v3/ChangeLog: * include/bits/atomic_wait.h (__notify_impl): Increment the proxy value before returning early for the uncontended case.
2025-05-30libstdc++: Various fixes for atomic wait/notify codeJonathan Wakely3-186/+183
Pass __wait_args_base by const reference instead of const pointer. I don't see a reason it needs to be passed by pointer to the internals. We can also avoid constructing a __wait_args from __wait_args_base in some places, instaad just using the latter directly. The code using the __wait_flags bitmask type is broken, because the __spin_only constant includes the __do_spin element. This means that testing (__args & __wait_flags::__spin_only) will be inadvertently true when only __do_spin is set. This causes the __wait_until_impl function to never actually wait on the futex (or condition variable), turning all uses of that function into expensive busy spins. Change __spin_only to be a single bit (i.e. a bitmask element) and adjust the places where that bit is set so that they also use the __do_spin element. Update the __args._M_old value when looping in __atomic_wait_address, so that the next wait doesn't fail spuriously. With the new __atomic_wait_address logic, the value function needs to return the correct type, not just a bool. Without that change, the boolean value returned by the value function is used as the value passed to the futex wait, but that mean we're comparing (_M_a == 0) to _M_a and so can block on the futex when we shouldn't, and then never wake up. libstdc++-v3/ChangeLog: * include/bits/atomic_timed_wait.h (__cond_wait_impl): Add missing inline keyword. (__spin_until_impl): Change parameter from pointer to reference. Replace make_pair with list-initialization. Initialize variable for return value. (__wait_until_impl): Likewise. Remove some preprocessor conditional logic. Use _S_track for contention tracking. Avoid unnecessary const_cast. (__wait_until): Change parameter from pointer to reference. Replace make_pair with list-initialization. (__wait_for): Change parameter from pointer to reference. Add __do_spin flag to args. * include/bits/atomic_wait.h (__waiter_pool_impl::_S_track): New function returning an RAII object for contention tracking. (__wait_flags): Do not set the __do_spin flag in the __spin_only enumerator. Comment out the unused __abi_version_mask enumerator. Define operator| and operator|= overloads. (__wait_args_base::operator&): Define. (__wait_args::operator&, __wait_args::_S_default_flags): Remove. (__wait_args::operator|, __wait_args::operator|=): Remove. (__spin_impl): Change parameter from pointer to reference. Replace make_pair call with list-initialization. (__wait_impl): Likewise. Remove some preprocessor conditional logic. Always store old value in __args._M_old. Avoid unnecessary const_cast. Use _S_track. (__notify_impl): Change parameter to reference. Remove some preprocessor conditional logic. (__atomic_wait_address): Add comment. Update __args._M_old on each iteration. (__atomic_wait_address_v): Add comment. * include/std/latch (latch::wait): Adjust predicates for new logic. * testsuite/29_atomics/atomic_integral/wait_notify.cc: Improve test.
2025-05-30libstdc++: Whitespace fixes in atomic wait/notify codeJonathan Wakely2-111/+105
libstdc++-v3/ChangeLog: * include/bits/atomic_timed_wait.h: Whitespace fixes. * include/bits/atomic_wait.h: Likewise.
2025-05-30libstdc++: Pass __wait_args to internal API by const pointerThomas Rodgers2-33/+64
This change splits the __wait_args data members to a new struct __wait_args_base and then passes that type by const pointer to the low level implementation functions. libstdc++-v3/ChangeLog: * include/bits/atomic_timed_wait.h (__spin_until_impl): Accept __wait_args as const __wait_args_base*. (__wait_until_impl): Likewise. (__wait_until): Likewise. (__wait_for): Likewise. (__atomic_wait_address_until): Pass __wait_args by address. (__atomic_wait_address_for): Likewise. * include/bits/atomic_wait.h (__wait_args_base): New struct. (__wait_args): Derive from __wait_args_base. (__wait_args::__wait_args()): Adjust ctors to call call base ctor. (__wait_args::__wait_args(const __wait_args_base&)): New ctor. (__wait_args::operator|=): New method. (__wait_args::_S_flags_for): Change return type to __wait_flags. (__spin_impl): Accept __wait_args as const __wait_args_base*. (__wait_impl): Likewise. (__notify_impl): Likewise. (__atomic_wait_address): Pass __wait_args by address. (__atomic_wait_address_v): Likewise. (__atomic_notify_address): Likewise.
2025-05-30libstdc++: Atomic wait/notify ABI stabilizationThomas Rodgers5-568/+493
This represents a major refactoring of the previous atomic::wait and atomic::notify implementation detail. The aim of this change is to simplify the implementation details and position the resulting implementation so that much of the current header-only detail can be moved into the shared library, while also accounting for anticipated changes to wait/notify functionality for C++26. The previous implementation implemented spin logic in terms of the types __default_spin_policy, __timed_backoff_spin_policy, and the free function __atomic_spin. These are replaced in favor of two new free functions; __spin_impl and __spin_until_impl. These currently inline free functions are expected to be moved into the libstdc++ shared library in a future commit. The previous implementation derived untimed and timed wait implementation detail from __detail::__waiter_pool_base. This is-a relationship is removed in the new version and the previous implementation detail is renamed to reflect this change. The static _S_for member has been renamed as well to indicate that it returns the __waiter_pool_impl entry in the static 'side table' for a given awaited address. This new implementation replaces all of the non-templated waiting detail of __waiter_base, __waiter_pool, __waiter, __enters_wait, and __bare_wait with the __wait_impl free function, and the supporting __wait_flags enum and __wait_args struct. This currenly inline free function is expected to be moved into the libstdc++ shared library in a future commit. This new implementation replaces all of the non-templated notifying detail of __waiter_base, __waiter_pool, and __waiter with the __notify_impl free function. This currently inline free function is expected to be moved into the libstdc++ shared library in a future commit. The __atomic_wait_address template function is updated to account for the above changes and to support the expected C++26 change to pass the most recent observed value to the caller supplied predicate. A new non-templated __atomic_wait_address_v free function is added that only works for atomic types that operate only on __platform_wait_t and requires the caller to supply a memory order. This is intended to be the simplest code path for such types. The __atomic_wait_address_v template function is now implemented in terms of new __atomic_wait_address template and continues to accept a user supplied "value function" to retrieve the current value of the atomic. The __atomic_notify_address template function is updated to account for the above changes. The template __platform_wait_until_impl is renamed to __wait_clock_t. The previous __platform_wait_until template is deleted and the functionality previously provided is moved t the new tempalate function __wait_until. A similar change is made to the __cond_wait_until_impl/__cond_wait_until implementation. This new implementation similarly replaces all of the non-templated waiting detail of __timed_waiter_pool, __timed_waiter, etc. with the new __wait_until_impl free function. This currently inline free function is expected to be moved into the libstdc++ shared library in a future commit. This implementation replaces all templated waiting functions that manage clock conversion as well as relative waiting (wait_for) with the new template functions __wait_until and __wait_for. Similarly the previous implementation detail for the various __atomic_wait_address_Xxx templates is adjusted to account for the implementation changes outlined above. All of the "bare wait" versions of __atomic_wait_Xxx have been removed and replaced with a defaulted boolean __bare_wait parameter on the new version of these templates. libstdc++-v3/ChangeLog: * include/bits/atomic_timed_wait.h: (__detail::__platform_wait_until_impl): Rename to __platform_wait_until. (__detail::__platform_wait_until): Remove previous definition. (__detail::__cond_wait_until_impl): Rename to __cond_wait_until. (__detail::__cond_wait_until): Remove previous definition. (__detail::__spin_until_impl): New function. (__detail::__wait_until_impl): New function. (__detail::__wait_until): New function. (__detail::__wait_for): New function. (__detail::__timed_waiter_pool): Remove type. (__detail::__timed_backoff_spin_policy): Remove type. (__detail::__timed_waiter): Remove type. (__detail::__enters_timed_wait): Remove type alias. (__detail::__bare_timed_wait): Remove type alias. (__atomic_wait_address_until): Adjust to new implementation detail. (__atomic_wait_address_until_v): Likewise. (__atomic_wait_address_bare): Remove. (__atomic_wait_address_for): Adjust to new implementation detail. (__atomic_wait_address_for_v): Likewise. (__atomic_wait_address_for_bare): Remove. * include/bits/atomic_wait.h: Include bits/stl_pair.h. (__detail::__default_spin_policy): Remove type. (__detail::__atomic_spin): Remove function. (__detail::__waiter_pool_base): Rename to __waiter_pool_impl. Remove _M_notify. Rename _S_for to _S_impl_for. (__detail::__waiter_base): Remove type. (__detail::__waiter_pool): Remove type. (__detail::__waiter): Remove type. (__detail::__enters_wait): Remove type alias. (__detail::__bare_wait): Remove type alias. (__detail::__wait_flags): New enum. (__detail::__wait_args): New struct. (__detail::__wait_result_type): New type alias. (__detail::__spin_impl): New function. (__detail::__wait_impl): New function. (__atomic_wait_address): Adjust to new implementation detail. (__atomic_wait_address_v): Likewise. (__atomic_notify_address): Likewise. (__atomic_wait_address_bare): Delete. (__atomic_notify_address_bare): Likewise. * include/bits/semaphore_base.h: Adjust implementation to use new __atomic_wait_address_v contract. * include/std/barrier: Adjust implementation to use new __atomic_wait contract. * include/std/latch: Adjust implementation to use new __atomic_wait contract. * testsuite/29_atomics/atomic/wait_notify/100334.cc (main): Adjust to for __detail::__waiter_pool_base renaming.
2025-05-29libstdc++: Compare keys and values separately in flat_map::operator==Patrick Palka1-1/+4
Instead of effectively doing a zipped comparison of the keys and values, compare them separately to leverage the underlying containers' optimized equality implementations. libstdc++-v3/ChangeLog: * include/std/flat_map (_Flat_map_impl::operator==): Compare keys and values separately. Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
2025-05-29libstdc++: Fix tuple/pair confusion with std::erase_if(flat_map) [PR120465]Patrick Palka1-1/+4
std::erase_if for flat_map/multimap is implemented via ranges::erase_if over a zip_view of the keys and values, the value_type of which is a tuple, but the given predicate needs to be called with a pair (flat_map's value_type). So use a projection to convert the tuple into a suitable pair. PR libstdc++/120465 libstdc++-v3/ChangeLog: * include/std/flat_map (_Flat_map_impl::_M_erase_if): Use a projection with ranges::remove_if to pass a pair instead of a tuple to the predicate. * testsuite/23_containers/flat_map/1.cc (test07): Strengthen to expect the argument passed to the predicate is a pair. * testsuite/23_containers/flat_multimap/1.cc (test07): Likewise. Co-authored-by: Jonathan Wakely <jwakely@redhat.com> Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com> Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
2025-05-29libstdc++: Disable -Wlong-long warnings in boost_concept_check.hJonathan Wakely1-0/+1
The _IntegerConcept, _SignedIntegerConcept and _UnsignedIntegerConcept class template are specialized for long long, which gives warnings with -Wsystem-headers in C++98 mode. libstdc++-v3/ChangeLog: * include/bits/boost_concept_check.h: Disable -Wlong-long warnings. * testsuite/24_iterators/operations/prev_neg.cc: Adjust dg-error line number.
2025-05-27libstdc++: Regenerate include/Makefile.inJonathan Wakely1-1/+1
libstdc++-v3/ChangeLog: * include/Makefile.in: Regenerate.
2025-05-27libstdc++: Support std::abs for 128-bit integers and floats [PR96710]Jonathan Wakely1-1/+8
Currently we only provide std::abs(__int128) and std::abs(__float128) for non-strict modes, i.e. -std=gnu++NN but not -std=c++NN. This defines those overloads for strict modes too, as a small step towards resolving PR 96710 (which will eventually mean that __int128 satisfies the std::integral concept). libstdc++-v3/ChangeLog: PR libstdc++/96710 * include/bits/std_abs.h [__SIZEOF_INT128__] (abs(__int128)): Define. [_GLIBCXX_USE_FLOAT128] (abs(__float128)): Enable definition for strict modes. * testsuite/26_numerics/headers/cmath/82644.cc: Use strict_std instead of defining __STRICT_ANSI__. * testsuite/26_numerics/headers/cstdlib/abs128.cc: New test. Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-27libstdc++: Fix bug in default ctor of extents.Luc Grosheintz1-1/+1
The array that stores the dynamic extents used to be default initialized. The standard requires value intialization. This commit fixes the bug and adds a test. libstdc++-v3/ChangeLog: * include/std/mdspan: Value initialize the array storing the dynamic extents. * testsuite/23_containers/mdspan/extents/ctor_default.cc: New test. Signed-off-by: Luc Grosheintz <luc.grosheintz@gmail.com>
2025-05-26libstdc++: Implement C++26 std::indirect [PR119152]Jonathan Wakely6-0/+485
This patch implements C++26 std::indirect as specified in P3019 with amendment to move assignment from LWG 4251. PR libstdc++/119152 libstdc++-v3/ChangeLog: * doc/doxygen/stdheader.cc: Added indirect.h file. * include/Makefile.am: Add new header. * include/Makefile.in: Regenerate. * include/bits/indirect.h: New file. * include/bits/version.def (indirect): Define. * include/bits/version.h: Regenerate. * include/std/memory: Include new header. * testsuite/std/memory/indirect/copy.cc * testsuite/std/memory/indirect/copy_alloc.cc * testsuite/std/memory/indirect/ctor.cc * testsuite/std/memory/indirect/incomplete.cc * testsuite/std/memory/indirect/invalid_neg.cc * testsuite/std/memory/indirect/move.cc * testsuite/std/memory/indirect/move_alloc.cc * testsuite/std/memory/indirect/relops.cc Co-authored-by: Tomasz Kamiński <tkaminsk@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-26libstdc++: Implement C++26 function_ref [PR119126]Tomasz Kamiński8-47/+379
This patch implements C++26 function_ref as specified in P0792R14, with correction for constraints for constructor accepting nontype_t parameter from LWG 4256. As function_ref may store a pointer to the const object, __Ptrs::_M_obj is changed to const void*, so again we do not cast away const from const objects. To help with necessary casts, a __polyfunc::__cast_to helper is added, that accepts reference to or target type direclty. The _Invoker now defines additional call methods used by function_ref: _S_ptrs() for invoking target passed by reference, and __S_nttp, _S_bind_ptr, _S_bind_ref for handling constructors accepting nontype_t. The existing _S_call_storage is changed to thin wrapper, that initialies _Ptrs, and forwards to _S_call_ptrs. This reduced the most uses of _Storage::_M_ptr and _Storage::_M_ref, so this functions was removed, and _Manager uses were adjusted. Finally we make function_ref available in freestanding mode, as move_only_function and copyable_function are currently only available in hosted, so we define _Manager and _Mo_base only if either __glibcxx_move_only_function or __glibcxx_copyable_function is defined. PR libstdc++/119126 libstdc++-v3/ChangeLog: * doc/doxygen/stdheader.cc: Added funcref_impl.h file. * include/Makefile.am: Added funcref_impl.h file. * include/Makefile.in: Added funcref_impl.h file. * include/bits/funcref_impl.h: New file. * include/bits/funcwrap.h: (_Ptrs::_M_obj): Const-qualify. (_Storage::_M_ptr, _Storage::_M_ref): Remove. (__polyfunc::__cast_to) Define. (_Base_invoker::_S_ptrs, _Base_invoker::_S_nttp) (_Base_invoker::_S_bind_ptrs, _Base_invoker::_S_bind_ref) (_Base_invoker::_S_call_ptrs): Define. (_Base_invoker::_S_call_storage): Foward to _S_call_ptrs. (_Manager::_S_local, _Manager::_S_ptr): Adjust for _M_obj being const qualified. (__polyfunc::_Manager, __polyfunc::_Mo_base): Guard with __glibcxx_move_only_function || __glibcxx_copyable_function. (__polyfunc::__skip_first_arg, __polyfunc::__deduce_funcref) (std::function_ref) [__glibcxx_function_ref]: Define. * include/bits/utility.h (std::nontype_t, std::nontype) (__is_nontype_v) [__glibcxx_function_ref]: Define. * include/bits/version.def: Define function_ref. * include/bits/version.h: Regenerate. * include/std/functional: Define __cpp_lib_function_ref. * src/c++23/std.cc.in (std::nontype_t, std::nontype) (std::function_ref) [__cpp_lib_function_ref]: Export. * testsuite/20_util/function_ref/assign.cc: New test. * testsuite/20_util/function_ref/call.cc: New test. * testsuite/20_util/function_ref/cons.cc: New test. * testsuite/20_util/function_ref/cons_neg.cc: New test. * testsuite/20_util/function_ref/conv.cc: New test. * testsuite/20_util/function_ref/deduction.cc: New test. * testsuite/20_util/function_ref/mutation.cc: New test. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-23libstdc++: Fix concept checks for std::unique_copy [PR120384]Jonathan Wakely1-14/+3
This looks to have been wrong since r0-125454-gea89b2482f97aa which introduced the predefined_ops.h. Since that change, the binary predicate passed to std::__unique_copy is _Iter_comp_iter, which takes arguments of the iterator type, not the iterator's value type. This removes the checks from the __unique_copy overloads and moves them into the second overload of std::unique_copy, where we have the original binary predicate, not the adapted one from predefined_ops.h. The third __unique_copy overload currently checks that the predicate is callable with the input range value type and the output range value type. This change alters that, so that we only ever check that the predicate can be called with two arguments of the same type. That is intentional, because calling the predicate with different types is a bug that will be fixed in a later commit (see PR libstdc++/120386). libstdc++-v3/ChangeLog: PR libstdc++/120384 * include/bits/stl_algo.h (__unique_copy): Remove all _BinaryPredicateConcept concept checks. (unique_copy): Check _BinaryPredicateConcept in overload that takes a predicate. * testsuite/25_algorithms/unique_copy/120384.cc: New test. Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-23libstdc++: Add always_inline to std::is_constant_evaluated()Jonathan Wakely1-1/+2
We already have the attribute on std::__is_constant_evaluated() but for some reason not on std::is_constant_evaluated(). libstdc++-v3/ChangeLog: * include/std/type_traits (is_constant_evaluated): Add always_inline attribute.
2025-05-22libstdc++: Define _Scoped_allocation RAII helperJonathan Wakely1-0/+96
libstdc++-v3/ChangeLog: * include/bits/allocated_ptr.h (_Scoped_allocation): New class template. Co-authored-by: Tomasz Kamiński <tkaminsk@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-22libstdc++: Fix vector(from_range_t, R&&) for exceptions [PR120367]Jonathan Wakely1-1/+2
Because this constructor delegates to vector(a) the object has been fully constructed and the destructor will run if an exception happens. That means we need to set _M_finish == _M_start so that the destructor doesn't try to destroy any elements. libstdc++-v3/ChangeLog: PR libstdc++/120367 * include/bits/stl_vector.h (_M_range_initialize): Initialize _M_impl._M_finish. * testsuite/23_containers/vector/cons/from_range.cc: Check with a type that throws on construction. exceptions during construction. Reviewed-by: Patrick Palka <ppalka@redhat.com>
2025-05-21libstdc++: use maintained size when split pb_ds binary search treesXℹ Ruoyao1-1/+3
libstdc++-v3/ChangeLog: PR libstdc++/81806 * include/ext/pb_ds/detail/bin_search_tree_/split_join_fn_imps.hpp (split_finish): Use maintained size, instead of calling std::distance.
2025-05-21libstdc++: maintain subtree size in pb_ds binary search treesXℹ Ruoyao4-4/+46
libstdc++-v3/ChangeLog: * include/ext/pb_ds/detail/rb_tree_map_/node.hpp (rb_tree_node_::size_type): New typedef. (rb_tree_node_::m_subtree_size): New field. * include/ext/pb_ds/detail/splay_tree_/node.hpp (splay_tree_node_::size_type): New typedef. (splay_tree_node_::m_subtree_size): New field. * include/ext/pb_ds/detail/bin_search_tree_/bin_search_tree_.hpp (PB_DS_BIN_TREE_NAME::update_subtree_size): Declare new member function. * include/ext/pb_ds/detail/bin_search_tree_/rotate_fn_imps.hpp (update_subtree_size): Define. (apply_update, update_to_top): Call update_subtree_size.
2025-05-21libstdc++: remove two redundant statements in pb_ds binary treeXℹ Ruoyao1-2/+0
libstdc++-v3/ChangeLog: * include/ext/pb_ds/detail/bin_search_tree_/insert_fn_imps.hpp (insert_leaf_new, insert_imp_empty): remove redundant statements.
2025-05-20libstdc++: Cleanup and stabilize format _Spec<_CharT> and _Pres_type.Tomasz Kamiński3-133/+145
These patch makes following changes to _Pres_type values: * _Pres_esc is replaced with separate _M_debug flag. * _Pres_s, _Pres_p do not overlap with _Pres_none. * hexadecimal presentation use same values for pointer, integer and floating point types. The members of _Spec<_CharT> are rearranged so the class contains 8 bits reserved for future use (_M_reserved) and 8 bits of tail padding. Derived classes (like _ChronoSpec<_CharT>) can reuse the storage for initial members. We also add _SpecBase as the base class for _Spec<_CharT> to make it non-C++98 POD, which allows tail padding to be reused on Itanium ABI. Finally, the format enumerators are defined as enum class with unsigned char as underlying type, followed by using enum to bring names in scope. _Term_char names are adjusted for consistency, and enumerator values are changed so it can fit in smaller bitfields. The '?' is changed to separate _M_debug flag, to allow debug format to be independent from the presentation type, and applied to multiple presentation types. For example it could be used to trigger memberwise or reflection based formatting. The _M_format_character and _M_format_character_escaped functions are merged to single function that handle normal and debug presentation. In particular this would allow future support for '?c' for printing integer types as escaped character. _S_character_width is also folded in the merged function. Decoupling _Pres_s value from _Pres_none, allows it to be used for string presentation for range formatting, and removes the need for separate _Pres_seq and _Pres_str. This does not affect formatting of bool as __formatter_int::_M_parse overrides default value of _M_type. And with separation of the _M_debug flag, __formatter_str::format behavior is now agnostic to _M_type value. The values for integer presentation types, are arranged so textual presentations (_Prec_s, _Pres_c) are grouped together. For consistency floating point hexadecimal presentation uses the same values as integer ones. New _Pres_p and setting for _M_alt enables using some spec to configure formatting of uintptr_t with __formatter_int, and const void* with __formatter_ptr. Differentiating it from _Pres_none would allow future of formatter<T*, _CharT> that would require explicit presentation type to be specified. This would allow std::vector<T*> to be formatted directly with '{::p}' format spec. The constructors for __formatter_int and _formatter_ptr from _Spec<_CharT>, now also set default presentation modes, as format functions expects them. libstdc++-v3/ChangeLog: * include/bits/chrono_io.h (_ChronoSpec::_M_locale_specific): Declare as bit fiekd in tail-padding.. * include/bits/formatfwd.h (__format::_Align): Defined as enum class and add using enum. * include/std/format (__format::_Pres_type, __format::_Sign) (__format::_WidthPrec, __format::_Arg_t): Defined as enum class and add using enum. (_Pres_type::_Pres_esc): Replace with _Pres_max. (_Pres_type::_Pres_seq, _Pres_type::_Pres_str): Remove. (__format::_Pres_type): Updated values of enumerators as described above. (__format::_Spec): Rearranged members to have 8 bits of tail-padding. (_Spec::_M_debug): Defined. (_Spec::_M_reserved): Extended to 8 bits and moved at the end. (_Spec::_M_reserved2): Removed. (_Spec::_M_parse_fill_and_align, _Spec::_M_parse_sign) (__format::__write_padded_as_spec): Adjusted default value checks. (__format::_Term_char): Add using enum and adjust enumertors. (__Escapes::_S_term): Adjusted for _Term_char values. (__format::__should_escape_ascii): Adjusted _Term_char uses. (__format::__write_escaped): Adjusted for _Term_char. (__formatter_str::parse): Set _Pres_s if specifed and _M_debug instead of _Pres_esc. (__formatter_str::set_debug_format): Set _M_debug instead of _Pres_esc. (__formatter_str::format, __formatter_str::_M_format_range): Check _M_debug instead of _Prec_esc. (__formatter_str::_M_format_escaped): Adjusted _Term_char uses. (__formatter_int::__formatter_int(_Spec<_CharT>)): Set _Pres_d if default presentation type is not set. (__formatter_int::_M_parse): Adjusted default value checks. (__formatter_int::_M_do_parse): Set _M_debug instead of _Pres_esc. (__formatter_int::_M_format_character): Handle escaped presentation. (__formatter_int::_M_format_character_escaped) (__formatter_int::_S_character_width): Merged into _M_format_character. (__formatter_ptr::__formatter_ptr(_Spec<_CharT>)): Set _Pres_p if default presentation type is not set. (__formatter_ptr::parse): Add default __type parameter, store _Pres_p, and handle _M_alt to be consistent with meaning for integers. (__foramtter_ptr<_CharT>::_M_set_default): Define. (__format::__pack_arg_types, std::basic_format_args): Add necessary casts. (formatter<_CharT, _CharT>::set_debug_format) (formatter<char, wchar_t>::set_debug_format): Set _M_debug instead of _Pres_esc. (formatter<_CharT, _CharT>::format, formatter<char, wchar_t>::format): Simplify calls to _M_format_character. (range_formatter<_Rg, _CharT>::parse): Replace _Pres_str with _Pres_s and set _M_debug instead of _Pres_esc. (range_formatter<_Rg, _CharT>::format): Replace _Pres_str with _Pres_s. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-19libstdc++: Fix some Clang -Wsystem-headers warnings in <ranges>Jonathan Wakely1-6/+6
libstdc++-v3/ChangeLog: * include/std/ranges (_ZipTransform::operator()): Remove name of unused parameter. (chunk_view::_Iterator, stride_view::_Iterator): Likewise. (join_with_view): Declare _Iterator and _Sentinel as class instead of struct. (repeat_view): Declare _Iterator as class instead of struct. Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-19libstdc++: Fix std::format of chrono::local_days with {} [PR120293]Jonathan Wakely1-0/+3
Formatting of chrono::local_days with an empty chrono-specs should be equivalent to inserting it into an ostream, which should use the overload for inserting chrono::sys_days into an ostream. The implementation of empty chrono-specs in _M_format_to_ostream takes some short cuts, and that wasn't being done correctly for chrono::local_days. libstdc++-v3/ChangeLog: PR libstdc++/120293 * include/bits/chrono_io.h (_M_format_to_ostream): Add special case for local_time convertible to local_days. * testsuite/std/time/clock/local/io.cc: Check formatting of chrono::local_days. Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-16libstdc++: Use __is_invocable/nothrow_invocable builtins morePatrick Palka1-1/+18
As a follow-up to r15-1253 and r15-1254 which made us use these builtins in the standard std::is_invocable/nothrow_invocable class templates, let's also use them directly in the standard variable templates and our internal C++11 __is_invocable/nothrow_invocable class templates. libstdc++-v3/ChangeLog: * include/std/type_traits (__is_invocable): Define in terms of corresponding builtin if available. (__is_nothrow_invocable): Likewise. (is_invocable_v): Likewise. (is_nothrow_invocable_v): Likewise. Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
2025-05-15libstdc++: Fix class mandate for extents.Luc Grosheintz1-2/+3
The standard states that the IndexType must be a signed or unsigned integer. This mandate was implemented using `std::is_integral_v`. Which also includes (among others) char and bool, which neither signed nor unsigned integers. libstdc++-v3/ChangeLog: * include/std/mdspan: Implement the mandate for extents as signed or unsigned integer and not any interal type. Remove leading underscores from names in static_assert message. * testsuite/23_containers/mdspan/extents/class_mandates_neg.cc: Check that extents<char,...> and extents<bool,...> are invalid. Adjust dg-prune-output pattern. * testsuite/23_containers/mdspan/extents/misc.cc: Update tests to avoid `char` and `bool` as IndexType. Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com> Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
2025-05-15libstdc++: Fix std::format_kind primary template for Clang [PR120190]Jonathan Wakely1-5/+14
Although Clang trunk has been adjusted to handle our std::format_kind definition (because they need to be able to compile the GCC 15.1.0 release), it's probably better to not rely on something that they might start diagnosing again in future. Define the primary template in terms of an immediately invoked function expression, so that we can put a static_assert(false) in the body. libstdc++-v3/ChangeLog: PR libstdc++/120190 * include/std/format (format_kind): Adjust primary template to not depend on itself. * testsuite/std/format/ranges/format_kind_neg.cc: Adjust expected errors. Check more invalid specializations. Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com> Reviewed-by: Daniel Krügler <daniel.kruegler@gmail.com>
2025-05-15libstdc++: Micro-optimization in std::arg overload for scalarsJonathan Wakely1-2/+2
Use __builtin_signbit directly instead of std::signbit. libstdc++-v3/ChangeLog: * include/std/complex (arg(T)): Use __builtin_signbit instead of std::signbit. Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-15libstdc++: Deprecate non-standard std::fabs(const complex<T>&) [PR120235]Jonathan Wakely1-11/+11
There was an overload of fabs for std::complex in TR1 and in some C++0x drafts, but it was removed from the working draft by LWG 595. Since we've been providing it for decades we should deprecate it before removing it. libstdc++-v3/ChangeLog: PR libstdc++/120235 * doc/html/*: Regenerate. * doc/xml/manual/evolution.xml: Document deprecation. * include/std/complex: Replace references to TR1 subclauses with corresponding C++11 subclauses. (fabs): Add deprecated attribute. * testsuite/26_numerics/complex/fabs_neg.cc: New test. Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-15libstdc++: Fix preprocessor check for __float128 formatter [PR119246]Tomasz Kamiński1-1/+1
The previous check `_GLIBCXX_FORMAT_F128 != 1` was passing if _GLIBCXX_FORMAT_F128 was not defined, i.e. evaluted to zero. This broke sparc-sun-solaris2.11 and x86_64-darwin. PR libstdc++/119246 libstdc++-v3/ChangeLog: * include/std/format: Updated check for _GLIBCXX_FORMAT_F128.
2025-05-14libstdc++: Renamed bits/move_only_function.h to bits/funcwrap.h [PR119125]Tomasz Kamiński4-22/+22
The file now includes copyable_function in addition to move_only_function. PR libstdc++/119125 libstdc++-v3/ChangeLog: * include/bits/move_only_function.h: Move to... * include/bits/funcwrap.h: ...here. * doc/doxygen/stdheader.cc (init_map): Replaced move_only_function.h with funcwrap.h, and changed include guard to use feature test macro. Move bits/version.h include before others. * include/Makefile.am: Likewise. * include/Makefile.in: Likewise. * include/std/functional: Likewise. Reviewed-by: Patrick Palka <ppalka@redhat.com> Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-14libstdc++: Implement C++26 copyable_function [PR119125]Tomasz Kamiński8-4/+383
This patch implements C++26 copyable_function as specified in P2548R6. It also implements LWG 4255 that adjust move_only_function so constructing from empty copyable_function, produces empty functor. This falls from existing checks, after specializing __is_polymorphic_function_v for copyable_function specializations. For compatible invoker signatures, the move_only_function may be constructed from copyable_funciton without double indirection. To achieve that we derive _Cpy_base from _Mo_base, and specialize __is_polymorphic_function_v for copyable_function. Similary copyable_functions with compatible signatures can be converted without double indirection. As we starting to use _Op::_Copy operation from the _M_manage function, invocations of that functions may now throw exceptions, so noexcept needs to be removed from the signature of stored _M_manage pointers. This also affects operations in _Mo_base, however we already wrap _M_manage invocations in noexcept member functions (_M_move, _M_destroy, swap). PR libstdc++/119125 libstdc++-v3/ChangeLog: * doc/doxygen/stdheader.cc: Addded cpyfunc_impl.h header. * include/Makefile.am: Add bits cpyfunc_impl.h. * include/Makefile.in: Add bits cpyfunc_impl.h. * include/bits/cpyfunc_impl.h: New file. * include/bits/mofunc_impl.h: Mention LWG 4255. * include/bits/move_only_function.h: Update header description and change guard to also check __glibcxx_copyable_function. (_Manager::_Func): Remove noexcept. (std::__is_polymorphic_function_v<move_only_function<_Tp>>) (__variant::_Never_valueless_alt<std::move_only_function<_Signature...>>) (move_only_function) [__glibcxx_move_only_function]: Adjust guard. (std::__is_polymorphic_function_v<copyable_function<_Tp>>) (__variant::_Never_valueless_alt<std::copyable_function<_Signature...>>) (__polyfunc::_Cpy_base, std::copyable_function) [__glibcxx_copyable_function]: Define. * include/bits/version.def: Define copyable_function. * include/bits/version.h: Regenerate. * include/std/functional: Define __cpp_lib_copyable_function. * src/c++23/std.cc.in (copyable_function) [__cpp_lib_copyable_function]: Export. * testsuite/20_util/copyable_function/call.cc: New test based on move_only_function tests. * testsuite/20_util/copyable_function/cons.cc: New test based on move_only_function tests. * testsuite/20_util/copyable_function/conv.cc: New test based on move_only_function tests. * testsuite/20_util/copyable_function/copy.cc: New test. * testsuite/20_util/copyable_function/move.cc: New test based on move_only_function tests. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-14libstdc++: Avoid double indirection in move_only_function when possible ↵Tomasz Kamiński2-154/+375
[PR119125] Based on the provision in C++26 [func.wrap.general] p2 this patch adjust the generic move_only_function(_Fn&&) constructor, such that when _Fn refers to selected move_only_function instantiations, the ownership of the target object is directly transfered to constructor object. This avoid cost of double indirection in this situation. We apply this also in C++23 mode. We also fix handling of self assignments, to match behavior required by standard, due use of copy and swap idiom. An instantiations MF1 of move_only_function can transfer target of another instantiation MF2, if it can be constructed via usual rules (__is_callable_from<_MF2>), and their invoker are convertible (__is_invoker_convertible<MF2, MF1>()), i.e.: * MF1 is less noexcept than MF2, * return types are the same after stripping cv-quals, * adujsted parameters type are the same (__poly::_param_t), i.e. param of types T and T&& are compatible for non-trivially copyable objects. Compatiblity of cv ref qualification is checked via __is_callable_from<_MF2>. To achieve above the generation of _M_invoke functions is moved to _Invoker class templates, that only depends on noexcept, return type and adjusted parameter of the signature. To make the invoker signature compatible between const and mutable qualified signatures, we always accept _Storage as const& and perform a const_cast for locally stored object. This approach guarantees that we never strip const from const object. Another benefit of this approach is that move_only_function<void(std::string)> and move_only_function<void(std::string&&)> use same funciton pointer, which should reduce binary size. The _Storage and _Manager functionality was also extracted and adjusted from _Mofunc_base, in preparation for implementation for copyable_function and function_ref. The _Storage was adjusted to store functions pointers as void(*)(). The manage function, now accepts _Op enum parameter, and supports additional operations: * _Op::_Address stores address of target object in destination * _Op::_Copy, when enabled, copies from source to destination Furthermore, we provide a type-independent mamange functions for handling all: * function pointer types * trivially copyable object stored locally. Similary as in case of invoker, we always pass source as const (for copy), and cast away constness in case of move operations, where we know that source is mutable. Finally, the new helpers are defined in __polyfunc internal namespace. PR libstdc++/119125 libstdc++-v3/ChangeLog: * include/bits/mofunc_impl.h: (std::move_only_function): Adjusted for changes in bits/move_only_function.h (move_only_function::move_only_function(_Fn&&)): Special case move_only_functions with same invoker. (move_only_function::operator=(move_only_function&&)): Handle self assigment. * include/bits/move_only_function.h (__polyfunc::_Ptrs) (__polyfunc::_Storage): Refactored from _Mo_func::_Storage. (__polyfunc::__param_t): Moved from move_only_function::__param_t. (__polyfunc::_Base_invoker, __polyfunc::_Invoke): Refactored from move_only_function::_S_invoke. (__polyfunc::_Manager): Refactored from _Mo_func::_S_manager. (std::_Mofunc_base): Moved into __polyfunc::_Mo_base with parts extracted to __polyfunc::_Storage and __polyfunc::_Manager. (__polyfunc::__deref_as, __polyfunc::__invoker_of) (__polyfunc::__base_of, __polyfunc::__is_invoker_convertible): Define. (std::__is_move_only_function_v): Renamed to __is_polymorphic_function_v. (std::__is_polymorphic_function_v): Renamed from __is_move_only_function_v. * testsuite/20_util/move_only_function/call.cc: Test for functions pointers. * testsuite/20_util/move_only_function/conv.cc: New test. * testsuite/20_util/move_only_function/move.cc: Tests for self assigment. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-14libstdc++: Preserve the argument type in basic_format_args [PR119246]Tomasz Kamiński1-71/+146
This commits adjust the way how the arguments are stored in the _Arg_value (and thus basic_format_args), by preserving the types of fixed width floating-point types, that were previously converted to float, double, long double. The _Arg_value union now contains alternatives with std::bfloat16_t, std::float16_t, std::float32_t, std::float64_t that use pre-existing _Arg_bf16, _Arg_f16, _Arg_f32, _Arg_f32 argument types. This does not affect formatting, as specialization of formatters for fixed width floating-point types formats them by casting to the corresponding standard floating point type. For the 128bit floating we need to handle the ppc64 architecture, (_GLIBCXX_LONG_DOUBLE_ALT128_COMPAT) for which the long double may (per TU basis) designate either __ibm128 and __ieee128 type, we need to store both types in the _Arg_value and have two _Arg_types (_Arg_ibm128, _Arg_ieee128). On other architectures we use extra enumerator value to store __float128, that is different from long double and _Float128. This is consistent with ppc64, for which __float128, if present, is same type as __ieee128. We use _Arg_float128 _M_float128 names that deviate from _Arg_fN naming scheme, to emphasize that this flag is not used for std::float128_t (_Float128) type, that is consistenly formatted via handle. The __format::__float128_t type is renamed to __format::__flt128_t, to mitigate visual confusion between this type and __float128. We also introduce __bflt16_t typedef instead of using of decltype. We add new alternative for the _Arg_value and allow them to be accessed via _S_get, when the types are available. However, we produce and handle corresponding _Arg_type, only when we can format them. See also r14-3329-g27d0cfcb2b33de. The formatter<_Float128, _CharT> that formats via __format::__flt128_t is always provided, when type is available. It is still correct when __format::__flt128_t is _Float128. We also provide formatter<__float128, _CharT> that formats via __flt128_t. As this type may be disabled (-mno-float128), extra care needs to be taken, for situation when __float128 is same as long double. If the formatter would be defined in such case, the formatter<long double, _CharT> would be generated from different specializations, and have different mangling: * formatter<__float128, _CharT> if __float128 is present, * formatter<__format::__formattable_float, _CharT> otherwise. To best of my knowledge this happens only on ppc64 for __ieee128 and __float128, so the formatter is not defined in this case. static_assert is added to detect other configurations like that. In such case we should replace it with constraint. PR libstdc++/119246 libstdc++-v3/ChangeLog: * include/std/format (__format::__bflt16_t): Define. (_GLIBCXX_FORMAT_F128): Separate value for cases where _Float128 is used. (__format::__float128_t): Renamed to __format::__flt128_t. (std::formatter<_Float128, _CharT>): Define always if there is formattable 128bit float. (std::formatter<__float128, _CharT>): Define. (_Arg_type::_Arg_f128): Rename to _Arg_float128 and adjust value. (_Arg_type::_Arg_ibm128): Change value to _Arg_ldbl. (_Arg_type::_Arg_ieee128): Define as alias to _Arg_float128. (_Arg_value::_M_f128): Replaced with _M_ieee128 and _M_float128. (_Arg_value::_M_ieee128, _Arg_value::_M_float128) (_Arg_value::_M_bf16, _Arg_value::_M_f16, _Arg_value::_M_f32) (_Arg_value::_M_f64): Define. (_Arg_value::_S_get, basic_format_arg::_S_to_enum): Handle __bflt16, _Float16, _Float32, _Float64, and __float128 types. (basic_format_arg::_S_to_arg_type): Preserve _bflt16, _Float16, _Float32, _Float64 and __float128 types. (basic_format_arg::_M_visit): Handle _Arg_float128, _Arg_ieee128, _Arg_b16, _Arg_f16, _Arg_f32, _Arg_f64. * testsuite/std/format/arguments/args.cc: Updated to illustrate that extended floating point types use handles now. Added test for __float128. * testsuite/std/format/parse_ctx.cc: Extended test to cover class to check_dynamic_spec with floating point types and handles. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-14Add std::to_underlying to the set of stdlib functions that are always foldedVille Voutilainen1-1/+1
gcc/cp/ChangeLog: * cp-gimplify.cc (cp_fold): Add to_underlying. gcc/testsuite/ChangeLog: * g++.dg/opt/pr96780_cpp23.C: New. libstdc++-v3/ChangeLog: * include/std/utility (to_underlying): Add the __always_inline__ attribute. Signed-off-by: Ville Voutilainen <ville.voutilainen@gmail.com>
2025-05-12libstdc++: Fix constraint recursion in std::expected's operator== [PR119714]Patrick Palka1-2/+2
This std::expected friend operator== is prone to constraint recursion after CWG 2369 for the same reason as basic_const_iterator's comparison operators were before the r15-7757-g4342c50ca84ae5 workaround. This patch works around the constraint recursion here in a similar manner, by making the function parameter of type std::expected dependent in a trivial way. PR libstdc++/119714 PR libstdc++/112490 libstdc++-v3/ChangeLog: * include/std/expected (expected::operator==): Replace non-dependent std::expected function parameter with a dependent one of type expected<_Vp, _Er> where _Vp matches _Tp. * testsuite/20_util/expected/119714.cc: New test. Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com> Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
2025-05-12libstdc++: Remove #warning from <ciso646> for C++17 [PR120187]Jonathan Wakely5-7/+19
Although <ciso646> was removed from C++20, it was not formally deprecated in C++17. In contrast, <ctgmath>, <cstdalign>, etc. were formally deprecated in C++17 before being removed in C++20. Due to the widespread convention of including <ciso646> to detect implementation-specific macros (such as _GLIBCXX_RELEASE) it causes quite a lot of noise to issue deprecation warnings in C++17 mode. The recommendation to include <version> instead does work for recent compilers, even in C++17 mode, but isn't portable to older compilers that don't provide <version> yet (e.g. GCC 8). There are also potential objections to including <version> pre-C++20 when it wasn't defined by the standard. I don't have much sympathy for this position, because including <ciso646> for implementation-specific macros wasn't part of the C++17 standard either. It's no more non-standard to rely on <version> being present and defining those macros than to rely on <ciso646> defining them, and __has_include can be used to detect whether <version> is present. However, <ciso646> is being used in the wild by popular libraries like Abseil and we can't change versions of those that have already been released. This removes the #warning in <ciso646> for C++17 mode, so that we only emit diagnostics for C++20 and later. With this change, including <ciso646> in C++20 or later gives an error if _GLIBCXX_USE_DEPRECATED is defined to zero, otherwise a warning if -Wdeprecated is enabled, otherwise no diagnostic is given. This also adds "@since C++11 (removed in C++20)" to the Doxygen @file comments in all the relevant headers. The test for <ciso646> needs to be updated to no longer expect a warning for c++17_only. A new test is added to ensure that we get a warning instead of an error when -D_GLIBCXX_USE_DEPRECATED=0 is not used. libstdc++-v3/ChangeLog: PR libstdc++/120187 * include/c_global/ciso646: Only give deprecated warning for C++20 and later. * include/c_global/ccomplex: Add @since to Doxygen comment. * include/c_global/cstdalign: Likewise. * include/c_global/cstdbool: Likewise. * include/c_global/ctgmath: Likewise. * testsuite/18_support/headers/ciso646/macros.cc: Remove dg-warning for c++17_only effective target. * testsuite/18_support/headers/ciso646/macros-2.cc: New test. Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-12libstdc++: Restore std::scoped_lock for non-gthreads targets [PR120198]Jonathan Wakely3-4/+2
This was a regression introduced with using version.def to define feature test macros (r14-3248-g083b7f2833d71d). std::scoped_lock doesn't need to depend on gthreads and so can be defined unconditionally, even for freestanding. libstdc++-v3/ChangeLog: PR libstdc++/120198 * include/bits/version.def (scoped_lock): Do not depend on gthreads or hosted. * include/bits/version.h: Regenerate. * include/std/mutex (scoped_lock): Update comment. * testsuite/30_threads/scoped_lock/requirements/typedefs.cc: Remove dg-require-gthreads and use custom lockable type instead of std::mutex. Check that typedef is only present for a single template argument. Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-09libstdc++: Use _Padding_sink in __formatter_chrono to produce padded output.Tomasz Kamiński1-35/+20
Formatting code is extracted to _M_format_to function, that produced output to specified iterator. This function is now invoked either with __fc.out() directly (if width is not specified) or _Padding_sink::out(). This avoid formatting to temporary string if no padding is requested, and minimize allocations otherwise. For more details see commit message of r16-142-g01e5ef3e8b91288f5d387a27708f9f8979a50edf. This should not increase number of instantiations, as implementation only produce basic_format_context with _Sink_iter as iterator, which is also _Padding_sink iterator. libstdc++-v3/ChangeLog: * include/bits/chrono_io.h (__formatter_chrono::_M_format_to): Extracted from _M_format. (__formatter_chrono::_M_format): Use _Padding_sink and delegate to _M_format_to. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-09libstdc++: Provide ability to query _Sink_iter if writes are discarded.Tomasz Kamiński1-12/+52
This patch provides _M_discarding functiosn for _Sink_iter and _Sink function that returns true, if any further writes to the _Sink_iter and underlying _Sink, will be discared, and thus can be omitted. Currently only the _Padding_sink reports discarding mode of if width of sequence characters is greater than _M_maxwidth (precision), or underlying _Sink is discarding characters. The _M_discarding override, is separate function from _M_ignoring, that remain annotated with [[__gnu__::__always_inline__]]. Despite having notion of maximum characters to be written (_M_max), _Iter_sink nevers discard characters, as the total number of characters that would be written needs to be returned by format_to_n. This is documented in-source by providing an _Iter_sink::_M_discarding override, that always returns false. The function is currently queried only by the _Padding_sinks, that may be stacked for example a range is formatted, with padding with being specified both for range itself and it's elements. The state of underlying sink is checked during construction and after each write (_M_sync_discarding). libstdc++-v3/ChangeLog: * include/std/format (__Sink_iter<_CharT>::_M_discarding) (__Sink<_CharT>::_M_discarding, _Iter_sink<_CharT, _OutIter>::_M_discarding) (_Padding_sinl<_CharT, _Out>::_M_padwidth) (_Padding_sink<_CharT, _Out>::_M_maxwidth): Remove const. (_Padding_sink<_CharT, _Out>::_M_sync_discarding) (_Padding_sink<_CharT, _Out>::_M_discarding): Define. (_Padding_sink<_CharT, _Out>::_Padding_sink(_Out, size_t, size_t)) (_Padding_sink<_CharT, _Out>::_M_force_update): (_Padding_sink<_CharT, _Out>::_M_flush): Call _M_sync_discarding. (_Padding_sink<_CharT, _Out>::_Padding_sink(_Out, size_t)): Delegate. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>