Details
- Reviewers
• Quuxplusone ldionne - Group Reviewers
Restricted Project - Commits
- rG7756216547e5: [libc++] NFCI: Remove code duplication and obsolete declarations in wrap_iter
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
If buildkite is happy, I'm happy.
libcxx/include/__iterator/wrap_iter.h | ||
---|---|---|
221–227 | Could this operator+ become a hidden friend of __wrap_iter? |
Fixed and verified the modular build locally. We were missing an include of __algorithm/move.h in inplace_merge.h.
libcxx/include/__iterator/wrap_iter.h | ||
---|---|---|
221–227 | I think I'd rather be consistent and have them all be non-member functions. |
Hi Louis,
This patch introduces an error when std::rel_ops are used.
Here's a small reproducer:
#include <utility> // for std::rel_ops. #include <vector> using namespace std::rel_ops; struct T; void fn() { std::vector<T>::const_iterator a; for (std::vector<T>::const_iterator i; i >= a;) ; }
The compilation result:
repro.cc:9:44: error: use of overloaded operator '>=' is ambiguous (with operand types 'std::vector<T>::const_iterator' (aka '__wrap_iter<const T *>') and 'std::vector<T>::const_iterator' (aka '__wrap_iter<const T *>')) for (std::vector<T>::const_iterator i; i >= a;) ~ ^ ~ /google/src/cloud/bgraur/cherrypick/google3/third_party/crosstool/v18/llvm_unstable/toolchain/bin/../include/c++/v1/__utility/rel_ops.h:56:1: note: candidate function [with _Tp = std::__wrap_iter<const T *>] operator>=(const _Tp& __x, const _Tp& __y) ^ /google/src/cloud/bgraur/cherrypick/google3/third_party/crosstool/v18/llvm_unstable/toolchain/bin/../include/c++/v1/__iterator/wrap_iter.h:201:6: note: candidate function [with _Iter1 = const T *, _Iter2 = const T *] bool operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT ^ 1 error generated.
Could you please take a look?
Amusing comment in GNU libstdc++ about this.
https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/bits/stl_iterator.h#L1081-L1087
It appears that the state-of-the-art fix is that we need to provide both
template <class _Iter1> bool operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT { return !(__x == __y); } template <class _Iter1, class _Iter2> bool operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT { return !(__x == __y); }
and so on. The single-_Iter1 versions are precisely the bits @ldionne removed. I hadn't even noticed they were there! We should put them back, plus a test case.
Could this operator+ become a hidden friend of __wrap_iter?
I'm not asking for all the relational operators to become hidden friends, because they're parameterized on two types, _Iter1 and _Iter2 (and I don't understand the ramifications/rationale of that). But for this operator+, the transformation to hidden friend should be pretty trivial.