native.hpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. #ifndef BOOST_SAFE_NUMERICS_NATIVE_HPP
  2. #define BOOST_SAFE_NUMERICS_NATIVE_HPP
  3. // Copyright (c) 2012 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 <type_traits>
  9. #include <limits>
  10. // policy which creates results types and values equal to that of C++ promotions.
  11. // When used in conjunction with a desired exception policy, traps errors but
  12. // does not otherwise alter the results produced by the program using it.
  13. namespace boost {
  14. namespace safe_numerics {
  15. struct native {
  16. public:
  17. // arithmetic operators
  18. template<typename T, typename U>
  19. struct addition_result {
  20. using type = decltype(
  21. typename base_type<T>::type()
  22. + typename base_type<U>::type()
  23. );
  24. };
  25. template<typename T, typename U>
  26. struct subtraction_result {
  27. using type = decltype(
  28. typename base_type<T>::type()
  29. - typename base_type<U>::type()
  30. );
  31. };
  32. template<typename T, typename U>
  33. struct multiplication_result {
  34. using type = decltype(
  35. typename base_type<T>::type()
  36. * typename base_type<U>::type()
  37. );
  38. };
  39. template<typename T, typename U>
  40. struct division_result {
  41. using type = decltype(
  42. typename base_type<T>::type()
  43. / typename base_type<U>::type()
  44. );
  45. };
  46. template<typename T, typename U>
  47. struct modulus_result {
  48. using type = decltype(
  49. typename base_type<T>::type()
  50. % typename base_type<U>::type()
  51. );
  52. };
  53. // note: comparison_result (<, >, ...) is special.
  54. // The return value is always a bool. The type returned here is
  55. // the intermediate type applied to make the values comparable.
  56. template<typename T, typename U>
  57. struct comparison_result {
  58. using type = decltype(
  59. typename base_type<T>::type()
  60. + typename base_type<U>::type()
  61. );
  62. };
  63. // shift operators
  64. template<typename T, typename U>
  65. struct left_shift_result {
  66. using type = decltype(
  67. typename base_type<T>::type()
  68. << typename base_type<U>::type()
  69. );
  70. };
  71. template<typename T, typename U>
  72. struct right_shift_result {
  73. using type = decltype(
  74. typename base_type<T>::type()
  75. >> typename base_type<U>::type()
  76. );
  77. };
  78. // bitwise operators
  79. template<typename T, typename U>
  80. struct bitwise_or_result {
  81. using type = decltype(
  82. typename base_type<T>::type()
  83. | typename base_type<U>::type()
  84. );
  85. };
  86. template<typename T, typename U>
  87. struct bitwise_and_result {
  88. using type = decltype(
  89. typename base_type<T>::type()
  90. & typename base_type<U>::type()
  91. );
  92. };
  93. template<typename T, typename U>
  94. struct bitwise_xor_result {
  95. using type = decltype(
  96. typename base_type<T>::type()
  97. ^ typename base_type<U>::type()
  98. );
  99. };
  100. };
  101. } // safe_numerics
  102. } // boost
  103. #endif // BOOST_SAFE_NUMERICS_NATIVE_HPP