Skip to content

Conversation

caspernorrbin
Copy link
Member

@caspernorrbin caspernorrbin commented Sep 12, 2025

Hi everyone,

C++17 lets us tidy up som of the ugly templating done in the red-black tree. We can replace the std::false_type/std::true_type tricks used to discover comparator and verifier signatures with the new std::is_invocable(_r_v), and most of the overload/SFINAE noise can disappear thanks to if constexpr.

We can now write one-liners such as:

static constexpr bool HasKeyComparator = std::is_invocable_r_v<RBTreeOrdering, decltype(&CMP::cmp), K, K>;

and then select the right branch with

if constexpr (HasKeyComparator<CMP>) { }

inside a single function instead of having several ENABLE_IF overloads.

This results in fewer lines, clearer intent, and more readable errors, while keeping behaviour identical.

Testing:

  • Oracle tiers 1-3

Progress

  • Change must be properly reviewed (1 review required, with at least 1 Reviewer)
  • Change must not contain extraneous whitespace
  • Commit message must refer to an issue

Issue

  • JDK-8367536: Change RBTree to use C++17 features (Enhancement - P4)

Reviewers

Reviewing

Using git

Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/27260/head:pull/27260
$ git checkout pull/27260

Update a local copy of the PR:
$ git checkout pull/27260
$ git pull https://git.openjdk.org/jdk.git pull/27260/head

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 27260

View PR using the GUI difftool:
$ git pr show -t 27260

Using diff file

Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/27260.diff

Using Webrev

Link to Webrev Comment

@bridgekeeper
Copy link

bridgekeeper bot commented Sep 12, 2025

👋 Welcome back cnorrbin! A progress list of the required criteria for merging this PR into master will be added to the body of your pull request. There are additional pull request commands available for use with this pull request.

@openjdk
Copy link

openjdk bot commented Sep 12, 2025

@caspernorrbin This change now passes all automated pre-integration checks.

ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details.

After integration, the commit message for the final commit will be:

8367536: Change RBTree to use C++17 features

Reviewed-by: kbarrett, ayang

You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed.

At the time when this comment was updated there had been 114 new commits pushed to the master branch:

As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details.

➡️ To integrate this PR with the above commit message to the master branch, type /integrate in a new comment.

@openjdk
Copy link

openjdk bot commented Sep 12, 2025

@caspernorrbin The following label will be automatically applied to this pull request:

  • hotspot

When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing list. If you would like to change these labels, use the /label pull request command.

@openjdk openjdk bot added hotspot [email protected] rfr Pull request is ready for review labels Sep 12, 2025
@mlbridge
Copy link

mlbridge bot commented Sep 12, 2025

Webrevs

@openjdk openjdk bot added the ready Pull request is ready to be integrated label Sep 12, 2025
Copy link

@kimbarrett kimbarrett left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good.

template <typename CMP>
static constexpr bool HasKeyComparator = has_cmp_type<CMP, RBTreeOrdering, K, K>::value;
static constexpr bool HasKeyComparator =
std::is_invocable_r_v<RBTreeOrdering, decltype(&CMP::cmp), K, K>;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that these are static data member templates, which were not permitted by the style
guide until about an hour ago. :)

@openjdk openjdk bot removed the ready Pull request is ready to be integrated label Sep 17, 2025
@caspernorrbin
Copy link
Member Author

Thank you both for reviewing!

There seems to be a bug in older versions of gcc with partial template specialization of constexpr inside classes. This makes GHA fail on linux since it uses that older version, but works fine on newer versions or other platforms. I think the correct solutions is to make some changes to HasNodeVerifier to make GHA pass.

I have turned that back into a struct with std::false_type/std::true_type, similar in style to what it was before. It is still cleaner than the previous solutions, since we can still use std::is_invocable_r_v, and now also use std::bool_constant. With this we can get rid of the templated constexpr variables.

@kimbarrett
Copy link

There seems to be a bug in older versions of gcc with partial template specialization of constexpr inside classes. This makes GHA fail on linux since it uses that older version, but works fine on newer versions or other platforms. I think the correct solutions is to make some changes to HasNodeVerifier to make GHA pass.

Well that's annoying. Good job tracking down the issue.

This looks like a relatively narrow bug, only affecting static data member
templates with specializations. That's not a case I'd used in experiments and
ongoing work that have used variable templates, so thankfully I don't need to
rewrite any of those.

Sorry I seem to have not explicitly tested for this case when I proposed
permitting variable templates. It's very hard to test new features thoroughly,
and I mostly rely on compilers doing their own testing.

We could add a note to the style guide about it, though I'm reluctant to
clutter that document with this kind of thing. The fix is in gcc14, so quite
recent, even though the bug has been around for quite a while. My inclination
is to just leave things be, as it's a pretty narrow issue that seems to me
unlikely to come up often. And someday it will be moot, because we'll be
requiring a more recent version of gcc. Of course, there's the contrary
argument that you hit this pretty much right out of the gate...

Maybe leave a comment with has_not_verifier about the issue, referring to that
gcc bug? Oh, and has_node_verifier is a type, so should normally be studly
capped. Add an "Impl" suffix to avoid collision with the constant, and also
make it more obvious other code shouldn't be referencing it directly.

@caspernorrbin
Copy link
Member Author

Maybe leave a comment with has_not_verifier about the issue, referring to that gcc bug? Oh, and has_node_verifier is a type, so should normally be studly capped. Add an "Impl" suffix to avoid collision with the constant, and also make it more obvious other code shouldn't be referencing it directly.

Thank you for the comment. It's unfortunate that such a bug exists, and that we had to encounter it almost immediately. I can definitely understand why it wasn't caught though. Seeing as it is pretty niche, I agree it shouldn't be added to the style guide at this time, perhaps in the future if it were to become a (somewhat) regular problem. Nevertheless, I pushed an update to document the issue (with the GCC PR ID) in the code along with changing the struct name to HasNodeVerifierImpl.

Copy link

@kimbarrett kimbarrett left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good.

@openjdk openjdk bot added the ready Pull request is ready to be integrated label Sep 18, 2025
struct has_less_than_type : std::false_type {};
template <typename CMP, typename RET, typename ARG1, typename ARG2>
struct has_less_than_type<CMP, RET, ARG1, ARG2, decltype(static_cast<RET(*)(ARG1, ARG2)>(CMP::less), void())> : std::true_type {};
// Due to a bug in older GCC versions with static templeted constexpr data members (see GCC PR 71954),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

templeted -> templated

@openjdk openjdk bot removed the ready Pull request is ready to be integrated label Sep 19, 2025
Copy link

@kimbarrett kimbarrett left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still good.

@openjdk openjdk bot added the ready Pull request is ready to be integrated label Sep 19, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
hotspot [email protected] ready Pull request is ready to be integrated rfr Pull request is ready for review
Development

Successfully merging this pull request may close these issues.

4 participants