xref: /llvm-project/libcxx/test/std/utilities/optional/optional.comp_with_t/compare.three_way.pass.cpp (revision 03cda77409023e64d6338dcb4e36bf1e40b33ea3)
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
10 
11 // <optional>
12 
13 // [optional.comp.with.t], comparison with T
14 
15 // template<class T, class U>
16 //     requires (!is-derived-from-optional<U>) && three_way_comparable_with<T, U>
17 //   constexpr compare_three_way_result_t<T, U>
18 //     operator<=>(const optional<T>&, const U&);
19 
20 #include <cassert>
21 #include <compare>
22 #include <optional>
23 
24 #include "test_comparisons.h"
25 
26 struct SomeInt {
27   int value_;
28 
SomeIntSomeInt29   constexpr explicit SomeInt(int value = 0) : value_(value) {}
30 
31   auto operator<=>(const SomeInt&) const = default;
32 };
33 
34 template <class T, class U>
35 concept HasSpaceship = requires(T t, U u) { t <=> u; };
36 
37 // SFINAE tests.
38 
39 static_assert(std::three_way_comparable_with<std::optional<int>, std::optional<int>>);
40 static_assert(HasSpaceship<std::optional<int>, std::optional<int>>);
41 
42 static_assert(std::three_way_comparable_with<std::optional<SomeInt>, std::optional<SomeInt>>);
43 static_assert(HasSpaceship<std::optional<SomeInt>, std::optional<SomeInt>>);
44 
45 static_assert(!HasSpaceship<std::optional<int>, std::optional<SomeInt>>);
46 
47 // Runtime and static tests.
48 
test_custom_integral()49 constexpr void test_custom_integral() {
50   {
51     SomeInt t{3};
52     std::optional<SomeInt> op{3};
53     assert((t <=> op) == std::strong_ordering::equal);
54     assert(testOrder(t, op, std::strong_ordering::equal));
55   }
56   {
57     SomeInt t{2};
58     std::optional<SomeInt> op{3};
59     assert((t <=> op) == std::strong_ordering::less);
60     assert(testOrder(t, op, std::strong_ordering::less));
61   }
62   {
63     SomeInt t{3};
64     std::optional<SomeInt> op{2};
65     assert((t <=> op) == std::strong_ordering::greater);
66     assert(testOrder(t, op, std::strong_ordering::greater));
67   }
68 }
69 
test_int()70 constexpr void test_int() {
71   {
72     int t{3};
73     std::optional<int> op{3};
74     assert((t <=> op) == std::strong_ordering::equal);
75     assert(testOrder(t, op, std::strong_ordering::equal));
76   }
77   {
78     int t{2};
79     std::optional<int> op{3};
80     assert((t <=> op) == std::strong_ordering::less);
81     assert(testOrder(t, op, std::strong_ordering::less));
82   }
83   {
84     int t{3};
85     std::optional<int> op{2};
86     assert((t <=> op) == std::strong_ordering::greater);
87     assert(testOrder(t, op, std::strong_ordering::greater));
88   }
89 }
90 
test()91 constexpr bool test() {
92   test_custom_integral();
93   test_int();
94 
95   return true;
96 }
97 
main(int,char **)98 int main(int, char**) {
99   assert(test());
100   static_assert(test());
101   return 0;
102 }
103