• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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>
testComparisons6(const T & t1,const T & t2,bool isEqual,bool isLess)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>
testComparisons6Values(Param val1,Param val2)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>
AssertComparisons6AreNoexcept()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>
AssertComparisons6ReturnBool()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>
AssertComparisons6ConvertibleToBool()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>
testComparisons2(const T & t1,const T & t2,bool isEqual)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>
testComparisons2Values(Param val1,Param val2)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>
AssertComparisons2AreNoexcept()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>
AssertComparisons2ReturnBool()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>
AssertComparisons2ConvertibleToBool()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