• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifndef TEST_HAS_NO_EXCEPTIONS
47 struct MakeEmptyT {
48   MakeEmptyT() = default;
MakeEmptyTMakeEmptyT49   MakeEmptyT(MakeEmptyT &&) { throw 42; }
operator =MakeEmptyT50   MakeEmptyT &operator=(MakeEmptyT &&) { throw 42; }
51 };
operator ==(const MakeEmptyT &,const MakeEmptyT &)52 inline bool operator==(const MakeEmptyT &, const MakeEmptyT &) {
53   assert(false);
54   return false;
55 }
operator !=(const MakeEmptyT &,const MakeEmptyT &)56 inline bool operator!=(const MakeEmptyT &, const MakeEmptyT &) {
57   assert(false);
58   return false;
59 }
operator <(const MakeEmptyT &,const MakeEmptyT &)60 inline bool operator<(const MakeEmptyT &, const MakeEmptyT &) {
61   assert(false);
62   return false;
63 }
operator <=(const MakeEmptyT &,const MakeEmptyT &)64 inline bool operator<=(const MakeEmptyT &, const MakeEmptyT &) {
65   assert(false);
66   return false;
67 }
operator >(const MakeEmptyT &,const MakeEmptyT &)68 inline bool operator>(const MakeEmptyT &, const MakeEmptyT &) {
69   assert(false);
70   return false;
71 }
operator >=(const MakeEmptyT &,const MakeEmptyT &)72 inline bool operator>=(const MakeEmptyT &, const MakeEmptyT &) {
73   assert(false);
74   return false;
75 }
76 
makeEmpty(Variant & v)77 template <class Variant> void makeEmpty(Variant &v) {
78   Variant v2(std::in_place_type<MakeEmptyT>);
79   try {
80     v = std::move(v2);
81     assert(false);
82   } catch (...) {
83     assert(v.valueless_by_exception());
84   }
85 }
86 #endif // TEST_HAS_NO_EXCEPTIONS
87 
test_equality()88 void test_equality() {
89   {
90     using V = std::variant<int, long>;
91     constexpr V v1(42);
92     constexpr V v2(42);
93     static_assert(v1 == v2, "");
94     static_assert(v2 == v1, "");
95     static_assert(!(v1 != v2), "");
96     static_assert(!(v2 != v1), "");
97   }
98   {
99     using V = std::variant<int, long>;
100     constexpr V v1(42);
101     constexpr V v2(43);
102     static_assert(!(v1 == v2), "");
103     static_assert(!(v2 == v1), "");
104     static_assert(v1 != v2, "");
105     static_assert(v2 != v1, "");
106   }
107   {
108     using V = std::variant<int, long>;
109     constexpr V v1(42);
110     constexpr V v2(42l);
111     static_assert(!(v1 == v2), "");
112     static_assert(!(v2 == v1), "");
113     static_assert(v1 != v2, "");
114     static_assert(v2 != v1, "");
115   }
116   {
117     using V = std::variant<int, long>;
118     constexpr V v1(42l);
119     constexpr V v2(42l);
120     static_assert(v1 == v2, "");
121     static_assert(v2 == v1, "");
122     static_assert(!(v1 != v2), "");
123     static_assert(!(v2 != v1), "");
124   }
125 #ifndef TEST_HAS_NO_EXCEPTIONS
126   {
127     using V = std::variant<int, MakeEmptyT>;
128     V v1;
129     V v2;
130     makeEmpty(v2);
131     assert(!(v1 == v2));
132     assert(!(v2 == v1));
133     assert(v1 != v2);
134     assert(v2 != v1);
135   }
136   {
137     using V = std::variant<int, MakeEmptyT>;
138     V v1;
139     makeEmpty(v1);
140     V v2;
141     assert(!(v1 == v2));
142     assert(!(v2 == v1));
143     assert(v1 != v2);
144     assert(v2 != v1);
145   }
146   {
147     using V = std::variant<int, MakeEmptyT>;
148     V v1;
149     makeEmpty(v1);
150     V v2;
151     makeEmpty(v2);
152     assert(v1 == v2);
153     assert(v2 == v1);
154     assert(!(v1 != v2));
155     assert(!(v2 != v1));
156   }
157 #endif
158 }
159 
160 template <class Var>
test_less(const Var & l,const Var & r,bool expect_less,bool expect_greater)161 constexpr bool test_less(const Var &l, const Var &r, bool expect_less,
162                          bool expect_greater) {
163   return ((l < r) == expect_less) && (!(l >= r) == expect_less) &&
164          ((l > r) == expect_greater) && (!(l <= r) == expect_greater);
165 }
166 
test_relational()167 void test_relational() {
168   { // same index, same value
169     using V = std::variant<int, long>;
170     constexpr V v1(1);
171     constexpr V v2(1);
172     static_assert(test_less(v1, v2, false, false), "");
173   }
174   { // same index, value < other_value
175     using V = std::variant<int, long>;
176     constexpr V v1(0);
177     constexpr V v2(1);
178     static_assert(test_less(v1, v2, true, false), "");
179   }
180   { // same index, value > other_value
181     using V = std::variant<int, long>;
182     constexpr V v1(1);
183     constexpr V v2(0);
184     static_assert(test_less(v1, v2, false, true), "");
185   }
186   { // LHS.index() < RHS.index()
187     using V = std::variant<int, long>;
188     constexpr V v1(0);
189     constexpr V v2(0l);
190     static_assert(test_less(v1, v2, true, false), "");
191   }
192   { // LHS.index() > RHS.index()
193     using V = std::variant<int, long>;
194     constexpr V v1(0l);
195     constexpr V v2(0);
196     static_assert(test_less(v1, v2, false, true), "");
197   }
198 #ifndef TEST_HAS_NO_EXCEPTIONS
199   { // LHS.index() < RHS.index(), RHS is empty
200     using V = std::variant<int, MakeEmptyT>;
201     V v1;
202     V v2;
203     makeEmpty(v2);
204     assert(test_less(v1, v2, false, true));
205   }
206   { // LHS.index() > RHS.index(), LHS is empty
207     using V = std::variant<int, MakeEmptyT>;
208     V v1;
209     makeEmpty(v1);
210     V v2;
211     assert(test_less(v1, v2, true, false));
212   }
213   { // LHS.index() == RHS.index(), LHS and RHS are empty
214     using V = std::variant<int, MakeEmptyT>;
215     V v1;
216     makeEmpty(v1);
217     V v2;
218     makeEmpty(v2);
219     assert(test_less(v1, v2, false, false));
220   }
221 #endif
222 }
223 
main()224 int main() {
225   test_equality();
226   test_relational();
227 }
228