-
Notifications
You must be signed in to change notification settings - Fork 1.6k
[xutility] Modernize _Equal_memcmp_is_safe to use variable templates #831
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
6ff69a1 to
1ab5481
Compare
|
Just one more round is great for civilization bot not good for PRs. This should now be ready for initial review. |
stl/inc/xutility
Outdated
| return _Equal_unchecked(_UFirst1, _ULast1, _UFirst2, _Pass_fn(_Pred)); | ||
| } | ||
| #endif // _HAS_IF_CONSTEXPR | ||
| #endif // !_HAS_IF_CONSTEXPR |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this what we typically do? If you look at the example just below (line 4793-4871 before changes), the #endif is commented with the original condition (not negated). Doing a quick search throughout the code base also shows that the original comment follows our convention.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As far as I know there was a discussion early after open sourcing and I have the memory that the majority was in favor of
#if foo
#else // ^^^ foo / !foo vvv
#endif // !fooThe reason was that for longer clauses such as this just reading #endif // foo would lead you to believe that foo is active or require you to check the start of the block.
That said sleep was rather short this year so I doubt any memory I have
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is #351 - existing code has accumulated inconsistent patterns. I'm not sure how we ended up with the "hybrid arrow" examples that @mnatsuhara pointed out - I think they evolved from our classic pattern of
#if _HAS_CATS
#else // _HAS_CATS
#endif // _HAS_CATS
#ifdef __cpp_lib_kittens
#else // __cpp_lib_kittens
#endif // __cpp_lib_kittensby replacing just the middle portion with arrows.
My personal opinion: Aside from the question of when comments can be omitted, I'd prefer for us to standardize on consistent arrow comments:
#if _HAS_CATS
#else // ^^^ _HAS_CATS ^^^ / vvv !_HAS_CATS vvv
#endif // ^^^ !_HAS_CATS ^^^
#ifdef __cpp_lib_kittens
#else // ^^^ defined(__cpp_lib_kittens) ^^^ / vvv !defined(__cpp_lib_kittens) vvv
#endif // ^^^ !defined(__cpp_lib_kittens) ^^^(I'm not very concerned with whether ^^^ / vvv or just / appears in the middle; I like the former slightly more.) I prefer this because it's the clearest in dense regions of preprocessor logic, and it's also unambiguous about whether the final comment should say _HAS_CATS or !_HAS_CATS (because it points to a specific section of code).
I could see an argument that "of course an #endif closes a section of code, so we just need to consistently identify what we closed", which would argue for !_HAS_CATS here.
Somewhat related: I believe we've accumulated some inconsistency about how to refer to #ifdef (and #if defined(MEOW) etc.) conditions in comments - I have seen some comments switch from the defined(MEOW) / !defined(MEOW) domain to the MEOW / !MEOW domain which I find confusing. This is because of the danger of actually confusing the definedness versus valueness domains in the test (and the compiler warning about #if NOT_DEFINED being treated as #if 0).
There are "only" 444 occurrences of #else in stl/inc, but 2049 #endifs - tedious to audit, but still easier than bracing all control flow, which we finally did and it was awesome. I should probably just submit a PR to prevent this from burning up valuable time in the future. 🔥
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have to agree that we should be consistent. As I had to rebase anyway I removed that change so that it can be tackled with all the other comments in a consistent fashion
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe this would be a "good second issue"
|
I am still kind of stuck here. My problem with the top level const is that I cannot really constrain the Given that this is essentially soon to be reworked code I am actually considering just hand rolling the 4 combinations of |
|
Ah, I see - it's a partial specialization of a variable template, so you can't really interfere with the partial-specialization-ness. What about the following? (I can prepare a fully worked example later if you want.) Give the primary template a default template argument of the form |
|
@StephanTLavavej thanks a lot that is exactly what I needed 😲 |
miscco
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I again managed to screw the push up, the review comments should now all be satisfied and this ready for final review
|
@CaseyCarter this should now close #819 |
Thanks for the reminder; I've attached #819 and tagged it as "work in progress." |
|
@StephanTLavavej Thanks for improving the comments |
|
I am working on overhauling the metaprogramming - I believe I verified the correctness of your additions yesterday, but the original design was messy to extend and it was exceeding my ability to easily reason about. I think I have something simpler that preserves your additions and enhancements, and avoids replicating too much code for concepts and non-concepts. Will add comments, test, and push soon. |
|
Given that you had trouble we can estimate hoe long I struggled to get something working. Thanks a lot for improving it further |
miscco
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is indeed so much better. Thanks a lot
StephanTLavavej
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm fixing the test coverage.
Include `<cstddef>` for `byte`. Test it when it's available. Style: Use `is_unsigned_v`. Add more test cases for mixed `int` and `long`. Remove a duplicated line (the cv pattern is clear).
|
I'm porting this to MSVC and will need to update that internal PR if any more changes are pushed here. |
|
Thanks for enhancing this optimization! Now, users of C++20 ranges will get the same codegen as for classic algorithms. 😸 |
|
I would also like to thank me for pushing you to write awesome code |
|
This seems to cause DevCom-1263877 ( #1433 contains a fix, but a smaller PR might be preferable. |
|
I don't think smaller PR would be preferable, #1433 is not huge. |
This moves the helper structs
_Equal_memcmp_is_safeand_Equal_memcmp_is_safe_helperto use variable templates rather than structs.This is a precursor to #819