diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2025-04-24 14:58:58 +0100 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2025-04-25 11:47:12 +0100 |
commit | 876d1a22dfaf873d167bd2ffad190a1d07a81b22 (patch) | |
tree | a21244a9d63262874fe067602b75a14a5148456b /libstdc++-v3/testsuite/std | |
parent | aafe942227baf8c2bcd4cac2cb150e49a4b895a9 (diff) | |
download | gcc-876d1a22dfaf873d167bd2ffad190a1d07a81b22.zip gcc-876d1a22dfaf873d167bd2ffad190a1d07a81b22.tar.gz gcc-876d1a22dfaf873d167bd2ffad190a1d07a81b22.tar.bz2 |
libstdc++: Add _M_key_compare helper to associative containers
In r10-452-ge625ccc21a91f3 I noted that we don't have an accessor for
invoking _M_impl._M_key_compare in the associative containers. That
meant that the static assertions to check for valid comparison functions
were squirrelled away in _Rb_tree::_S_key instead. As Jason noted in
https://gcc.gnu.org/pipermail/gcc-patches/2025-April/681436.html this
means that the static assertions fail later than we'd like.
This change adds a new _Rb_tree::_M_key_compare member function which
invokes the _M_impl._M_key_compare function object, and then moves the
static_assert from _S_key into _M_key_compare. Now if the static_assert
fails, that's the first error we get, before the "no match for call" and
and "invalid conversion" errors.
Because the new function is const-qualified, we now treat LWG 2542 as a
DR for older standards, requiring the comparison function to be const
invocable. Previously we only enforced the LWG 2542 rule for C++17 and
later.
I did consider deprecating support for comparisons which aren't const
invocable, something like this:
// Before LWG 2542 it wasn't strictly necessary for _Compare to be
// const invocable, if you only used non-const container members.
// Define a non-const overload for pre-C++17, deprecated for C++11/14.
#if __cplusplus < 201103L
bool
_M_key_compare(const _Key& __k1, const _Key& __k2)
{ return _M_impl._M_key_compare(__k1, __k2); }
#elif __cplusplus < 201703L
template<typename _Key1, typename _Key2>
[[__deprecated__("support for comparison functions that are not "
"const invocable is deprecated")]]
__enable_if_t<
__and_<__is_invocable<_Compare&, const _Key1&, const _Key2&>,
__not_<__is_invocable<const _Compare&, const _Key1&, const _Key2&>>>::value,
bool>
_M_key_compare(const _Key1& __k1, const _Key2& __k2)
{
static_assert(
__is_invocable<_Compare&, const _Key&, const _Key&>::value,
"comparison object must be invocable with two arguments of key type"
);
return _M_impl._M_key_compare(__k1, __k2);
}
#endif
But I decided that this isn't necessary, because we've been enforcing
the C++17 rule since GCC 8.4 and 9.2, and C++17 has been the default
since GCC 11.1. Users have had plenty of time to fix their invalid
comparison functions.
libstdc++-v3/ChangeLog:
* include/bits/stl_tree.h (_Rb_tree::_M_key_compare): New member
function to invoke comparison function.
(_Rb_tree): Use new member function instead of accessing the
comparison function directly.
Reviewed-by: Tomasz KamiĆski <tkaminsk@redhat.com>
Diffstat (limited to 'libstdc++-v3/testsuite/std')
0 files changed, 0 insertions, 0 deletions