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