1 // -*- C++ -*-
2 //===----------------------------------------------------------------------===//
3 //
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //
8 //===----------------------------------------------------------------------===//
9
10 // UNSUPPORTED: c++03, c++11, c++14
11
12 // <variant>
13
14 // template <class ...Types>
15 // constexpr bool
16 // operator==(variant<Types...> const&, variant<Types...> const&) noexcept;
17 //
18 // template <class ...Types>
19 // constexpr bool
20 // operator!=(variant<Types...> const&, variant<Types...> const&) noexcept;
21 //
22 // template <class ...Types>
23 // constexpr bool
24 // operator<(variant<Types...> const&, variant<Types...> const&) noexcept;
25 //
26 // template <class ...Types>
27 // constexpr bool
28 // operator>(variant<Types...> const&, variant<Types...> const&) noexcept;
29 //
30 // template <class ...Types>
31 // constexpr bool
32 // operator<=(variant<Types...> const&, variant<Types...> const&) noexcept;
33 //
34 // template <class ...Types>
35 // constexpr bool
36 // operator>=(variant<Types...> const&, variant<Types...> const&) noexcept;
37
38 #include <cassert>
39 #include <type_traits>
40 #include <utility>
41 #include <variant>
42
43 #include "test_macros.h"
44
45
46 struct MyBoolExplicit {
47 bool value;
MyBoolExplicitMyBoolExplicit48 constexpr explicit MyBoolExplicit(bool v) : value(v) {}
operator boolMyBoolExplicit49 constexpr explicit operator bool() const noexcept { return value; }
50 };
51
52 struct ComparesToMyBoolExplicit {
53 int value = 0;
54 };
operator ==(const ComparesToMyBoolExplicit & LHS,const ComparesToMyBoolExplicit & RHS)55 inline constexpr MyBoolExplicit operator==(const ComparesToMyBoolExplicit& LHS, const ComparesToMyBoolExplicit& RHS) noexcept {
56 return MyBoolExplicit(LHS.value == RHS.value);
57 }
operator !=(const ComparesToMyBoolExplicit & LHS,const ComparesToMyBoolExplicit & RHS)58 inline constexpr MyBoolExplicit operator!=(const ComparesToMyBoolExplicit& LHS, const ComparesToMyBoolExplicit& RHS) noexcept {
59 return MyBoolExplicit(LHS.value != RHS.value);
60 }
operator <(const ComparesToMyBoolExplicit & LHS,const ComparesToMyBoolExplicit & RHS)61 inline constexpr MyBoolExplicit operator<(const ComparesToMyBoolExplicit& LHS, const ComparesToMyBoolExplicit& RHS) noexcept {
62 return MyBoolExplicit(LHS.value < RHS.value);
63 }
operator <=(const ComparesToMyBoolExplicit & LHS,const ComparesToMyBoolExplicit & RHS)64 inline constexpr MyBoolExplicit operator<=(const ComparesToMyBoolExplicit& LHS, const ComparesToMyBoolExplicit& RHS) noexcept {
65 return MyBoolExplicit(LHS.value <= RHS.value);
66 }
operator >(const ComparesToMyBoolExplicit & LHS,const ComparesToMyBoolExplicit & RHS)67 inline constexpr MyBoolExplicit operator>(const ComparesToMyBoolExplicit& LHS, const ComparesToMyBoolExplicit& RHS) noexcept {
68 return MyBoolExplicit(LHS.value > RHS.value);
69 }
operator >=(const ComparesToMyBoolExplicit & LHS,const ComparesToMyBoolExplicit & RHS)70 inline constexpr MyBoolExplicit operator>=(const ComparesToMyBoolExplicit& LHS, const ComparesToMyBoolExplicit& RHS) noexcept {
71 return MyBoolExplicit(LHS.value >= RHS.value);
72 }
73
74
main(int,char **)75 int main(int, char**) {
76 using V = std::variant<int, ComparesToMyBoolExplicit>;
77 V v1(42);
78 V v2(101);
79 // expected-error-re@variant:* 6 {{static_assert failed {{.*}}"the relational operator does not return a type which is implicitly convertible to bool"}}
80 // expected-error@variant:* 6 {{no viable conversion}}
81 (void)(v1 == v2); // expected-note {{here}}
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
88 return 0;
89 }
90