test_xor.hpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. #ifndef BOOST_TEST_XOR_HPP
  2. #define BOOST_TEST_XOR_HPP
  3. // Copyright (c) 2015 Robert Ramey
  4. //
  5. // Distributed under the Boost Software License, Version 1.0. (See
  6. // accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. #include <iostream>
  9. #include <iosfwd>
  10. #include <boost/safe_numerics/safe_integer.hpp>
  11. #include <boost/safe_numerics/range_value.hpp>
  12. template<class T1, class T2>
  13. bool test_xor(
  14. T1 v1,
  15. T2 v2,
  16. const char *av1,
  17. const char *av2,
  18. char expected_result
  19. ){
  20. std::cout << "testing"<< std::endl;
  21. {
  22. safe_t<T1> t1 = v1;
  23. using result_type = decltype(t1 ^ v2);
  24. std::cout << "safe<" << av1 << "> ^ " << av2 << " -> ";
  25. static_assert(
  26. boost::safe_numerics::is_safe<safe_t<T1> >::value,
  27. "safe_t not safe!"
  28. );
  29. static_assert(
  30. boost::safe_numerics::is_safe<result_type>::value,
  31. "Expression failed to return safe type"
  32. );
  33. try{
  34. // use auto to avoid checking assignment.
  35. auto result = t1 ^ v2;
  36. std::cout << make_result_display(result);
  37. if(expected_result == 'x'){
  38. std::cout
  39. << " ! = "<< av1 << " ^ " << av2
  40. << " failed to detect error in xor operation"
  41. << std::endl;
  42. t1 ^ v2;
  43. return false;
  44. }
  45. else
  46. if(result != (v1 ^ v2)){
  47. std::cout
  48. << " ! = "<< av1 << " ^ " << av2
  49. << " incorrect result in xor operation"
  50. << std::endl;
  51. t1 ^ v2;
  52. boost::safe_numerics::safe_compare::equal(base_value(result), (v1 ^ v2));
  53. return false;
  54. }
  55. std::cout << std::endl;
  56. }
  57. catch(const std::exception &){
  58. if(expected_result == '.'){
  59. std::cout
  60. << " == "<< av1 << " ^ " << av2
  61. << " erroneously detected error in xor operation"
  62. << std::endl;
  63. try{
  64. t1 ^ v2;
  65. }
  66. catch(const std::exception &){}
  67. return false;
  68. }
  69. }
  70. }
  71. {
  72. safe_t<T2> t2 = v2;
  73. using result_type = decltype(v1 ^ t2);
  74. std::cout << av1 << " ^ " << "safe<" << av2 << "> -> ";
  75. static_assert(
  76. boost::safe_numerics::is_safe<safe_t<T2> >::value,
  77. "safe_t not safe!"
  78. );
  79. static_assert(
  80. boost::safe_numerics::is_safe<result_type>::value,
  81. "Expression failed to return safe type"
  82. );
  83. try{
  84. // use auto to avoid checking assignment.
  85. auto result = v1 ^ t2;
  86. std::cout << make_result_display(result);
  87. if(expected_result == 'x'){
  88. std::cout
  89. << " ! = "<< av1 << " ^ " << av2
  90. << " failed to detect error in and operation"
  91. << std::endl;
  92. v1 ^ t2;
  93. return false;
  94. }
  95. else
  96. if(result != (v1 ^ v2)){
  97. std::cout
  98. << " ! = "<< av1 << " ^ " << av2
  99. << " incorrect result in xor operation"
  100. << std::endl;
  101. v1 ^ t2;
  102. return false;
  103. }
  104. std::cout << std::endl;
  105. }
  106. catch(const std::exception &){
  107. if(expected_result == '.'){
  108. std::cout
  109. << " == "<< av1 << " ^ " << av2
  110. << " erroneously detected error in and operation"
  111. << std::endl;
  112. try{
  113. v1 ^ t2;
  114. }
  115. catch(const std::exception &){}
  116. return false;
  117. }
  118. }
  119. }
  120. {
  121. safe_t<T1> t1 = v1;
  122. safe_t<T2> t2 = v2;
  123. using result_type = decltype(t1 ^ t2);
  124. std::cout << "safe<" << av1 << "> ^ " << "safe<" << av2 << "> -> ";
  125. static_assert(
  126. boost::safe_numerics::is_safe<result_type>::value,
  127. "Expression failed to return safe type"
  128. );
  129. try{
  130. // use auto to avoid checking assignment.
  131. auto result = t1 ^ t2;
  132. std::cout << make_result_display(result);
  133. if(expected_result == 'x'){
  134. std::cout
  135. << " ! = "<< av1 << " ^ " << av2
  136. << " failed to detect error in and operation"
  137. << std::endl;
  138. t1 ^ t2;
  139. return false;
  140. }
  141. else
  142. if(result != (v1 ^ v2)){
  143. std::cout
  144. << " ! = "<< av1 << " ^ " << av2
  145. << " incorrect result in xor operation"
  146. << std::endl;
  147. t1 ^ t2;
  148. return false;
  149. }
  150. std::cout << std::endl;
  151. }
  152. catch(const std::exception &){
  153. if(expected_result == '.'){
  154. std::cout
  155. << " == "<< av1 << " ^ " << av2
  156. << " erroneously detected error in and operation"
  157. << std::endl;
  158. try{
  159. t1 ^ t2;
  160. }
  161. catch(const std::exception &){}
  162. return false;
  163. }
  164. }
  165. }
  166. return true; // correct result
  167. }
  168. #endif // BOOST_TEST_XOR_HPP