test_checked_left_shift_constexpr.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  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_left_shift(
  11. const T & v1,
  12. const 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 '.':
  19. return ! result.exception();
  20. case '-':
  21. return safe_numerics_error::negative_overflow_error == result.m_e;
  22. case '+':
  23. return safe_numerics_error::positive_overflow_error == result.m_e;
  24. case '!':
  25. return safe_numerics_error::range_error == result.m_e;
  26. case 'n': // n negative_shift
  27. return safe_numerics_error::negative_shift == result.m_e;
  28. case 's': // s negative_value_shift
  29. return safe_numerics_error::negative_value_shift == result.m_e;
  30. case 'l': // l shift_too_large
  31. return safe_numerics_error::shift_too_large == result.m_e;
  32. default:
  33. assert(false);
  34. }
  35. return false;
  36. }
  37. #include "test_checked_left_shift.hpp"
  38. template<typename T, typename First, typename Second>
  39. struct test_signed_pair {
  40. static const std::size_t i = First();
  41. static const std::size_t j = Second();
  42. // note: is constexpr really required here? compilers disagree!
  43. constexpr static const bool value = test_checked_left_shift(
  44. signed_values<T>[i],
  45. signed_values<T>[j],
  46. signed_left_shift_results[i][j]
  47. );
  48. };
  49. template<typename T, typename First, typename Second>
  50. struct test_unsigned_pair {
  51. static const std::size_t i = First();
  52. static const std::size_t j = Second();
  53. // note: is constexpr really required here? compilers disagree!
  54. constexpr static const bool value = test_checked_left_shift(
  55. unsigned_values<T>[i],
  56. unsigned_values<T>[j],
  57. unsigned_left_shift_results[i][j]
  58. );
  59. };
  60. #include <boost/mp11/algorithm.hpp>
  61. int main(){
  62. using namespace boost::mp11;
  63. static_assert(
  64. mp_all_of<
  65. mp_product<
  66. test_signed_pair,
  67. signed_test_types,
  68. signed_value_indices, signed_value_indices
  69. >,
  70. mp_to_bool
  71. >(),
  72. "all values for all signed types correctly shifted"
  73. );
  74. static_assert(
  75. mp_all_of<
  76. mp_product<
  77. test_unsigned_pair,
  78. unsigned_test_types,
  79. unsigned_value_indices, unsigned_value_indices
  80. >,
  81. mp_to_bool
  82. >(),
  83. "all values for all unsigned types correctly shifted"
  84. );
  85. return 0;
  86. }