1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
10 
11 // template<class T2, class E2> requires (!is_void_v<T2>)
12 //   friend constexpr bool operator==(const expected& x, const expected<T2, E2>& y);
13 
14 #include <cassert>
15 #include <concepts>
16 #include <expected>
17 #include <type_traits>
18 #include <utility>
19 
20 #include "test_macros.h"
21 
22 // Test constraint
23 template <class T1, class T2>
24 concept CanCompare = requires(T1 t1, T2 t2) { t1 == t2; };
25 
26 struct Foo{};
27 static_assert(!CanCompare<Foo, Foo>);
28 
29 static_assert(CanCompare<std::expected<int, int>, std::expected<int, int>>);
30 static_assert(CanCompare<std::expected<int, int>, std::expected<short, short>>);
31 
32 // Note this is true because other overloads are unconstrained
33 static_assert(CanCompare<std::expected<int, int>, std::expected<void, int>>);
34 
35 constexpr bool test() {
36   // x.has_value() && y.has_value()
37   {
38     const std::expected<int, int> e1(5);
39     const std::expected<int, int> e2(10);
40     const std::expected<int, int> e3(5);
41     assert(e1 != e2);
42     assert(e1 == e3);
43   }
44 
45   // !x.has_value() && y.has_value()
46   {
47     const std::expected<int, int> e1(std::unexpect, 5);
48     const std::expected<int, int> e2(10);
49     const std::expected<int, int> e3(5);
50     assert(e1 != e2);
51     assert(e1 != e3);
52   }
53 
54   // x.has_value() && !y.has_value()
55   {
56     const std::expected<int, int> e1(5);
57     const std::expected<int, int> e2(std::unexpect, 10);
58     const std::expected<int, int> e3(std::unexpect, 5);
59     assert(e1 != e2);
60     assert(e1 != e3);
61   }
62 
63   // !x.has_value() && !y.has_value()
64   {
65     const std::expected<int, int> e1(std::unexpect, 5);
66     const std::expected<int, int> e2(std::unexpect, 10);
67     const std::expected<int, int> e3(std::unexpect, 5);
68     assert(e1 != e2);
69     assert(e1 == e3);
70   }
71 
72   return true;
73 }
74 
75 int main(int, char**) {
76   test();
77   static_assert(test());
78   return 0;
79 }
80