xref: /llvm-project/libcxx/test/std/language.support/cmp/cmp.common/common_comparison_category.pass.cpp (revision 4ff2fe1df0cea28e3ef2963116385c86bf3b5055)
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>
test_cat()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:
main(int,char **)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