This is an archive of the discontinued LLVM Phabricator instance.

[libc++] [test] Refactor range.prim/empty.pass.cpp
ClosedPublic

Authored by Quuxplusone on Dec 7 2021, 11:13 AM.

Details

Reviewers
ldionne
var-const
Group Reviewers
Restricted Project
Summary

This PR now contains three single-file diffs, each orthogonal to the other two, each NFC, each to be landed in a separate commit.

[libc++] [test] Refactor range.prim/empty.pass.cpp

No decrease in test coverage intended. The original goal here
was just to get rid of the global name sentinel so that we can
rename the sentinel_wrapper in "test_iterators.h" to sentinel;
but then I took a closer look at the offending tests and saw
that some of them probably weren't testing what they intended.

[libc++] [test_iterators] Make all ADL base() functions into hidden friends. NFCI.

This follows up on my addition of base(cpp20_input_iterator) in D115177, making all the ADL base() functions consistent.
Also, align cpp20_input_iterator with the other test iterators' style.

[libc++] [test] Use sized_sentinel<int*> in range.prim/ssize.pass.cpp.

Diff Detail

Event Timeline

Quuxplusone requested review of this revision.Dec 7 2021, 11:13 AM
Quuxplusone created this revision.
Herald added 1 blocking reviewer(s): Restricted Project. · View Herald TranscriptDec 7 2021, 11:13 AM
Quuxplusone edited the summary of this revision. (Show Details)

Actually, since I've got a ton of these little diffs sitting around, let me roll three orthogonal diffs into one Differential...

ldionne requested changes to this revision.Dec 7 2021, 2:36 PM

FWIW, it's usually easier to instead create three differential revisions and link them in the UI as parent/children.

libcxx/test/std/ranges/range.access/range.prim/empty.pass.cpp
101

Was forward_iterator not relevant for test coverage? I guess we were only relying on the fact that it was not a sized_range?

106–114

I don't understand why this removal doesn't reduce test coverage.

142–146

How does this not reduce coverage? Now we don't test with a empty() const method anymore.

This revision now requires changes to proceed.Dec 7 2021, 2:36 PM
Quuxplusone edited the summary of this revision. (Show Details)
var-const added inline comments.Dec 7 2021, 3:14 PM
libcxx/test/std/ranges/range.access/range.prim/empty.pass.cpp
122

Question: why is it okay to remove this test?

libcxx/test/std/ranges/range.access/range.prim/ssize.pass.cpp
43–46

Nit: is there a reason not to make it a member variable?

Quuxplusone marked 5 inline comments as done.Dec 7 2021, 6:24 PM
Quuxplusone added inline comments.
libcxx/test/std/ranges/range.access/range.prim/empty.pass.cpp
101

Right — I take BeginEndNotSizedSentinel to mean "we're gonna call begin() == end(), and the sentinel is not a sized sentinel." (If it were sized, then ranges::size would be well-formed and thus we'd end up calling ranges::size instead of begin() == end(). So its being not-sized is important.)
If it's not sized and not a forward iterator, then we (that is, ranges::empty) can't even call begin() == end() because we don't want to invalidate its begin().
I've now added a (passing) test case for "if the iterators are just input iterators, then ranges::empty(e) is ill-formed."

106–114

On old line 114, we're verifying that ranges::size(b) would be ill-formed if we were to call it on old line 153. What actually happens on line 153 is that ranges::empty(b) calls b.begin() == b.end() to find out if the range is empty, because what we have here is not a sized sentinel — this is the same case tested with BeginEndNotSizedSentinel on new lines 118–119.

122

IntPtrBeginAndEnd tests the case where ranges::empty(e) will do ranges::size(e), so we look in testUsingRangesSize()... and hmm, indeed there's no test case in there for the plain old sized-sentinel case (merely test cases for member and ADL size() functions). I guess I should add back one of those.
(The counterargument is that we already have tests for all the different ways to enable ranges::size(e)... in size.pass.cpp. So repeating all those tests here is a little silly. But it's easy to add, so I'm just gonna do it. I'll call it BeginEndSizedSentinel.)

142–144

These comments are backwards. Will fix.

142–146

In that case we would expect ranges::empty(x) to call x.empty(), so you'll find that up in testEmptyMember (which hasn't changed much):

struct HasMemberAndFunction {
  constexpr bool empty() const { return true; }
  // We should never do ADL lookup for std::ranges::empty.
  friend bool empty(const HasMemberAndFunction&) { return false; }
};
~~~
  HasMemberAndFunction a;
  assert(std::ranges::empty(a) == true);
Quuxplusone marked 4 inline comments as done.

Review comments. Mark a TODO (which I have a patch for now).

ldionne accepted this revision.Dec 8 2021, 12:40 PM

This LGTM now.

This revision is now accepted and ready to land.Dec 8 2021, 12:40 PM