Home | History | Annotate | Download | only in cmp.strongord
      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 // class strong_ordering
     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 void test_static_members() {
     26   DoNotOptimize(&std::strong_ordering::less);
     27   DoNotOptimize(&std::strong_ordering::equal);
     28   DoNotOptimize(&std::strong_ordering::equivalent);
     29   DoNotOptimize(&std::strong_ordering::greater);
     30 }
     31 
     32 void test_signatures() {
     33   auto& Eq = std::strong_ordering::equivalent;
     34 
     35   ASSERT_NOEXCEPT(Eq == 0);
     36   ASSERT_NOEXCEPT(0 == Eq);
     37   ASSERT_NOEXCEPT(Eq != 0);
     38   ASSERT_NOEXCEPT(0 != Eq);
     39   ASSERT_NOEXCEPT(0 < Eq);
     40   ASSERT_NOEXCEPT(Eq < 0);
     41   ASSERT_NOEXCEPT(0 <= Eq);
     42   ASSERT_NOEXCEPT(Eq <= 0);
     43   ASSERT_NOEXCEPT(0 > Eq);
     44   ASSERT_NOEXCEPT(Eq > 0);
     45   ASSERT_NOEXCEPT(0 >= Eq);
     46   ASSERT_NOEXCEPT(Eq >= 0);
     47 #ifndef TEST_HAS_NO_SPACESHIP_OPERATOR
     48   ASSERT_NOEXCEPT(0 <=> Eq);
     49   ASSERT_NOEXCEPT(Eq <=> 0);
     50   ASSERT_SAME_TYPE(decltype(Eq <=> 0), std::strong_ordering);
     51   ASSERT_SAME_TYPE(decltype(0 <=> Eq), std::strong_ordering);
     52 #endif
     53 }
     54 
     55 constexpr bool test_conversion() {
     56   static_assert(std::is_convertible<const std::strong_ordering&,
     57       std::weak_equality>::value, "");
     58   { // value == 0
     59     auto V = std::strong_ordering::equivalent;
     60     std::weak_equality WV = V;
     61     assert(WV == 0);
     62   }
     63   std::strong_ordering WeakTestCases[] = {
     64       std::strong_ordering::less,
     65       std::strong_ordering::greater,
     66   };
     67   for (auto V : WeakTestCases)
     68   { // value != 0
     69     std::weak_equality WV = V;
     70     assert(WV != 0);
     71   }
     72   static_assert(std::is_convertible<const std::strong_ordering&,
     73       std::strong_equality>::value, "");
     74   { // value == 0
     75     auto V = std::strong_ordering::equivalent;
     76     std::strong_equality WV = V;
     77     assert(WV == 0);
     78   }
     79   { // value == 0
     80     auto V = std::strong_ordering::equal;
     81     std::strong_equality WV = V;
     82     assert(WV == 0);
     83   }
     84   std::strong_ordering StrongTestCases[] = {
     85       std::strong_ordering::less,
     86       std::strong_ordering::greater,
     87   };
     88   for (auto V : StrongTestCases)
     89   { // value != 0
     90     std::strong_equality WV = V;
     91     assert(WV != 0);
     92   }
     93 
     94   static_assert(std::is_convertible<const std::strong_ordering&,
     95       std::partial_ordering>::value, "");
     96   { // value == 0
     97     auto V = std::strong_ordering::equivalent;
     98     std::partial_ordering WV = V;
     99     assert(WV == 0);
    100   }
    101   { // value < 0
    102     auto V = std::strong_ordering::less;
    103     std::partial_ordering WV = V;
    104     assert(WV < 0);
    105   }
    106   { // value > 0
    107     auto V = std::strong_ordering::greater;
    108     std::partial_ordering WV = V;
    109     assert(WV > 0);
    110   }
    111 
    112   static_assert(std::is_convertible<const std::strong_ordering&,
    113       std::weak_ordering>::value, "");
    114   { // value == 0
    115     auto V = std::strong_ordering::equivalent;
    116     std::weak_ordering WV = V;
    117     assert(WV == 0);
    118   }
    119   { // value < 0
    120     auto V = std::strong_ordering::less;
    121     std::weak_ordering WV = V;
    122     assert(WV < 0);
    123   }
    124   { // value > 0
    125     auto V = std::strong_ordering::greater;
    126     std::weak_ordering WV = V;
    127     assert(WV > 0);
    128   }
    129   return true;
    130 }
    131 
    132 constexpr bool test_constexpr() {
    133   auto& Eq = std::strong_ordering::equal;
    134   auto& Equiv = std::strong_ordering::equivalent;
    135   auto& Less = std::strong_ordering::less;
    136   auto& Greater = std::strong_ordering::greater;
    137   struct {
    138     std::strong_ordering Value;
    139     bool ExpectEq;
    140     bool ExpectNeq;
    141     bool ExpectLess;
    142     bool ExpectGreater;
    143   } TestCases[] = {
    144       {Eq, true, false, false, false},
    145       {Equiv, true, false, false, false},
    146       {Less, false, true, true, false},
    147       {Greater, false, true, false, true},
    148   };
    149   for (auto TC : TestCases) {
    150     auto V = TC.Value;
    151     assert((V == 0) == TC.ExpectEq);
    152     assert((0 == V) == TC.ExpectEq);
    153     assert((V != 0) == TC.ExpectNeq);
    154     assert((0 != V) == TC.ExpectNeq);
    155 
    156     assert((V < 0) == TC.ExpectLess);
    157     assert((V > 0) == TC.ExpectGreater);
    158     assert((V <= 0) == (TC.ExpectLess || TC.ExpectEq));
    159     assert((V >= 0) == (TC.ExpectGreater || TC.ExpectEq));
    160 
    161     assert((0 < V) == TC.ExpectGreater);
    162     assert((0 > V) == TC.ExpectLess);
    163     assert((0 <= V) == (TC.ExpectGreater || TC.ExpectEq));
    164     assert((0 >= V) == (TC.ExpectLess || TC.ExpectEq));
    165   }
    166 #ifndef TEST_HAS_NO_SPACESHIP_OPERATOR
    167   {
    168     std::strong_ordering res = (Eq <=> 0);
    169     ((void)res);
    170     res = (0 <=> Eq);
    171     ((void)res);
    172   }
    173   enum ExpectRes {
    174     ER_Greater,
    175     ER_Less,
    176     ER_Equiv
    177   };
    178   struct {
    179     std::strong_ordering Value;
    180     ExpectRes Expect;
    181   } SpaceshipTestCases[] = {
    182       {std::strong_ordering::equivalent, ER_Equiv},
    183       {std::strong_ordering::less, ER_Less},
    184       {std::strong_ordering::greater, ER_Greater},
    185   };
    186   for (auto TC : SpaceshipTestCases)
    187   {
    188     std::strong_ordering Res = (0 <=> TC.Value);
    189     switch (TC.Expect) {
    190     case ER_Equiv:
    191       assert(Res == 0);
    192       assert(0 == Res);
    193       break;
    194     case ER_Less:
    195       assert(Res < 0);
    196       break;
    197     case ER_Greater:
    198       assert(Res > 0);
    199       break;
    200     }
    201   }
    202 #endif
    203 
    204   return true;
    205 }
    206 
    207 int main() {
    208   test_static_members();
    209   test_signatures();
    210   static_assert(test_conversion(), "conversion test failed");
    211   static_assert(test_constexpr(), "constexpr test failed");
    212 }
    213