1 | // Copyright (c) 2000-2011 Joerg Walter, Mathias Koch, David Bellot |
2 | // |
3 | // Distributed under the Boost Software License, Version 1.0. (See |
4 | // accompanying file LICENSE_1_0.txt or copy at |
5 | // http://www.boost.org/LICENSE_1_0.txt) |
6 | |
7 | #ifndef _BOOST_UBLAS_EXCEPTION_ |
8 | #define _BOOST_UBLAS_EXCEPTION_ |
9 | |
10 | #if ! defined (BOOST_NO_EXCEPTIONS) && ! defined (BOOST_UBLAS_NO_EXCEPTIONS) |
11 | #include <stdexcept> |
12 | #else |
13 | #include <cstdlib> |
14 | #endif |
15 | #ifndef BOOST_UBLAS_NO_STD_CERR |
16 | #include <iostream> |
17 | #endif |
18 | |
19 | #include <boost/numeric/ublas/detail/config.hpp> |
20 | |
21 | namespace boost { namespace numeric { namespace ublas { |
22 | |
23 | /** \brief Exception raised when a division by zero occurs |
24 | */ |
25 | struct divide_by_zero |
26 | #if ! defined (BOOST_NO_EXCEPTIONS) && ! defined (BOOST_UBLAS_NO_EXCEPTIONS) |
27 | // Inherit from standard exceptions as requested during review. |
28 | : public std::runtime_error |
29 | { |
30 | explicit divide_by_zero (const char *s = "divide by zero" ) : |
31 | std::runtime_error (s) {} |
32 | void raise () { |
33 | throw *this; |
34 | } |
35 | #else |
36 | { |
37 | divide_by_zero () |
38 | {} |
39 | explicit divide_by_zero (const char *) |
40 | {} |
41 | void raise () { |
42 | std::abort (); |
43 | } |
44 | #endif |
45 | }; |
46 | |
47 | /** \brief Expception raised when some interal errors occurs like computations errors, zeros values where you should not have zeros, etc... |
48 | */ |
49 | struct internal_logic |
50 | #if ! defined (BOOST_NO_EXCEPTIONS) && ! defined (BOOST_UBLAS_NO_EXCEPTIONS) |
51 | // Inherit from standard exceptions as requested during review. |
52 | : public std::logic_error { |
53 | explicit internal_logic (const char *s = "internal logic" ) : |
54 | std::logic_error (s) {} |
55 | void raise () { |
56 | throw *this; |
57 | } |
58 | #else |
59 | { |
60 | internal_logic () |
61 | {} |
62 | explicit internal_logic (const char *) |
63 | {} |
64 | void raise () { |
65 | std::abort (); |
66 | } |
67 | #endif |
68 | }; |
69 | |
70 | struct external_logic |
71 | #if ! defined (BOOST_NO_EXCEPTIONS) && ! defined (BOOST_UBLAS_NO_EXCEPTIONS) |
72 | // Inherit from standard exceptions as requested during review. |
73 | : public std::logic_error { |
74 | explicit external_logic (const char *s = "external logic" ) : |
75 | std::logic_error (s) {} |
76 | // virtual const char *what () const throw () { |
77 | // return "exception: external logic"; |
78 | // } |
79 | void raise () { |
80 | throw *this; |
81 | } |
82 | #else |
83 | { |
84 | external_logic () |
85 | {} |
86 | explicit external_logic (const char *) |
87 | {} |
88 | void raise () { |
89 | std::abort (); |
90 | } |
91 | #endif |
92 | }; |
93 | |
94 | struct bad_argument |
95 | #if ! defined (BOOST_NO_EXCEPTIONS) && ! defined (BOOST_UBLAS_NO_EXCEPTIONS) |
96 | // Inherit from standard exceptions as requested during review. |
97 | : public std::invalid_argument { |
98 | explicit bad_argument (const char *s = "bad argument" ) : |
99 | std::invalid_argument (s) {} |
100 | void raise () { |
101 | throw *this; |
102 | } |
103 | #else |
104 | { |
105 | bad_argument () |
106 | {} |
107 | explicit bad_argument (const char *) |
108 | {} |
109 | void raise () { |
110 | std::abort (); |
111 | } |
112 | #endif |
113 | }; |
114 | |
115 | /** |
116 | */ |
117 | struct bad_size |
118 | #if ! defined (BOOST_NO_EXCEPTIONS) && ! defined (BOOST_UBLAS_NO_EXCEPTIONS) |
119 | // Inherit from standard exceptions as requested during review. |
120 | : public std::domain_error { |
121 | explicit bad_size (const char *s = "bad size" ) : |
122 | std::domain_error (s) {} |
123 | void raise () { |
124 | throw *this; |
125 | } |
126 | #else |
127 | { |
128 | bad_size () |
129 | {} |
130 | explicit bad_size (const char *) |
131 | {} |
132 | void raise () { |
133 | std::abort (); |
134 | } |
135 | #endif |
136 | }; |
137 | |
138 | struct bad_index |
139 | #if ! defined (BOOST_NO_EXCEPTIONS) && ! defined (BOOST_UBLAS_NO_EXCEPTIONS) |
140 | // Inherit from standard exceptions as requested during review. |
141 | : public std::out_of_range { |
142 | explicit bad_index (const char *s = "bad index" ) : |
143 | std::out_of_range (s) {} |
144 | void raise () { |
145 | throw *this; |
146 | } |
147 | #else |
148 | { |
149 | bad_index () |
150 | {} |
151 | explicit bad_index (const char *) |
152 | {} |
153 | void raise () { |
154 | std::abort (); |
155 | } |
156 | #endif |
157 | }; |
158 | |
159 | struct singular |
160 | #if ! defined (BOOST_NO_EXCEPTIONS) && ! defined (BOOST_UBLAS_NO_EXCEPTIONS) |
161 | // Inherit from standard exceptions as requested during review. |
162 | : public std::runtime_error { |
163 | explicit singular (const char *s = "singular" ) : |
164 | std::runtime_error (s) {} |
165 | void raise () { |
166 | throw *this; |
167 | } |
168 | #else |
169 | { |
170 | singular () |
171 | {} |
172 | explicit singular (const char *) |
173 | {} |
174 | void raise () { |
175 | std::abort (); |
176 | } |
177 | #endif |
178 | }; |
179 | |
180 | struct non_real |
181 | #if ! defined (BOOST_NO_EXCEPTIONS) && ! defined (BOOST_UBLAS_NO_EXCEPTIONS) |
182 | // Inherit from standard exceptions as requested during review. |
183 | : public std::domain_error { |
184 | explicit non_real (const char *s = "exception: non real" ) : |
185 | std::domain_error (s) {} |
186 | void raise () { |
187 | throw *this; |
188 | } |
189 | #else |
190 | { |
191 | non_real () |
192 | {} |
193 | explicit non_real (const char *) |
194 | {} |
195 | void raise () { |
196 | std::abort (); |
197 | } |
198 | #endif |
199 | }; |
200 | |
201 | #if BOOST_UBLAS_CHECK_ENABLE |
202 | // Macros are equivilent to |
203 | // template<class E> |
204 | // BOOST_UBLAS_INLINE |
205 | // void check (bool expression, const E &e) { |
206 | // if (! expression) |
207 | // e.raise (); |
208 | // } |
209 | // template<class E> |
210 | // BOOST_UBLAS_INLINE |
211 | // void check_ex (bool expression, const char *file, int line, const E &e) { |
212 | // if (! expression) |
213 | // e.raise (); |
214 | // } |
215 | #ifndef BOOST_UBLAS_NO_STD_CERR |
216 | #define BOOST_UBLAS_CHECK_FALSE(e) \ |
217 | std::cerr << "Check failed in file " << __FILE__ << " at line " << __LINE__ << ":" << std::endl; \ |
218 | e.raise (); |
219 | #define BOOST_UBLAS_CHECK(expression, e) \ |
220 | if (! (expression)) { \ |
221 | std::cerr << "Check failed in file " << __FILE__ << " at line " << __LINE__ << ":" << std::endl; \ |
222 | std::cerr << #expression << std::endl; \ |
223 | e.raise (); \ |
224 | } |
225 | #define BOOST_UBLAS_CHECK_EX(expression, file, line, e) \ |
226 | if (! (expression)) { \ |
227 | std::cerr << "Check failed in file " << (file) << " at line " << (line) << ":" << std::endl; \ |
228 | std::cerr << #expression << std::endl; \ |
229 | e.raise (); \ |
230 | } |
231 | #else |
232 | #define BOOST_UBLAS_CHECK_FALSE(e) \ |
233 | e.raise (); |
234 | #define BOOST_UBLAS_CHECK(expression, e) \ |
235 | if (! (expression)) { \ |
236 | e.raise (); \ |
237 | } |
238 | #define BOOST_UBLAS_CHECK_EX(expression, file, line, e) \ |
239 | if (! (expression)) { \ |
240 | e.raise (); \ |
241 | } |
242 | #endif |
243 | #else |
244 | // Macros are equivilent to |
245 | // template<class E> |
246 | // BOOST_UBLAS_INLINE |
247 | // void check (bool expression, const E &e) {} |
248 | // template<class E> |
249 | // BOOST_UBLAS_INLINE |
250 | // void check_ex (bool expression, const char *file, int line, const E &e) {} |
251 | #define BOOST_UBLAS_CHECK_FALSE(e) |
252 | #define BOOST_UBLAS_CHECK(expression, e) |
253 | #define BOOST_UBLAS_CHECK_EX(expression, file, line, e) |
254 | #endif |
255 | |
256 | |
257 | #ifndef BOOST_UBLAS_USE_FAST_SAME |
258 | // Macro is equivilent to |
259 | // template<class T> |
260 | // BOOST_UBLAS_INLINE |
261 | // const T &same_impl (const T &size1, const T &size2) { |
262 | // BOOST_UBLAS_CHECK (size1 == size2, bad_argument ()); |
263 | // return (std::min) (size1, size2); |
264 | // } |
265 | // #define BOOST_UBLAS_SAME(size1, size2) same_impl ((size1), (size2)) |
266 | // need two types here because different containers can have |
267 | // different size_types (especially sparse types) |
268 | template<class T1, class T2> |
269 | BOOST_UBLAS_INLINE |
270 | // Kresimir Fresl and Dan Muller reported problems with COMO. |
271 | // We better change the signature instead of libcomo ;-) |
272 | // const T &same_impl_ex (const T &size1, const T &size2, const char *file, int line) { |
273 | T1 same_impl_ex (const T1 &size1, const T2 &size2, const char *file, int line) { |
274 | BOOST_UBLAS_CHECK_EX (size1 == size2, file, line, bad_argument ()); |
275 | return (size1 < size2)?(size1):(size2); |
276 | } |
277 | template<class T> |
278 | BOOST_UBLAS_INLINE |
279 | T same_impl_ex (const T &size1, const T &size2, const char *file, int line) { |
280 | BOOST_UBLAS_CHECK_EX (size1 == size2, file, line, bad_argument ()); |
281 | return (std::min) (size1, size2); |
282 | } |
283 | #define BOOST_UBLAS_SAME(size1, size2) same_impl_ex ((size1), (size2), __FILE__, __LINE__) |
284 | #else |
285 | // Macros are equivilent to |
286 | // template<class T> |
287 | // BOOST_UBLAS_INLINE |
288 | // const T &same_impl (const T &size1, const T &size2) { |
289 | // return size1; |
290 | // } |
291 | // #define BOOST_UBLAS_SAME(size1, size2) same_impl ((size1), (size2)) |
292 | #define BOOST_UBLAS_SAME(size1, size2) (size1) |
293 | #endif |
294 | |
295 | }}} |
296 | |
297 | #endif |
298 | |