[libcxx-commits] [PATCH] D103335: [libcxx][ranges] Adds `common_iterator`.
Louis Dionne via Phabricator via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Jul 7 06:36:50 PDT 2021
ldionne requested changes to this revision.
ldionne added inline comments.
This revision now requires changes to proceed.
================
Comment at: libcxx/include/__iterator/common_iterator.h:33-41
+ union _Hold {
+ _Iter __iter; // __index == 0;
+ _Sent __sent; // __index == 1;
+
+ _Hold() = default;
+ constexpr _Hold(_Iter __iter) : __iter(_VSTD::move(__iter)) {}
+ constexpr _Hold(_Sent __sent) : __sent(_VSTD::move(__sent)) {}
----------------
Reminder that this should be using `std::variant`.
================
Comment at: libcxx/include/__iterator/common_iterator.h:115
+ } else if constexpr (requires (_Iter& __i) { { *__i++ } -> __referenceable; } ||
+ !constructible_from<iter_value_t<_Iter>, iter_reference_t<_Iter>>) {
+ return __u.__iter++;
----------------
http://eel.is/c++draft/iterators.common#common.iter.nav-5 says:
> Otherwise, if `requires (I& i) { { *i++ } -> can-reference; }` is `true` or `constructible_from<iter_value_t<I>, iter_reference_t<I>> && move_constructible<iter_value_t<I>>` is `false`, equivalent to: `return get<I>(v_)++;`
We're missing `&& move_constructible<...>` here?
================
Comment at: libcxx/include/__iterator/common_iterator.h:118
+ } else {
+ __postfix_proxy __p(*this);
+ ++*this;
----------------
This should be `__postfix_proxy __p(**this);` (double-dereference to get the value pointed-to by the iterator).
It also means you have a hole in your coverage since your tests were passing, i.e. this branch of the `if constexpr` was never exercised. Please make sure all branches of the `if constexpr` are exercised (here and in `operator->` above too).
================
Comment at: libcxx/include/__iterator/common_iterator.h:99
+ assignable_from<const _I2, _Iter> && assignable_from<const _S2&, _Sent>
+ constexpr common_iterator& operator=(const common_iterator<_I2, _S2>& __other) {
+ __u = __other.__u;
----------------
cjdb wrote:
> zoecarver wrote:
> > Note: all of these constexprs aren't required by the standard, but I'm filing an lwg issue for it.
> Please link the issue in this PR before submitting (it doesn't need to be in the patch itself).
I think we should not make them `constexpr` until the LWG issue has been accepted and resolved. I strongly suspect the reason why they are not `constexpr` is that the type is expected to use `variant`, which isn't `constexpr` yet. You can structure the tests so that `constexpr` is easy to test when we add it, but please don't add it in the implementation yet.
================
Comment at: libcxx/test/std/iterators/predef.iterators/iterators.common/arrow.pass.cpp:26
+ {
+ auto iter1 = simple_iterator<int*>(buffer);
+ auto commonIter1 = std::common_iterator<decltype(iter1), sentienl_type<int*>>(iter1);
----------------
Here and for `operator++(int)`, I'd like you to explicitly call out which part is testing each sub-bullet in the spec (which maps to the `if constexpr` in the implementation).
================
Comment at: libcxx/test/std/iterators/predef.iterators/iterators.common/assign.pass.cpp:30
+ auto iter1 = cpp17_input_iterator<int*>(buffer);
+ auto commonIter1 = std::common_iterator<decltype(iter1), sentienl_type<int*>>(iter1);
+ auto commonIter2 = std::common_iterator<decltype(iter1), sentienl_type<int*>>(cpp17_input_iterator<int*>(buffer + 1));
----------------
You have a typo in `sentienl_type`.
================
Comment at: libcxx/test/support/test_iterators.h:164
+template <class It>
+class no_default_constructor
+{
----------------
zoecarver wrote:
> I think this will be a very helpful type to have now that we need to test the default constructibility of all our views/iterators.
I agree, but I would instead call it something like `non_default_constructible_iterator`. Or whatever you prefer, but I think it's important for the name to reflect the fact that it's an iterator.
================
Comment at: libcxx/test/support/test_iterators.h:170
+public:
+ typedef std::forward_iterator_tag iterator_category;
+ typedef typename std::iterator_traits<It>::value_type value_type;
----------------
Shouldn't this be `std::iterator_traits<It>::iterator_category`? Actually, we could perhaps do this instead:
```
template<class It>
struct std::iterator_traits<no_default_constructor<It>> : std::iterator_traits<It> { };
```
Then, could we simply drop all the typedefs in `no_default_constructor`?
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D103335/new/
https://reviews.llvm.org/D103335
More information about the libcxx-commits
mailing list