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.