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
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
77 return std::numeric_limits<real>::infinity();
78 }
79
80
82 inline bool is_inf(real x) {
83 return (x == inf()) || (x == -inf());
84 }
85
86
87#if defined(THEORETICA_THROW_EXCEPTIONS) || defined(THEORETICA_ONLY_EXCEPTIONS)
88
89 class math_exception : std::exception {
90
91 private:
92 MATH_ERRCODE err;
93 std::string func_name;
94 std::string file_name;
95 unsigned int code_line;
96 real val;
97
98 public:
99 math_exception(MATH_ERRCODE a_err, const std::string& a_func_name,
100 const std::string& a_file_name, unsigned int a_code_line, real a_val)
103
104 ~math_exception() = default;
105
106
108 inline const char* what() const noexcept {
109
110 switch(err) {
111 case NO_ERROR: return "No error"; break;
112 case DIV_BY_ZERO: return "Division by zero"; break;
113 case OUT_OF_DOMAIN:
114 return "An argument was out of the domain of the called function"; break;
115 case IMPOSSIBLE_OPERATION:
116 return "A mathematically impossible operation was requested"; break;
117 case NO_ALGO_CONVERGENCE: return "The algorithm did not converge"; break;
118 case INVALID_ARGUMENT: return "Invalid argument size or value"; break;
119 default: return "Unknown error"; break;
120 }
121 }
122
123
125 inline MATH_ERRCODE err_code() const {
126 return err;
127 }
128
129
131 inline std::string get_function_name() const {
132 return func_name;
133 }
134
135
137 inline std::string get_file_name() const {
138 return file_name;
139 }
140
141
143 inline unsigned int get_line_number() const {
144 return code_line;
145 }
146
147
149 inline real get_value() const {
150 return val;
151 }
152
153
154#ifndef THEORETICA_NO_PRINT
155
157 inline std::string to_string() const {
158
159 std::stringstream err_str;
160
161 err_str << file_name << "(" << code_line << "):";
162 err_str << func_name << "(" << val << "): ";
163
164 switch(err) {
165 case NO_ERROR: err_str << "No error"; break;
166 case DIV_BY_ZERO: err_str << "Division by zero"; break;
167 case OUT_OF_DOMAIN:
168 err_str << "An argument was out of the domain of the called function"; break;
169 case IMPOSSIBLE_OPERATION:
170 err_str << "A mathematically impossible operation was requested"; break;
171 case NO_ALGO_CONVERGENCE: err_str << "The algorithm did not converge"; break;
172 case INVALID_ARGUMENT: err_str << "Invalid argument size or value"; break;
173 default: err_str << "Unknown error"; break;
174 }
175
176 return err_str.str();
177 }
178
179
181 inline operator std::string() {
182 return to_string();
183 }
184
185
188 inline friend std::ostream& operator<<(std::ostream& out, const math_exception& obj) {
189 return out << obj.to_string();
190 }
191
192#endif
193
194 };
195
196#endif
197
198}
199
200
204
205
206// Only throw exceptions, without modifying errno
207#ifdef THEORETICA_ONLY_EXCEPTIONS
208
209#define TH_MATH_ERROR(F_NAME, VALUE, EXCEPTION) \
210 { throw math_exception(EXCEPTION, F_NAME, __FILE__, __LINE__, VALUE); }
211
212#define TH_MATH_ERROR_R(F_NAME, VALUE, EXCEPTION) \
213 TH_MATH_ERROR(F_NAME, VALUE, EXCEPTION)
214
215// Throw exceptions and modify errno
216#elif defined(THEORETICA_THROW_EXCEPTIONS)
217
218#define TH_MATH_ERROR(F_NAME, VALUE, EXCEPTION) \
219 { errno = th_errcode_to_errno(EXCEPTION); \
220 throw math_exception(EXCEPTION, F_NAME, __FILE__, __LINE__, VALUE); }
221
222// Modify errno only by default
223#else
224
225#define TH_MATH_ERROR(F_NAME, VALUE, EXCEPTION) \
226 { errno = th_errcode_to_errno(EXCEPTION); }
227
228#endif
229
230
231// Output the value of an expression with additional information,
232// for debugging purposes.
233#define TH_DEBUG(VARIABLE) { \
234 std::cout << __FILE__ << ":" << __LINE__ << ": " \
235 << #VARIABLE << " = " << VARIABLE << std::endl; }
236
237
238#endif
Mathematical constants and default algorithm parameters.
#define TH_CONSTEXPR
Enable constexpr in function declarations if C++14 is supported.
Definition constants.h:161
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
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
TH_CONSTEXPR real nan()
Return a quiet NaN number in floating point representation.
Definition error.h:54
bool is_inf(real x)
Check whether a real number is infinite.
Definition error.h:82
TH_CONSTEXPR real inf()
Get positive infinity in floating point representation.
Definition error.h:76