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 | // <compare> |
12 | |
13 | // template <class ...Ts> struct common_comparison_category |
14 | // template <class ...Ts> using common_comparison_category_t |
15 | |
16 | |
17 | #include <compare> |
18 | #include <type_traits> |
19 | #include <cassert> |
20 | |
21 | #include "test_macros.h" |
22 | |
23 | const volatile void* volatile sink; |
24 | |
25 | template <class Expect, class ...Args> |
26 | void test_cat() { |
27 | using Cat = std::common_comparison_category<Args...>; |
28 | using CatT = typename Cat::type; |
29 | static_assert(std::is_same<CatT, std::common_comparison_category_t<Args...>>::value, "" ); |
30 | static_assert(std::is_same<CatT, Expect>::value, "expected different category" ); |
31 | }; |
32 | |
33 | |
34 | // [class.spaceship]p4: The 'common comparison type' U of a possibly-empty list |
35 | // of 'n' types T0, T1, ..., TN, is defined as follows: |
36 | int main(int, char**) { |
37 | using PO = std::partial_ordering; |
38 | using WO = std::weak_ordering; |
39 | using SO = std::strong_ordering; |
40 | |
41 | // [cmp.common]p2: The member typedef-name type denotes the common comparison |
42 | /// type ([class.spaceship]) of Ts..., the expanded parameter pack, or void if |
43 | // any element of Ts is not a comparison category type. |
44 | { |
45 | test_cat<void, void>(); |
46 | test_cat<void, int*>(); |
47 | test_cat<void, SO&>(); |
48 | test_cat<void, SO const>(); |
49 | test_cat<void, SO*>(); |
50 | test_cat<void, SO, void, SO>(); |
51 | } |
52 | |
53 | // [class.spaceship]p4.1: If at least one Ti is std::partial_ordering, U is |
54 | // std::partial_ordering ([cmp.partialord]). |
55 | { |
56 | test_cat<PO, PO>(); |
57 | test_cat<PO, SO, PO, SO>(); |
58 | test_cat<PO, WO, PO, SO>(); |
59 | } |
60 | |
61 | // [class.spaceship]p4.2: Otherwise, if at least one Ti is std::weak_ordering, |
62 | // U is std::weak_ordering |
63 | { |
64 | test_cat<WO, WO>(); |
65 | test_cat<WO, SO, WO, SO>(); |
66 | } |
67 | |
68 | // [class.spaceship]p4.3: Otherwise, U is std::strong_ordering. |
69 | { |
70 | test_cat<SO, SO>(); |
71 | test_cat<SO, SO, SO>(); |
72 | } |
73 | |
74 | // [cmp.common]p2, note 2: This is std::strong_ordering if the expansion is empty. |
75 | // [class.spaceship]p4.3, note 2: In particular this is the result when n is 0. |
76 | { |
77 | test_cat<SO>(); // empty type list |
78 | } |
79 | |
80 | return 0; |
81 | } |
82 | |