test_safe_compare.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. // Copyright (c) 2014 Robert Ramey
  2. //
  3. // Distributed under the Boost Software License, Version 1.0. (See
  4. // accompanying file LICENSE_1_0.txt or copy at
  5. // http://www.boost.org/LICENSE_1_0.txt)
  6. #include <iostream>
  7. #include <boost/core/demangle.hpp>
  8. #include <boost/safe_numerics/safe_compare.hpp>
  9. template<class T1, class T2>
  10. void print_argument_types(
  11. T1 v1,
  12. T2 v2
  13. ){
  14. const std::type_info & ti1 = typeid(v1);
  15. const std::type_info & ti2 = typeid(v2);
  16. std::cout
  17. << boost::core::demangle(ti1.name()) << ','
  18. << boost::core::demangle(ti2.name());
  19. }
  20. #include <boost/mp11/algorithm.hpp>
  21. using namespace boost::safe_numerics;
  22. template<class T1, class T2>
  23. bool test_safe_compare_impl(
  24. T1 v1,
  25. T2 v2,
  26. char expected_result
  27. ){
  28. switch(expected_result){
  29. case '=': {
  30. if(! safe_compare::equal(v1, v2))
  31. return false;
  32. if(safe_compare::less_than(v1, v2))
  33. return false;
  34. if(safe_compare::greater_than(v1, v2))
  35. return false;
  36. break;
  37. }
  38. case '<': {
  39. if(! safe_compare::less_than(v1, v2))
  40. return false;
  41. if(safe_compare::greater_than(v1, v2))
  42. return false;
  43. if(safe_compare::equal(v1, v2))
  44. return false;
  45. break;
  46. }
  47. case '>':{
  48. if(! safe_compare::greater_than(v1, v2))
  49. return false;
  50. if(safe_compare::less_than(v1, v2))
  51. return false;
  52. if(safe_compare::equal(v1, v2))
  53. return false;
  54. break;
  55. }
  56. }
  57. return true;
  58. }
  59. template<class T1, class T2>
  60. bool test_safe_compare(
  61. T1 v1,
  62. T2 v2,
  63. char expected_result
  64. ){
  65. print_argument_types(v1, v2);
  66. const bool result = test_safe_compare_impl(v1, v2, expected_result);
  67. if(! result)
  68. std::cout << " failed";
  69. std::cout << '\n';
  70. return result;
  71. }
  72. #include "test_values.hpp"
  73. const char *test_compare_result[boost::mp11::mp_size<test_values>::value] = {
  74. // 0 0 0 0
  75. // 012345670123456701234567012345670
  76. // 012345678901234567890123456789012
  77. /* 0*/ "=<>>=<>>=<>>=<>>=<<<=<<<=<<<=<<<>",
  78. /* 1*/ ">=>>><>>><>>><>>>=<<><<<><<<><<<>",
  79. /* 2*/ "<<=<<<><<<><<<><<<<<<<<<<<<<<<<<<",
  80. /* 3*/ "<<>=<<>=<<>=<<>=<<<<<<<<<<<<<<<<<",
  81. /* 4*/ "=<>>=<>>=<>>=<>>=<<<=<<<=<<<=<<<>",
  82. /* 5*/ ">>>>>=>>><>>><>>>>>>>=<<><<<><<<>",
  83. /* 6*/ "<<<<<<=<<<><<<><<<<<<<<<<<<<<<<<<",
  84. /* 7*/ "<<>=<<>=<<>=<<>=<<<<<<<<<<<<<<<<<",
  85. /* 8*/ "=<>>=<>>=<>>=<>>=<<<=<<<=<<<=<<<>",
  86. /* 9*/ ">>>>>>>>>=>>><>>>>>>>>>>>=<<><<<>",
  87. /*10*/ "<<<<<<<<<<=<<<><<<<<<<<<<<<<<<<<<",
  88. /*11*/ "<<>=<<>=<<>=<<>=<<<<<<<<<<<<<<<<<",
  89. /*12*/ "=<>>=<>>=<>>=<>>=<<<=<<<=<<<=<<<>",
  90. /*13*/ ">>>>>>>>>>>>>=>>>>>>>>>>>>>>>=<<>",
  91. /*14*/ "<<<<<<<<<<<<<<=<<<<<<<<<<<<<<<<<<",
  92. /*15*/ "<<>=<<>=<<>=<<>=<<<<<<<<<<<<<<<<",
  93. // 0 0 0 0
  94. // 012345670123456701234567012345670
  95. // 012345678901234567890123456789012
  96. /*16*/ "=<>>=<>>=<>>=<>>=<<<=<<<=<<<=<<<>",
  97. /*17*/ ">=>>><>>><>>><>>>=<<><<<><<<><<<>",
  98. /*18*/ ">>>>><>>><>>><>>>>=<><<<><<<><<<>",
  99. /*19*/ ">>>>><>>><>>><>>>>>=><<<><<<><<<>",
  100. /*20*/ "=<>>=<>>=<>>=<>>=<<<=<<<=<<<=<<<>",
  101. /*21*/ ">>>>>=>>><>>><>>>>>>>=<<><<<><<<>",
  102. /*22*/ ">>>>>>>>><>>><>>>>>>>>=<><<<><<<>",
  103. /*23*/ ">>>>>>>>><>>><>>>>>>>>>=><<<><<<>",
  104. /*24*/ "=<>>=<>>=<>>=<>>=<<<=<<<=<<<=<<<>",
  105. /*25*/ ">>>>>>>>>=>>><>>>>>>>>>>>=<<><<<>",
  106. /*26*/ ">>>>>>>>>>>>><>>>>>>>>>>>>=<><<<>",
  107. /*27*/ ">>>>>>>>>>>>><>>>>>>>>>>>>>=><<<>",
  108. /*28*/ "=<>>=<>>=<>>=<>>=<<<=<<<=<<<=<<<>",
  109. /*29*/ ">>>>>>>>>>>>>=>>>>>>>>>>>>>>>=<<>",
  110. /*30*/ ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>=<>",
  111. /*31*/ ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>=>",
  112. /*32*/ "<<>><<>><<>><<>><<<<<<<<<<<<<<<<="
  113. };
  114. using namespace boost::mp11;
  115. template<typename L>
  116. struct test {
  117. static_assert(mp_is_list<L>(), "must be a list of integral constants");
  118. bool m_error;
  119. test(bool b = true) : m_error(b) {}
  120. operator bool(){
  121. return m_error;
  122. }
  123. template<typename T>
  124. void operator()(const T &){
  125. static_assert(mp_is_list<T>(), "must be a list of two integral constants");
  126. constexpr size_t i1 = mp_first<T>(); // index of first argument
  127. constexpr size_t i2 = mp_second<T>();// index of second argument
  128. std::cout << i1 << ',' << i2 << ',';
  129. using T1 = typename boost::mp11::mp_at_c<L, i1>::value_type;
  130. using T2 = typename boost::mp11::mp_at_c<L, i2>::value_type;
  131. m_error &= test_safe_compare<T1, T2>(
  132. boost::mp11::mp_at_c<L, i1>(), // value of first argument
  133. boost::mp11::mp_at_c<L, i2>(), // value of second argument
  134. test_compare_result[i1][i2]
  135. );
  136. }
  137. };
  138. int main(){
  139. //TEST_EACH_VALUE_PAIR
  140. test<test_values> rval(true);
  141. using value_indices = mp_iota_c<mp_size<test_values>::value>;
  142. mp_for_each<
  143. mp_product<mp_list, value_indices, value_indices>
  144. >(rval);
  145. std::cout << (rval ? "success!" : "failure") << std::endl;
  146. return ! rval ;
  147. }