[llvm] [STLExctras] Add out-of-line definition of friend operator== for C++20 (PR #72348)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 14 21:41:38 PST 2023
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-adt
Author: Utkarsh Saxena (usx95)
<details>
<summary>Changes</summary>
The last attempt at https://github.com/llvm/llvm-project/pull/72220 was reverted by https://github.com/llvm/llvm-project/commit/94d6699bf5eeb5aa4c50d1d90f8bf69b79201ceb because it breaks C++20 build in clang-17 and before.
This is a workaround of https://github.com/llvm/llvm-project/issues/70210 and unblocks https://github.com/llvm/llvm-project/pull/72213 which rectifies rewriting template operator and thus introduces new breakages.
Moving the function definition out of the class makes clang find a matching `operator!=` for the `operator==`. This makes clang not rewrite the `operator==` with reversed args. Hence, the ambiguity is resolved.
The final plan, when https://github.com/llvm/llvm-project/issues/70210 is fixed, is to move these back to inline definition or even convert to a member template operator. This should not be urgent and could even wait for a major clang release including https://github.com/llvm/llvm-project/pull/72213
---
Full diff: https://github.com/llvm/llvm-project/pull/72348.diff
1 Files Affected:
- (modified) llvm/include/llvm/ADT/STLExtras.h (+30-10)
``````````diff
diff --git a/llvm/include/llvm/ADT/STLExtras.h b/llvm/include/llvm/ADT/STLExtras.h
index 18bc4d108b156bf..380d4d461c4e8db 100644
--- a/llvm/include/llvm/ADT/STLExtras.h
+++ b/llvm/include/llvm/ADT/STLExtras.h
@@ -1291,16 +1291,19 @@ class indexed_accessor_range_base {
}
/// Compare this range with another.
- template <typename OtherT>
- friend bool operator==(const indexed_accessor_range_base &lhs,
- const OtherT &rhs) {
- return std::equal(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
- }
- template <typename OtherT>
- friend bool operator!=(const indexed_accessor_range_base &lhs,
- const OtherT &rhs) {
- return !(lhs == rhs);
- }
+ // FIXME: Make me a member function instead of friend when it works in C++20.
+ template <typename OtherT, typename DerivedT2, typename BaseT2, typename T2,
+ typename PointerT2, typename ReferenceT2>
+ friend bool
+ operator==(const indexed_accessor_range_base<DerivedT2, BaseT2, T2, PointerT2,
+ ReferenceT2> &lhs,
+ const OtherT &rhs);
+ template <typename OtherT, typename DerivedT2, typename BaseT2, typename T2,
+ typename PointerT2, typename ReferenceT2>
+ friend bool
+ operator!=(const indexed_accessor_range_base<DerivedT2, BaseT2, T2, PointerT2,
+ ReferenceT2> &lhs,
+ const OtherT &rhs);
/// Return the size of this range.
size_t size() const { return count; }
@@ -1364,6 +1367,23 @@ class indexed_accessor_range_base {
/// The size from the owning range.
ptrdiff_t count;
};
+
+// FIXME: Make me a member function instead of friend when it works in C++20.
+template <typename OtherT, typename DerivedT2, typename BaseT2, typename T2,
+ typename PointerT2, typename ReferenceT2>
+bool operator==(const indexed_accessor_range_base<DerivedT2, BaseT2, T2,
+ PointerT2, ReferenceT2> &lhs,
+ const OtherT &rhs) {
+ return std::equal(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
+}
+
+template <typename OtherT, typename DerivedT2, typename BaseT2, typename T2,
+ typename PointerT2, typename ReferenceT2>
+bool operator!=(const indexed_accessor_range_base<DerivedT2, BaseT2, T2,
+ PointerT2, ReferenceT2> &lhs,
+ const OtherT &rhs) {
+ return !(lhs == rhs);
+}
} // end namespace detail
/// This class provides an implementation of a range of
``````````
</details>
https://github.com/llvm/llvm-project/pull/72348
More information about the llvm-commits
mailing list