1 // -*- C++ -*-
2 //===----------------------------------------------------------------------===//
3 //
4 //                     The LLVM Compiler Infrastructure
5 //
6 // This file is dual licensed under the MIT and the University of Illinois Open
7 // Source Licenses. See LICENSE.TXT for details.
8 //
9 //===----------------------------------------------------------------------===//
10 
11 // UNSUPPORTED: c++98, c++03, c++11, c++14
12 
13 // <variant>
14 
15 // template <class ...Types>
16 // constexpr bool
17 // operator==(variant<Types...> const&, variant<Types...> const&) noexcept;
18 //
19 // template <class ...Types>
20 // constexpr bool
21 // operator!=(variant<Types...> const&, variant<Types...> const&) noexcept;
22 //
23 // template <class ...Types>
24 // constexpr bool
25 // operator<(variant<Types...> const&, variant<Types...> const&) noexcept;
26 //
27 // template <class ...Types>
28 // constexpr bool
29 // operator>(variant<Types...> const&, variant<Types...> const&) noexcept;
30 //
31 // template <class ...Types>
32 // constexpr bool
33 // operator<=(variant<Types...> const&, variant<Types...> const&) noexcept;
34 //
35 // template <class ...Types>
36 // constexpr bool
37 // operator>=(variant<Types...> const&, variant<Types...> const&) noexcept;
38 
39 #include <cassert>
40 #include <type_traits>
41 #include <utility>
42 #include <variant>
43 
44 #include "test_macros.h"
45 
46 
47 struct MyBoolExplicit {
48   bool value;
MyBoolExplicitMyBoolExplicit49   constexpr explicit MyBoolExplicit(bool v) : value(v) {}
operator boolMyBoolExplicit50   constexpr explicit operator bool() const noexcept { return value; }
51 };
52 
53 struct ComparesToMyBoolExplicit {
54   int value = 0;
55 };
operator ==(const ComparesToMyBoolExplicit & LHS,const ComparesToMyBoolExplicit & RHS)56 inline constexpr MyBoolExplicit operator==(const ComparesToMyBoolExplicit& LHS, const ComparesToMyBoolExplicit& RHS) noexcept {
57   return MyBoolExplicit(LHS.value == RHS.value);
58 }
operator !=(const ComparesToMyBoolExplicit & LHS,const ComparesToMyBoolExplicit & RHS)59 inline constexpr MyBoolExplicit operator!=(const ComparesToMyBoolExplicit& LHS, const ComparesToMyBoolExplicit& RHS) noexcept {
60   return MyBoolExplicit(LHS.value != RHS.value);
61 }
operator <(const ComparesToMyBoolExplicit & LHS,const ComparesToMyBoolExplicit & RHS)62 inline constexpr MyBoolExplicit operator<(const ComparesToMyBoolExplicit& LHS, const ComparesToMyBoolExplicit& RHS) noexcept {
63   return MyBoolExplicit(LHS.value < RHS.value);
64 }
operator <=(const ComparesToMyBoolExplicit & LHS,const ComparesToMyBoolExplicit & RHS)65 inline constexpr MyBoolExplicit operator<=(const ComparesToMyBoolExplicit& LHS, const ComparesToMyBoolExplicit& RHS) noexcept {
66   return MyBoolExplicit(LHS.value <= RHS.value);
67 }
operator >(const ComparesToMyBoolExplicit & LHS,const ComparesToMyBoolExplicit & RHS)68 inline constexpr MyBoolExplicit operator>(const ComparesToMyBoolExplicit& LHS, const ComparesToMyBoolExplicit& RHS) noexcept {
69   return MyBoolExplicit(LHS.value > RHS.value);
70 }
operator >=(const ComparesToMyBoolExplicit & LHS,const ComparesToMyBoolExplicit & RHS)71 inline constexpr MyBoolExplicit operator>=(const ComparesToMyBoolExplicit& LHS, const ComparesToMyBoolExplicit& RHS) noexcept {
72   return MyBoolExplicit(LHS.value >= RHS.value);
73 }
74 
75 
main()76 int main() {
77   using V = std::variant<int, ComparesToMyBoolExplicit>;
78   V v1(42);
79   V v2(101);
80   // expected-error-re@variant:* 6 {{static_assert failed {{.*}}"the relational operator does not return a type which is implicitly convertible to bool"}}
81   // expected-error@variant:* 6 {{no viable conversion}}
82   (void)(v1 == v2); // expected-note {{here}}
83   (void)(v1 != v2); // expected-note {{here}}
84   (void)(v1 < v2); // expected-note {{here}}
85   (void)(v1 <= v2); // expected-note {{here}}
86   (void)(v1 > v2); // expected-note {{here}}
87   (void)(v1 >= v2); // expected-note {{here}}
88 }
89