Home | History | Annotate | Download | only in support
      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 //  A set of routines for testing the comparison operators of a type
     10 //
     11 //      XXXX6 tests all six comparison operators
     12 //      XXXX2 tests only op== and op!=
     13 //
     14 //      AssertComparisonsXAreNoexcept       static_asserts that the operations are all noexcept.
     15 //      AssertComparisonsXReturnBool        static_asserts that the operations return bool.
     16 //      AssertComparisonsXConvertibleToBool static_asserts that the operations return something convertible to bool.
     17 
     18 
     19 #ifndef TEST_COMPARISONS_H
     20 #define TEST_COMPARISONS_H
     21 
     22 #include <type_traits>
     23 #include "test_macros.h"
     24 
     25 //  Test all six comparison operations for sanity
     26 template <class T>
     27 TEST_CONSTEXPR_CXX14 bool testComparisons6(const T& t1, const T& t2, bool isEqual, bool isLess)
     28 {
     29     if (isEqual)
     30         {
     31         if (!(t1 == t2)) return false;
     32         if (!(t2 == t1)) return false;
     33         if ( (t1 != t2)) return false;
     34         if ( (t2 != t1)) return false;
     35         if ( (t1  < t2)) return false;
     36         if ( (t2  < t1)) return false;
     37         if (!(t1 <= t2)) return false;
     38         if (!(t2 <= t1)) return false;
     39         if ( (t1  > t2)) return false;
     40         if ( (t2  > t1)) return false;
     41         if (!(t1 >= t2)) return false;
     42         if (!(t2 >= t1)) return false;
     43         }
     44     else if (isLess)
     45         {
     46         if ( (t1 == t2)) return false;
     47         if ( (t2 == t1)) return false;
     48         if (!(t1 != t2)) return false;
     49         if (!(t2 != t1)) return false;
     50         if (!(t1  < t2)) return false;
     51         if ( (t2  < t1)) return false;
     52         if (!(t1 <= t2)) return false;
     53         if ( (t2 <= t1)) return false;
     54         if ( (t1  > t2)) return false;
     55         if (!(t2  > t1)) return false;
     56         if ( (t1 >= t2)) return false;
     57         if (!(t2 >= t1)) return false;
     58         }
     59     else /* greater */
     60         {
     61         if ( (t1 == t2)) return false;
     62         if ( (t2 == t1)) return false;
     63         if (!(t1 != t2)) return false;
     64         if (!(t2 != t1)) return false;
     65         if ( (t1  < t2)) return false;
     66         if (!(t2  < t1)) return false;
     67         if ( (t1 <= t2)) return false;
     68         if (!(t2 <= t1)) return false;
     69         if (!(t1  > t2)) return false;
     70         if ( (t2  > t1)) return false;
     71         if (!(t1 >= t2)) return false;
     72         if ( (t2 >= t1)) return false;
     73         }
     74 
     75     return true;
     76 }
     77 
     78 //  Easy call when you can init from something already comparable.
     79 template <class T, class Param>
     80 TEST_CONSTEXPR_CXX14 bool testComparisons6Values(Param val1, Param val2)
     81 {
     82     const bool isEqual = val1 == val2;
     83     const bool isLess  = val1  < val2;
     84 
     85     return testComparisons6(T(val1), T(val2), isEqual, isLess);
     86 }
     87 
     88 template <class T>
     89 void AssertComparisons6AreNoexcept()
     90 {
     91     ASSERT_NOEXCEPT(std::declval<const T&>() == std::declval<const T&>());
     92     ASSERT_NOEXCEPT(std::declval<const T&>() != std::declval<const T&>());
     93     ASSERT_NOEXCEPT(std::declval<const T&>() <  std::declval<const T&>());
     94     ASSERT_NOEXCEPT(std::declval<const T&>() <= std::declval<const T&>());
     95     ASSERT_NOEXCEPT(std::declval<const T&>() >  std::declval<const T&>());
     96     ASSERT_NOEXCEPT(std::declval<const T&>() >= std::declval<const T&>());
     97 }
     98 
     99 template <class T>
    100 void AssertComparisons6ReturnBool()
    101 {
    102     ASSERT_SAME_TYPE(decltype(std::declval<const T&>() == std::declval<const T&>()), bool);
    103     ASSERT_SAME_TYPE(decltype(std::declval<const T&>() != std::declval<const T&>()), bool);
    104     ASSERT_SAME_TYPE(decltype(std::declval<const T&>() <  std::declval<const T&>()), bool);
    105     ASSERT_SAME_TYPE(decltype(std::declval<const T&>() <= std::declval<const T&>()), bool);
    106     ASSERT_SAME_TYPE(decltype(std::declval<const T&>() >  std::declval<const T&>()), bool);
    107     ASSERT_SAME_TYPE(decltype(std::declval<const T&>() >= std::declval<const T&>()), bool);
    108 }
    109 
    110 
    111 template <class T>
    112 void AssertComparisons6ConvertibleToBool()
    113 {
    114     static_assert((std::is_convertible<decltype(std::declval<const T&>() == std::declval<const T&>()), bool>::value), "");
    115     static_assert((std::is_convertible<decltype(std::declval<const T&>() != std::declval<const T&>()), bool>::value), "");
    116     static_assert((std::is_convertible<decltype(std::declval<const T&>() <  std::declval<const T&>()), bool>::value), "");
    117     static_assert((std::is_convertible<decltype(std::declval<const T&>() <= std::declval<const T&>()), bool>::value), "");
    118     static_assert((std::is_convertible<decltype(std::declval<const T&>() >  std::declval<const T&>()), bool>::value), "");
    119     static_assert((std::is_convertible<decltype(std::declval<const T&>() >= std::declval<const T&>()), bool>::value), "");
    120 }
    121 
    122 //  Test all six comparison operations for sanity
    123 template <class T>
    124 TEST_CONSTEXPR_CXX14 bool testComparisons2(const T& t1, const T& t2, bool isEqual)
    125 {
    126     if (isEqual)
    127         {
    128         if (!(t1 == t2)) return false;
    129         if (!(t2 == t1)) return false;
    130         if ( (t1 != t2)) return false;
    131         if ( (t2 != t1)) return false;
    132         }
    133     else /* greater */
    134         {
    135         if ( (t1 == t2)) return false;
    136         if ( (t2 == t1)) return false;
    137         if (!(t1 != t2)) return false;
    138         if (!(t2 != t1)) return false;
    139         }
    140 
    141     return true;
    142 }
    143 
    144 //  Easy call when you can init from something already comparable.
    145 template <class T, class Param>
    146 TEST_CONSTEXPR_CXX14 bool testComparisons2Values(Param val1, Param val2)
    147 {
    148     const bool isEqual = val1 == val2;
    149 
    150     return testComparisons2(T(val1), T(val2), isEqual);
    151 }
    152 
    153 template <class T>
    154 void AssertComparisons2AreNoexcept()
    155 {
    156     ASSERT_NOEXCEPT(std::declval<const T&>() == std::declval<const T&>());
    157     ASSERT_NOEXCEPT(std::declval<const T&>() != std::declval<const T&>());
    158 }
    159 
    160 template <class T>
    161 void AssertComparisons2ReturnBool()
    162 {
    163     ASSERT_SAME_TYPE(decltype(std::declval<const T&>() == std::declval<const T&>()), bool);
    164     ASSERT_SAME_TYPE(decltype(std::declval<const T&>() != std::declval<const T&>()), bool);
    165 }
    166 
    167 
    168 template <class T>
    169 void AssertComparisons2ConvertibleToBool()
    170 {
    171     static_assert((std::is_convertible<decltype(std::declval<const T&>() == std::declval<const T&>()), bool>::value), "");
    172     static_assert((std::is_convertible<decltype(std::declval<const T&>() != std::declval<const T&>()), bool>::value), "");
    173 }
    174 
    175 #endif // TEST_COMPARISONS_H
    176