libcxx

libcxx mirror with random patches
git clone https://git.neptards.moe/neptards/libcxx.git
Log | Files | Refs

relops.pass.cpp (8058B)


      1 // -*- C++ -*-
      2 //===----------------------------------------------------------------------===//
      3 //
      4 //                     The LLVM Compiler Infrastructure
      5 //
      6 // This file is dual licensed under the MIT and the University of Illinois Open
      7 // Source Licenses. See LICENSE.TXT for details.
      8 //
      9 //===----------------------------------------------------------------------===//
     10 
     11 // UNSUPPORTED: c++98, c++03, c++11, c++14
     12 
     13 // <variant>
     14 
     15 // template <class ...Types>
     16 // constexpr bool
     17 // operator==(variant<Types...> const&, variant<Types...> const&) noexcept;
     18 //
     19 // template <class ...Types>
     20 // constexpr bool
     21 // operator!=(variant<Types...> const&, variant<Types...> const&) noexcept;
     22 //
     23 // template <class ...Types>
     24 // constexpr bool
     25 // operator<(variant<Types...> const&, variant<Types...> const&) noexcept;
     26 //
     27 // template <class ...Types>
     28 // constexpr bool
     29 // operator>(variant<Types...> const&, variant<Types...> const&) noexcept;
     30 //
     31 // template <class ...Types>
     32 // constexpr bool
     33 // operator<=(variant<Types...> const&, variant<Types...> const&) noexcept;
     34 //
     35 // template <class ...Types>
     36 // constexpr bool
     37 // operator>=(variant<Types...> const&, variant<Types...> const&) noexcept;
     38 
     39 #include <cassert>
     40 #include <type_traits>
     41 #include <utility>
     42 #include <variant>
     43 
     44 #include "test_macros.h"
     45 
     46 #ifndef TEST_HAS_NO_EXCEPTIONS
     47 struct MakeEmptyT {
     48   MakeEmptyT() = default;
     49   MakeEmptyT(MakeEmptyT &&) { throw 42; }
     50   MakeEmptyT &operator=(MakeEmptyT &&) { throw 42; }
     51 };
     52 inline bool operator==(const MakeEmptyT &, const MakeEmptyT &) {
     53   assert(false);
     54   return false;
     55 }
     56 inline bool operator!=(const MakeEmptyT &, const MakeEmptyT &) {
     57   assert(false);
     58   return false;
     59 }
     60 inline bool operator<(const MakeEmptyT &, const MakeEmptyT &) {
     61   assert(false);
     62   return false;
     63 }
     64 inline bool operator<=(const MakeEmptyT &, const MakeEmptyT &) {
     65   assert(false);
     66   return false;
     67 }
     68 inline bool operator>(const MakeEmptyT &, const MakeEmptyT &) {
     69   assert(false);
     70   return false;
     71 }
     72 inline bool operator>=(const MakeEmptyT &, const MakeEmptyT &) {
     73   assert(false);
     74   return false;
     75 }
     76 
     77 template <class Variant> void makeEmpty(Variant &v) {
     78   Variant v2(std::in_place_type<MakeEmptyT>);
     79   try {
     80     v = std::move(v2);
     81     assert(false);
     82   } catch (...) {
     83     assert(v.valueless_by_exception());
     84   }
     85 }
     86 #endif // TEST_HAS_NO_EXCEPTIONS
     87 
     88 struct MyBool {
     89   bool value;
     90   constexpr explicit MyBool(bool v) : value(v) {}
     91   constexpr operator bool() const noexcept { return value; }
     92 };
     93 
     94 struct ComparesToMyBool {
     95   int value = 0;
     96 };
     97 inline constexpr MyBool operator==(const ComparesToMyBool& LHS, const ComparesToMyBool& RHS) noexcept {
     98   return MyBool(LHS.value == RHS.value);
     99 }
    100 inline constexpr MyBool operator!=(const ComparesToMyBool& LHS, const ComparesToMyBool& RHS) noexcept {
    101   return MyBool(LHS.value != RHS.value);
    102 }
    103 inline constexpr MyBool operator<(const ComparesToMyBool& LHS, const ComparesToMyBool& RHS) noexcept {
    104   return MyBool(LHS.value < RHS.value);
    105 }
    106 inline constexpr MyBool operator<=(const ComparesToMyBool& LHS, const ComparesToMyBool& RHS) noexcept {
    107   return MyBool(LHS.value <= RHS.value);
    108 }
    109 inline constexpr MyBool operator>(const ComparesToMyBool& LHS, const ComparesToMyBool& RHS) noexcept {
    110   return MyBool(LHS.value > RHS.value);
    111 }
    112 inline constexpr MyBool operator>=(const ComparesToMyBool& LHS, const ComparesToMyBool& RHS) noexcept {
    113   return MyBool(LHS.value >= RHS.value);
    114 }
    115 
    116 template <class T1, class T2>
    117 void test_equality_basic() {
    118   {
    119     using V = std::variant<T1, T2>;
    120     constexpr V v1(std::in_place_index<0>, T1{42});
    121     constexpr V v2(std::in_place_index<0>, T1{42});
    122     static_assert(v1 == v2, "");
    123     static_assert(v2 == v1, "");
    124     static_assert(!(v1 != v2), "");
    125     static_assert(!(v2 != v1), "");
    126   }
    127   {
    128     using V = std::variant<T1, T2>;
    129     constexpr V v1(std::in_place_index<0>, T1{42});
    130     constexpr V v2(std::in_place_index<0>, T1{43});
    131     static_assert(!(v1 == v2), "");
    132     static_assert(!(v2 == v1), "");
    133     static_assert(v1 != v2, "");
    134     static_assert(v2 != v1, "");
    135   }
    136   {
    137     using V = std::variant<T1, T2>;
    138     constexpr V v1(std::in_place_index<0>, T1{42});
    139     constexpr V v2(std::in_place_index<1>, T2{42});
    140     static_assert(!(v1 == v2), "");
    141     static_assert(!(v2 == v1), "");
    142     static_assert(v1 != v2, "");
    143     static_assert(v2 != v1, "");
    144   }
    145   {
    146     using V = std::variant<T1, T2>;
    147     constexpr V v1(std::in_place_index<1>, T2{42});
    148     constexpr V v2(std::in_place_index<1>, T2{42});
    149     static_assert(v1 == v2, "");
    150     static_assert(v2 == v1, "");
    151     static_assert(!(v1 != v2), "");
    152     static_assert(!(v2 != v1), "");
    153   }
    154 }
    155 
    156 void test_equality() {
    157   test_equality_basic<int, long>();
    158   test_equality_basic<ComparesToMyBool, int>();
    159   test_equality_basic<int, ComparesToMyBool>();
    160   test_equality_basic<ComparesToMyBool, ComparesToMyBool>();
    161 #ifndef TEST_HAS_NO_EXCEPTIONS
    162   {
    163     using V = std::variant<int, MakeEmptyT>;
    164     V v1;
    165     V v2;
    166     makeEmpty(v2);
    167     assert(!(v1 == v2));
    168     assert(!(v2 == v1));
    169     assert(v1 != v2);
    170     assert(v2 != v1);
    171   }
    172   {
    173     using V = std::variant<int, MakeEmptyT>;
    174     V v1;
    175     makeEmpty(v1);
    176     V v2;
    177     assert(!(v1 == v2));
    178     assert(!(v2 == v1));
    179     assert(v1 != v2);
    180     assert(v2 != v1);
    181   }
    182   {
    183     using V = std::variant<int, MakeEmptyT>;
    184     V v1;
    185     makeEmpty(v1);
    186     V v2;
    187     makeEmpty(v2);
    188     assert(v1 == v2);
    189     assert(v2 == v1);
    190     assert(!(v1 != v2));
    191     assert(!(v2 != v1));
    192   }
    193 #endif
    194 }
    195 
    196 template <class Var>
    197 constexpr bool test_less(const Var &l, const Var &r, bool expect_less,
    198                          bool expect_greater) {
    199   static_assert(std::is_same_v<decltype(l < r), bool>, "");
    200   static_assert(std::is_same_v<decltype(l <= r), bool>, "");
    201   static_assert(std::is_same_v<decltype(l > r), bool>, "");
    202   static_assert(std::is_same_v<decltype(l >= r), bool>, "");
    203 
    204   return ((l < r) == expect_less) && (!(l >= r) == expect_less) &&
    205          ((l > r) == expect_greater) && (!(l <= r) == expect_greater);
    206 }
    207 
    208 template <class T1, class T2>
    209 void test_relational_basic() {
    210   { // same index, same value
    211     using V = std::variant<T1, T2>;
    212     constexpr V v1(std::in_place_index<0>, T1{1});
    213     constexpr V v2(std::in_place_index<0>, T1{1});
    214     static_assert(test_less(v1, v2, false, false), "");
    215   }
    216   { // same index, value < other_value
    217     using V = std::variant<T1, T2>;
    218     constexpr V v1(std::in_place_index<0>, T1{0});
    219     constexpr V v2(std::in_place_index<0>, T1{1});
    220     static_assert(test_less(v1, v2, true, false), "");
    221   }
    222   { // same index, value > other_value
    223     using V = std::variant<T1, T2>;
    224     constexpr V v1(std::in_place_index<0>, T1{1});
    225     constexpr V v2(std::in_place_index<0>, T1{0});
    226     static_assert(test_less(v1, v2, false, true), "");
    227   }
    228   { // LHS.index() < RHS.index()
    229     using V = std::variant<T1, T2>;
    230     constexpr V v1(std::in_place_index<0>, T1{0});
    231     constexpr V v2(std::in_place_index<1>, T2{0});
    232     static_assert(test_less(v1, v2, true, false), "");
    233   }
    234   { // LHS.index() > RHS.index()
    235     using V = std::variant<T1, T2>;
    236     constexpr V v1(std::in_place_index<1>, T2{0});
    237     constexpr V v2(std::in_place_index<0>, T1{0});
    238     static_assert(test_less(v1, v2, false, true), "");
    239   }
    240 }
    241 
    242 void test_relational() {
    243   test_relational_basic<int, long>();
    244   test_relational_basic<ComparesToMyBool, int>();
    245   test_relational_basic<int, ComparesToMyBool>();
    246   test_relational_basic<ComparesToMyBool, ComparesToMyBool>();
    247 #ifndef TEST_HAS_NO_EXCEPTIONS
    248   { // LHS.index() < RHS.index(), RHS is empty
    249     using V = std::variant<int, MakeEmptyT>;
    250     V v1;
    251     V v2;
    252     makeEmpty(v2);
    253     assert(test_less(v1, v2, false, true));
    254   }
    255   { // LHS.index() > RHS.index(), LHS is empty
    256     using V = std::variant<int, MakeEmptyT>;
    257     V v1;
    258     makeEmpty(v1);
    259     V v2;
    260     assert(test_less(v1, v2, true, false));
    261   }
    262   { // LHS.index() == RHS.index(), LHS and RHS are empty
    263     using V = std::variant<int, MakeEmptyT>;
    264     V v1;
    265     makeEmpty(v1);
    266     V v2;
    267     makeEmpty(v2);
    268     assert(test_less(v1, v2, false, false));
    269   }
    270 #endif
    271 }
    272 
    273 int main() {
    274   test_equality();
    275   test_relational();
    276 }