test_checked_right_shift_constexpr.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  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 <iostream>
  7. #include <boost/core/demangle.hpp>
  8. #include <boost/safe_numerics/checked_result.hpp>
  9. #include <boost/safe_numerics/checked_result_operations.hpp>
  10. #include <boost/safe_numerics/checked_integer.hpp>
  11. // note: T should be of tyme checked_result<R> for some integer type R
  12. template<class T>
  13. constexpr bool test_checked_right_shift(
  14. const T & v1,
  15. const T & v2,
  16. char expected_result
  17. ){
  18. using namespace boost::safe_numerics;
  19. const T result = v1 >> v2;
  20. switch(expected_result){
  21. case '.':
  22. if(result.exception()){
  23. return false;
  24. }
  25. return true;
  26. case '-':
  27. if(safe_numerics_error::negative_overflow_error == result.m_e)
  28. return true;
  29. break;
  30. case '+':
  31. if(safe_numerics_error::positive_overflow_error == result.m_e)
  32. return true;
  33. break;
  34. case '!':
  35. if(safe_numerics_error::range_error == result.m_e)
  36. return true;
  37. break;
  38. case 'n': // n negative_shift
  39. if(safe_numerics_error::negative_shift == result.m_e)
  40. return true;
  41. break;
  42. case 's': // s negative_value_shift
  43. if(safe_numerics_error::negative_value_shift == result.m_e)
  44. return true;
  45. break;
  46. case 'l': // l shift_too_large
  47. if(safe_numerics_error::shift_too_large == result.m_e)
  48. return true;
  49. break;
  50. default:
  51. assert(false);
  52. }
  53. return false;
  54. }
  55. #include "test_checked_right_shift.hpp"
  56. template<typename T, typename First, typename Second>
  57. struct test_signed_pair {
  58. static const std::size_t i = First();
  59. static const std::size_t j = Second();
  60. // note: is constexpr really required here? compilers disagree!
  61. constexpr static const bool value = test_checked_right_shift(
  62. signed_values<T>[i],
  63. signed_values<T>[j],
  64. signed_right_shift_results[i][j]
  65. );
  66. };
  67. template<typename T, typename First, typename Second>
  68. struct test_unsigned_pair {
  69. static const std::size_t i = First();
  70. static const std::size_t j = Second();
  71. // note: is constexpr really required here? compilers disagree!
  72. constexpr static const bool value = test_checked_right_shift(
  73. unsigned_values<T>[i],
  74. unsigned_values<T>[j],
  75. unsigned_right_shift_results[i][j]
  76. );
  77. };
  78. #include <boost/mp11/algorithm.hpp>
  79. int main(){
  80. using namespace boost::mp11;
  81. static_assert(
  82. mp_all_of<
  83. mp_product<
  84. test_signed_pair,
  85. signed_test_types,
  86. signed_value_indices, signed_value_indices
  87. >,
  88. mp_to_bool
  89. >(),
  90. "all values for all signed types correctly right_shifted"
  91. );
  92. static_assert(
  93. mp_all_of<
  94. mp_product<
  95. test_unsigned_pair,
  96. unsigned_test_types,
  97. unsigned_value_indices, unsigned_value_indices
  98. >,
  99. mp_to_bool
  100. >(),
  101. "all values for all unsigned types correctly right_shifted"
  102. );
  103. return 0;
  104. }