Don't require relops on variant alternatives to all return the same
type.

Libc++ correctly asserts that a set of visitors for a variant all
return the same type. However, we use the visitation machinary to
perform relational operations. This causes a static assertion when
some of the alternatives relops return a UDT which is implicitly
convertible to bool instead of 'bool' exactly.

llvm-svn: 342560
Cr-Mirrored-From: sso://chromium.googlesource.com/_direct/external/github.com/llvm/llvm-project
Cr-Mirrored-Commit: 7dca3127c2ad98c3f5a291d8f4878348772bb558
diff --git a/include/variant b/include/variant
index 6a52356..f9505bf 100644
--- a/include/variant
+++ b/include/variant
@@ -1438,6 +1438,16 @@
   return _VSTD::get_if<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
 }
 
+template <class _Operator>
+struct __convert_to_bool {
+  template <class _T1, class _T2>
+  _LIBCPP_INLINE_VISIBILITY constexpr bool operator()(_T1 && __t1, _T2&& __t2) const {
+    static_assert(std::is_convertible<decltype(_Operator{}(_VSTD::forward<_T1>(__t1), _VSTD::forward<_T2>(__t2))), bool>::value,
+        "the relational operator does not return a type which is implicitly convertible to bool");
+    return _Operator{}(_VSTD::forward<_T1>(__t1), _VSTD::forward<_T2>(__t2));
+  }
+};
+
 template <class... _Types>
 inline _LIBCPP_INLINE_VISIBILITY
 constexpr bool operator==(const variant<_Types...>& __lhs,
@@ -1445,7 +1455,7 @@
   using __variant_detail::__visitation::__variant;
   if (__lhs.index() != __rhs.index()) return false;
   if (__lhs.valueless_by_exception()) return true;
-  return __variant::__visit_value_at(__lhs.index(), equal_to<>{}, __lhs, __rhs);
+  return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<equal_to<>>{}, __lhs, __rhs);
 }
 
 template <class... _Types>
@@ -1456,7 +1466,7 @@
   if (__lhs.index() != __rhs.index()) return true;
   if (__lhs.valueless_by_exception()) return false;
   return __variant::__visit_value_at(
-      __lhs.index(), not_equal_to<>{}, __lhs, __rhs);
+      __lhs.index(), __convert_to_bool<not_equal_to<>>{}, __lhs, __rhs);
 }
 
 template <class... _Types>
@@ -1468,7 +1478,7 @@
   if (__lhs.valueless_by_exception()) return true;
   if (__lhs.index() < __rhs.index()) return true;
   if (__lhs.index() > __rhs.index()) return false;
-  return __variant::__visit_value_at(__lhs.index(), less<>{}, __lhs, __rhs);
+  return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<less<>>{}, __lhs, __rhs);
 }
 
 template <class... _Types>
@@ -1480,7 +1490,7 @@
   if (__rhs.valueless_by_exception()) return true;
   if (__lhs.index() > __rhs.index()) return true;
   if (__lhs.index() < __rhs.index()) return false;
-  return __variant::__visit_value_at(__lhs.index(), greater<>{}, __lhs, __rhs);
+  return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<greater<>>{}, __lhs, __rhs);
 }
 
 template <class... _Types>
@@ -1493,7 +1503,7 @@
   if (__lhs.index() < __rhs.index()) return true;
   if (__lhs.index() > __rhs.index()) return false;
   return __variant::__visit_value_at(
-      __lhs.index(), less_equal<>{}, __lhs, __rhs);
+      __lhs.index(), __convert_to_bool<less_equal<>>{}, __lhs, __rhs);
 }
 
 template <class... _Types>
@@ -1506,7 +1516,7 @@
   if (__lhs.index() > __rhs.index()) return true;
   if (__lhs.index() < __rhs.index()) return false;
   return __variant::__visit_value_at(
-      __lhs.index(), greater_equal<>{}, __lhs, __rhs);
+      __lhs.index(), __convert_to_bool<greater_equal<>>{}, __lhs, __rhs);
 }
 
 template <class _Visitor, class... _Vs>