Home | History | Annotate | Download | only in cmp.common
      1 //===----------------------------------------------------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is dual licensed under the MIT and the University of Illinois Open
      6 // Source Licenses. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 // UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
     11 
     12 // <compare>
     13 
     14 // template <class ...Ts> struct common_comparison_category
     15 // template <class ...Ts> using common_comparison_category_t
     16 
     17 
     18 #include <compare>
     19 #include <type_traits>
     20 #include <cassert>
     21 
     22 #include "test_macros.h"
     23 
     24 const volatile void* volatile sink;
     25 
     26 template <class Expect, class ...Args>
     27 void test_cat() {
     28   using Cat = std::common_comparison_category<Args...>;
     29   using CatT = typename Cat::type;
     30   static_assert(std::is_same<CatT, std::common_comparison_category_t<Args...>>::value, "");
     31   static_assert(std::is_same<CatT, Expect>::value, "expected different category");
     32 };
     33 
     34 
     35 // [class.spaceship]p4: The 'common comparison type' U of a possibly-empty list
     36 //   of 'n' types T0, T1, ..., TN, is defined as follows:
     37 int main() {
     38   using WE = std::weak_equality;
     39   using SE = std::strong_equality;
     40   using PO = std::partial_ordering;
     41   using WO = std::weak_ordering;
     42   using SO = std::strong_ordering;
     43 
     44   // [class.spaceship]p4.1: If any Ti is not a comparison category tpe, U is void.
     45   {
     46     test_cat<void, void>();
     47     test_cat<void, int*>();
     48     test_cat<void, SO&>();
     49     test_cat<void, SO const>();
     50     test_cat<void, SO*>();
     51     test_cat<void, SO, void, SO>();
     52   }
     53 
     54   // [class.spaceship]p4.2: Otherwise, if at least on Ti is
     55   // std::weak_equality, or at least one Ti is std::strong_equality and at least
     56   // one Tj is std::partial_ordering or std::weak_ordering, U is std::weak_equality
     57   {
     58     test_cat<WE, WE>();
     59     test_cat<WE, SO, WE, SO>();
     60     test_cat<WE, SE, SO, PO>();
     61     test_cat<WE, WO, SO, SE>();
     62   }
     63 
     64   // [class.spaceship]p4.3: Otherwise, if at least one Ti is std::strong_equality,
     65   // U is std::strong_equality
     66   {
     67     test_cat<SE, SE>();
     68     test_cat<SE, SO, SE, SO>();
     69   }
     70 
     71   // [class.spaceship]p4.4: Otherwise, if at least one Ti is std::partial_ordering,
     72   // U is std::partial_ordering
     73   {
     74     test_cat<PO, PO>();
     75     test_cat<PO, SO, PO, SO>();
     76     test_cat<PO, WO, PO, SO>();
     77   }
     78 
     79   // [class.spaceship]p4.5: Otherwise, if at least one Ti is std::weak_ordering,
     80   // U is std::weak_ordering
     81   {
     82     test_cat<WO, WO>();
     83     test_cat<WO, SO, WO, SO>();
     84   }
     85 
     86   // [class.spaceship]p4.6: Otherwise, U is std::strong_ordering. [Note: in
     87   // particular this is the result when n is 0. -- end note]
     88   {
     89     test_cat<SO>(); // empty type list
     90     test_cat<SO, SO>();
     91     test_cat<SO, SO, SO>();
     92   }
     93 }
     94