Theoretica
A C++ numerical and automatic mathematical library
Loading...
Searching...
No Matches
error.h
Go to the documentation of this file.
1
5
6#ifndef THEORETICA_ERROR_H
7#define THEORETICA_ERROR_H
8
9#if defined(THEORETICA_THROW_EXCEPTIONS) || defined(THEORETICA_ONLY_EXCEPTIONS)
10#include <exception>
11#include <string>
12
13#ifndef THEORETICA_NO_PRINT
14#include <sstream>
15#endif
16
17#endif
18
19#include <cerrno>
20#include <limits>
21#include "./constants.h"
22
23
24namespace theoretica {
25
28 NO_ERROR = 0x00, // No error
29 DIV_BY_ZERO = 0x01, // Division by zero
30 OUT_OF_DOMAIN = 0x02, // An argument is out of range
31 OUT_OF_RANGE = 0x04, // The result would be out of range
32 IMPOSSIBLE_OPERATION = 0x08, // Impossible operation
33 NO_ALGO_CONVERGENCE = 0x10, // The algorithm did not converge
34 INVALID_ARGUMENT = 0x20 // Invalid argument size or value
35 };
36
37
40 switch(err) {
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;
49 }
50 }
51
52
54 inline real nan() {
55 return std::numeric_limits<real>::quiet_NaN();
56 }
57
58
69 template<typename T>
70 inline bool is_nan(const T& x) {
71 return !(x == x);
72 }
73
74
76 inline real inf() {
77 return std::numeric_limits<real>::infinity();
78 }
79
80
81#if defined(THEORETICA_THROW_EXCEPTIONS) || defined(THEORETICA_ONLY_EXCEPTIONS)
82
83 class math_exception : std::exception {
84
85 private:
86 MATH_ERRCODE err;
87 std::string func_name;
88 std::string file_name;
89 unsigned int code_line;
90 real val;
91
92 public:
93 math_exception(MATH_ERRCODE a_err, const std::string& a_func_name,
94 const std::string& a_file_name, unsigned int a_code_line, real a_val)
97
98 ~math_exception() = default;
99
100
102 inline const char* what() const noexcept {
103
104 switch(err) {
105 case NO_ERROR: return "No error"; break;
106 case DIV_BY_ZERO: return "Division by zero"; break;
107 case OUT_OF_DOMAIN:
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;
114 }
115 }
116
117
119 inline MATH_ERRCODE err_code() const {
120 return err;
121 }
122
123
125 inline std::string get_function_name() const {
126 return func_name;
127 }
128
129
131 inline std::string get_file_name() const {
132 return file_name;
133 }
134
135
137 inline unsigned int get_line_number() const {
138 return code_line;
139 }
140
141
143 inline real get_value() const {
144 return val;
145 }
146
147
148#ifndef THEORETICA_NO_PRINT
149
151 inline std::string to_string() const {
152
153 std::stringstream err_str;
154
155 err_str << file_name << "(" << code_line << "):";
156 err_str << func_name << "(" << val << "): ";
157
158 switch(err) {
159 case NO_ERROR: err_str << "No error"; break;
160 case DIV_BY_ZERO: err_str << "Division by zero"; break;
161 case OUT_OF_DOMAIN:
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;
168 }
169
170 return err_str.str();
171 }
172
173
175 inline operator std::string() {
176 return to_string();
177 }
178
179
182 inline friend std::ostream& operator<<(std::ostream& out, const math_exception& obj) {
183 return out << obj.to_string();
184 }
185
186#endif
187
188 };
189
190#endif
191
192}
193
194
198
199
200// Only throw exceptions, without modifying errno
201#ifdef THEORETICA_ONLY_EXCEPTIONS
202
203#define TH_MATH_ERROR(F_NAME, VALUE, EXCEPTION) \
204 { throw math_exception(EXCEPTION, F_NAME, __FILE__, __LINE__, VALUE); }
205
206#define TH_MATH_ERROR_R(F_NAME, VALUE, EXCEPTION) \
207 TH_MATH_ERROR(F_NAME, VALUE, EXCEPTION)
208
209// Throw exceptions and modify errno
210#elif defined(THEORETICA_THROW_EXCEPTIONS)
211
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); }
215
216// Modify errno only by default
217#else
218
219#define TH_MATH_ERROR(F_NAME, VALUE, EXCEPTION) \
220 { errno = th_errcode_to_errno(EXCEPTION); }
221
222#endif
223
224
225// Output the value of an expression with additional information,
226// for debugging purposes.
227#define TH_DEBUG(VARIABLE) { \
228 std::cout << __FILE__ << ":" << __LINE__ << ": " \
229 << #VARIABLE << " = " << VARIABLE << std::endl; }
230
231
232#endif
Mathematical constants and default algorithm parameters.
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:198
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
std::remove_reference_t< decltype(std::declval< Structure >()[0])> vector_element_t
Extract the type of a vector (or any indexable container) from its operator[].
Definition core_traits.h:134
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