test_checked_multiply_constexpr.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. // Copyright (c) 2018 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 <boost/safe_numerics/checked_result.hpp>
  7. #include <boost/safe_numerics/checked_result_operations.hpp>
  8. #include <boost/safe_numerics/checked_integer.hpp>
  9. template<class T>
  10. constexpr bool test_checked_multiply(
  11. T v1,
  12. T v2,
  13. char expected_result
  14. ){
  15. using namespace boost::safe_numerics;
  16. const T result = v1 * v2;
  17. switch(expected_result){
  18. case '0':
  19. case '.':
  20. if(result.exception()){
  21. return false;
  22. }
  23. if(expected_result == '0'
  24. && result != T(0)
  25. ){
  26. return false;
  27. }
  28. return true;
  29. case '-':
  30. return safe_numerics_error::negative_overflow_error == result.m_e;
  31. case '+':
  32. return safe_numerics_error::positive_overflow_error == result.m_e;
  33. case '!':
  34. return safe_numerics_error::range_error == result.m_e;
  35. }
  36. return false;
  37. }
  38. #include "test_checked_multiply.hpp"
  39. template<typename T, typename First, typename Second>
  40. struct test_signed_pair {
  41. static const std::size_t i = First();
  42. static const std::size_t j = Second();
  43. // note: is constexpr really required here? compilers disagree!
  44. constexpr static const bool value = test_checked_multiply(
  45. signed_values<T>[i],
  46. signed_values<T>[j],
  47. signed_multiplication_results[i][j]
  48. );
  49. };
  50. template<typename T, typename First, typename Second>
  51. struct test_unsigned_pair {
  52. static const std::size_t i = First();
  53. static const std::size_t j = Second();
  54. // note: is constexpr really required here? compilers disagree!
  55. constexpr static const bool value = test_checked_multiply(
  56. unsigned_values<T>[i],
  57. unsigned_values<T>[j],
  58. unsigned_multiplication_results[i][j]
  59. );
  60. };
  61. #include "check_symmetry.hpp"
  62. #include <boost/mp11/algorithm.hpp>
  63. int main(){
  64. using namespace boost::mp11;
  65. check_symmetry(signed_multiplication_results);
  66. check_symmetry(unsigned_multiplication_results);
  67. static_assert(
  68. mp_all_of<
  69. mp_product<
  70. test_signed_pair,
  71. signed_test_types,
  72. signed_value_indices, signed_value_indices
  73. >,
  74. mp_to_bool
  75. >(),
  76. "all values for all signed types correctly multiplied"
  77. );
  78. static_assert(
  79. mp_all_of<
  80. mp_product<
  81. test_unsigned_pair,
  82. unsigned_test_types,
  83. unsigned_value_indices, unsigned_value_indices
  84. >,
  85. mp_to_bool
  86. >(),
  87. "all values for all unsigned types correctly multiplied"
  88. );
  89. return 0;
  90. }