File indexing completed on 2025-01-18 09:51:36
0001 #ifndef BOOST_NUMERIC_EXCEPTION_POLICIES_HPP
0002 #define BOOST_NUMERIC_EXCEPTION_POLICIES_HPP
0003
0004
0005
0006
0007
0008
0009
0010 #include <boost/mp11.hpp>
0011 #include <boost/config.hpp> // BOOST_NO_EXCEPTIONS
0012 #include "exception.hpp"
0013
0014 namespace boost {
0015 namespace safe_numerics {
0016
0017 template<
0018 typename AE,
0019 typename IDB,
0020 typename UB,
0021 typename UV
0022 >
0023 struct exception_policy {
0024 constexpr static void on_arithmetic_error(
0025 const safe_numerics_error & e,
0026 const char * msg
0027 ){
0028 AE()(e, msg);
0029 }
0030 constexpr static void on_implementation_defined_behavior(
0031 const safe_numerics_error & e,
0032 const char * msg
0033 ){
0034 IDB()(e, msg);
0035 }
0036 constexpr static void on_undefined_behavior(
0037 const safe_numerics_error & e,
0038 const char * msg
0039 ){
0040 UB()(e, msg);
0041 }
0042 constexpr static void on_uninitialized_value(
0043 const safe_numerics_error & e,
0044 const char * msg
0045 ){
0046 UV()(e, msg);
0047 }
0048 };
0049
0050
0051
0052
0053
0054 struct ignore_exception {
0055 constexpr ignore_exception() = default;
0056 constexpr void operator () (
0057 const boost::safe_numerics::safe_numerics_error &,
0058 const char *
0059 ){}
0060 };
0061
0062
0063 struct trap_exception {
0064 constexpr trap_exception() = default;
0065
0066
0067 };
0068
0069
0070 struct throw_exception {
0071 constexpr throw_exception() = default;
0072 #ifndef BOOST_NO_EXCEPTIONS
0073 void operator()(
0074 const safe_numerics_error & e,
0075 const char * message
0076 ){
0077 throw std::system_error(std::error_code(e), message);
0078 }
0079 #else
0080 constexpr trap_exception()(const safe_numerics_error & e, const char * message);
0081 #endif
0082 };
0083
0084
0085 constexpr inline safe_numerics_actions
0086 make_safe_numerics_action(const safe_numerics_error & e){
0087
0088
0089 switch(e){
0090 case safe_numerics_error::negative_overflow_error:
0091 case safe_numerics_error::underflow_error:
0092 case safe_numerics_error::range_error:
0093 case safe_numerics_error::domain_error:
0094 case safe_numerics_error::positive_overflow_error:
0095 case safe_numerics_error::precision_overflow_error:
0096 return safe_numerics_actions::arithmetic_error;
0097
0098 case safe_numerics_error::negative_value_shift:
0099 case safe_numerics_error::negative_shift:
0100 case safe_numerics_error::shift_too_large:
0101 return safe_numerics_actions::implementation_defined_behavior;
0102
0103 case safe_numerics_error::uninitialized_value:
0104 return safe_numerics_actions::uninitialized_value;
0105
0106 case safe_numerics_error::success:
0107 return safe_numerics_actions::no_action;
0108 default:
0109 assert(false);
0110 }
0111
0112
0113 return safe_numerics_actions::no_action;
0114 }
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124 using loose_exception_policy = exception_policy<
0125 throw_exception,
0126 ignore_exception,
0127 ignore_exception,
0128 ignore_exception
0129 >;
0130
0131
0132
0133
0134
0135
0136 using loose_trap_policy = exception_policy<
0137 trap_exception,
0138 ignore_exception,
0139 ignore_exception,
0140 ignore_exception
0141 >;
0142
0143
0144
0145
0146
0147
0148
0149 using strict_exception_policy = exception_policy<
0150 throw_exception,
0151 throw_exception,
0152 throw_exception,
0153 ignore_exception
0154 >;
0155
0156
0157
0158
0159
0160
0161 using strict_trap_policy = exception_policy<
0162 trap_exception,
0163 trap_exception,
0164 trap_exception,
0165 trap_exception
0166 >;
0167
0168
0169
0170
0171 using default_exception_policy = strict_exception_policy;
0172
0173 }
0174 }
0175
0176 #endif