178 Commits
Author SHA1 Message Date
Nathan Myers 94d5ca4583 libstdc++: container heterogeneous insertion (P2363) [PR117402]
Implements P2353R5 "Extending associative containers with the
remaining heterogeneous overloads". Adds overloads templated on
heterogeneous key types for several members of associative
containers, particularly insertions:

                      /-- unordered --\
 set  map  mset mmap set  map  mset mmap
  @    .    .    .    @    .    .    .    insert
  .    @    .    .    .    @    .    .    op[], at, try_emplace,
                                            insert_or_assign
  .    .    .    .    @    @    @    @    bucket

(Nothing is added to the multiset or multimap tree containers.)
All the insert*() and try_emplace() members also get a hinted
overload.  The at() members get const and non-const overloads.

The new overloads enforce concept __heterogeneous_tree_key or
__heterogeneous_hash_key, as in P2077, to enforce that the
function objects provided meet requirements, and that the key
supplied is not an iterator or the native key. Insertions
implicitly construct the required key_type object from the
argument, by move where permitted.

libstdc++-v3/ChangeLog:
	PR libstdc++/117402
	* include/bits/stl_map.h (operator[], at (2x), try_emplace (2x),
	insert_or_assign (2x)): Add overloads.
	* include/bits/unordered_map.h (operator[], at (2x),
	try_emplace (2x), insert_or_assign (2x), bucket (2x)): Add overloads.
	* include/bits/stl_set.h (insert (2x)): Add overloads.
	* include/bits/unordered_set.h (insert (2x), bucket (2x)): Add overloads.
	* include/bits/hashtable.h (_M_bucket_tr, _M_insert_tr): Define.
	* include/bits/hashtable_policy.h (_M_at_tr (2x)): Define.
	* include/bits/stl_tree.h (_M_emplace_here, _M_get_insert_unique_pos_tr,
	_M_get_insert_hint_unique_pos_tr): Define new heterogeneous insertion
	code path for set and map.
	* include/bits/version.def (associative_heterogeneous_insertion):
	Define.
	* include/bits/version.h: Regenerate.
	* include/std/map (__glibcxx_want_associative_heterogeneous_insertion):
	Define macro.
	* include/std/set: Same.
	* include/std/unordered_map: Same.
	* include/std/unordered_set: Same.
	* testsuite/23_containers/map/modifiers/hetero/insert.cc: New tests.
	* testsuite/23_containers/set/modifiers/hetero/insert.cc: Same.
	* testsuite/23_containers/unordered_map/modifiers/hetero/insert.cc:
	Same.
	* testsuite/23_containers/unordered_multimap/modifiers/hetero/insert.cc:
	Same.
	* testsuite/23_containers/unordered_multiset/modifiers/hetero/insert.cc:
	Same.
	* testsuite/23_containers/unordered_set/modifiers/hetero/insert.cc:
	Same.
2026-03-04 03:59:15 -05:00
Tomasz Kamiński 9b85fcc00e libstdc++: Update guards on __heterogeneous_hash_key and __heterogeneous_tree_key
The r16-7359-gae04c1afd1526a changed __heterogeneous_key to be
defined if __glibcxx_associative_heterogeneous_erasure, but missed
guards on derived __heterogeneous_hash_key and __heterogeneous_tree_key
concept.

libstdc++-v3/ChangeLog:

	* include/bits/hashtable.h (std::__heterogeneous_hash_key)
	[__glibcxx_associative_heterogeneous_erasure]: Changed guard.
	* include/bits/stl_tree.h (std::__heterogeneous_tree_key)
	[__glibcxx_associative_heterogeneous_erasure]: Likewise.
	* include/bits/stl_function.h: Add comment with C++ version
	for __glibcxx_associative_heterogeneous_erasure guard.
2026-02-06 14:06:46 +01:00
Nathan Myers 3f79055504 libstdc++: container erasure overloads (P2077) [PR117404]
Remaining to do:
 * Add new declarations in debug headers too.

Implement C++23 P2077R3 "Heterogeneous erasure overloads for
associative containers". Adds template overloads for members
erase and extract to address elements using an alternative key
type, such as string_view for a container of strings, without
need to construct an actual key object.

The new overloads enforce concept __heterogeneous_tree_key or
__heterogeneous_hash_key to verify the function objects provided
meet requirements, and that the key supplied is not an iterator
or the native key.

libstdc++-v3/ChangeLog:
	PR libstdc++/117404
	* include/bits/version.def (associative_heterogeneous_erasure):
	Define.
	* include/bits/version.h: Regenerate.
	* include/std/map: Request new feature from version.h.
	* include/std/set: Same.
	* include/std/unordered_map: Same.
	* include/std/unordered_set: Same.
	* include/bits/stl_map.h (extract, erase): Define overloads.
	* include/bits/stl_set.h: Same.
	* include/bits/stl_multimap.h: Same.
	* include/bits/stl_multiset.h: Same.
	* include/bits/unordered_map.h: Same, 2x.
	* include/bits/unordered_set.h: Same, 2x.
	* include/bits/stl_function.h (concepts __not_container_iterator,
	__heterogeneous_key): Define.
	* include/bits/hashtable.h (_M_find_before_node, _M_locate, extract):
	Delegate to more-general _tr version.
	(_M_find_before_node_tr, _M_locate_tr, _M_extract_tr, _M_erase_tr):
	Add new members to support a heterogeneous key argument.
	(_M_erase_some): Add new helper function.
	(concept __heterogeneous_hash_key): Define.
	* include/bits/stl_tree.h (_M_lower_bound_tr, _M_upper_bound_tr,
	_M_erase_tr, _M_extract_tr): Add new members to support a
	heterogeneous key argument.
	(concept __heterogeneous_tree_key): Define.
	* testsuite/23_containers/map/modifiers/hetero/erase.cc: New test.
	* testsuite/23_containers/multimap/modifiers/hetero/erase.cc: Same.
	* testsuite/23_containers/multiset/modifiers/hetero/erase.cc: Same.
	* testsuite/23_containers/set/modifiers/hetero/erase.cc: Same.
	* testsuite/23_containers/unordered_map/modifiers/hetero/erase.cc: Same.
	* testsuite/23_containers/unordered_multimap/modifiers/hetero/erase.cc:
	Same.
	* testsuite/23_containers/unordered_multiset/modifiers/hetero/erase.cc:
	Same.
	* testsuite/23_containers/unordered_set/modifiers/hetero/erase.cc: Same.
2026-02-04 17:39:51 -05:00
Jakub Jelinek 254a858ae7 Update copyright years. 2026-01-02 09:56:11 +01:00
Jonathan Wakely 9b44420488 libstdc++: Test specific feature test macros instead of __cplusplus
This changes the associative and unordered containers to check
__glibcxx_node_extract, __glibcxx_generic_associative_lookup, and
__glibcxx_generic_unordered_lookup instead of just checking the value of
__cplusplus.

libstdc++-v3/ChangeLog:

	* include/bits/hashtable.h: Check specific feature test macros
	instead of checking thevalue of __cplusplus.
	* include/bits/stl_map.h: Likewise.
	* include/bits/stl_multimap.h: Likewise.
	* include/bits/stl_multiset.h: Likewise.
	* include/bits/stl_set.h: Likewise.
	* include/bits/stl_tree.h: Likewise.
	* include/bits/unordered_map.h: Likewise.
	* include/bits/unordered_set.h: Likewise.
	* include/debug/map.h: Likewise.
	* include/debug/multimap.h: Likewise.
	* include/debug/multiset.h: Likewise.
	* include/debug/set.h: Likewise.
	* include/debug/unordered_map: Likewise.
	* include/debug/unordered_set: Likewise.

Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-10-14 15:47:20 +01:00
Jonathan Wakely ea05497d4a libstdc++: Extend constexpr if to C++14 in _Hashtable::_S_nothrow_move()
We can use diagnostic pragmas to allow the constexpr if version of this
function to be used for C++14 as well. We still need the __and_ version
for C++11 because we can't use 'if' in constexpr functions at all before
C++14.

Also use the integral_constant::value static data member instead of
invoking integral_constant::operator(), as it's a tiny bit cheaper to
compiler.

libstdc++-v3/ChangeLog:

	* include/bits/hashtable.h (_Hashtable::_S_nothrow_move): Use
	diagnostic pragmas to allow constexpr if in C++14. Use value
	member instead of operator().

Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-10-09 15:26:08 +01:00
Tomasz Kamiński 5f033bf164 libstdc++: Add P1206R7 from_range members to unordered sets [PR111055]
This is another piece of P1206R7, adding new members to std::unordered_set
and std::unordered_multiset.

	PR libstdc++/111055

libstdc++-v3/ChangeLog:

	* include/bits/hashtable.h (_M_rehash_insert)
	(_M_insert_range_multi): Extracted rehashing for range insertion
	to separate function.
	* include/bits/unordered_set.h (unordered_set): Define from_range
	constructors and insert_range member.
	(unordered_multiset) Likewise.
	* testsuite/23_containers/unordered_multiset/cons/from_range.cc:
	New test.
	* testsuite/23_containers/unordered_multiset/modifiers/insert_range.cc:
	New test.
	* testsuite/23_containers/unordered_set/cons/from_range.cc:
	New test.
	* testsuite/23_containers/unordered_set/modifiers/insert_range.cc:
	New test.

Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-03-18 15:12:53 +01:00
François Dumont bcc8dea6a4 libstdc++: [_Hashtable] Fix hash code cache usage when stateful hash functor
It is wrong to reuse a cached hash code from another container when this code depends
on the state of the container's Hash functor.

Add checks that Hash functor is stateless before reusing the cached hash code.

libstdc++-v3/ChangeLog:

	* include/bits/hashtable_policy.h
	(_Hash_code_base::_M_copy_code, _Hash_code_base::_M_store_code): Remove.
	* include/bits/hashtable.h (_M_hash_code_ext): New.
	(_M_merge_multi(_Hashtable&)): Use latter.
	(_M_copy_code): New.
	(_M_assign): Use latter.
	(_M_bucket_index_ex): New.
	(_M_equals): Use latter.
	(_M_store_code): New.
	(_M_src_hash_code): Remove key_type parameter.
	* testsuite/23_containers/unordered_map/modifiers/merge.cc (test10): New
	test case.
2025-02-25 22:27:14 +01:00
Jakub Jelinek 6441eb6dc0 Update copyright years. 2025-01-02 11:59:57 +01:00
Tamar Christina f8f686a129 libstdc++: Adjust probabilities of hashmap loop conditions
We are currently generating a loop which has more comparisons than you'd
typically need as the probablities on the small size loop are such that it
assumes the likely case is that an element is not found.

This again generates a pattern that's harder for branch predictors to follow,
but also just generates more instructions for the what one could say is the
typical case: That your hashtable contains the entry you are looking for.

This patch adds a __builtin_expect in _M_find_before_node where at the moment
the loop is optimized for the case where we don't do any iterations.

A simple testcase is (compiled with -fno-split-path to simulate the loop
in libstdc++):

#include <stdbool.h>

bool foo (int **a, int n, int val, int *tkn)
{
    for (int i = 0; i < n; i++)
    {
        if (!a[i] || a[i]==tkn)
          return false;

        if (*a[i] == val)
          return true;
    }
}

which generataes:

foo:
        cmp     w1, 0
        ble     .L1
        add     x1, x0, w1, uxtw 3
        b       .L4
.L9:
        ldr     w4, [x4]
        cmp     w4, w2
        beq     .L6
        cmp     x0, x1
        beq     .L1
.L4:
        ldr     x4, [x0]
        add     x0, x0, 8
        cmp     x4, 0
        ccmp    x4, x3, 4, ne
        bne     .L9
        mov     w0, 0
.L1:
        ret
.L6:
        mov     w0, 1
        ret

i.e. BB rotation makes is generate an unconditional branch to a conditional
branch. However this method is only called when the size is above a certain
threshold, and so it's likely that we have to do that first iteration.

Adding:

#include <stdbool.h>

bool foo (int **a, int n, int val, int *tkn)
{
    for (int i = 0; i < n; i++)
    {
        if (__builtin_expect(!a[i] || a[i]==tkn, 0))
          return false;

        if (*a[i] == val)
          return true;
    }
}

to indicate that we will likely do an iteration more generates:

foo:
        cmp     w1, 0
        ble     .L1
        add     x1, x0, w1, uxtw 3
.L4:
        ldr     x4, [x0]
        add     x0, x0, 8
        cmp     x4, 0
        ccmp    x4, x3, 4, ne
        beq     .L5
        ldr     w4, [x4]
        cmp     w4, w2
        beq     .L6
        cmp     x0, x1
        bne     .L4
.L1:
        ret
.L5:
        mov     w0, 0
        ret
.L6:
        mov     w0, 1
        ret

which results in ~0-10% extra on top of the previous patch.

In table form:

+-------------+---------------+-------+--------------------+-------------------+-----------------+
| benchmark   | Type          | Size  | Inline vs baseline | final vs baseline | final vs inline |
+-------------+---------------+-------+--------------------+-------------------+-----------------+
| find many   | uint64_t      | 11253 | -15.67%            | -22.96%           | -8.65%          |
| find many   | uint64_t      | 11253 | -16.74%            | -23.37%           | -7.96%          |
| find single | uint64_t      | 345   | -5.88%             | -11.54%           | -6.02%          |
| find many   | string        | 11253 | -4.50%             | -9.56%            | -5.29%          |
| find single | uint64_t      | 345   | -4.38%             | -9.41%            | -5.26%          |
| find single | shared string | 11253 | -6.67%             | -11.00%           | -4.64%          |
| find single | shared string | 11253 | -4.63%             | -9.03%            | -4.61%          |
| find single | shared string | 345   | -10.41%            | -14.44%           | -4.50%          |
| find many   | string        | 11253 | -3.41%             | -7.51%            | -4.24%          |
| find many   | shared string | 11253 | -2.30%             | -5.72%            | -3.50%          |
| find many   | string        | 13    | 2.86%              | -0.30%            | -3.07%          |
| find single | string        | 11253 | 4.47%              | 1.34%             | -3.00%          |
| find many   | custom string | 11253 | 0.25%              | -2.75%            | -2.99%          |
| find single | uint64_t      | 345   | 2.99%              | 0.01%             | -2.90%          |
| find single | shared string | 345   | -11.53%            | -13.67%           | -2.41%          |
| find single | uint64_t      | 11253 | 0.49%              | -1.59%            | -2.07%          |
+-------------+---------------+-------+--------------------+-------------------+-----------------+

libstdc++-v3/ChangeLog:

	* include/bits/hashtable.h
	(_M_find_before_node): Make it likely that the map has at least one
	entry and so we do at least one iteration.
2024-12-18 18:12:42 +00:00
Tamar Christina 18aff7644a libstdc++: Add inline keyword to _M_locate
In GCC 12 there was a ~40% regression in the performance of hashmap->find.

This regression came about accidentally:

Before GCC 12 the find function was small enough that IPA would inline it even
though it wasn't marked inline.  In GCC-12 an optimization was added to perform
a linear search when the entries in the hashmap are small.

This increased the size of the function enough that IPA would no longer inline.
Inlining had two benefits:

1.  The return value is a reference. so it has to be returned and dereferenced
    even though the search loop may have already dereference it.
2.  The pattern is a hard pattern to track for branch predictors.  This causes
    a large number of branch misses if the value is immediately checked and
    branched on. i.e. if (a != m.end()) which is a common pattern.

The patch fixes both these issues by adding the inline keyword to _M_locate
to allow the inliner to consider inlining again.

This and the other patches have been ran through serveral benchmarks where
the size, number of elements searched for and type (reference vs value) etc
were tested.

The change shows no statistical regression, but an average find improvement of
~27% and a range between ~10-60% improvements.  A selection of the results:

+-----------+--------------------+-------+----------+
| Group     | Benchmark          | Size  | % Inline |
+-----------+--------------------+-------+----------+
| Find      | unord<uint64_t     | 11274 | 53.52%   |
| Find      | unord<uint64_t     | 11254 | 47.98%   |
| Find Mult | unord<uint64_t     | 12    | 47.62%   |
| Find Mult | unord<std::string  | 12    | 44.94%   |
| Find Mult | unord<std::string  | 10    | 44.89%   |
| Find Mult | unord<uint64_t     | 11    | 40.90%   |
| Find Mult | unord<uint64_t     | 352   | 30.57%   |
| Find      | unord<uint64_t     | 351   | 28.27%   |
| Find Mult | unord<uint64_t     | 342   | 26.80%   |
| Find      | unord<std::string  | 12    | 25.66%   |
| Find Mult | unord<std::string  | 352   | 23.12%   |
| Find      | unord<std::string  | 13    | 20.36%   |
| Find Mult | unord<std::string  | 355   | 19.23%   |
| Find      | unord<std::string  | 353   | 18.59%   |
| Find      | unord<uint64_t     | 350   | 15.43%   |
| Find      | unord<std::string  | 11260 | 11.80%   |
| Find      | unord<std::string  | 352   | 11.12%   |
| Find      | unord<std::string  | 11262 | 9.97%    |
+-----------+--------------------+-------+----------+

libstdc++-v3/ChangeLog:

	* include/bits/hashtable.h: Inline _M_locate.
2024-12-18 09:03:37 +00:00
Jonathan Wakely 689d4abc0b libstdc++: Further simplify _Hashtable inheritance hierarchy
The main change here is using [[no_unique_address]] instead of the Empty
Base-class Optimization. Using the attribute allows us to use data
members instead of base-classes. That simplifies the inheritance
hierarchy, which means less work for the compiler. It also means that
ADL has fewer associated classes and associated namespaces to consider,
further reducing the work the compiler has to do.

Reducing the differences between the _Hashtable_ebo_helper primary
template and the partial specialization means we no longer need to use
member functions to access the stored object, because it's now always a
data member called _M_obj.  This means we can also remove a number of
other helper functions that were using those member functions to access
the object, for example we can swap the _Hash and _Equal objects
directly in _Hashtable::swap instead of calling _Hashtable_base::_M_swap
which then calls _Hash_code_base::_M_swap.

Although [[no_unique_address]] would allow us to reduce the size for
empty types that are also 'final', doing so would be an ABI break
because those types were previously excluded from using the EBO. So we
still need the _Hashtable_ebo_helper class template and a partial
specialization, so that we only use the attribute under exactly the same
conditions as we previously used the EBO. This could be avoided with a
non-standard [[no_unique_address(expr)]] attribute that took a boolean
condition, or with reflection and token sequence injection, but we don't
have either of those things.

Because _Hashtable_ebo_helper is no longer used as a base-class we don't
need to disambiguate possible identical bases, so it doesn't need an
integral non-type template parameter.

libstdc++-v3/ChangeLog:

	* include/bits/hashtable.h (_Hashtable::swap): Swap hash
	function and equality predicate here. Inline allocator swap
	instead of using __alloc_on_swap.
	* include/bits/hashtable_policy.h (_Hashtable_ebo_helper):
	Replace EBO with no_unique_address attribute. Remove NTTP.
	(_Hash_code_base): Replace base class with data member using
	no_unique_address attribute.
	(_Hash_code_base::_M_swap): Remove.
	(_Hash_code_base::_M_hash): Remove.
	(_Hashtable_base): Replace base class with data member using
	no_unique_address attribute.
	(_Hashtable_base::_M_swap): Remove.
	(_Hashtable_alloc): Replace base class with data member using
	no_unique_address attribute.
2024-12-16 14:05:09 +00:00
Jonathan Wakely 4484945c53 libstdc++: Fix std::unordered_set::emplace optimization [PR117686]
The __is_key_type specialization that matches a pair<key_type, T>
argument is intended for std::unordered_map, not for
std::unordered_set<std::pair<K,T>>.

This uses a pair<const Args&...> as the template argument for
__is_key_type, so that it won't match a set's key_type.

libstdc++-v3/ChangeLog:

	PR libstdc++/117686
	* include/bits/hashtable.h (_Hashtable::_M_emplace_uniq):
	Adjust usage of __is_key_type to avoid false positive.
	* testsuite/23_containers/unordered_set/insert/117686.cc:
	New test.
2024-11-20 06:44:43 +00:00
Jonathan Wakely dffc37dead libstdc++: Fix invalid casts in unordered container merge functions
François pointed out that static_cast<__node_ptr>(&_M_before_begin) is
invalid, because _M_before_begin is only a node-base not a node.

Refactor the new merge overloads to only cast when we know we have a
valid node.

He also pointed out some optimizations to allow reusing hash codes that
might be cached in the node. The _M_src_hash_code function already has
the right logic to decide when a cached hash code can be reused by a
different _Hashtable object.

libstdc++-v3/ChangeLog:

	* include/bits/hashtable.h (_Hashtable::_M_src_hash_code):
	Improve comments.
	(_Hashtable::_M_merge_unique(_Hashtable&)): Use pointer_traits
	to get before-begin pointer. Only use static_cast on valid
	nodes, not the before-begin pointer. Reuse a hash code cached in
	the node when possible.
	(_Hashtable::_M_merge_multi(_Hashtable&)): Likewise.

Reviewed-by: François Dumont <fdumont@gcc.gnu.org>
2024-11-18 08:22:27 +00:00
Jonathan Wakely 84e39b0750 libstdc++: Add _Hashtable::_M_locate(const key_type&)
We have two overloads of _M_find_before_node but they have quite
different performance characteristics, which isn't necessarily obvious.

The original version, _M_find_before_node(bucket, key, hash_code), looks
only in the specified bucket, doing a linear search within that bucket
for an element that compares equal to the key. This is the typical fast
lookup for hash containers, assuming the load factor is low so that each
bucket isn't too large.

The newer _M_find_before_node(key) was added in r12-6272-ge3ef832a9e8d6a
and could be naively assumed to calculate the hash code and bucket for
key and then call the efficient _M_find_before_node(bkt, key, code)
function. But in fact it does a linear search of the entire container.
This is potentially very slow and should only be used for a suitably
small container, as determined by the __small_size_threshold() function.
We don't even have a comment pointing out this O(N) performance of the
newer overload.

Additionally, the newer overload is only ever used in exactly one place,
which would suggest it could just be removed. However there are several
places that do the linear search of the whole container with an explicit
loop each time.

This adds a new member function, _M_locate, and uses it to replace most
uses of _M_find_node and the loops doing linear searches. This new
member function does both forms of lookup, the linear search for small
sizes and the _M_find_node(bkt, key, code) lookup within a single
bucket. The new function returns a __location_type which is a struct
that contains a pointer to the first node matching the key (if such a
node is present), or the hash code and bucket index for the key. The
hash code and bucket index allow the caller to know where a new node
with that key should be inserted, for the cases where the lookup didn't
find a matching node.

The result struct actually contains a pointer to the node *before* the
one that was located, as that is needed for it to be useful in erase and
extract members. There is a member function that returns the found node,
i.e. _M_before->_M_nxt downcast to __node_ptr, which should be used in
most cases.

This new function greatly simplifies the functions that currently have
to do two kinds of lookup and explicitly check the current size against
the small size threshold.

Additionally, now that try_emplace is defined directly in _Hashtable
(not in _Insert_base) we can use _M_locate in there too, to speed up
some try_emplace calls. Previously it did not do the small-size linear
search.

It would be possible to add a function to get a __location_type from an
iterator, and then rewrite some functions like _M_erase and
_M_extract_node to take a __location_type parameter. While that might be
conceptually nice, it wouldn't really make the code any simpler or more
readable than it is now. That isn't done in this change.

libstdc++-v3/ChangeLog:

	* include/bits/hashtable.h (__location_type): New struct.
	(_M_locate): New member function.
	(_M_find_before_node(const key_type&)): Remove.
	(_M_find_node): Move variable initialization into condition.
	(_M_find_node_tr): Likewise.
	(operator=(initializer_list<T>), try_emplace, _M_reinsert_node)
	(_M_merge_unique, find, erase(const key_type&)): Use _M_locate
	for lookup.
2024-11-13 20:21:41 +00:00
Jonathan Wakely a147bfcaf1 libstdc++: Simplify _Hashtable merge functions
I realised that _M_merge_unique and _M_merge_multi call extract(iter)
which then has to call _M_get_previous_node to iterate through the
bucket to find the node before the one iter points to. Since the merge
function is already iterating over the entire container, we had the
previous node a moment ago. Walking the whole bucket to find it again is
wasteful. We could just rewrite the loop in terms of node pointers
instead of iterators, and then call _M_extract_node directly. However,
this is only possible when the source container is the same type as the
destination, because otherwise we can't access the source's private
members (_M_before_begin, _M_begin, _M_extract_node etc.)

Add overloads of _M_merge_unique and _M_merge_multi that work with
source containers of the same type, to enable this optimization.

For both overloads of _M_merge_unique we can also remove the conditional
modifications to __n_elt and just consistently decrement it for every
element processed. Use a multiplier of one or zero that dictates whether
__n_elt is passed to _M_insert_unique_node or not. We can also remove
the repeated calls to size() and just keep track of the size in a local
variable.

Although _M_merge_unique and _M_merge_multi should be safe for
"self-merge", i.e. when doing c.merge(c), it's wasteful to search/insert
every element when we don't need to do anything. Add 'this == &source'
checks to the overloads taking an lvalue of the container's own type.
Because those checks aren't needed for the rvalue overloads, change
those to call the underlying _M_merge_xxx function directly instead of
going through the lvalue overload that checks the address.

I've also added more extensive tests for better coverage of the new
overloads added in this commit.

libstdc++-v3/ChangeLog:

	* include/bits/hashtable.h (_M_merge_unique): Add overload for
	merging from same type.
	(_M_merge_unique<Compatible>): Simplify size tracking. Add
	comment.
	(_M_merge_multi): Add overload for merging from same type.
	(_M_merge_multi<Compatible>): Add comment.
	* include/bits/unordered_map.h (unordered_map::merge): Check for
	self-merge in the lvalue overload. Call _M_merge_unique directly
	for the rvalue overload.
	(unordered_multimap::merge): Likewise.
	* include/bits/unordered_set.h (unordered_set::merge): Likewise.
	(unordered_multiset::merge): Likewise.
	* testsuite/23_containers/unordered_map/modifiers/merge.cc:
	Add more tests.
	* testsuite/23_containers/unordered_multimap/modifiers/merge.cc:
	Likewise.
	* testsuite/23_containers/unordered_multiset/modifiers/merge.cc:
	Likewise.
	* testsuite/23_containers/unordered_set/modifiers/merge.cc:
	Likewise.
2024-11-13 20:21:41 +00:00
Jonathan Wakely 247e82c72f libstdc++: Remove _Equality base class from _Hashtable
libstdc++-v3/ChangeLog:

	* include/bits/hashtable.h (_Hashtable): Remove _Equality base
	class.
	(_Hashtable::_M_equal): Define equality comparison here instead
	of in _Equality::_M_equal.
	* include/bits/hashtable_policy.h (_Equality): Remove.
2024-11-13 20:21:40 +00:00
Jonathan Wakely 0935d0d6e6 libstdc++: Remove _Insert base class from _Hashtable
There's no reason to have a separate base class defining the insert
member functions now. They can all be moved into the _Hashtable class,
which simplifies them slightly.

libstdc++-v3/ChangeLog:

	* include/bits/hashtable.h (_Hashtable): Remove inheritance from
	__detail::_Insert and move its members into _Hashtable.
	* include/bits/hashtable_policy.h (__detail::_Insert): Remove.

Reviewed-by: François Dumont <fdumont@gcc.gnu.org>
2024-11-13 20:21:40 +00:00
Jonathan Wakely d2970e86c4 libstdc++: Use RAII in _Hashtable
Use scoped guard types to clean up if an exception is thrown. This
allows some try-catch blocks to be removed.

libstdc++-v3/ChangeLog:

	* include/bits/hashtable.h (operator=(const _Hashtable&)): Use
	RAII instead of try-catch.
	(_M_assign(_Ht&&, _NodeGenerator&)): Likewise.

Reviewed-by: François Dumont <fdumont@gcc.gnu.org>
2024-11-13 20:21:40 +00:00
Jonathan Wakely e717c322c6 libstdc++: Replace _Hashtable::__fwd_value_for with cast
We can just use a cast to the appropriate type instead of calling a
function to do it. This gives the compiler less work to compile and
optimize, and at -O0 avoids a function call per element.

libstdc++-v3/ChangeLog:

	* include/bits/hashtable.h (_Hashtable::__fwd_value_for):
	Remove.
	(_Hashtable::_M_assign): Use static_cast instead of
	__fwd_value_for.

Reviewed-by: François Dumont <fdumont@gcc.gnu.org>
2024-11-13 20:21:39 +00:00
Jonathan Wakely 37b17388fc libstdc++: Add _Hashtable::_M_assign for the common case
This adds a convenient _M_assign overload for the common case where the
node generator is the _AllocNode type. Only two places need to call
_M_assign with a _ReuseOrAllocNode node generator, so all the other
calls to _M_assign can use the new overload instead of manually
constructing a node generator.

The _AllocNode::operator(Args&&...) function doesn't need to be a
variadic template. It is only ever called with a single argument of type
const value_type& or value_type&&, so could be simplified. That isn't
done in this commit.

libstdc++-v3/ChangeLog:

	* include/bits/hashtable.h (_Hashtable): Remove typedefs for
	node generators.
	(_Hashtable::_M_assign(_Ht&&)): Add new overload.
	(_Hashtable::operator=(initializer_list<value_type>)): Add local
	typedef for node generator.
	(_Hashtable::_M_assign_elements): Likewise.
	(_Hashtable::operator=(const _Hashtable&)): Use new _M_assign
	overload.
	(_Hashtable(const _Hashtable&)): Likewise.
	(_Hashtable(const _Hashtable&, const allocator_type&)):
	Likewise.
	(_Hashtable(_Hashtable&&, __node_alloc_type&&, false_type)):
	Likewise.
	* include/bits/hashtable_policy.h (_Insert): Remove typedef for
	node generator.

Reviewed-by: François Dumont <fdumont@gcc.gnu.org>
2024-11-13 20:21:39 +00:00
Jonathan Wakely 73676cfb20 libstdc++: Refactor Hashtable erasure
This reworks the internal member functions for erasure from
unordered containers, similarly to the earlier commit doing it for
insertion.

Instead of multiple overloads of _M_erase which are selected via tag
dispatching, the erase(const key_type&) member can use 'if constexpr' to
choose an appropriate implementation (returning after erasing a single
element for unique keys, or continuing to erase all equivalent elements
for non-unique keys).

libstdc++-v3/ChangeLog:

	* include/bits/hashtable.h (_Hashtable::_M_erase): Remove
	overloads for erasing by key, moving logic to ...
	(_Hashtable::erase): ... here.

Reviewed-by: François Dumont <fdumont@gcc.gnu.org>
2024-11-13 20:21:39 +00:00
Jonathan Wakely ce2cf1f032 libstdc++: Refactor Hashtable insertion [PR115285]
This completely reworks the internal member functions for insertion into
unordered containers. Currently we use a mixture of tag dispatching (for
unique vs non-unique keys) and template specialization (for maps vs
sets) to correctly implement insert and emplace members.

This removes a lot of complexity and indirection by using 'if constexpr'
to select the appropriate member function to call.

Previously there were four overloads of _M_emplace, for unique keys and
non-unique keys, and for hinted insertion and non-hinted. However two of
those were redundant, because we always ignore the hint for unique keys
and always use a hint for non-unique keys. Those four overloads have
been replaced by two new non-overloaded function templates:
_M_emplace_uniq and _M_emplace_multi. The former is for unique keys and
doesn't take a hint, and the latter is for non-unique keys and takes a
hint.

In the body of _M_emplace_uniq there are special cases to handle
emplacing values from which a key_type can be extracted directly. This
means we don't need to allocate a node and construct a value_type that
might be discarded if an equivalent key is already present. The special
case applies when emplacing the key_type into std::unordered_set, or
when emplacing std::pair<cv key_type, X> into std::unordered_map, or
when emplacing two values into std::unordered_map where the first has
type cv key_type. For the std::unordered_set case, obviously if we're
inserting something that's already the key_type, we can look it up
directly. For the std::unordered_map cases, we know that the inserted
std::pair<const key_type, mapped_type> would have its first element
initialized from first member of a std::pair value, or from the first of
two values, so if that is a key_type, we can look that up directly.

All the _M_insert overloads used a node generator parameter, but apart
from the one case where _M_insert_range was called from
_Hashtable::operator=(initializer_list<value_type>), that parameter was
always the _AllocNode type, never the _ReuseOrAllocNode type. Because
operator=(initializer_list<value_type>) was rewritten in an earlier
commit, all calls to _M_insert now use _AllocNode, so there's no reason
to pass the generator as a template parameter when inserting.

The multiple overloads of _Hashtable::_M_insert can all be removed now,
because the _Insert_base::insert members now call either _M_emplace_uniq
or _M_emplace_multi directly, only passing a hint to the latter. Which
one to call is decided using 'if constexpr (__unique_keys::value)' so
there is no unnecessary code instantiation, and overload resolution is
much simpler.

The partial specializations of the _Insert class template can be
entirely removed, moving the minor differences in 'insert' member
functions into the common _Insert_base base class. The different
behaviour for maps and sets can be implemented using enable_if
constraints and 'if constexpr'. With the _Insert class template no
longer needed, the _Insert_base class template can be renamed to
_Insert. This is a minor simplification for the complex inheritance
hierarchy used by _Hashtable, removing one base class. It also means
one less class template instantiation, and no need to match the right
partial specialization of _Insert. The _Insert base class could be
removed entirely by moving all its 'insert' members into _Hashtable,
because without any variation in specializations of _Insert there is no
reason to use a base class to define those members. That is left for a
later commit.

Consistently using _M_emplace_uniq or _M_emplace_multi for insertion
means we no longer attempt to avoid constructing a value_type object to
find its key, removing the PR libstdc++/96088 optimizations. This fixes
the bugs caused by those optimizations, such as PR libstdc++/115285, but
causes regressions in the expected number of allocations and temporary
objects constructed for the PR 96088 tests.  It should be noted that the
"regressions" in the 96088 tests put us exactly level with the number of
allocations done by libc++ for those same tests.

To mitigate this to some extent, _M_emplace_uniq detects when the
emplace arguments already contain a key_type (either as the sole
argument, for unordered_set, or as the first part of a pair of
arguments, for unordered_map). In that specific case we don't need to
allocate a node and construct a value type to check for an existing
element with equivalent key.

The remaining regressions in the number of allocations and temporaries
should be addressed separately, with more conservative optimizations
specific to std::string. That is not part of this commit.

libstdc++-v3/ChangeLog:

	PR libstdc++/115285
	* include/bits/hashtable.h (_Hashtable::_M_emplace): Replace
	with _M_emplace_uniq and _M_emplace_multi.
	(_Hashtable::_S_forward_key, _Hashtable::_M_insert_unique)
	(_Hashtable::_M_insert_unique_aux, _Hashtable::_M_insert):
	Remove.
	* include/bits/hashtable_policy.h (_ConvertToValueType):
	Remove.
	(_Insert_base::_M_insert_range): Remove overload for unique keys
	and rename overload for non-unique keys to ...
	(_Insert_base::_M_insert_range_multi): ... this.
	(_Insert_base::insert): Call _M_emplace_uniq or _M_emplace_multi
	instead of _M_insert.  Add insert overloads from _Insert.
	(_Insert_base): Rename to _Insert.
	(_Insert): Remove
	* testsuite/23_containers/unordered_map/96088.cc: Adjust
	expected number of allocations.
	* testsuite/23_containers/unordered_set/96088.cc: Likewise.
2024-11-13 20:21:39 +00:00
Jonathan Wakely 9fcbbb3d10 libstdc++: Refactor _Hashtable::operator=(initializer_list<value_type>)
This replaces a call to _M_insert_range with open coding the loop. This
will allow removing the node generator parameter from _M_insert_range in
a later commit.

libstdc++-v3/ChangeLog:

	* include/bits/hashtable.h (operator=(initializer_list)):
	Refactor to not use _M_insert_range.

Reviewed-by: François Dumont <fdumont@gcc.gnu.org>
2024-11-13 20:21:38 +00:00
Jonathan Wakely 7e1d9f5885 libstdc++: Make some _Hashtable members inline
libstdc++-v3/ChangeLog:

	* include/bits/hashtable.h (_Hashtable): Add 'inline' to some
	one-line constructors.

Reviewed-by: François Dumont <fdumont@gcc.gnu.org>
2024-11-08 15:23:41 +00:00
Jonathan Wakely e97179bacd libstdc++: Improve comment for _Hashtable::_M_insert_unique_node
Clarify the effects if rehashing is needed. Document the __n_elt
parameter.

libstdc++-v3/ChangeLog:

	* include/bits/hashtable.h (_M_insert_unique_node): Improve
	comment.
2024-11-07 21:58:31 +00:00
Jonathan Wakely 90c578654a libstdc++: Fix conversions to key/value types for hash table insertion [PR115285]
The conversions to key_type and value_type that are performed when
inserting into _Hashtable need to be fixed to do any required
conversions explicitly. The current code assumes that conversions from
the parameter to the key_type or value_type can be done implicitly,
which isn't necessarily true.

Remove the _S_forward_key function which doesn't handle all cases and
either forward the parameter if it already has type cv key_type, or
explicitly construct a temporary of type key_type.

Similarly, the _ConvertToValueType specialization for maps doesn't
handle all cases either, for std::pair arguments only some value
categories are handled. Remove _ConvertToValueType and for the _M_insert
function for unique keys, either forward the argument unchanged or
explicitly construct a temporary of type value_type.

For the _M_insert overload for non-unique keys we don't need any
conversion at all, we can just forward the argument directly to where we
construct a node.

libstdc++-v3/ChangeLog:

	PR libstdc++/115285
	* include/bits/hashtable.h (_Hashtable::_S_forward_key): Remove.
	(_Hashtable::_M_insert_unique_aux): Replace _S_forward_key with
	a static_cast to a type defined using conditional_t.
	(_Hashtable::_M_insert): Replace _ConvertToValueType with a
	static_cast to a type defined using conditional_t.
	* include/bits/hashtable_policy.h (_ConvertToValueType): Remove.
	* testsuite/23_containers/unordered_map/insert/115285.cc: New test.
	* testsuite/23_containers/unordered_set/insert/115285.cc: New test.
	* testsuite/23_containers/unordered_set/96088.cc: Adjust
	expected number of allocations.
2024-11-07 21:58:31 +00:00
Jonathan Wakely c26e83918b libstdc++: Fix grammar in comment, again
libstdc++-v3/ChangeLog:

	* include/bits/hashtable.h (_Hashtable): Fix comment grammar.
2024-11-07 21:58:31 +00:00
Jonathan Wakely 6a6b8b847b libstdc++: Tweak comments on includes in hashtable headers
std::is_permutation is only used in <bits/hashtable.h> not in
<bits/hashtable_policy.h>, so move the comment referring to it.

libstdc++-v3/ChangeLog:

	* include/bits/hashtable.h: Add is_permutation to comment.
	* include/bits/hashtable_policy.h: Remove it from comment.
2024-11-07 15:47:07 +00:00
Jonathan Wakely bcf40c70f8 libstdc++: Fix typo in comment in hashtable.h
And tweak grammar in a couple of comments.

libstdc++-v3/ChangeLog:

	* include/bits/hashtable.h: Fix spelling in comment.
2024-11-07 15:47:07 +00:00
Jonathan Wakely db798ee38a libstdc++: Minor comment improvements in <bits/hashtable.h>
libstdc++-v3/ChangeLog:

	* include/bits/hashtable.h: Improve comments.
2024-11-01 20:36:53 +00:00
Jakub Jelinek 45ab93d9af non-gcc: Remove trailing whitespace
I've tried to build stage3 with
-Wleading-whitespace=blanks -Wtrailing-whitespace=blank -Wno-error=leading-whitespace=blanks -Wno-error=trailing-whitespace=blank
added to STRICT_WARN and that expectably resulted in about
2744 unique trailing whitespace warnings and 124837 leading whitespace
warnings when excluding *.md files (which obviously is in big part a
generator issue).  Others from that are generator related, I think those
need to be solved later.

The following patch just fixes up the easy case (trailing whitespace),
which could be easily automated:
for i in `find . -name \*.h -o -name \*.cc -o -name \*.c | xargs grep -l '[ 	]$' | grep -v testsuite/`; do sed -i -e 's/[ 	]*$//' $i; done
I've excluded files which I knew are obviously generated or go FE.

Is there anything else we'd want to avoid the changes?

Due to patch size, I've split it between gcc/ part
and rest (include/, libiberty/, libgcc/, libcpp/, libstdc++-v3/;
this part).

2024-10-24  Jakub Jelinek  <jakub@redhat.com>

include/
	* dyn-string.h: Remove trailing whitespace.
	* libiberty.h: Likewise.
	* xregex.h: Likewise.
	* splay-tree.h: Likewise.
	* partition.h: Likewise.
	* plugin-api.h: Likewise.
	* demangle.h: Likewise.
	* vtv-change-permission.h: Likewise.
	* fibheap.h: Likewise.
	* hsa_ext_image.h: Likewise.
	* hashtab.h: Likewise.
	* libcollector.h: Likewise.
	* sort.h: Likewise.
	* symcat.h: Likewise.
	* hsa_ext_amd.h: Likewise.
libcpp/
	* directives.cc: Remove trailing whitespace.
	* mkdeps.cc: Likewise.
	* line-map.cc: Likewise.
	* internal.h: Likewise.
	* files.cc: Likewise.
	* init.cc: Likewise.
	* makeucnid.cc: Likewise.
	* system.h: Likewise.
	* include/line-map.h: Likewise.
	* include/symtab.h: Likewise.
	* include/cpplib.h: Likewise.
	* expr.cc: Likewise.
	* charset.cc: Likewise.
	* macro.cc: Likewise.
	* errors.cc: Likewise.
	* lex.cc: Likewise.
	* traditional.cc: Likewise.
libgcc/
	* crtstuff.c: Remove trailing whitespace.
	* libgcov.h: Likewise.
	* config/alpha/crtfastmath.c: Likewise.
	* config/alpha/vms-gcc_shell_handler.c: Likewise.
	* config/alpha/vms-unwind.h: Likewise.
	* config/pa/linux-atomic.c: Likewise.
	* config/pa/linux-unwind.h: Likewise.
	* config/pa/quadlib.c: Likewise.
	* config/pa/fptr.c: Likewise.
	* config/s390/32/_fixsfdi.c: Likewise.
	* config/s390/32/_fixunssfdi.c: Likewise.
	* config/s390/32/_fixunsdfdi.c: Likewise.
	* config/c6x/pr-support.c: Likewise.
	* config/lm32/_udivsi3.c: Likewise.
	* config/lm32/libgcc_lm32.h: Likewise.
	* config/lm32/_udivmodsi4.c: Likewise.
	* config/lm32/_mulsi3.c: Likewise.
	* config/lm32/_modsi3.c: Likewise.
	* config/lm32/_umodsi3.c: Likewise.
	* config/lm32/_divsi3.c: Likewise.
	* config/darwin-crt3.c: Likewise.
	* config/msp430/mpy.c: Likewise.
	* config/ia64/tf-signs.c: Likewise.
	* config/ia64/fde-vms.c: Likewise.
	* config/ia64/unwind-ia64.c: Likewise.
	* config/ia64/vms-unwind.h: Likewise.
	* config/ia64/sfp-exceptions.c: Likewise.
	* config/ia64/quadlib.c: Likewise.
	* config/ia64/unwind-ia64.h: Likewise.
	* config/rl78/vregs.h: Likewise.
	* config/arm/bpabi.c: Likewise.
	* config/arm/unwind-arm.c: Likewise.
	* config/arm/pr-support.c: Likewise.
	* config/arm/linux-atomic.c: Likewise.
	* config/arm/bpabi-lib.h: Likewise.
	* config/frv/frvend.c: Likewise.
	* config/frv/cmovw.c: Likewise.
	* config/frv/frvbegin.c: Likewise.
	* config/frv/cmovd.c: Likewise.
	* config/frv/cmovh.c: Likewise.
	* config/aarch64/cpuinfo.c: Likewise.
	* config/i386/crtfastmath.c: Likewise.
	* config/i386/cygming-crtend.c: Likewise.
	* config/i386/32/tf-signs.c: Likewise.
	* config/i386/crtprec.c: Likewise.
	* config/i386/sfp-exceptions.c: Likewise.
	* config/i386/w32-unwind.h: Likewise.
	* config/m32r/initfini.c: Likewise.
	* config/sparc/crtfastmath.c: Likewise.
	* config/gcn/amdgcn_veclib.h: Likewise.
	* config/nios2/linux-atomic.c: Likewise.
	* config/nios2/linux-unwind.h: Likewise.
	* config/nios2/lib2-mul.c: Likewise.
	* config/nios2/lib2-nios2.h: Likewise.
	* config/xtensa/unwind-dw2-xtensa.c: Likewise.
	* config/rs6000/darwin-fallback.c: Likewise.
	* config/rs6000/ibm-ldouble.c: Likewise.
	* config/rs6000/sfp-machine.h: Likewise.
	* config/rs6000/darwin-asm.h: Likewise.
	* config/rs6000/darwin-crt2.c: Likewise.
	* config/rs6000/aix-unwind.h: Likewise.
	* config/rs6000/sfp-exceptions.c: Likewise.
	* config/gthr-vxworks.c: Likewise.
	* config/riscv/atomic.c: Likewise.
	* config/visium/memcpy.c: Likewise.
	* config/darwin-crt-tm.c: Likewise.
	* config/stormy16/lib2funcs.c: Likewise.
	* config/arc/ieee-754/divtab-arc-sf.c: Likewise.
	* config/arc/ieee-754/divtab-arc-df.c: Likewise.
	* config/arc/initfini.c: Likewise.
	* config/sol2/gmon.c: Likewise.
	* config/microblaze/divsi3_table.c: Likewise.
	* config/m68k/fpgnulib.c: Likewise.
	* libgcov-driver.c: Likewise.
	* unwind-dw2.c: Likewise.
	* fp-bit.c: Likewise.
	* dfp-bit.h: Likewise.
	* dfp-bit.c: Likewise.
	* libgcov-driver-system.c: Likewise.
libgcc/config/libbid/
	* _le_td.c: Remove trailing whitespace.
	* bid128_compare.c: Likewise.
	* bid_div_macros.h: Likewise.
	* bid64_to_bid128.c: Likewise.
	* bid64_to_uint32.c: Likewise.
	* bid128_to_uint64.c: Likewise.
	* bid64_div.c: Likewise.
	* bid128_round_integral.c: Likewise.
	* bid_binarydecimal.c: Likewise.
	* bid128_string.c: Likewise.
	* bid_flag_operations.c: Likewise.
	* bid128_to_int64.c: Likewise.
	* _mul_sd.c: Likewise.
	* bid64_mul.c: Likewise.
	* bid128_noncomp.c: Likewise.
	* _gt_dd.c: Likewise.
	* bid64_add.c: Likewise.
	* bid64_string.c: Likewise.
	* bid_from_int.c: Likewise.
	* bid128.c: Likewise.
	* _ge_dd.c: Likewise.
	* _ne_sd.c: Likewise.
	* _dd_to_td.c: Likewise.
	* _unord_sd.c: Likewise.
	* bid64_to_uint64.c: Likewise.
	* _gt_sd.c: Likewise.
	* _sd_to_td.c: Likewise.
	* _addsub_td.c: Likewise.
	* _ne_td.c: Likewise.
	* bid_dpd.c: Likewise.
	* bid128_add.c: Likewise.
	* bid128_next.c: Likewise.
	* _lt_sd.c: Likewise.
	* bid64_next.c: Likewise.
	* bid128_mul.c: Likewise.
	* _lt_dd.c: Likewise.
	* _ge_td.c: Likewise.
	* _unord_dd.c: Likewise.
	* bid64_sqrt.c: Likewise.
	* bid_sqrt_macros.h: Likewise.
	* bid64_fma.c: Likewise.
	* _sd_to_dd.c: Likewise.
	* bid_conf.h: Likewise.
	* bid64_noncomp.c: Likewise.
	* bid_gcc_intrinsics.h: Likewise.
	* _gt_td.c: Likewise.
	* _ge_sd.c: Likewise.
	* bid128_minmax.c: Likewise.
	* bid128_quantize.c: Likewise.
	* bid32_to_bid64.c: Likewise.
	* bid_round.c: Likewise.
	* _td_to_sd.c: Likewise.
	* bid_inline_add.h: Likewise.
	* bid128_fma.c: Likewise.
	* _eq_td.c: Likewise.
	* bid32_to_bid128.c: Likewise.
	* bid64_rem.c: Likewise.
	* bid128_2_str_tables.c: Likewise.
	* _mul_dd.c: Likewise.
	* _dd_to_sd.c: Likewise.
	* bid128_div.c: Likewise.
	* _lt_td.c: Likewise.
	* bid64_compare.c: Likewise.
	* bid64_to_int32.c: Likewise.
	* _unord_td.c: Likewise.
	* bid128_rem.c: Likewise.
	* bid_internal.h: Likewise.
	* bid64_to_int64.c: Likewise.
	* _eq_dd.c: Likewise.
	* _td_to_dd.c: Likewise.
	* bid128_to_int32.c: Likewise.
	* bid128_to_uint32.c: Likewise.
	* _ne_dd.c: Likewise.
	* bid64_quantize.c: Likewise.
	* _le_dd.c: Likewise.
	* bid64_round_integral.c: Likewise.
	* _le_sd.c: Likewise.
	* bid64_minmax.c: Likewise.
libgcc/config/avr/libf7/
	* f7-renames.h: Remove trailing whitespace.
libstdc++-v3/
	* include/debug/debug.h: Remove trailing whitespace.
	* include/parallel/base.h: Likewise.
	* include/parallel/types.h: Likewise.
	* include/parallel/settings.h: Likewise.
	* include/parallel/multiseq_selection.h: Likewise.
	* include/parallel/partition.h: Likewise.
	* include/parallel/random_number.h: Likewise.
	* include/parallel/find_selectors.h: Likewise.
	* include/parallel/partial_sum.h: Likewise.
	* include/parallel/list_partition.h: Likewise.
	* include/parallel/search.h: Likewise.
	* include/parallel/algorithmfwd.h: Likewise.
	* include/parallel/random_shuffle.h: Likewise.
	* include/parallel/multiway_mergesort.h: Likewise.
	* include/parallel/sort.h: Likewise.
	* include/parallel/algobase.h: Likewise.
	* include/parallel/numericfwd.h: Likewise.
	* include/parallel/multiway_merge.h: Likewise.
	* include/parallel/losertree.h: Likewise.
	* include/bits/basic_ios.h: Likewise.
	* include/bits/stringfwd.h: Likewise.
	* include/bits/ostream_insert.h: Likewise.
	* include/bits/stl_heap.h: Likewise.
	* include/bits/unordered_map.h: Likewise.
	* include/bits/hashtable_policy.h: Likewise.
	* include/bits/stl_iterator_base_funcs.h: Likewise.
	* include/bits/valarray_before.h: Likewise.
	* include/bits/regex.h: Likewise.
	* include/bits/postypes.h: Likewise.
	* include/bits/stl_iterator.h: Likewise.
	* include/bits/localefwd.h: Likewise.
	* include/bits/stl_algo.h: Likewise.
	* include/bits/ios_base.h: Likewise.
	* include/bits/stl_function.h: Likewise.
	* include/bits/basic_string.h: Likewise.
	* include/bits/hashtable.h: Likewise.
	* include/bits/valarray_after.h: Likewise.
	* include/bits/char_traits.h: Likewise.
	* include/bits/gslice.h: Likewise.
	* include/bits/locale_facets_nonio.h: Likewise.
	* include/bits/mask_array.h: Likewise.
	* include/bits/specfun.h: Likewise.
	* include/bits/random.h: Likewise.
	* include/bits/slice_array.h: Likewise.
	* include/bits/valarray_array.h: Likewise.
	* include/tr1/float.h: Likewise.
	* include/tr1/functional_hash.h: Likewise.
	* include/tr1/math.h: Likewise.
	* include/tr1/hashtable_policy.h: Likewise.
	* include/tr1/stdio.h: Likewise.
	* include/tr1/complex.h: Likewise.
	* include/tr1/stdbool.h: Likewise.
	* include/tr1/stdarg.h: Likewise.
	* include/tr1/inttypes.h: Likewise.
	* include/tr1/fenv.h: Likewise.
	* include/tr1/stdlib.h: Likewise.
	* include/tr1/wchar.h: Likewise.
	* include/tr1/tgmath.h: Likewise.
	* include/tr1/limits.h: Likewise.
	* include/tr1/wctype.h: Likewise.
	* include/tr1/stdint.h: Likewise.
	* include/tr1/ctype.h: Likewise.
	* include/tr1/random.h: Likewise.
	* include/tr1/shared_ptr.h: Likewise.
	* include/ext/mt_allocator.h: Likewise.
	* include/ext/sso_string_base.h: Likewise.
	* include/ext/debug_allocator.h: Likewise.
	* include/ext/vstring_fwd.h: Likewise.
	* include/ext/pointer.h: Likewise.
	* include/ext/pod_char_traits.h: Likewise.
	* include/ext/malloc_allocator.h: Likewise.
	* include/ext/vstring.h: Likewise.
	* include/ext/bitmap_allocator.h: Likewise.
	* include/ext/pool_allocator.h: Likewise.
	* include/ext/type_traits.h: Likewise.
	* include/ext/ropeimpl.h: Likewise.
	* include/ext/codecvt_specializations.h: Likewise.
	* include/ext/throw_allocator.h: Likewise.
	* include/ext/extptr_allocator.h: Likewise.
	* include/ext/atomicity.h: Likewise.
	* include/ext/concurrence.h: Likewise.
	* include/c_compatibility/wchar.h: Likewise.
	* include/c_compatibility/stdint.h: Likewise.
	* include/backward/hash_fun.h: Likewise.
	* include/backward/binders.h: Likewise.
	* include/backward/hashtable.h: Likewise.
	* include/backward/auto_ptr.h: Likewise.
	* libsupc++/eh_arm.cc: Likewise.
	* libsupc++/unwind-cxx.h: Likewise.
	* libsupc++/si_class_type_info.cc: Likewise.
	* libsupc++/vec.cc: Likewise.
	* libsupc++/class_type_info.cc: Likewise.
	* libsupc++/vmi_class_type_info.cc: Likewise.
	* libsupc++/guard_error.cc: Likewise.
	* libsupc++/bad_typeid.cc: Likewise.
	* libsupc++/eh_personality.cc: Likewise.
	* libsupc++/atexit_arm.cc: Likewise.
	* libsupc++/pmem_type_info.cc: Likewise.
	* libsupc++/vterminate.cc: Likewise.
	* libsupc++/eh_terminate.cc: Likewise.
	* libsupc++/bad_cast.cc: Likewise.
	* libsupc++/exception_ptr.h: Likewise.
	* libsupc++/eh_throw.cc: Likewise.
	* libsupc++/bad_alloc.cc: Likewise.
	* libsupc++/nested_exception.cc: Likewise.
	* libsupc++/pointer_type_info.cc: Likewise.
	* libsupc++/pbase_type_info.cc: Likewise.
	* libsupc++/bad_array_new.cc: Likewise.
	* libsupc++/pure.cc: Likewise.
	* libsupc++/eh_exception.cc: Likewise.
	* libsupc++/bad_array_length.cc: Likewise.
	* libsupc++/cxxabi.h: Likewise.
	* libsupc++/guard.cc: Likewise.
	* libsupc++/eh_catch.cc: Likewise.
	* libsupc++/cxxabi_forced.h: Likewise.
	* libsupc++/tinfo.h: Likewise.
2024-10-25 10:03:17 +02:00
François Dumont ee030b2800 libstdc++: Always instantiate key_type to compute hash code [PR115285]
Even if it is possible to compute a hash code from the inserted arguments
we need to instantiate the key_type to guaranty hash code consistency.

Preserve the lazy instantiation of the mapped_type in the context of
associative containers.

libstdc++-v3/ChangeLog:

	PR libstdc++/115285
	* include/bits/hashtable.h (_S_forward_key<_Kt>): Always return a temporary
	key_type instance.
	* testsuite/23_containers/unordered_map/96088.cc: Adapt to additional instanciation.
	Also check that mapped_type is not instantiated when there is no insertion.
	* testsuite/23_containers/unordered_multimap/96088.cc: Adapt to additional
	instanciation.
	* testsuite/23_containers/unordered_multiset/96088.cc: Likewise.
	* testsuite/23_containers/unordered_set/96088.cc: Likewise.
	* testsuite/23_containers/unordered_set/pr115285.cc: New test case.
2024-10-23 06:25:21 +02:00
François Dumont ccb6e08a4d libstdc++: [_Hashtable] Fix some implementation inconsistencies
Get rid of the different usages of the mutable keyword except in
_Prime_rehash_policy where it is preserved for abi compatibility reason.

Fix comment to explain that we need the computation of bucket index noexcept
to be able to rehash the container when needed.

For Standard instantiations through std::unordered_xxx containers we already
force caching of hash code when hash functor is not noexcep so it is guarantied.

The static_assert purpose in _Hashtable on _M_bucket_index is thus limited
to usages of _Hashtable with exotic _Hashtable_traits.

libstdc++-v3/ChangeLog:

	* include/bits/hashtable_policy.h (_NodeBuilder<>::_S_build): Remove
	const qualification on _NodeGenerator instance.
	(_ReuseOrAllocNode<>::operator()(_Args&&...)): Remove const qualification.
	(_ReuseOrAllocNode<>::_M_nodes): Remove mutable.
	(_Insert_base<>::_M_insert_range): Remove _NodeGetter const qualification.
	(_Hash_code_base<>::_M_bucket_index(const _Hash_node_value<>&, size_t)):
	Simplify noexcept declaration, we already static_assert that _RangeHash functor
	is noexcept.
	* include/bits/hashtable.h: Rework comments. Remove const qualifier on
	_NodeGenerator& arguments.

Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
2024-10-03 06:44:21 +02:00
Jason Merrill 63a598deb0 libstdc++: #ifdef out #pragma GCC system_header
In r15-3714-gd3a7302ec5985a I added -Wsystem-headers to the libstdc++ build
flags to help catch problems in the library.  This patch takes a different
approach, of disabling the #pragma system_header unless _GLIBCXX_SYSHDR is
defined.  As a result, the testsuites will treat them as non-system-headers
to get better warning coverage during regression testing of both gcc and
libstdc++, not just when building the library.

My rationale for the #ifdef instead of just removing the #pragma is the
three G++ tests that want to test libstdc++ system header behavior, so we
need a way to select it.

This doesn't affect installed libraries, as they get their
system-header status from the lookup path.  But testsuite_flags
--build-includes gives -I directives rather than -isystem.

This patch doesn't change the headers in config/ because I'm not compiling
with most of them, so won't see any warnings that need fixing.  Adjusting
them could happen later, or we can not bother.

libstdc++-v3/ChangeLog:

	* acinclude.m4 (WARN_FLAGS): Remove -Wsystem-headers.
	* configure: Regenerate.
	* include/bits/algorithmfwd.h: #ifdef out #pragma GCC system_header.
	* include/bits/atomic_base.h
	* include/bits/atomic_futex.h
	* include/bits/atomic_timed_wait.h
	* include/bits/atomic_wait.h
	* include/bits/basic_ios.h
	* include/bits/basic_string.h
	* include/bits/boost_concept_check.h
	* include/bits/char_traits.h
	* include/bits/charconv.h
	* include/bits/chrono.h
	* include/bits/chrono_io.h
	* include/bits/codecvt.h
	* include/bits/concept_check.h
	* include/bits/cpp_type_traits.h
	* include/bits/elements_of.h
	* include/bits/enable_special_members.h
	* include/bits/erase_if.h
	* include/bits/forward_list.h
	* include/bits/functional_hash.h
	* include/bits/gslice.h
	* include/bits/gslice_array.h
	* include/bits/hashtable.h
	* include/bits/indirect_array.h
	* include/bits/invoke.h
	* include/bits/ios_base.h
	* include/bits/iterator_concepts.h
	* include/bits/locale_classes.h
	* include/bits/locale_facets.h
	* include/bits/locale_facets_nonio.h
	* include/bits/localefwd.h
	* include/bits/mask_array.h
	* include/bits/max_size_type.h
	* include/bits/memory_resource.h
	* include/bits/memoryfwd.h
	* include/bits/move_only_function.h
	* include/bits/node_handle.h
	* include/bits/ostream_insert.h
	* include/bits/out_ptr.h
	* include/bits/parse_numbers.h
	* include/bits/postypes.h
	* include/bits/quoted_string.h
	* include/bits/range_access.h
	* include/bits/ranges_base.h
	* include/bits/refwrap.h
	* include/bits/sat_arith.h
	* include/bits/semaphore_base.h
	* include/bits/slice_array.h
	* include/bits/std_abs.h
	* include/bits/std_function.h
	* include/bits/std_mutex.h
	* include/bits/std_thread.h
	* include/bits/stl_iterator_base_funcs.h
	* include/bits/stl_iterator_base_types.h
	* include/bits/stl_tree.h
	* include/bits/stream_iterator.h
	* include/bits/streambuf_iterator.h
	* include/bits/stringfwd.h
	* include/bits/this_thread_sleep.h
	* include/bits/unique_lock.h
	* include/bits/uses_allocator_args.h
	* include/bits/utility.h
	* include/bits/valarray_after.h
	* include/bits/valarray_array.h
	* include/bits/valarray_before.h
	* include/bits/version.h
	* include/c_compatibility/fenv.h
	* include/c_compatibility/inttypes.h
	* include/c_compatibility/stdint.h
	* include/decimal/decimal.h
	* include/experimental/bits/net.h
	* include/experimental/bits/shared_ptr.h
	* include/ext/aligned_buffer.h
	* include/ext/alloc_traits.h
	* include/ext/atomicity.h
	* include/ext/concurrence.h
	* include/ext/numeric_traits.h
	* include/ext/pod_char_traits.h
	* include/ext/pointer.h
	* include/ext/stdio_filebuf.h
	* include/ext/stdio_sync_filebuf.h
	* include/ext/string_conversions.h
	* include/ext/type_traits.h
	* include/ext/vstring.h
	* include/ext/vstring_fwd.h
	* include/ext/vstring_util.h
	* include/parallel/algorithmfwd.h
	* include/parallel/numericfwd.h
	* include/tr1/functional_hash.h
	* include/tr1/hashtable.h
	* include/tr1/random.h
	* libsupc++/exception.h
	* libsupc++/hash_bytes.h
	* include/bits/basic_ios.tcc
	* include/bits/basic_string.tcc
	* include/bits/fstream.tcc
	* include/bits/istream.tcc
	* include/bits/locale_classes.tcc
	* include/bits/locale_facets.tcc
	* include/bits/locale_facets_nonio.tcc
	* include/bits/ostream.tcc
	* include/bits/sstream.tcc
	* include/bits/streambuf.tcc
	* include/bits/string_view.tcc
	* include/bits/version.tpl
	* include/experimental/bits/string_view.tcc
	* include/ext/pb_ds/detail/resize_policy/hash_prime_size_policy_imp.hpp
	* include/ext/random.tcc
	* include/ext/vstring.tcc
	* include/tr2/bool_set.tcc
	* include/tr2/dynamic_bitset.tcc
	* include/bits/c++config
	* include/c/cassert
	* include/c/cctype
	* include/c/cerrno
	* include/c/cfloat
	* include/c/ciso646
	* include/c/climits
	* include/c/clocale
	* include/c/cmath
	* include/c/csetjmp
	* include/c/csignal
	* include/c/cstdarg
	* include/c/cstddef
	* include/c/cstdio
	* include/c/cstdlib
	* include/c/cstring
	* include/c/ctime
	* include/c/cuchar
	* include/c/cwchar
	* include/c/cwctype
	* include/c_global/cassert
	* include/c_global/ccomplex
	* include/c_global/cctype
	* include/c_global/cerrno
	* include/c_global/cfenv
	* include/c_global/cfloat
	* include/c_global/cinttypes
	* include/c_global/ciso646
	* include/c_global/climits
	* include/c_global/clocale
	* include/c_global/cmath
	* include/c_global/csetjmp
	* include/c_global/csignal
	* include/c_global/cstdalign
	* include/c_global/cstdarg
	* include/c_global/cstdbool
	* include/c_global/cstddef
	* include/c_global/cstdint
	* include/c_global/cstdio
	* include/c_global/cstdlib
	* include/c_global/cstring
	* include/c_global/ctgmath
	* include/c_global/ctime
	* include/c_global/cuchar
	* include/c_global/cwchar
	* include/c_global/cwctype
	* include/c_std/cassert
	* include/c_std/cctype
	* include/c_std/cerrno
	* include/c_std/cfloat
	* include/c_std/ciso646
	* include/c_std/climits
	* include/c_std/clocale
	* include/c_std/cmath
	* include/c_std/csetjmp
	* include/c_std/csignal
	* include/c_std/cstdarg
	* include/c_std/cstddef
	* include/c_std/cstdio
	* include/c_std/cstdlib
	* include/c_std/cstring
	* include/c_std/ctime
	* include/c_std/cuchar
	* include/c_std/cwchar
	* include/c_std/cwctype
	* include/debug/array
	* include/debug/bitset
	* include/debug/deque
	* include/debug/forward_list
	* include/debug/list
	* include/debug/map
	* include/debug/set
	* include/debug/string
	* include/debug/unordered_map
	* include/debug/unordered_set
	* include/debug/vector
	* include/decimal/decimal
	* include/experimental/algorithm
	* include/experimental/any
	* include/experimental/array
	* include/experimental/buffer
	* include/experimental/chrono
	* include/experimental/contract
	* include/experimental/deque
	* include/experimental/executor
	* include/experimental/filesystem
	* include/experimental/forward_list
	* include/experimental/functional
	* include/experimental/internet
	* include/experimental/io_context
	* include/experimental/iterator
	* include/experimental/list
	* include/experimental/map
	* include/experimental/memory
	* include/experimental/memory_resource
	* include/experimental/net
	* include/experimental/netfwd
	* include/experimental/numeric
	* include/experimental/propagate_const
	* include/experimental/ratio
	* include/experimental/regex
	* include/experimental/scope
	* include/experimental/set
	* include/experimental/socket
	* include/experimental/string
	* include/experimental/string_view
	* include/experimental/synchronized_value
	* include/experimental/system_error
	* include/experimental/timer
	* include/experimental/tuple
	* include/experimental/type_traits
	* include/experimental/unordered_map
	* include/experimental/unordered_set
	* include/experimental/vector
	* include/ext/algorithm
	* include/ext/cmath
	* include/ext/functional
	* include/ext/iterator
	* include/ext/memory
	* include/ext/numeric
	* include/ext/random
	* include/ext/rb_tree
	* include/ext/rope
	* include/parallel/algorithm
	* include/std/algorithm
	* include/std/any
	* include/std/array
	* include/std/atomic
	* include/std/barrier
	* include/std/bit
	* include/std/bitset
	* include/std/charconv
	* include/std/chrono
	* include/std/codecvt
	* include/std/complex
	* include/std/concepts
	* include/std/condition_variable
	* include/std/coroutine
	* include/std/deque
	* include/std/execution
	* include/std/expected
	* include/std/filesystem
	* include/std/format
	* include/std/forward_list
	* include/std/fstream
	* include/std/functional
	* include/std/future
	* include/std/generator
	* include/std/iomanip
	* include/std/ios
	* include/std/iosfwd
	* include/std/iostream
	* include/std/istream
	* include/std/iterator
	* include/std/latch
	* include/std/limits
	* include/std/list
	* include/std/locale
	* include/std/map
	* include/std/memory
	* include/std/memory_resource
	* include/std/mutex
	* include/std/numbers
	* include/std/numeric
	* include/std/optional
	* include/std/ostream
	* include/std/print
	* include/std/queue
	* include/std/random
	* include/std/ranges
	* include/std/ratio
	* include/std/regex
	* include/std/scoped_allocator
	* include/std/semaphore
	* include/std/set
	* include/std/shared_mutex
	* include/std/span
	* include/std/spanstream
	* include/std/sstream
	* include/std/stack
	* include/std/stacktrace
	* include/std/stdexcept
	* include/std/streambuf
	* include/std/string
	* include/std/string_view
	* include/std/syncstream
	* include/std/system_error
	* include/std/text_encoding
	* include/std/thread
	* include/std/tuple
	* include/std/type_traits
	* include/std/typeindex
	* include/std/unordered_map
	* include/std/unordered_set
	* include/std/utility
	* include/std/valarray
	* include/std/variant
	* include/std/vector
	* include/std/version
	* include/tr1/array
	* include/tr1/cfenv
	* include/tr1/cinttypes
	* include/tr1/cmath
	* include/tr1/complex
	* include/tr1/cstdbool
	* include/tr1/cstdint
	* include/tr1/cstdio
	* include/tr1/cstdlib
	* include/tr1/cwchar
	* include/tr1/cwctype
	* include/tr1/functional
	* include/tr1/memory
	* include/tr1/random
	* include/tr1/regex
	* include/tr1/tuple
	* include/tr1/type_traits
	* include/tr1/unordered_map
	* include/tr1/unordered_set
	* include/tr1/utility
	* include/tr2/bool_set
	* include/tr2/dynamic_bitset
	* include/tr2/type_traits
	* libsupc++/atomic_lockfree_defines.h
	* libsupc++/compare
	* libsupc++/cxxabi.h
	* libsupc++/cxxabi_forced.h
	* libsupc++/cxxabi_init_exception.h
	* libsupc++/exception
	* libsupc++/initializer_list
	* libsupc++/new
	* libsupc++/typeinfo: Likewise.
	* testsuite/20_util/ratio/operations/ops_overflow_neg.cc
	* testsuite/23_containers/array/tuple_interface/get_neg.cc
	* testsuite/23_containers/vector/cons/destructible_debug_neg.cc
	* testsuite/24_iterators/operations/prev_neg.cc
	* testsuite/ext/type_traits/add_unsigned_floating_neg.cc
	* testsuite/ext/type_traits/add_unsigned_integer_neg.cc
	* testsuite/ext/type_traits/remove_unsigned_floating_neg.cc
	* testsuite/ext/type_traits/remove_unsigned_integer_neg.cc: Adjust
	line numbers.

gcc/testsuite/ChangeLog

	* g++.dg/analyzer/fanalyzer-show-events-in-system-headers-default.C
	* g++.dg/analyzer/fanalyzer-show-events-in-system-headers-no.C
	* g++.dg/diagnostic/disable.C: #define _GLIBCXX_SYSHDR.
2024-09-25 08:20:45 -04:00
Jason Merrill d3a7302ec5 libstdc++: add #pragma diagnostic
The use of #pragma GCC system_header in libstdc++ has led to bugs going
undetected for a while due to the silencing of compiler warnings that would
have revealed them promptly, and also interferes with warnings about
problematic template instantiations induced by user code.

But removing it, or even compiling with -Wsystem-header, is also problematic
due to warnings about deliberate uses of extensions.

So this patch adds #pragma GCC diagnostic as needed to suppress these
warnings.

The change to acinclude.m4 changes -Wabi to warn only in comparison to ABI
19, to avoid lots of warnings that we now mangle concept requirements, which
are in any case still experimental.  I checked for any other changes against
ABI v15, and found only the <format> lambda mangling, which we can ignore.

This also enables -Wsystem-headers while building the library, so we see any
warnings not silenced by these #pragmas.

libstdc++-v3/ChangeLog:

	* include/bits/algorithmfwd.h:
	* include/bits/allocator.h:
	* include/bits/codecvt.h:
	* include/bits/concept_check.h:
	* include/bits/cpp_type_traits.h:
	* include/bits/hashtable.h:
	* include/bits/iterator_concepts.h:
	* include/bits/ostream_insert.h:
	* include/bits/ranges_base.h:
	* include/bits/regex_automaton.h:
	* include/bits/std_abs.h:
	* include/bits/stl_algo.h:
	* include/c_compatibility/fenv.h:
	* include/c_compatibility/inttypes.h:
	* include/c_compatibility/stdint.h:
	* include/ext/concurrence.h:
	* include/ext/type_traits.h:
	* testsuite/ext/type_traits/add_unsigned_floating_neg.cc:
	* testsuite/ext/type_traits/add_unsigned_integer_neg.cc:
	* testsuite/ext/type_traits/remove_unsigned_floating_neg.cc:
	* testsuite/ext/type_traits/remove_unsigned_integer_neg.cc:
	* include/bits/basic_ios.tcc:
	* include/bits/basic_string.tcc:
	* include/bits/fstream.tcc:
	* include/bits/istream.tcc:
	* include/bits/locale_classes.tcc:
	* include/bits/locale_facets.tcc:
	* include/bits/ostream.tcc:
	* include/bits/regex_compiler.tcc:
	* include/bits/sstream.tcc:
	* include/bits/streambuf.tcc:
	* configure: Regenerate.
	* include/bits/c++config:
	* include/c/cassert:
	* include/c/cctype:
	* include/c/cerrno:
	* include/c/cfloat:
	* include/c/climits:
	* include/c/clocale:
	* include/c/cmath:
	* include/c/csetjmp:
	* include/c/csignal:
	* include/c/cstdarg:
	* include/c/cstddef:
	* include/c/cstdio:
	* include/c/cstdlib:
	* include/c/cstring:
	* include/c/ctime:
	* include/c/cwchar:
	* include/c/cwctype:
	* include/c_global/climits:
	* include/c_global/cmath:
	* include/c_global/cstddef:
	* include/c_global/cstdlib:
	* include/decimal/decimal:
	* include/ext/rope:
	* include/std/any:
	* include/std/charconv:
	* include/std/complex:
	* include/std/coroutine:
	* include/std/format:
	* include/std/iomanip:
	* include/std/limits:
	* include/std/numbers:
	* include/tr1/functional:
	* include/tr1/tuple:
	* include/tr1/type_traits:
	* libsupc++/compare:
	* libsupc++/new: Add #pragma GCC diagnostic to suppress
	undesired warnings.
	* acinclude.m4: Change -Wabi version from 2 to 19.

gcc/ChangeLog:

	* ginclude/stdint-wrap.h: Add #pragma GCC diagnostic to suppress
	undesired warnings.
	* gsyslimits.h: Likewise.
2024-09-19 10:23:16 -04:00
Jonathan Wakely cc38bdf093 libstdc++: Improve diagnostics for invalid std::hash specializations [PR115420]
When using a key type without a valid std::hash specialization the
unordered containers give confusing diagnostics about the default
constructor being deleted. Add a static_assert that will fail for
disabled std::hash specializations (and for a subset of custom hash
functions).

libstdc++-v3/ChangeLog:

	PR libstdc++/115420
	* include/bits/hashtable.h (_Hashtable): Add static_assert to
	check that hash function is copy constructible.
	* testsuite/23_containers/unordered_map/115420.cc: New test.
2024-06-13 14:08:36 +01:00
Jonathan Wakely 3f2f9059c7 libstdc++: Do not use memset in _Hashtable::clear()
Using memset is incorrect if the __bucket_ptr type is non-trivial, or
does not use an all-zero bit pattern for its null value.

Replace the three uses of memset with std::fill_n to set the pointers to
nullptr.

libstdc++-v3/ChangeLog:

	* include/bits/hashtable.h (_Hashtable::clear): Do not use
	memset to zero out bucket pointers.
	(_Hashtable::_M_assign_elements): Likewise.
2024-06-12 15:06:47 +01:00
François Dumont 6ef8881772 libstdc++: [_Hashtable] Optimize destructor
Hashtable destructor do not need to call clear() method that in addition to
destroying all nodes also reset all buckets to nullptr.

libstdc++-v3/ChangeLog:

	* include/bits/hashtable.h (~_Hashtable()): Replace clear call with
	a _M_deallocate_nodes call.
2024-06-10 18:57:32 +02:00
Jonathan Wakely c2e28df90a libstdc++: Destroy allocators in re-inserted container nodes [PR114401]
The allocator objects in container node handles were not being destroyed
after the node was re-inserted into a container. They are stored in a
union and so need to be explicitly destroyed when the node becomes
empty. The containers were zeroing the node handle's pointer, which
makes it empty, causing the handle's destructor to think there's nothign
to clean up.

Add a new member function to the node handle which destroys the
allocator and zeros the pointer. Change the containers to call that
instead of just changing the pointer manually.

We can also remove the _M_empty member of the union which is not
necessary.

libstdc++-v3/ChangeLog:

	PR libstdc++/114401
	* include/bits/hashtable.h (_Hashtable::_M_reinsert_node): Call
	release() on node handle instead of just zeroing its pointer.
	(_Hashtable::_M_reinsert_node_multi): Likewise.
	(_Hashtable::_M_merge_unique): Likewise.
	(_Hashtable::_M_merge_multi): Likewise.
	* include/bits/node_handle.h (_Node_handle_common::release()):
	New member function.
	(_Node_handle_common::_Optional_alloc::_M_empty): Remove
	unnecessary union member.
	(_Node_handle_common): Declare _Hashtable as a friend.
	* include/bits/stl_tree.h (_Rb_tree::_M_reinsert_node_unique):
	Call release() on node handle instead of just zeroing its
	pointer.
	(_Rb_tree::_M_reinsert_node_equal): Likewise.
	(_Rb_tree::_M_reinsert_node_hint_unique): Likewise.
	(_Rb_tree::_M_reinsert_node_hint_equal): Likewise.
	* testsuite/23_containers/multiset/modifiers/114401.cc: New test.
	* testsuite/23_containers/set/modifiers/114401.cc: New test.
	* testsuite/23_containers/unordered_multiset/modifiers/114401.cc: New test.
	* testsuite/23_containers/unordered_set/modifiers/114401.cc: New test.
2024-03-22 22:39:06 +00:00
Huanghui NieandThéo Papadopoulo ec0a68b9ee libstdc++: [_Hashtable] Remove useless check for _M_before_begin node
When removing the first node of a bucket it is useless to check if this bucket
is the one containing the _M_before_begin node. The bucket before-begin node is
already transfered to the next pointed-to bucket regardeless if it is the container
before-begin node.

libstdc++-v3/ChangeLog:

	* include/bits/hashtable.h (_Hahstable<>::_M_remove_bucket_begin): Remove
	_M_before_begin check and cleanup implementation.

Co-authored-by: Théo Papadopoulo  <papadopoulo@gmail.com>
2024-01-24 06:36:04 +01:00
Jakub Jelinek a945c346f5 Update copyright years. 2024-01-03 12:19:35 +01:00
François Dumont 505110bb91 libstdc++: [_Hashtable] Extend the small size optimization
A number of methods were still not using the small size optimization which
is to prefer an O(N) research to a hash computation as long as N is small.

libstdc++-v3/ChangeLog:

	* include/bits/hashtable.h: Move comment about all equivalent values
	being next to each other in the class documentation header.
	(_M_reinsert_node, _M_merge_unique): Implement small size optimization.
	(_M_find_tr, _M_count_tr, _M_equal_range_tr): Likewise.
2023-12-31 18:00:29 +01:00
Jonathan Wakely 7ffa63df8f libstdc++: Only declare feature test macros in standard headers
This change moves the definitions of feature test macros (or strictly
speaking, the requests for <bits/version.h> to define them) so that only
standard headers define them. For example, <bits/shared_ptr.h> will no
longer define macros related to std::shared_ptr, only <memory> and
<version> will define them. This means that __cpp_lib_shared_ptr_arrays
will not be defined by <future> or by other headers that include
<bits/shared_ptr.h>. It will only be defined when <memory> has been
included. This will discourage users from relying on transitive
includes.

As a result, internal headers that need to query the macros should use
the internal macros like __glibcxx_shared_ptr_arrays instead of
__cpp_lib_shared_ptr_arrays, as those internal macros are defined by the
internal headers after icluding <bits/version.h>. There are some
exceptions to this rule, because __cpp_lib_is_constant_evaluated is
defined by bits/c++config.h and so is available everywhere, and
__cpp_lib_three_way_comparison is defined by <compare> which several
headers are explicitly specified to include, so its macro is guaranteed
to be usable too.

N.B. not many internal headers actually need an explicit include of
<bits/version.h>, because most of them include <type_traits> and so get
all the __glibcxx_foo internal macros from there.

libstdc++-v3/ChangeLog:

	* include/bits/algorithmfwd.h: Do not define standard feature
	test macro here.
	* include/bits/align.h: Likewise. Test internal macros instead
	of standard macros.
	* include/bits/alloc_traits.h: Likewise.
	* include/bits/allocator.h: Likewise.
	* include/bits/atomic_base.h: Likewise.
	* include/bits/atomic_timed_wait.h: Likewise.
	* include/bits/atomic_wait.h: Likewise.
	* include/bits/basic_string.h: Likewise.
	* include/bits/basic_string.tcc: Likewise.
	* include/bits/char_traits.h: Likewise.
	* include/bits/chrono.h: Likewise.
	* include/bits/cow_string.h: Likewise.
	* include/bits/forward_list.h: Likewise.
	* include/bits/hashtable.h: Likewise.
	* include/bits/ios_base.h: Likewise.
	* include/bits/memory_resource.h: Likewise.
	* include/bits/move.h: Likewise.
	* include/bits/move_only_function.h: Likewise.
	* include/bits/node_handle.h: Likewise.
	* include/bits/ptr_traits.h: Likewise.
	* include/bits/range_access.h: Likewise.
	* include/bits/ranges_algo.h: Likewise.
	* include/bits/ranges_cmp.h: Likewise.
	* include/bits/ranges_util.h: Likewise.
	* include/bits/semaphore_base.h: Likewise.
	* include/bits/shared_ptr.h: Likewise.
	* include/bits/shared_ptr_atomic.h: Likewise.
	* include/bits/shared_ptr_base.h: Likewise.
	* include/bits/stl_algo.h: Likewise.
	* include/bits/stl_algobase.h: Likewise.
	* include/bits/stl_function.h: Likewise.
	* include/bits/stl_iterator.h: Likewise.
	* include/bits/stl_list.h: Likewise.
	* include/bits/stl_map.h: Likewise.
	* include/bits/stl_pair.h: Likewise.
	* include/bits/stl_queue.h: Likewise.
	* include/bits/stl_stack.h: Likewise.
	* include/bits/stl_tree.h: Likewise.
	* include/bits/stl_uninitialized.h: Likewise.
	* include/bits/stl_vector.h: Likewise.
	* include/bits/unique_ptr.h: Likewise.
	* include/bits/unordered_map.h: Likewise.
	* include/bits/uses_allocator_args.h: Likewise.
	* include/bits/utility.h: Likewise.
	* include/bits/erase_if.h: Add comment.
	* include/std/algorithm: Define standard feature test macros
	here.
	* include/std/atomic: Likewise.
	* include/std/array: Likewise.
	* include/std/chrono: Likewise.
	* include/std/condition_variable: Likewise.
	* include/std/deque: Likewise.
	* include/std/format: Likewise.
	* include/std/functional: Likewise.
	* include/std/forward_list: Likewise.
	* include/std/ios: Likewise.
	* include/std/iterator: Likewise.
	* include/std/list: Likewise.
	* include/std/map: Likewise.
	* include/std/memory: Likewise.
	* include/std/numeric: Likewise.
	* include/std/queue: Likewise.
	* include/std/ranges: Likewise.
	* include/std/regex: Likewise.
	* include/std/set: Likewise.
	* include/std/stack: Likewise.
	* include/std/stop_token: Likewise.
	* include/std/string: Likewise.
	* include/std/string_view:
	* include/std/tuple: Likewise.
	* include/std/unordered_map:
	* include/std/unordered_set:
	* include/std/utility: Likewise.
	* include/std/vector: Likewise.
	* include/std/scoped_allocator: Query internal macros instead of
	standard macros.
2023-11-16 08:10:19 +00:00
François Dumont c4cf9aa247 libstdc++: [_Hashtable] Use RAII type to manage rehash functor state
Replace usage of __try/__catch with a RAII type to restore rehash functor
state when needed.

libstdc++-v3/ChangeLog:

	* include/bits/hashtable_policy.h (_RehashStateGuard): New.
	(_Insert_base<>::_M_insert_range(_IIt, _IIt, const _NodeGet&, false_type)):
	Adapt.
	* include/bits/hashtable.h (__rehash_guard_t): New.
	(__rehash_state): Remove.
	(_M_rehash): Remove.
	(_M_rehash_aux): Rename into _M_rehash.
	(_M_assign_elements, _M_insert_unique_node, _M_insert_multi_node): Adapt.
	(rehash): Adapt.
2023-11-09 19:16:35 +01:00
François Dumont c714b4d30d libstdc++: [_Hashtable] Do not reuse untrusted cached hash code
On merge, reuse a merged node's possibly cached hash code only if we are on the
same type of hash and this hash is stateless.

Usage of function pointers or std::function as hash functor will prevent reusing
cached hash code.

libstdc++-v3/ChangeLog

	* include/bits/hashtable_policy.h
	(_Hash_code_base::_M_hash_code(const _Hash&, const _Hash_node_value<>&)): Remove.
	(_Hash_code_base::_M_hash_code<_H2>(const _H2&, const _Hash_node_value<>&)): Remove.
	* include/bits/hashtable.h
	(_M_src_hash_code<_H2>(const _H2&, const key_type&, const __node_value_type&)): New.
	(_M_merge_unique<>, _M_merge_multi<>): Use latter.
	* testsuite/23_containers/unordered_map/modifiers/merge.cc
	(test04, test05, test06): New test cases.
2023-10-19 19:06:08 +02:00
Arsen Arsenović 083b7f2833 libstdc++: Replace all manual FTM definitions and use
libstdc++-v3/ChangeLog:

	* libsupc++/typeinfo: Switch to bits/version.h for
	__cpp_lib_constexpr_typeinfo.
	* libsupc++/new: Switch to bits/version.h for
	__cpp_lib_{launder,hardware_interference_size,destroying_delete}.
	(launder): Guard behind __cpp_lib_launder.
	(hardware_destructive_interference_size)
	(hardware_constructive_interference_size): Guard behind
	__cpp_lib_hardware_interference_size.
	* libsupc++/exception: Switch to bits/version.h for
	__cpp_lib_uncaught_exceptions.
	(uncaught_exceptions): Guard behind __cpp_lib_uncaught_exceptions.
	* libsupc++/compare: Switch to bits/version.h for
	__cpp_lib_three_way_comparison.
	(three_way_comparable, three_way_comparable_with)
	(compare_three_way, weak_order, strong_order, partial_order):
	Guard behind __cpp_lib_three_way_comparison >= 201907L.
	* include/std/chrono: Drop __cpp_lib_chrono definition.
	* include/std/vector: Switch to bits/version.h for
	__cpp_lib_erase_if.
	(erase, erase_if): Guard behind __cpp_lib_erase_if.
	* include/std/variant: Switch to bits/version.h for
	__cpp_lib_variant.  Guard whole header behind that FTM.
	* include/std/utility: Switch to bits/version.h for
	__cpp_lib_{exchange_function,constexpr_algorithms,as_const},
	__cpp_lib_{integer_comparison_functions,to_underlying}, and
	__cpp_lib_unreachable.
	(exchange): Guard behind __cpp_lib_exchange_function.
	(cmp_equal, cmp_not_equal, cmp_less, cmp_greater, cmp_less_equal)
	(cmp_greater_equal, in_range): Guard behind
	__cpp_lib_integer_comparison_functions.
	(to_underlying): Guard behind __cpp_lib_to_underlying.
	(unreachable): Guard behind __cpp_lib_unreachable.
	* include/std/type_traits: Switch to bits/version.h for
	__cpp_lib_is_{null_pointer,final,nothrow_convertible,aggregate},
	__cpp_lib_is_{constant_evaluated,invocable,layout_compatible},
	__cpp_lib_is_{pointer_interconvertible,scoped_enum,swappable},
	__cpp_lib_{logical_traits,reference_from_temporary,remove_cvref},
	__cpp_lib_{result_of_sfinae,transformation_trait_aliases},
	__cpp_lib_{type_identity,type_trait_variable_templates},
	__cpp_lib_{unwrap_ref,void_t,integral_constant_callable},
	__cpp_lib_{bool_constant,bounded_array_traits}, and
	__cpp_lib_has_unique_object_representations.
	(integral_constant::operator()): Guard behind
	__cpp_lib_integral_constant_callable.
	(bool_constant): Guard behind __cpp_lib_bool_constant.
	(conjunction, disjunction, negation, conjunction_v, disjunction_v)
	(negation_v): Guard behind __cpp_lib_logical_traits.
	(is_null_pointer): Guard behind __cpp_lib_is_null_pointer.
	(is_final): Guard behind __cpp_lib_is_final.
	(is_nothrow_convertible, is_nothrow_convertible_v): Guard behind
	__cpp_lib_is_nothrow_convertible.
	(remove_const_t, remove_volatile_t, remove_cv_t)
	(add_const_t, add_volatile_t, add_cv_t): Guard behind
	__cpp_lib_transformation_trait_aliases.
	(void_t): Guard behind __cpp_lib_void_t.
	(is_swappable_with_v, is_nothrow_swappable_with_v)
	(is_swappable_with, is_nothrow_swappable_with): Guard behind
	__cpp_lib_is_swappable.
	(is_nothrow_invocable_r, is_invocable_r, invoke_result)
	(is_invocable, invoke_result_t): Guard behind
	__cpp_lib_is_invocable.
	(alignment_of_v, extent_v, has_virtual_destructor_v)
	(is_abstract_v, is_arithmetic_v, is_array_v)
	(is_assignable_v, is_base_of_v, is_class_v, is_compound_v)
	(is_constructible_v, is_const_v, is_convertible_v)
	(is_copy_assignable_v, is_copy_constructible_v)
	(is_default_constructible_v, is_destructible_v)
	(is_empty_v, is_enum_v, is_final_v, is_floating_point_v)
	(is_function_v, is_fundamental_v, is_integral_v)
	(is_invocable_r_v, is_invocable_v, is_literal_type_v)
	(is_lvalue_reference_v, is_member_function_pointer_v)
	(is_member_object_pointer_v, is_member_pointer_v)
	(is_move_assignable_v, is_move_constructible_v)
	(is_nothrow_assignable_v, is_nothrow_constructible_v)
	(is_nothrow_copy_assignable_v, is_nothrow_copy_constructible_v)
	(is_nothrow_default_constructible_v, is_nothrow_destructible_v)
	(is_nothrow_invocable_r_v, is_nothrow_invocable_v)
	(is_nothrow_move_assignable_v, is_nothrow_move_constructible_v)
	(is_null_pointer_v, is_object_v, is_pod_v, is_pointer_v)
	(is_polymorphic_v, is_reference_v, is_rvalue_reference_v)
	(is_same_v, is_scalar_v, is_signed_v, is_standard_layout_v)
	(is_trivially_assignable_v, is_trivially_constructible_v)
	(is_trivially_copyable_v, is_trivially_copy_assignable_v)
	(is_trivially_copy_constructible_v)
	(is_trivially_default_constructible_v)
	(is_trivially_destructible_v, is_trivially_move_assignable_v)
	(is_trivially_move_constructible_v, is_trivial_v, is_union_v)
	(is_unsigned_v, is_void_v, is_volatile_v, rank_v, as variadic):
	Guard behind __cpp_lib_type_trait_variable_templates.
	(has_unique_object_representations)
	(has_unique_object_representations_v): Guard behind
	__cpp_lib_has_unique_object_representation.
	(is_aggregate): Guard behind __cpp_lib_is_aggregate.
	(remove_cvref, remove_cvref_t): Guard behind
	__cpp_lib_remove_cvref.
	(type_identity, type_identity_t): Guard behind
	__cpp_lib_type_identity.
	(unwrap_reference, unwrap_reference_t, unwrap_ref_decay)
	(unwrap_ref_decay_t): Guard behind __cpp_lib_unwrap_ref.
	(is_bounded_array_v, is_unbounded_array_v, is_bounded_array)
	(is_unbounded_array): Guard behind __cpp_lib_bounded_array_traits.
	(is_scoped_enum, is_scoped_enum_v): Guard behind
	__cpp_lib_is_scoped_enum.
	(reference_constructs_from_temporary)
	(reference_constructs_from_temporary_v): Guard behind
	__cpp_lib_reference_from_temporary.
	* include/std/tuple: Switch to bits/version.h for
	__cpp_lib_{constexpr_tuple,tuple_by_type,apply_make_from_tuple}.
	(get<T>): Guard behind __cpp_lib_tuple_by_type.
	(apply): Guard behind __cpp_lib_apply.
	(make_from_tuple): Guard behind __cpp_lib_make_from_tuple.
	* include/std/syncstream: Switch to bits/version.h for
	__cpp_lib_syncbuf.  Guard header behind that FTM.
	* include/std/string_view: Switch to bits/version.h for
	__cpp_lib_{string_{view,contains},constexpr_string_view} and
	__cpp_lib_starts_ends_with.
	(basic_string_view::starts_with, basic_string_view::ends_with):
	Guard behind __cpp_lib_starts_ends_with.
	[C++23 && _GLIBCXX_HOSTED && !defined(__cpp_lib_string_contains)]:
	Assert as impossible ithout a bug in C++23.
	* include/std/string: Switch to bits/version.h for
	__cpp_lib_erase_if.
	(erase, erase_if): Guard behind __cpp_lib_erase_if.
	* include/std/thread: Switch to bits/version.h for
	__cpp_lib_jthread.
	* include/std/stop_token: Switch to bits/version.h for
	__cpp_lib_jthread.
	* include/std/spanstream: Switch to bits/version.h for
	__cpp_lib_spanstream.  Guard header behind that FTM.
	* include/std/span: Switch to bits/version.h for __cpp_lib_span.
	Guard header behind that FTM.
	* include/std/source_location: Switch to bits/version.h for
	__cpp_lib_source_location.  Guard header with that FTM.
	* include/std/shared_mutex: Switch to bits/version.h for
	__cpp_lib_shared{,_timed}_mutex.
	(shared_mutex): Guard behind __cpp_lib_shared_mutex.
	* include/std/semaphore: Switch to bits/version.h for
	__cpp_lib_semaphore.  Guard header behind that FTM.
	* include/std/ranges: Switch to bits/version.h for
	__cpp_lib_ranges_{zip,chunk{,_by},slide,join_with},
	__cpp_lib_ranges_{repeat_stride,cartesian_product,as_rvalue},
	and __cpp_lib_ranges_{as_const,enumerate,iota}.
	(ranges::zip et al, ranges::chunk et al, ranges::slide et al)
	(ranges::chunk_by et al, ranges::join_with et al)
	(ranges::stride et al, ranges::cartesian_product et al)
	(ranges::as_rvalue et al, ranges::as_const et al)
	(ranges::enumerate et al): Guard behind appropriate FTM.
	* include/std/optional: Switch to bits/version.h for
	__cpp_lib_optional.  Guard header behind that FTM.
	* include/std/numeric: Switch to bits/version.h for
	__cpp_lib_{gcd{,_lcm},lcm,constexpr_numeric,interpolate}
	and __cpp_lib_parallel_algorithm.
	(gcd, lcm): Guard behind __cpp_lib_gcd_lcm.
	(midpoint): Guard behind __cpp_lib_interpolate.
	* include/std/numbers: Switch to bits/version.h for
	__cpp_lib_math_constants.  Guard header behind that FTM.
	* include/std/mutex: Switch to bits/version.h for
	__cpp_lib_scoped_lock.
	(scoped_Lock): Guard behind __cpp_lib_scoped_lock.
	* include/std/memory_resource: Switch to bits/version.h for
	__cpp_lib_{polymorphic_allocator,memory_resource}.
	(synchronized_pool_resource): Guard behind
	__cpp_lib_memory_resource >= 201603L.
	(polymorphic_allocator): Guard behind
	__cpp_lib_polymorphic_allocator.
	* include/std/memory: Switch to bits/version.h for
	__cpp_lib_{parallel_algorithm,atomic_value_initialization}.
	* include/std/list: Switch to bits/version.h for
	__cpp_lib_erase_if.
	(erase, erase_if): Guard behind __cpp_lib_erase_if.
	* include/std/latch: Switch to bits/version.h for __cpp_lib_latch.
	Guard header behind that FTM.
	* include/std/iterator: Switch to bits/version.h for
	__cpp_lib_null_iterators.
	* include/std/iomanip: Switch to bits/version.h for
	__cpp_lib_quoted_string_io.
	(quoted): Guard behind __cpp_lib_quoted_string_io.
	* include/std/functional: Switch to bits/version.h for
	__cpp_lib_{invoke{,_r},constexpr_functional,bind_front} and
	__cpp_lib_{not_fn,booyer_moore_searcher}.
	(invoke): Guard behind __cpp_lib_invoke.
	(invoke_r): Guard behind __cpp_lib_invoke_r.
	(bind_front): Guard behind __cpp_lib_bind_front.
	(not_fn): Guard behind __cpp_lib_not_fn.
	(boyer_moore_searcher, boyer_moore_horspool_searcher): Guard
	definition behind __cpp_lib_boyer_moore_searcher.
	* include/std/forward_list: Switch to bits/version.h for
	__cpp_lib_erase_if.
	(erase, erase_if): Guard behind __cpp_lib_erase_if.
	* include/std/format: Switch to bits/version.h for
	__cpp_lib_format.  Guard header behind that FTM.
	* include/std/filesystem: Switch to bits/version.h for
	__cpp_lib_filesystem.  Guard header behind that FTM.
	* include/std/expected: Switch to bits/version.h for
	__cpp_lib_expected.  Guard header behind it.
	* include/std/execution: Switch to bits/version.h for
	__cpp_lib_{execution,parallel_algorithm}.  Guard header behind
	either.
	* include/std/deque: Switch to bits/version.h for
	__cpp_lib_erase_if.
	(erase, erase_if): Guard behind __cpp_lib_erase_if.
	* include/std/coroutine: Switch to bits/version.h for
	__cpp_lib_coroutine.  Guard header behind that FTM.
	* include/std/concepts: Switch to bits/version.h for
	__cpp_lib_concepts.  Guard header behind that FTM.
	* include/std/complex: Switch to bits/version.h for
	__cpp_lib_{complex_udls,constexpr_complex}.
	(operator""if, operator""i, operator""il): Guard behind
	__cpp_lib_complex_udls.
	* include/std/charconv: Swtich to bits/version.h for
	__cpp_lib_{to_chars,constexpr_charconv}.
	* include/std/bitset: Switch to bits/version.h for
	__cpp_lib_constexpr_bitset.
	* include/std/bit: Switch to bits/version.h for
	__cpp_lib_{bit_cast,byteswap,bitops,int_pow2,endian}.
	(bit_cast): Guard behind __cpp_lib_bit_cast.
	(byteswap): Guard behind __cpp_lib_byteswap.
	(rotl, rotr, countl_zero, countl_one, countr_zero, countr_one)
	(popcount): Guard behind __cpp_lib_bitops.
	(has_single_bit, bit_ceil, bit_floor, bit_width): Guard behind
	__cpp_lib_int_pow2.
	(endian): Guard behind __cpp_lib_endian.
	* include/std/barrier: Switch to bits/version.h for
	__cpp_lib_barrier.  Guard header behind that FTM.
	* include/std/atomic: Switch to bits/version.h for
	__cpp_lib_atomic_{is_always_lock_free,float,ref}
	and __cpp_lib_lock_free_type_aliases.
	(*::is_always_lock_free): Guard behind
	__cpp_lib_atomic_is_always_lock_free.
	(atomic<float>): Guard behind __cpp_lib_atomic_float.
	(atomic_ref): Guard behind __cpp_lib_atomic_ref.
	(atomic_signed_lock_free, atomic_unsigned_lock_free): Guard behind
	__cpp_lib_atomic_lock_free_type_aliases.
	* include/std/array: Switch to bits/version.h for
	__cpp_lib_to_array.
	(to_array): Guard behind __cpp_lib_to_array.
	* include/std/any: Switch to bits/version.h for __cpp_lib_any.
	Guard header behind that FTM.
	* include/std/algorithm: Switch to bits/version.h for
	__cpp_lib_parallel_algorithm.
	* include/c_global/cstddef: Switch to bits/version.h for
	__cpp_lib_byte.
	(byte): Guard behind __cpp_lib_byte.
	* include/c_global/cmath: Switch to bits/version.h for
	__cpp_lib_{hypot,interpolate}.
	(hypot3): Guard behind __cpp_lib_hypot.
	(lerp): Guard behind __cpp_lib_interpolate.
	* include/c_compatibility/stdatomic.h: Switch to
	bits/stl_version.h for __cpp_lib_atomic.  Guard header behind that
	FTM.
	* include/bits/utility.h: Switch to bits/version.h for
	__cpp_lib_{tuple_element_t,integer_sequence,ranges_zip}.
	(tuple_element_t): Guard behind __cpp_lib_tuple_element_t.
	(integer_sequence et al): Guard behind __cpp_lib_integer_sequence.
	* include/bits/uses_allocator_args.h: Switch to bits/version.h for
	__cpp_lib_make_obj_using_allocator.  Guard header behind that FTM.
	* include/bits/unordered_map.h: Switch to bits/version.h for
	__cpp_lib_unordered_map_try_emplace.
	(try_emplace): Guard behind __cpp_lib_unordered_map_try_emplace.
	* include/bits/unique_ptr.h: Switch to bits/version.h for
	__cpp_lib_{constexpr_memory,make_unique}.
	(make_unique): Guard behind __cpp_lib_make_unique.
	* include/bits/stl_vector.h: Switch to bits/version.h for
	__cpp_lib_constexpr_vector.
	* include/bits/stl_uninitialized.h: Switch to bits/version.h for
	__cpp_lib_raw_memory_algorithms.
	(uninitialized_default_construct)
	(uninitialized_default_construct_n, uninitialized_move)
	(uninitialized_move_n, uninitialized_value_construct)
	(uninitialized_value_construct_n): Guard behind
	__cpp_lib_raw_memory_algorithms.
	* include/bits/stl_tree.h: Switch to bits/version.h for
	__cpp_lib_generic_associative_lookup.
	* include/bits/stl_stack.h: Switch to bits/version.h for
	__cpp_lib_adaptor_iterator_pair_constructor.
	(stack): Guard iterator-pair constructor behind
	__cpp_lib_adaptor_iterator_pair_constructor.
	* include/bits/stl_queue.h: Switch to bits/version.h for
	__cpp_lib_adaptor_iterator_pair_constructor.
	(queue): Guard iterator-pair constructor behind
	__cpp_lib_adaptor_iterator_pair_constructor.
	* include/bits/stl_pair.h: Switch to bits/version.h for
	__cpp_lib_{concepts,tuples_by_type}.
	(get): Guard type-getting overloads behind
	__cpp_lib_tuples_by_type.
	* include/bits/stl_map.h: Switch to bits/version.h for
	__cpp_lib_map_try_emplace.
	(map<>::try_emplace): Guard behind __cpp_lib_map_try_emplace.
	* include/bits/stl_list.h: Switch to bits/version.h for
	__cpp_lib_list_remove_return_type.
	(__remove_return_type, _GLIBCXX_LIST_REMOVE_RETURN_TYPE_TAG)
	[C++20]: guard behind __cpp_lib_list_remove_return_type instead.
	* include/bits/stl_iterator.h: Switch to bits/version.h for
	__cpp_lib_{constexpr_iterator,array_constexpr} and
	__cpp_lib_{make_reverse_iterator,move_iterator_concept}.
	(make_reverse_iterator): Guard behind
	__cpp_lib_make_reverse_iterator.
	(iterator_concept et al): Guard __cpp_lib_move_iterator_concept
	changes behind that FTM.
	* include/bits/stl_function.h: Switch to bits/version.h for
	__cpp_lib_transparent_operators.
	(equal_to, not_equal_to, greater, less, greater_equal)
	(less_equal, bit_and, bit_or, bit_xor, bit_not, logical_and)
	(logical_or, logical_not, plus, minus, multiplies, divides)
	(modulus, negate): Guard '= void' fwdecls behind
	__cpp_lib_transparent_operators.
	(plus<void>, minus<void>, multiplies<void>, divides<void>)
	(modulus<void>, negate<void>, logical_and<void>, logical_or<void>)
	(logical_not<void>, bit_and<void>, bit_or<void>, bit_xor<void>)
	(equal_to<void>, not_equal_to<void>, greater<void>, less<void>)
	(greater_equal<void>, less_equal<void>, bit_not<void>)
	(__has_is_transparent): Guard behind
	__cpp_lib_transparent_operators.
	* include/bits/stl_algobase.h: Switch to bits/version.h for
	__cpp_lib_robust_nonmodifying_seq_ops.
	(robust equal, mismatch): Guard behind
	__cpp_lib_nonmember_container_access.
	* include/bits/stl_algo.h: Swtich to bits/version.h for
	__cpp_lib_{clamp,sample}.
	(clamp): Guard behind __cpp_lib_clamp.
	(sample): Guard behind __cpp_lib_sample.
	* include/bits/specfun.h: Switch to bits/version.h for
	__cpp_lib_math_special_functions and __STDCPP_MATH_SPEC_FUNCS__.
	* include/bits/shared_ptr_base.h: Switch to bits/version.h for
	__cpp_lib_{smart_ptr_for_overwrite,shared_ptr_arrays}.
	(_Sp_overwrite_tag): Guard behind
	__cpp_lib_smart_ptr_for_overwrite.
	* include/bits/shared_ptr_atomic.h: Switch to bits/version.h for
	__cpp_lib_atomic_shared_ptr.
	* include/bits/shared_ptr.h: Switch to bits/version.h for
	__cpp_lib_{enable_shared_from_this,shared_ptr_weak_type}.
	(shared_ptr<T>::weak_type): Guard behind
	__cpp_lib_shared_ptr_weak_type.
	(enable_shared_from_this<T>::weak_from_this): Guard behind
	__cpp_lib_enable_shared_from_this.
	* include/bits/ranges_cmp.h: Switch to bits/version.h for
	__cpp_lib_ranges.
	* include/bits/ranges_algo.h: Switch to bits/version.h for
	__cpp_lib_{shift,ranges_{contains,find_last,fold,iota}}.
	* include/bits/range_access.h: Switch to bits/version.h for
	__cpp_lib_nonmember_container_access
	(size, empty, data): Guard behind
	__cpp_lib_nonmember_container_access.
	(ssize): Guard behind __cpp_lib_ssize.
	* include/bits/ptr_traits.h: Switch to bits/version.h. for
	__cpp_lib_{constexpr_memory,to_address}.
	(to_address): Guard behind __cpp_lib_to_address.
	* include/bits/node_handle.h: Switch to bits/version.h for
	__cpp_lib_node_extract.  Guard header behind that FTM.
	* include/bits/move_only_function.h: Switch to bits/version.h for
	__cpp_lib_move_only_function.  Guard header behind that FTM.
	* include/bits/move.h: Switch to bits/version.h for
	__cpp_lib_addressof_constexpr.
	* include/bits/ios_base.h: Switch to bits/version.h for
	__cpp_lib_ios_noreplace.
	(noreplace): Guard with __cpp_lib_ios_noreplace.
	* include/bits/hashtable.h: Switch to bits/version.h for
	__cpp_lib_generic_unordered_lookup.
	(_M_equal_range_tr, _M_count_tr, _M_find_tr): Guard behind
	__cpp_lib_generic_unordered_lookup.
	* include/bits/forward_list.h: Switch to bits/version.h for
	__cpp_lib_list_remove_return_type.
	(__remove_return_type): Guard behind
	__cpp_lib_list_remove_return_type.
	* include/bits/erase_if.h: Switch to bits/version.h for
	__cpp_lib_erase_if.
	* include/bits/cow_string.h: Switch to bits/version.h for
	__cpp_lib_constexpr_string.
	* include/bits/chrono.h: Swtich to bits/version.h for
	__cpp_lib_chrono{,_udls}.
	(ceil): Guard behind __cpp_lib_chrono.
	(operator""ns et al): Guard behind __cpp_lib_chrono_udls.
	* include/bits/char_traits.h: Switch to bits/version.h for
	__cpp_lib_constexpr_char_traits.
	* include/bits/basic_string.h: Switch to bits/version.h for
	__cpp_lib_{constexpr_string,string_{resize_and_overwrite,udls}}.
	(resize_and_overwrite): Guard behind
	__cpp_lib_string_resize_and_overwrite.
	(operator""s): Guard behind __cpp_lib_string_udls.
	* include/bits/atomic_wait.h: Switch to bits/version.h for
	__cpp_lib_atomic_wait.  Guard header behind that FTM.
	* include/bits/atomic_base.h: Switch to bits/version.h for
	__cpp_lib_atomic_value_initialization and
	__cpp_lib_atomic_flag_test.
	(atomic_flag::test): Guard behind __cpp_lib_atomic_flag_test,
	rather than C++20.
	* include/bits/allocator.h: Switch to bits/version.h for
	__cpp_lib_incomplete_container_elements.
	* include/bits/alloc_traits.h: Switch to using bits/version.h for
	__cpp_lib_constexpr_dynamic_alloc and
	__cpp_lib_allocator_traits_is_always_equal.
	* include/bits/align.h: Switch to bits/version.h for defining
	__cpp_lib_assume_aligned.
	(assume_aligned): Guard with __cpp_lib_assume_aligned.
	* include/bits/algorithmfwd.h: Switch to bits/version.h for
	defining __cpp_lib_constexpr_algorithms.
	* include/std/stacktrace: Switch to bits/version.h for
	__cpp_lib_stacktrace.  Guard header behind that FTM.
	* testsuite/23_containers/array/tuple_interface/get_neg.cc:
	Update line numbers.
2023-08-16 15:16:25 +02:00
François Dumont 5476c91428 libstdc++: [_Hashtable] Implement several small methods implicitly inline
Make implementation of 3 simple _Hashtable methods implicitly inline.

Avoid usage of const_iterator abstraction within _Hashtable implementation.

Replace several usages of __node_type* with expected __node_ptr.

libstdc++-v3/ChangeLog:

	* include/bits/hashtable_policy.h
	(_NodeBuilder<>::_S_build): Use __node_ptr.
	(_ReuseOrAllocNode<>): Use __node_ptr in place of __node_type*.
	(_AllocNode<>): Likewise.
	(_Equality<>::_M_equal): Remove const_iterator usages. Only preserved
	to call std::is_permutation in the non-unique key implementation.
	* include/bits/hashtable.h (_Hashtable<>::_M_update_begin()): Capture
	_M_begin() once.
	(_Hashtable<>::_M_bucket_begin(size_type)): Implement implicitly inline.
	(_Hashtable<>::_M_insert_bucket_begin): Likewise.
	(_Hashtable<>::_M_remove_bucket_begin): Likewise.
	(_Hashtable<>::_M_compute_hash_code): Use __node_ptr rather than
	const_iterator.
	(_Hashtable<>::find): Likewise.
	(_Hashtable<>::_M_emplace): Likewise.
	(_Hashtable<>::_M_insert_unique): Likewise.
2023-05-10 18:40:05 +02:00
Jakub Jelinek 83ffe9cde7 Update copyright years. 2023-01-16 11:52:17 +01:00
François Dumont dc9b92facf libstdc++: [_Hashtable] Insert range of types convertible to value_type PR 105717
Fix insertion of range of instances convertible to value_type.

libstdc++-v3/ChangeLog:

	PR libstdc++/105717
	* include/bits/hashtable_policy.h (_ConvertToValueType): New.
	* include/bits/hashtable.h (_Hashtable<>::_M_insert_unique_aux): New.
	(_Hashtable<>::_M_insert(_Arg&&, const _NodeGenerator&, true_type)): Use latters.
	(_Hashtable<>::_M_insert(_Arg&&, const _NodeGenerator&, false_type)): Likewise.
	(_Hashtable(_InputIterator, _InputIterator, size_type, const _Hash&, const _Equal&,
	const allocator_type&, true_type)): Use this.insert range.
	(_Hashtable(_InputIterator, _InputIterator, size_type, const _Hash&, const _Equal&,
	const allocator_type&, false_type)): Use _M_insert.
	* testsuite/23_containers/unordered_map/cons/56112.cc: Check how many times conversion
	is done.
	* testsuite/23_containers/unordered_map/insert/105717.cc: New test.
	* testsuite/23_containers/unordered_set/insert/105717.cc: New test.
2022-06-15 20:21:52 +02:00