[libcxx-commits] [PATCH] D103335: [libcxx][ranges] Adds `common_iterator`.
Tim Song via Phabricator via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Jul 8 17:34:49 PDT 2021
tcanens added inline comments.
================
Comment at: libcxx/include/__iterator/common_iterator.h:41
+ constexpr __proxy(iter_reference_t<_Iter>&& __x)
+ : __value(__x) {}
+
----------------
Missing move here.
================
Comment at: libcxx/include/__iterator/common_iterator.h:54
+ constexpr __postfix_proxy(iter_reference_t<_Iter>&& __x)
+ : __value(__x) {}
+
----------------
Missing forward here.
================
Comment at: libcxx/include/__iterator/common_iterator.h:71
+ constexpr common_iterator(const common_iterator<_I2, _S2>& __other)
+ : __hold(__other.__hold) {}
+
----------------
`variant` does not have heterogeneous conversions of this sort.
================
Comment at: libcxx/include/__iterator/common_iterator.h:77
+ common_iterator& operator=(const common_iterator<_I2, _S2>& __other) {
+ __hold = __other.__hold;
+ }
----------------
Likewise.
================
Comment at: libcxx/include/__iterator/common_iterator.h:80-83
+ decltype(auto) operator*() { return *_VSTD::get<_Iter>(__hold); }
+ decltype(auto) operator*() const
+ requires __dereferenceable<const _Iter>
+ { return *_VSTD::get<_Iter>(__hold); }
----------------
It's undefined if it is holding the wrong type, so the check-and-throw `get` performs is unnecessary (and hurts performance). There should be a way to avoid such checks.
================
Comment at: libcxx/include/__iterator/common_iterator.h:124
+ if (__x.__hold.index() == 0)
+ return _VSTD::get<_Iter>(__x.__hold) == _VSTD::get<_Sent>(__y.__hold);
+
----------------
`__y`'s sentinel type is `_S2`, not `_Sent`. Ditto below.
There seems to be a lack of test coverage here.
================
Comment at: libcxx/test/std/iterators/predef.iterators/iterators.common/plus_plus.pass.cpp:87
+ // Note: operator++ returns void.
+ // assert(*(commonIter1++) == 1);
+ assert(*commonIter1 == 2);
----------------
zoecarver wrote:
> @tcanens and others, is this correct? It seems like this goes against the other logic here (isn't the whole point to make sure that operator++ always returns a referencable type)?
Yes, `common_iterator` does its best to return something from postfix `++` that meets the C++17 input iterator requirements.
But hitting this case means that it doesn't know a way to produce anything meaningful, so it just gives up.
================
Comment at: libcxx/test/support/test_iterators.h:171
+public:
+ typedef std::forward_iterator_tag iterator_category;
+ typedef typename std::iterator_traits<It>::value_type value_type;
----------------
Something that's not default constructible can't be anything more than input.
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