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