6 #ifndef THEORETICA_ERROR_H
7 #define THEORETICA_ERROR_H
9 #if defined(THEORETICA_THROW_EXCEPTIONS) || defined(THEORETICA_ONLY_EXCEPTIONS)
13 #ifndef THEORETICA_NO_PRINT
32 IMPOSSIBLE_OPERATION = 0x08,
33 NO_ALGO_CONVERGENCE = 0x10,
34 INVALID_ARGUMENT = 0x20
41 case NO_ERROR:
return 0;
break;
42 case DIV_BY_ZERO:
return ERANGE;
break;
43 case OUT_OF_DOMAIN:
return EDOM;
break;
44 case OUT_OF_RANGE:
return ERANGE;
break;
45 case IMPOSSIBLE_OPERATION:
return EDOM;
break;
46 case NO_ALGO_CONVERGENCE:
return ERANGE;
break;
47 case INVALID_ARGUMENT:
return EINVAL;
break;
48 default:
return 0;
break;
55 return std::numeric_limits<real>::quiet_NaN();
77 return std::numeric_limits<real>::infinity();
81 #if defined(THEORETICA_THROW_EXCEPTIONS) || defined(THEORETICA_ONLY_EXCEPTIONS)
83 class math_exception : std::exception {
89 unsigned int code_line;
95 : err(a_err), func_name(a_func_name), file_name(a_file_name),
96 code_line(a_code_line), val(a_val) {}
98 ~math_exception() =
default;
102 inline const char* what() const noexcept {
105 case NO_ERROR:
return "No error";
break;
106 case DIV_BY_ZERO:
return "Division by zero";
break;
108 return "An argument was out of the domain of the called function";
break;
109 case IMPOSSIBLE_OPERATION:
110 return "A mathematically impossible operation was requested";
break;
111 case NO_ALGO_CONVERGENCE:
return "The algorithm did not converge";
break;
112 case INVALID_ARGUMENT:
return "Invalid argument size or value";
break;
113 default:
return "Unknown error";
break;
137 inline unsigned int get_line_number()
const {
143 inline real get_value()
const {
148 #ifndef THEORETICA_NO_PRINT
153 std::stringstream err_str;
155 err_str << file_name <<
"(" << code_line <<
"):";
156 err_str << func_name <<
"(" << val <<
"): ";
159 case NO_ERROR: err_str <<
"No error";
break;
160 case DIV_BY_ZERO: err_str <<
"Division by zero";
break;
162 err_str <<
"An argument was out of the domain of the called function";
break;
163 case IMPOSSIBLE_OPERATION:
164 err_str <<
"A mathematically impossible operation was requested";
break;
165 case NO_ALGO_CONVERGENCE: err_str <<
"The algorithm did not converge";
break;
166 case INVALID_ARGUMENT: err_str <<
"Invalid argument size or value";
break;
167 default: err_str <<
"Unknown error";
break;
170 return err_str.str();
182 inline friend std::ostream& operator<<(std::ostream& out,
const math_exception& obj) {
183 return out << obj.to_string();
201 #ifdef THEORETICA_ONLY_EXCEPTIONS
203 #define TH_MATH_ERROR(F_NAME, VALUE, EXCEPTION) \
204 { throw math_exception(EXCEPTION, F_NAME, __FILE__, __LINE__, VALUE); }
206 #define TH_MATH_ERROR_R(F_NAME, VALUE, EXCEPTION) \
207 TH_MATH_ERROR(F_NAME, VALUE, EXCEPTION)
210 #elif defined(THEORETICA_THROW_EXCEPTIONS)
212 #define TH_MATH_ERROR(F_NAME, VALUE, EXCEPTION) \
213 { errno = th_errcode_to_errno(EXCEPTION); \
214 throw math_exception(EXCEPTION, F_NAME, __FILE__, __LINE__, VALUE); }
219 #define TH_MATH_ERROR(F_NAME, VALUE, EXCEPTION) \
220 { errno = th_errcode_to_errno(EXCEPTION); }
227 #define TH_DEBUG(VARIABLE) { \
228 std::cout << __FILE__ << ":" << __LINE__ << ": " \
229 << #VARIABLE << " = " << VARIABLE << std::endl; }
Mathematical constants and default algorithm parameters.
std::string string(size_t length)
Generate a random string made of human-readable ASCII characters.
Definition: random.h:102
Main namespace of the library which contains all functions and objects.
Definition: algebra.h:27
double real
A real number, defined as a floating point type.
Definition: constants.h:188
bool is_nan(const T &x)
Check whether a generic variable is (equivalent to) a NaN number.
Definition: error.h:70
real inf()
Return positive infinity in floating point representation.
Definition: error.h:76
MATH_ERRCODE
Math error enumeration.
Definition: error.h:27
int th_errcode_to_errno(MATH_ERRCODE err)
Convert a MATH_ERRCODE to errno error codes.
Definition: error.h:39
real nan()
Return a quiet NaN number in floating point representation.
Definition: error.h:54