[libcxx-commits] [PATCH] D101079: [libcxx][ranges] Add ranges::size CPO.
Zoe Carver via Phabricator via libcxx-commits
libcxx-commits at lists.llvm.org
Tue May 4 13:36:13 PDT 2021
zoecarver added inline comments.
================
Comment at: libcxx/test/std/ranges/range.access/range.prim/size.pass.cpp:212-222
+struct sentinel {
+ bool operator==(std::input_or_output_iterator auto) const { return true; }
+};
+
+struct HasMinusBeginEnd {
+ friend constexpr forward_iterator<int*> begin(HasMinusBeginEnd) { return {}; }
+ friend constexpr sentinel end(HasMinusBeginEnd) { return {}; }
----------------
Quuxplusone wrote:
> Do this instead:
> ```
> struct HasMinusBeginEnd {
> struct sentinel {
> friend bool operator==(sentinel, forward_iterator<int*>);
> friend constexpr long operator-(sentinel, forward_iterator<int*>) { return 2; }
> friend long operator-(forward_iterator<int*>, sentinel);
> };
> friend constexpr forward_iterator<int*> begin(HasMinusBeginEnd) { return {}; }
> friend constexpr sentinel end(HasMinusBeginEnd) { return {}; }
> };
> ```
> This keeps everything nicely packaged together, and also indicates (by the presence of function bodies) which functions are actually called by the test, and even (by the presence of `constexpr`) which functions are constexpr-called by the test.
>
> Similarly for the other tests.
I don't want to have to define sentinel three times, so I'm going to keep it out-of-line. But I'll make the comparison operator a hidden friend.
================
Comment at: libcxx/test/std/ranges/range.access/range.prim/size.pass.cpp:266
+ // Ensure that this is converted to an *unsigned* type.
+ ASSERT_SAME_TYPE(decltype(std::ranges::size(a)), unsigned long);
+
----------------
Quuxplusone wrote:
> This should be `std::make_unsigned_t<std::ptrdiff_t>`, I believe. I don't think we should assume `ptrdiff_t` is invariably `signed long`.
> Ditto throughout.
> Let's test against `long` (or `short` or whatever) only when it's possible for the reader to grep back and see where that `long` (or `short` or whatever) comes from.
```
struct HasMinusBeginEnd {
friend constexpr forward_iterator<int*> begin(HasMinusBeginEnd) { return {}; }
friend constexpr sentinel end(HasMinusBeginEnd) { return {}; }
};
constexpr long operator-(const sentinel, const forward_iterator<int*>) { return 2; }
constexpr long operator-(const forward_iterator<int*>, const sentinel) { return 2; }
```
So `long` is hardcoded in this case (as the minus operator's return type).
================
Comment at: libcxx/test/std/ranges/range.access/range.prim/size.pass.cpp:266
+ // Ensure that this is converted to an *unsigned* type.
+ ASSERT_SAME_TYPE(decltype(std::ranges::size(a)), unsigned long);
+
----------------
zoecarver wrote:
> Quuxplusone wrote:
> > This should be `std::make_unsigned_t<std::ptrdiff_t>`, I believe. I don't think we should assume `ptrdiff_t` is invariably `signed long`.
> > Ditto throughout.
> > Let's test against `long` (or `short` or whatever) only when it's possible for the reader to grep back and see where that `long` (or `short` or whatever) comes from.
> ```
> struct HasMinusBeginEnd {
> friend constexpr forward_iterator<int*> begin(HasMinusBeginEnd) { return {}; }
> friend constexpr sentinel end(HasMinusBeginEnd) { return {}; }
> };
>
> constexpr long operator-(const sentinel, const forward_iterator<int*>) { return 2; }
> constexpr long operator-(const forward_iterator<int*>, const sentinel) { return 2; }
> ```
>
> So `long` is hardcoded in this case (as the minus operator's return type).
> I don't think we should assume ptrdiff_t is invariably signed long.
If that assumption is ever made in this test, it will be caught by the windows and arm bots.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D101079/new/
https://reviews.llvm.org/D101079
More information about the libcxx-commits
mailing list