Age | Commit message (Collapse) | Author | Files | Lines |
|
|
|
LWG 3569 adjusted join_view's iterator specification to handle non
default-constructible iterators by wrapping the corresponding data member
in std::optional, which we followed suit in r13-2649-g7aa80c82ecf3a3.
But this wrapping is unnecessary for iterators that are already
default-constructible. Rather than unconditionally using std::optional
here, which introduces time/space overhead, this patch conditionalizes
our LWG 3569 changes on the iterator in question being non-forward (and
thus non default-constructible). We check forwardness instead of
default-constructibility in order to accommodate input-only iterators
that satisfy but do not model default_initializable, e.g. whose default
constructor is underconstrained.
libstdc++-v3/ChangeLog:
* include/std/ranges (join_view::_Iterator::_M_satisfy):
Adjust to handle non-std::optional _M_inner as per before LWG 3569.
(join_view::_Iterator::_M_get_inner): New.
(join_view::_Iterator::_M_inner): Don't wrap in std::optional if
the iterator is forward. Initialize.
(join_view::_Iterator::operator*): Use _M_get_inner instead
of *_M_inner.
(join_view::_Iterator::operator++): Likewise.
(join_view::_Iterator::iter_move): Likewise.
(join_view::_Iterator::iter_swap): Likewise.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
|
|
This patch refactors ranges::_Partial to be implemented using _Bind_back_t.
This allows it to benefit from the changes in r16-3398-g250dd5b5604fbc,
specifically making the closure trivially copyable. Since _Bind_back_t
already provides an optimized implementation for a single bound argument,
specializations for _Partial with a single argument are now removed.
We still preserve a specialization of _Partial for trivially copy-constructible
arguments that define only a const overload of operator(). To avoid
re-checking invocability constraints, this specialization calls the now-public,
unconstrained _Binder::_S_call static method instead of the constrained
_Binder::operator().
The primary specialization of _Partial retains its operator(), which
uses a simpler __adaptor_invocable constraint that does not consider
member pointers, as they are not relevant here. This implementation also
calls _Binder::_S_call to avoid re-performing overload resolution and
invocability checks for _Binder::operator().
Finally, the _M_binder member (_Bind_back_t) is now marked
[[no_unique_address]]. This is beneficial as ranges::_Partial is used with
ranges::to, which commonly has zero or empty bound arguments (e.g., stateless
allocators, comparators, or hash functions).
libstdc++-v3/ChangeLog:
* include/bits/binders.h (_Binder::_S_call): Make public.
* include/std/ranges (ranges::_Partial<_Adaptor, _Args...>):
Replace tuple<_Args...> with _Bind_back_t<_Adaptor, _Args...>.
(ranges::_Partial<_Adaptor, _Arg>): Remove.
Reviewed-by: Patrick Palka <ppalka@redhat.com>
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
|
|
bits/binders.h is already mapped in libstdc++-v3/doc/doxygen/stdheader.cc.
libstdc++-v3/ChangeLog:
* include/Makefile.am: Add bits/binders.h
* include/Makefile.in: Add bits/binders.h
* include/std/functional (std::_Indexed_bound_arg, std::_Binder)
(std::__make_bound_args, std::_Bind_front_t, std::_Bind_back_t):
Moved to bits/binders.h file, that is now included.
* include/bits/binders.h: New file.
Reviewed-by: Patrick Palka <ppalka@redhat.com>
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
|
|
The _Bind_front and _Bind_back class templates are now merged into a single
_Binder implementation that accepts _Back as a template parameter. This makes
the bind_back implementation available in C++20 mode, allowing it to be used
for range adaptor closures.
With zero bound arguments, bind_back and bind_front have equivalent
functionality. Consequently, _Bind_back_t now produces the same type as
bind_front (_Binder<false, _Fd>). A simple copy of the functor cannot be
returned in this case, as it would visibly affect overload resolution
(see included test cases).
We also replace std::invoke in internal functions, with std::__invoke.
libstdc++-v3/ChangeLog:
* include/std/functional: (std::_Indexed_bound_arg): Fixed
indentation.
(__Bound_arg_storage::_S_apply_front)
(__Bound_arg_storage::_S_apply_front): Merged into _S_apply.
(__Bound_arg_storage::_S_apply): Merged above, add _Back template
parameter, replace std::invoke with std::__invoke.
(std::_Bind_front): Renamed to std::_Binder and add _Back
template parameter.
(std::_Binder): Renamed from std::_Bind_front.
(_Binder::_Result_t, _Binder::_S_noexcept_invoke): Define.
(_Binder::operator()): Use _Result_t and _S_noexcept_invoke.
(_Binder::_S_call): Handle zero args specially, replace std::invoke
with std::__invoke.
(std::_Bind_front_t, std::_Bind_back_t): Defined in terms
of _Binder.
(std::_Bind_back): Merged into _Binder.
* testsuite/20_util/function_objects/bind_back/1.cc: New tests.
* testsuite/20_util/function_objects/bind_back/111327.cc: Updated
error messages.
* testsuite/20_util/function_objects/bind_front/1.cc: New tests.
* testsuite/20_util/function_objects/bind_front/111327.cc: Updated
error messages.
Reviewed-by: Patrick Palka <ppalka@redhat.com>
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
|
|
In r16-2328-g29d53f6213e0a1 we fixed a bug related to user-defined
objects that can convert to an integers only via an rvalue reference.
The same commit also implemented LWG 4314 [1], but didn't mark it with
_GLIBCXX_RESOLVE_LIB_DEFECTS. This commit adds the missing markers.
[1]: https://cplusplus.github.io/LWG/issue4314
It also fixes one cases of trailing white-space near a ctor for
aligned_accessor.
libstdc++-v3/ChangeLog:
* include/std/mdspan (layout_left::mapping::operator()): Add
_GLIBCXX_RESOLVE_LIB_DEFECTS marker for 4314.
(layout_left::mapping::operator()): Ditto.
(layout_stride::mapping::operator()): Ditto.
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
Signed-off-by: Luc Grosheintz <luc.grosheintz@gmail.com>
|
|
Stable names are based on C++03 standard document, and some of then were
changed since then.
libstdc++-v3/ChangeLog:
* doc/html/manual/status.html: Regenerated the file.
* doc/xml/manual/status_cxx1998.xml: Add stable name to
each entry.
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
|
|
|
|
missing a constraint
libstdc++-v3/ChangeLog:
* include/std/expected (expected(U&&)): Add missing constraint
as per LWG 4222.
* testsuite/20_util/expected/lwg4222.cc: New test.
Signed-off-by: Yihan Wang <yronglin777@gmail.com>
|
|
Make the std::get<T> overloads for rvalues use std::forward<T>(p.first)
not std::move(p.first), so that lvalue reference members are not
incorrectly converted to rvalues.
It might appear that std::move(p).first would also work, but the
language rules say that for std::pair<T&&, U> that would produce T&
rather than the expected T&& (see the discussion in P2445R1 §8.2).
Additional tests are added to verify all combinations of reference
members, value categories, and const-qualification.
libstdc++-v3/ChangeLog:
PR libstdc++/121745
* include/bits/stl_pair.h (get): Use forward instead of move in
std::get<T> overloads for rvalue pairs.
* testsuite/20_util/pair/astuple/get_by_type.cc: Check all value
categories and cv-qualification.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
|
|
For the pair(T1, T2) explicit deduction type to decay its arguments as
intended, we need the pair(const T1&, const T2&) constructor to not be
used for CTAD. Otherwise we try to instantiate pair<T1, T2> without
decaying, which is ill-formed for function lvalues.
Use std::type_identity_t<T1> to make the constructor unusable for an
implicit deduction guide.
libstdc++-v3/ChangeLog:
PR libstdc++/110853
* include/bits/stl_pair.h [C++20] (pair(const T1&, const T2&)):
Use std::type_identity_t<T1> for first parameter.
* testsuite/20_util/pair/cons/110853.cc: New test.
Reviewed-by: Patrick Palka <ppalka@redhat.com>
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
|
|
The r16-3416-g806de30f51c8b9 change to use __cpp_lib_chrono in
preprocessor conditions broke support for <chrono> for freestanding and
the COW std::string ABI. That happened because __cpp_lib_chrono is only
defined to the C++20 value for hosted and for the new ABI, because the
full set of C++20 features are not defined for freestanding and tzdb is
not defined for the old ABI.
This introduces a new internal feature test macro that corresponds to
the features that are always supported (e.g. chrono::local_time,
chrono::year, chrono::weekday).
libstdc++-v3/ChangeLog:
* include/bits/version.def (chrono_cxx20): Define.
* include/bits/version.h: Regenerate.
* include/std/chrono: Check __glibcxx_chrono_cxx20 instead of
__cpp_lib_chrono for C++20 features that don't require the new
std::string ABI and/or can be used for freestanding.
* src/c++20/clock.cc: Adjust preprocessor condition.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
|
|
|
|
As preparation for implementing std::constant_wrapper that's part of the
C++26 version of the <type_traits> header, the two classes _Index_tuple
and _Build_index_tuple are moved to <type_traits>. These two helpers are
needed by std::constant_wrapper to initialize the elements of one C
array with another.
Since, <bits/utility.h> already includes <type_traits> this solution
avoids creating a very small header file for just these two internal
classes. This approach doesn't move std::index_sequence and related code
to <type_traits> and therefore doesn't change which headers provide
user-facing features.
libstdc++-v3/ChangeLog:
* include/bits/utility.h (_Index_tuple): Move to <type_traits>.
(_Build_index_tuple): Ditto.
* include/std/type_traits (_Index_tuple): Ditto.
(_Build_index_tuple): Ditto.
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
Signed-off-by: Luc Grosheintz <luc.grosheintz@gmail.com>
|
|
This slightly improve the readability of error message, by suggesting
that 0 (literal) is expected as argument:
invalid conversion from 'int' to 'std::__cmp_cat::__literal_zero*'
libstdc++-v3/ChangeLog:
* libsupc++/compare (__cmp_cat::__literal_zero): Rename
from __unspec.
(__cmp_cat::__unspec): Rename to __literal_zero.
(operator==, operator<, operator>, operator<=, operator>=):
Replace __cmp_cat::__unspec to __cmp_cat::__literal_zero.
|
|
|
|
libstdc++-v3:
* doc/xml/manual/using_exceptions.xml: Update link to
Boost's "Exception-Safety"
* doc/html/manual/using_exceptions.html: Rebuild.
|
|
ptrace on Darwin requires <sys/types.h>.
The inline x86 asm doesn't work with the Solaris assembler.
libstdc++-v3/ChangeLog:
* src/c++26/debugging.cc [_GLIBCXX_HAVE_SYS_PTRACE_H]: Include
<sys/types.h>.
(breakpoint) [__i386__ || __x86_64__]: Use "int 0x03" instead of
"int3".
|
|
|
|
This implements P2546R5 (Debugging Support), including the P2810R4
(is_debugger_present is_replaceable) changes, allowing
std::is_debugger_present to be replaced by the program.
It would be good to provide a macOS definition of is_debugger_present as
per https://developer.apple.com/library/archive/qa/qa1361/_index.html
but that isn't included in this change.
The src/c++26/debugging.cc file defines a global volatile int which can
be set by debuggers to indicate when they are attached and detached from
a running process. This allows std::is_debugger_present() to give a
reliable answer, and additionally allows a debugger to choose how
std::breakpoint() should behave. Setting the global to a positive value
will cause std::breakpoint() to use that value as an argument to
std::raise, so debuggers that prefer SIGABRT for breakpoints can select
that. By default std::breakpoint() will use a platform-specific action
such as the INT3 instruction on x86, or GCC's __builtin_trap().
On Linux the std::is_debugger_present() function checks whether the
process is being traced by a process named "gdb", "gdbserver" or
"lldb-server", to try to avoid interpreting other tracing processes
(such as strace) as a debugger. There have been comments suggesting this
isn't desirable and that std::is_debugger_present() should just return
true for any tracing process (which is the case for non-Linux targets
that support the ptrace system call).
libstdc++-v3/ChangeLog:
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.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
|
|
libstdc++-v3/ChangeLog:
* testsuite/18_support/comparisons/categories/zero_neg.cc: New test.
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
|
|
The current implementation of `complex<_Tp>` assumes that int
`int` is implicitly convertible to `_Tp`, e.g., when using
`complex<_Tp>(1)`.
This patch transforms the implicit conversions into explicit type casts.
As a result, `std::complex` is now able to support more types. One
example is the type `Eigen::Half` from
https://eigen.tuxfamily.org/dox-devel/Half_8h_source.html which does not
implement implicit type conversions.
libstdc++-v3/ChangeLog:
* include/std/complex (polar, __complex_sqrt, pow)
(__complex_pow_unsigned): Use explicit conversions from int to
the complex value_type.
|
|
Asking std::is_constructible_v<std::bitset<1>, NonTrivial*> gives an
error, rather than answering the query. The problem is that the
constructor for std::bitset("010101") is not constrained to only accept
pointers to char-like types, and for the second parameter (which has a
default argument) std::basic_string_view<CharT> gets instantiated. If
the type is not char-like then that has undefined behaviour, and might
trigger a static_assert to fail in the body of std::basic_string_view.
We can fix it by constraining that constructor using the requirements
for char-like types from [strings.general] p1. I've submitted LWG 4294
and proposed making this change in the standard.
libstdc++-v3/ChangeLog:
PR libstdc++/121046
* include/std/bitset (bitset(const CharT*, ...)): Add
constraints on CharT type.
* testsuite/23_containers/bitset/lwg4294.cc: New test.
|
|
ordering types.
This patch adds two new internal helpers for ordering types:
* __cmp_cat::__ord to retrieve an internal _Ord value,
* __cmp_cat::__make<Ordering> to create an ordering from an _Ord value.
Conversions between ordering types are now handled by __cmp_cat::__make. As a
result, ordering types no longer need to befriend each other, only the new
helpers.
The __fp_weak_ordering implementation has also been simplified by:
* using the new helpers to convert partial_ordering to weak_ordering,
* using strong_ordering to weak_ordering conversion operator,
for the __isnan_sign comparison,
* removing the unused __cat local variable.
Finally, the _Ncmp enum is removed, and the unordered enumerator is added
to the existing _Ord enum.
libstdc++-v3/ChangeLog:
* 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.
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
|
|
|
|
The patch r16-3414-gfcb3009a32dc33 changed the representation of unordered to
optimize reversing of order, but it did not update implementation of reversing
operator<=>(0, partial_order).
libstdc++-v3/ChangeLog:
* libsupc++/compare
(operator<=>(__cmp_cat::__unspec, partial_ordering)):
Implement using _M_reverse.
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
|
|
This patch moves std::tai_clock::now() and std::tai_clock::now()
definitions from header inlines to static members invoked via a
normal function call, in service of stabilizing the C++20 ABI.
It also changes #if guards to mention the actual __cpp_lib_*
feature gated, not just the language version, for clarity.
New global function symbols std::chrono::tai_clock::now
and std::chrono::gps_clock::now are exported.
libstdc++-v3/ChangeLog:
* 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.
|
|
For any minimum value of a signed type, its negation (with wraparound) results
in the same value, behaving like zero. Representing the unordered result with
this minimum value, along with 0 for equal, 1 for greater, and -1 for less
in partial_ordering, allows its value to be reversed using unary negation.
The operator<=(partial_order, 0) now checks if the reversed value is positive.
This works correctly because the unordered value remains unchanged and thus
negative.
libstdc++-v3/ChangeLog:
* 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.
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
|
|
Previously, an empty functor (EmptyIdFunc) stored inside a
std::move_only_function being first member of a Composite class could have the
same address as the base of the EmptyIdFunc type (see included test cases),
resulting in two objects of the same type at the same address.
This commit addresses the issue by moving the internal buffer from the start
of the wrapper object to a position after the manager function pointer. This
minimizes aliasing with the stored buffer but doesn't completely eliminate it,
especially when multiple empty base objects are involved (PR121180).
To facilitate this member reordering, the private section of _Mo_base was
eliminated, and the corresponding _M_manager and _M_destroy members were made
protected. They remain inaccessible to users, as user-facing wrappers derive
from _Mo_base privately.
libstdc++-v3/ChangeLog:
* 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.
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
Reviewed-by: Patrick Palka <ppalka@redhat.com>
Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
|
|
|
|
The offset-based partial specialization of _CachedPosition for
random-access iterators is currently only selected if the offset type is
smaller than the iterator type. Before r12-1018-g46ed811bcb4b86 this
made sense since the main partial specialization only stored the
iterator (incorrectly). After that bugfix, the main partial
specialization now effectively stores a std::optional<iter> so the
size constraint is inaccurate. And this main partial specialization
must invalidate itself upon copy/move unlike the offset-based partial
specialization. So I think we should just always prefer the
offset-based _CachedPosition for a random-access iterator, even if the
offset type happens to be larger than the iterator type.
libstdc++-v3/ChangeLog:
* include/std/ranges (__detail::_CachedPosition): Remove
additional size constraint on the offset-based partial
specialization.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
|
|
This patch introduces a new function, _M_fill_append, which is invoked when
copies of the same value are appended to the end of a vector. Unlike
_M_fill_insert(end(), n, v), _M_fill_append never permute elements in place,
so it does not require:
* vector element type to be assignable;
* a copy of the inserted value, in the case where it points to an
element of the vector.
vector::resize(n, v) now uses _M_fill_append, fixing the non-conformance where
element types were required to be assignable.
In addition, _M_fill_insert(end(), n, v) now delegates to _M_fill_append, which
eliminates an unnecessary copy of v when the existing capacity is used.
PR libstdc++/90192
libstdc++-v3/ChangeLog:
* 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.
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
|
|
This patch refactors the implementation of bind_front and bind_back to avoid
using std::tuple for argument storage. Instead, bound arguments are now:
* stored directly if there is only one,
* within a dedicated _Bound_arg_storage otherwise.
_Bound_arg_storage is less expensive to instantiate and access than std::tuple.
It can also be trivially copyable, as it doesn't require a non-trivial assignment
operator for reference types. Storing a single argument directly provides similar
benefits compared to both one element tuple or _Bound_arg_storage.
_Bound_arg_storage holds each argument in an _Indexed_bound_arg base object.
The base class is parameterized by both type and index to allow storing
multiple arguments of the same type. Invocations are handled by _S_apply_front
amd _S_apply_back static functions, which simulate explicit object parameters.
To facilitate this, the __like_t alias template is now unconditionally available
since C++11 in bits/move.h.
libstdc++-v3/ChangeLog:
* 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.
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
Reviewed-by: Patrick Palka <ppalka@redhat.com>
Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
|
|
stop_source
The move constructors for stop_source and stop_token are equivalent to
copying and clearing the raw pointer, as they are wrappers for a
counted-shared state.
For jthread, the move constructor performs a member-wise move of stop_source
and thread. While std::thread could also have a _Never_valueless_alt
specialization due to its inexpensive move (only moving a handle), doing
so now would change the ABI. This patch takes the opportunity to correct
this behavior for jthread, before C++20 API is marked stable.
libstdc++-v3/ChangeLog:
* 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.
|
|
|
|
This reverts r14-905-g3b7cb33033fbe6 which disabled the use of
pthread_mutex_clocklock when TSan is active. That's no longer needed,
because GCC has TSan interceptors for pthread_mutex_clocklock since GCC
15.1 and Clang has them since 18.1.0 (released March 2024).
The interceptor was added by https://github.com/llvm/llvm-project/pull/75713
libstdc++-v3/ChangeLog:
PR libstdc++/121496
* acinclude.m4 (GLIBCXX_CHECK_PTHREAD_MUTEX_CLOCKLOCK): Do not
use _GLIBCXX_TSAN in _GLIBCXX_USE_PTHREAD_MUTEX_CLOCKLOCK macro.
* configure: Regenerate.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
|
|
The change in r14-905-g3b7cb33033fbe6 to disable the use of
pthread_mutex_clocklock when TSan is active assumed that the
_GLIBCXX_USE_PTHREAD_MUTEX_CLOCKLOCK macro was always checked with #if
rather than #ifdef, which was not true.
This makes the checks use #if consistently.
libstdc++-v3/ChangeLog:
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.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
|
|
This commit completes the implementation of P2897R7 by implementing and
testing the template class aligned_accessor.
PR libstdc++/120994
libstdc++-v3/ChangeLog:
* 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.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
Signed-off-by: Luc Grosheintz <luc.grosheintz@gmail.com>
|
|
This commit implements and tests the function is_sufficiently_aligned
from P2897R7.
PR libstdc++/120994
libstdc++-v3/ChangeLog:
* 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.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
Signed-off-by: Luc Grosheintz <luc.grosheintz@gmail.com>
|
|
When I added this explicit specialization in r14-1433-gf150a084e25eaa I
used the wrong value for the number of mantissa digits (I used 112
instead of 113). Then when I refactored it in r14-1582-g6261d10521f9fd I
used the value calculated from the incorrect value (35 instead of 36).
libstdc++-v3/ChangeLog:
PR libstdc++/121374
* include/std/limits (numeric_limits<__float128>::max_digits10):
Fix value.
* testsuite/18_support/numeric_limits/128bit.cc: Check value.
|
|
libstdc++-v3/ChangeLog:
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.
|
|
This commit implements the C++26 feature std::dims described in P2389R2.
It sets the feature testing macro to 202406 and adds tests.
Also fixes the test mdspan/version.cc
libstdc++-v3/ChangeLog:
* 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.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
Signed-off-by: Luc Grosheintz <luc.grosheintz@gmail.com>
|
|
Prior to this commit, the partial products of static extents in <mdspan>
was done in a loop that calls a function that computes the partial
product. The complexity is quadratic in the rank.
This commit removes the quadratic complexity.
libstdc++-v3/ChangeLog:
* 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.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
Signed-off-by: Luc Grosheintz <luc.grosheintz@gmail.com>
|
|
This fixes an oversight in a previous commit that improved mdspan
related code. Because __size doesn't use __fwd_prod, __fwd_prod(__rank)
is not needed anymore. Hence, one can shrink the size of
__fwd_partial_prods.
libstdc++-v3/ChangeLog:
* include/std/mdspan (__fwd_partial_prods): Reduce size of the
array by 1 element.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
Signed-off-by: Luc Grosheintz <luc.grosheintz@gmail.com>
|
|
Using __int_traits avoids the need to include <limits> from <mdspan>.
This in turn should reduce the size of the pre-compiled <mdspan>.
Similar refactoring was carried out for PR92546. Unfortunately,
./gcc/xgcc -std=c++23 -P -E -x c++ - -include mdspan | wc -l
shows a decrease by 1(!) line. This is due to bits/max_size_type.h which
includes <limits>.
libstdc++-v3/ChangeLog:
* 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.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
Signed-off-by: Luc Grosheintz <luc.grosheintz@gmail.com>
|
|
An interesting case to consider is:
bool same11(const std::extents<int, dyn, 2, 3>& e1,
const std::extents<int, dyn, dyn, 3>& e2)
{ return e1 == e2; }
Which has the following properties:
- There's no mismatching static extents, preventing any
short-circuiting.
- There's a comparison between dynamic and static extents.
- There's one trivial comparison: ... && 3 == 3.
Let E[i] denote the array of static extents, D[k] denote the array of
dynamic extents and k[i] be the index of the i-th extent in D.
(Naturally, k[i] is only meaningful if i is a dynamic extent).
The previous implementation results in assembly that's more or less a
literal translation of:
for (i = 0; i < 3; ++i)
e1 = E1[i] == -1 ? D1[k1[i]] : E1[i];
e2 = E2[i] == -1 ? D2[k2[i]] : E2[i];
if e1 != e2:
return false
return true;
While the proposed method results in assembly for
if(D1[0] == D2[0]) return false;
return 2 == D2[1];
i.e.
110: 8b 17 mov edx,DWORD PTR [rdi]
112: 31 c0 xor eax,eax
114: 39 16 cmp DWORD PTR [rsi],edx
116: 74 08 je 120 <same11+0x10>
118: c3 ret
119: 0f 1f 80 00 00 00 00 nop DWORD PTR [rax+0x0]
120: 83 7e 04 02 cmp DWORD PTR [rsi+0x4],0x2
124: 0f 94 c0 sete al
127: c3 ret
It has the following nice properties:
- It eliminated the indirection D[k[i]], because k[i] is known at
compile time. Saving us a comparison E[i] == -1 and conditionally
loading k[i].
- It eliminated the trivial condition 3 == 3.
The result is code that only loads the required values and performs
exactly the number of comparisons needed by the algorithm. It also
results in smaller object files. Therefore, this seems like a sensible
change. We've check several other examples, including fully statically
determined cases and high-rank examples. The example given above
illustrates the other cases well.
The constexpr condition:
if constexpr (!_S_is_compatible_extents<...>)
return false;
is no longer needed, because the optimizer correctly handles this case.
However, it's retained for clarity/certainty.
libstdc++-v3/ChangeLog:
* include/std/mdspan (extents::operator==): Replace loop with
pack expansion.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
Signed-off-by: Luc Grosheintz <luc.grosheintz@gmail.com>
|
|
In both fully static and dynamic extents the comparison
static_extent(i) == dynamic_extent
is known at compile time. As a result, extents::extent doesn't
need to perform the check at runtime.
An illustrative example is:
using E = std::extents<int, 3, 5, 7, 11, 13, 17>;
int required_span_size(const typename Layout::mapping<E>& m)
{ return m.required_span_size(); }
Prior to this commit the generated code (on -O2) is:
2a0: b9 01 00 00 00 mov ecx,0x1
2a5: 31 d2 xor edx,edx
2a7: 66 66 2e 0f 1f 84 00 data16 cs nop WORD PTR [rax+rax*1+0x0]
2ae: 00 00 00 00
2b2: 66 66 2e 0f 1f 84 00 data16 cs nop WORD PTR [rax+rax*1+0x0]
2b9: 00 00 00 00
2bd: 0f 1f 00 nop DWORD PTR [rax]
2c0: 48 8b 04 d5 00 00 00 mov rax,QWORD PTR [rdx*8+0x0]
2c7: 00
2c8: 48 83 f8 ff cmp rax,0xffffffffffffffff
2cc: 0f 84 00 00 00 00 je 2d2 <required_span_size_6d_static+0x32>
2d2: 83 e8 01 sub eax,0x1
2d5: 0f af 04 97 imul eax,DWORD PTR [rdi+rdx*4]
2d9: 48 83 c2 01 add rdx,0x1
2dd: 01 c1 add ecx,eax
2df: 48 83 fa 06 cmp rdx,0x6
2e3: 75 db jne 2c0 <required_span_size_6d_static+0x20>
2e5: 89 c8 mov eax,ecx
2e7: c3 ret
which is a scalar loop, and notably includes the check
308: 48 83 f8 ff cmp rax,0xffffffffffffffff
to assert that the static extent is indeed not -1. Note, that on -O3 the
optimizer eliminates the comparison; and generates a sequence of scalar
operations: lea, shl, add and mov. The aim of this commit is to
eliminate this comparison also for -O2. With the optimization applied we
get:
2e0: f3 0f 6f 0f movdqu xmm1,XMMWORD PTR [rdi]
2e4: 66 0f 6f 15 00 00 00 movdqa xmm2,XMMWORD PTR [rip+0x0]
2eb: 00
2ec: 8b 57 10 mov edx,DWORD PTR [rdi+0x10]
2ef: 66 0f 6f c1 movdqa xmm0,xmm1
2f3: 66 0f 73 d1 20 psrlq xmm1,0x20
2f8: 66 0f f4 c2 pmuludq xmm0,xmm2
2fc: 66 0f 73 d2 20 psrlq xmm2,0x20
301: 8d 14 52 lea edx,[rdx+rdx*2]
304: 66 0f f4 ca pmuludq xmm1,xmm2
308: 66 0f 70 c0 08 pshufd xmm0,xmm0,0x8
30d: 66 0f 70 c9 08 pshufd xmm1,xmm1,0x8
312: 66 0f 62 c1 punpckldq xmm0,xmm1
316: 66 0f 6f c8 movdqa xmm1,xmm0
31a: 66 0f 73 d9 08 psrldq xmm1,0x8
31f: 66 0f fe c1 paddd xmm0,xmm1
323: 66 0f 6f c8 movdqa xmm1,xmm0
327: 66 0f 73 d9 04 psrldq xmm1,0x4
32c: 66 0f fe c1 paddd xmm0,xmm1
330: 66 0f 7e c0 movd eax,xmm0
334: 8d 54 90 01 lea edx,[rax+rdx*4+0x1]
338: 8b 47 14 mov eax,DWORD PTR [rdi+0x14]
33b: c1 e0 04 shl eax,0x4
33e: 01 d0 add eax,edx
340: c3 ret
Which shows eliminating the trivial comparison, unlocks a new set of
optimizations, i.e. SIMD-vectorization. In particular, the loop has been
vectorized by loading the first four constants from aligned memory; the
first four strides from non-aligned memory, then computes the product
and reduction. It interleaves the above with computing 1 + 12*S[4] +
16*S[5] (as scalar operations) and then finishes the reduction.
A similar effect can be observed for fully dynamic extents.
libstdc++-v3/ChangeLog:
* 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.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
Signed-off-by: Luc Grosheintz <luc.grosheintz@gmail.com>
|
|
One previous commit optimized fully dynamic extents; and another
refactored __size such that __fwd_prod is valid for __r = 0, ..., rank
(exclusive).
Therefore, by noticing that __rev_prod (and __fwd_prod) never accesses
the first (or last) extent, one can avoid pre-computing partial products
of static extents in those cases, if all other extents are dynamic.
We check that the size of the reference object file decreases further
and the .rodata sections for
__fwd_prod<dyn, ..., dyn, 11>
__rev_prod<3, dyn, ..., dyn>
are absent.
libstdc++-v3/ChangeLog:
* include/std/mdspan (__fwd_prods): Relax condition for fully-dynamic
extents to cover (dyn, ..., dyn, X).
(__rev_partial_prods): Analogous for (X, dyn, ..., dyn).
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
Signed-off-by: Luc Grosheintz <luc.grosheintz@gmail.com>
|
|
In mdspan related code, for extents with no static extents, i.e. only
dynamic extents, the following simplifications can be made:
- The array of dynamic extents has size rank.
- The two arrays dynamic-index and dynamic-index-inv become
trivial, e.g. k[i] == i.
- All elements of the arrays __{fwd,rev}_partial_prods are 1.
This commits eliminates the arrays for dynamic-index, dynamic-index-inv
and __{fwd,rev}_partial_prods. It also removes the indirection k[i] == i
from the source code, which isn't as relevant because the optimizer is
(often) capable of eliminating the indirection.
To check if it's working we look at:
using E2 = std::extents<int, dyn, dyn, dyn, dyn>;
int stride_left_E2(const std::layout_left::mapping<E2>& m, size_t r)
{ return m.stride(r); }
which generates the following
0000000000000190 <stride_left_E2>:
190: 48 c1 e6 02 shl rsi,0x2
194: 74 22 je 1b8 <stride_left_E2+0x28>
196: 48 01 fe add rsi,rdi
199: b8 01 00 00 00 mov eax,0x1
19e: 66 90 xchg ax,ax
1a0: 48 63 17 movsxd rdx,DWORD PTR [rdi]
1a3: 48 83 c7 04 add rdi,0x4
1a7: 48 0f af c2 imul rax,rdx
1ab: 48 39 fe cmp rsi,rdi
1ae: 75 f0 jne 1a0 <stride_left_E2+0x10>
1b0: c3 ret
1b1: 0f 1f 80 00 00 00 00 nop DWORD PTR [rax+0x0]
1b8: b8 01 00 00 00 mov eax,0x1
1bd: c3 ret
We see that:
- There's no code to load the partial product of static extents.
- There's no indirection D[k[i]], it's just D[i] (as before).
On a test file which computes both mapping::stride(r) and
mapping::required_span_size, we check for static storage with
objdump -h
we don't see the NTTP _Extents, anything (anymore) related to
_StaticExtents, __fwd_partial_prods or __rev_partial_prods. We also
check that the size of the reference object file (described three
commits prior) reduced by a few percent from 41.9kB to 39.4kB.
libstdc++-v3/ChangeLog:
* 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.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
Signed-off-by: Luc Grosheintz <luc.grosheintz@gmail.com>
|
|
The methods layout_{left,right}::mapping::stride are defined
as
\prod_{i = 0}^r E[i]
\prod_{i = r+1}^n E[i]
This is computed as the product of a precomputed static product and the
product of the required dynamic extents.
Disassembly shows that even for low-rank extents, i.e. rank == 1 and
rank == 2, with at least one dynamic extent, the generated code loads
two values; and then runs the loop over at most one element, e.g. for
stride_left_d5 defined below the generated code is:
220: 48 8b 04 f5 00 00 00 mov rax,QWORD PTR [rsi*8+0x0]
227: 00
228: 31 d2 xor edx,edx
22a: 48 85 c0 test rax,rax
22d: 74 23 je 252 <stride_left_d5+0x32>
22f: 48 8b 0c f5 00 00 00 mov rcx,QWORD PTR [rsi*8+0x0]
236: 00
237: 48 c1 e1 02 shl rcx,0x2
23b: 74 13 je 250 <stride_left_d5+0x30>
23d: 48 01 f9 add rcx,rdi
240: 48 63 17 movsxd rdx,DWORD PTR [rdi]
243: 48 83 c7 04 add rdi,0x4
247: 48 0f af c2 imul rax,rdx
24b: 48 39 f9 cmp rcx,rdi
24e: 75 f0 jne 240 <stride_left_d5+0x20>
250: 89 c2 mov edx,eax
252: 89 d0 mov eax,edx
254: c3 ret
If there's no dynamic extents, it simply loads the precomputed product
of static extents.
For rank == 1 the answer is the constant `1`; for rank == 2 it's either 1 or
extents.extent(k), with k == 0 for layout_left and k == 1 for
layout_right.
Consider,
using Ed = std::extents<int, dyn>;
int stride_left_d(const std::layout_left::mapping<Ed>& m, size_t r)
{ return m.stride(r); }
using E3d = std::extents<int, 3, dyn>;
int stride_left_3d(const std::layout_left::mapping<E3d>& m, size_t r)
{ return m.stride(r); }
using Ed5 = std::extents<int, dyn, 5>;
int stride_left_d5(const std::layout_left::mapping<Ed5>& m, size_t r)
{ return m.stride(r); }
The optimized code for these three cases is:
0000000000000060 <stride_left_d>:
60: b8 01 00 00 00 mov eax,0x1
65: c3 ret
0000000000000090 <stride_left_3d>:
90: 48 83 fe 01 cmp rsi,0x1
94: 19 c0 sbb eax,eax
96: 83 e0 fe and eax,0xfffffffe
99: 83 c0 03 add eax,0x3
9c: c3 ret
00000000000000a0 <stride_left_d5>:
a0: b8 01 00 00 00 mov eax,0x1
a5: 48 85 f6 test rsi,rsi
a8: 74 02 je ac <stride_left_d5+0xc>
aa: 8b 07 mov eax,DWORD PTR [rdi]
ac: c3 ret
For rank == 1 it simply returns 1 (as expected). For rank == 2, it
either implements a branchless formula, or conditionally loads one
value. In all cases involving a dynamic extent this seems like it's
always doing clearly less work, both in terms of computation and loads.
In cases not involving a dynamic extent, it replaces loading one value
with a branchless sequence of four instructions.
This commit also refactors __size to no use any of the precomputed
arrays. This prevents instantiating __{fwd,rev}_partial_prods for
low-rank extents. This results in a further size reduction of a
reference object file (described two commits prior) by 9% from 46.0kB to
41.9kB.
In a prior commit we optimized __size to produce better object code by
precomputing the static products. This refactor enables the optimizer to
generate the same optimized code.
libstdc++-v3/ChangeLog:
* 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.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
Signed-off-by: Luc Grosheintz <luc.grosheintz@gmail.com>
|