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>