test_comparisons.h 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. //===----------------------------------------------------------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. // A set of routines for testing the comparison operators of a type
  9. //
  10. // XXXX6 tests all six comparison operators
  11. // XXXX2 tests only op== and op!=
  12. //
  13. // AssertComparisonsXAreNoexcept static_asserts that the operations are all noexcept.
  14. // AssertComparisonsXReturnBool static_asserts that the operations return bool.
  15. // AssertComparisonsXConvertibleToBool static_asserts that the operations return something convertible to bool.
  16. #ifndef TEST_COMPARISONS_H
  17. #define TEST_COMPARISONS_H
  18. #include <type_traits>
  19. #include "test_macros.h"
  20. // Test all six comparison operations for sanity
  21. template <class T, class U = T>
  22. TEST_CONSTEXPR_CXX14 bool testComparisons6(const T& t1, const U& t2, bool isEqual, bool isLess)
  23. {
  24. if (isEqual)
  25. {
  26. if (!(t1 == t2)) return false;
  27. if (!(t2 == t1)) return false;
  28. if ( (t1 != t2)) return false;
  29. if ( (t2 != t1)) return false;
  30. if ( (t1 < t2)) return false;
  31. if ( (t2 < t1)) return false;
  32. if (!(t1 <= t2)) return false;
  33. if (!(t2 <= t1)) return false;
  34. if ( (t1 > t2)) return false;
  35. if ( (t2 > t1)) return false;
  36. if (!(t1 >= t2)) return false;
  37. if (!(t2 >= t1)) return false;
  38. }
  39. else if (isLess)
  40. {
  41. if ( (t1 == t2)) return false;
  42. if ( (t2 == t1)) return false;
  43. if (!(t1 != t2)) return false;
  44. if (!(t2 != t1)) return false;
  45. if (!(t1 < t2)) return false;
  46. if ( (t2 < t1)) return false;
  47. if (!(t1 <= t2)) return false;
  48. if ( (t2 <= t1)) return false;
  49. if ( (t1 > t2)) return false;
  50. if (!(t2 > t1)) return false;
  51. if ( (t1 >= t2)) return false;
  52. if (!(t2 >= t1)) return false;
  53. }
  54. else /* greater */
  55. {
  56. if ( (t1 == t2)) return false;
  57. if ( (t2 == t1)) return false;
  58. if (!(t1 != t2)) return false;
  59. if (!(t2 != t1)) return false;
  60. if ( (t1 < t2)) return false;
  61. if (!(t2 < t1)) return false;
  62. if ( (t1 <= t2)) return false;
  63. if (!(t2 <= t1)) return false;
  64. if (!(t1 > t2)) return false;
  65. if ( (t2 > t1)) return false;
  66. if (!(t1 >= t2)) return false;
  67. if ( (t2 >= t1)) return false;
  68. }
  69. return true;
  70. }
  71. // Easy call when you can init from something already comparable.
  72. template <class T, class Param>
  73. TEST_CONSTEXPR_CXX14 bool testComparisons6Values(Param val1, Param val2)
  74. {
  75. const bool isEqual = val1 == val2;
  76. const bool isLess = val1 < val2;
  77. return testComparisons6(T(val1), T(val2), isEqual, isLess);
  78. }
  79. template <class T, class U = T>
  80. void AssertComparisons6AreNoexcept()
  81. {
  82. ASSERT_NOEXCEPT(std::declval<const T&>() == std::declval<const U&>());
  83. ASSERT_NOEXCEPT(std::declval<const T&>() != std::declval<const U&>());
  84. ASSERT_NOEXCEPT(std::declval<const T&>() < std::declval<const U&>());
  85. ASSERT_NOEXCEPT(std::declval<const T&>() <= std::declval<const U&>());
  86. ASSERT_NOEXCEPT(std::declval<const T&>() > std::declval<const U&>());
  87. ASSERT_NOEXCEPT(std::declval<const T&>() >= std::declval<const U&>());
  88. }
  89. template <class T, class U = T>
  90. void AssertComparisons6ReturnBool()
  91. {
  92. ASSERT_SAME_TYPE(decltype(std::declval<const T&>() == std::declval<const U&>()), bool);
  93. ASSERT_SAME_TYPE(decltype(std::declval<const T&>() != std::declval<const U&>()), bool);
  94. ASSERT_SAME_TYPE(decltype(std::declval<const T&>() < std::declval<const U&>()), bool);
  95. ASSERT_SAME_TYPE(decltype(std::declval<const T&>() <= std::declval<const U&>()), bool);
  96. ASSERT_SAME_TYPE(decltype(std::declval<const T&>() > std::declval<const U&>()), bool);
  97. ASSERT_SAME_TYPE(decltype(std::declval<const T&>() >= std::declval<const U&>()), bool);
  98. }
  99. template <class T, class U = T>
  100. void AssertComparisons6ConvertibleToBool()
  101. {
  102. static_assert((std::is_convertible<decltype(std::declval<const T&>() == std::declval<const U&>()), bool>::value), "");
  103. static_assert((std::is_convertible<decltype(std::declval<const T&>() != std::declval<const U&>()), bool>::value), "");
  104. static_assert((std::is_convertible<decltype(std::declval<const T&>() < std::declval<const U&>()), bool>::value), "");
  105. static_assert((std::is_convertible<decltype(std::declval<const T&>() <= std::declval<const U&>()), bool>::value), "");
  106. static_assert((std::is_convertible<decltype(std::declval<const T&>() > std::declval<const U&>()), bool>::value), "");
  107. static_assert((std::is_convertible<decltype(std::declval<const T&>() >= std::declval<const U&>()), bool>::value), "");
  108. }
  109. // Test all two comparison operations for sanity
  110. template <class T, class U = T>
  111. TEST_CONSTEXPR_CXX14 bool testComparisons2(const T& t1, const U& t2, bool isEqual)
  112. {
  113. if (isEqual)
  114. {
  115. if (!(t1 == t2)) return false;
  116. if (!(t2 == t1)) return false;
  117. if ( (t1 != t2)) return false;
  118. if ( (t2 != t1)) return false;
  119. }
  120. else /* not equal */
  121. {
  122. if ( (t1 == t2)) return false;
  123. if ( (t2 == t1)) return false;
  124. if (!(t1 != t2)) return false;
  125. if (!(t2 != t1)) return false;
  126. }
  127. return true;
  128. }
  129. // Easy call when you can init from something already comparable.
  130. template <class T, class Param>
  131. TEST_CONSTEXPR_CXX14 bool testComparisons2Values(Param val1, Param val2)
  132. {
  133. const bool isEqual = val1 == val2;
  134. return testComparisons2(T(val1), T(val2), isEqual);
  135. }
  136. template <class T, class U = T>
  137. void AssertComparisons2AreNoexcept()
  138. {
  139. ASSERT_NOEXCEPT(std::declval<const T&>() == std::declval<const U&>());
  140. ASSERT_NOEXCEPT(std::declval<const T&>() != std::declval<const U&>());
  141. }
  142. template <class T, class U = T>
  143. void AssertComparisons2ReturnBool()
  144. {
  145. ASSERT_SAME_TYPE(decltype(std::declval<const T&>() == std::declval<const U&>()), bool);
  146. ASSERT_SAME_TYPE(decltype(std::declval<const T&>() != std::declval<const U&>()), bool);
  147. }
  148. template <class T, class U = T>
  149. void AssertComparisons2ConvertibleToBool()
  150. {
  151. static_assert((std::is_convertible<decltype(std::declval<const T&>() == std::declval<const U&>()), bool>::value), "");
  152. static_assert((std::is_convertible<decltype(std::declval<const T&>() != std::declval<const U&>()), bool>::value), "");
  153. }
  154. #endif // TEST_COMPARISONS_H