1 //
2 //  Copyright (c) 2000-2002
3 //  Joerg Walter, Mathias Koch
4 //
5 //  Permission to use, copy, modify, distribute and sell this software
6 //  and its documentation for any purpose is hereby granted without fee,
7 //  provided that the above copyright notice appear in all copies and
8 //  that both that copyright notice and this permission notice appear
9 //  in supporting documentation.  The authors make no representations
10 //  about the suitability of this software for any purpose.
11 //  It is provided "as is" without express or implied warranty.
12 //
13 //  The authors gratefully acknowledge the support of
14 //  GeNeSys mbH & Co. KG in producing this work.
15 //
16 
17 #ifndef _BOOST_UBLAS_EXCEPTION_
18 #define _BOOST_UBLAS_EXCEPTION_
19 
20 #if ! defined (BOOST_NO_EXCEPTIONS) && ! defined (BOOST_UBLAS_NO_EXCEPTIONS)
21 #include <stdexcept>
22 #else
23 #include <cstdlib>
24 #endif
25 #ifndef BOOST_UBLAS_NO_STD_CERR
26 #include <iostream>
27 #endif
28 
29 #include <boost/numeric/ublas/detail/config.hpp>
30 
31 namespace boost { namespace numeric { namespace ublas {
32 
33     struct divide_by_zero
34 #if ! defined (BOOST_NO_EXCEPTIONS) && ! defined (BOOST_UBLAS_NO_EXCEPTIONS)
35         // Inherit from standard exceptions as requested during review.
36         : public std::runtime_error {
37         explicit
divide_by_zeroboost::numeric::ublas::divide_by_zero38         divide_by_zero (const char *s = "divide by zero") :
39             std::runtime_error (s) {}
raiseboost::numeric::ublas::divide_by_zero40         void raise () {
41             throw *this;
42         }
43 #else
44     {
45         explicit
46         divide_by_zero (const char *s = 0)
47             {}
48         void raise () {
49             std::abort ();
50         }
51 #endif
52     };
53 
54     struct internal_logic
55 #if ! defined (BOOST_NO_EXCEPTIONS) && ! defined (BOOST_UBLAS_NO_EXCEPTIONS)
56         // Inherit from standard exceptions as requested during review.
57         : public std::logic_error {
58         explicit
internal_logicboost::numeric::ublas::internal_logic59         internal_logic (const char *s = "internal logic") :
60             std::logic_error (s) {}
raiseboost::numeric::ublas::internal_logic61         void raise () {
62             throw *this;
63         }
64 #else
65     {
66         explicit
67         internal_logic (const char *s = 0)
68             {}
69         void raise () {
70             std::abort ();
71         }
72 #endif
73     };
74 
75     struct external_logic
76 #if ! defined (BOOST_NO_EXCEPTIONS) && ! defined (BOOST_UBLAS_NO_EXCEPTIONS)
77         // Inherit from standard exceptions as requested during review.
78         : public std::logic_error {
79         explicit
external_logicboost::numeric::ublas::external_logic80         external_logic (const char *s = "external logic") :
81             std::logic_error (s) {}
82         // virtual const char *what () const throw () {
83         //     return "exception: external logic";
84         // }
raiseboost::numeric::ublas::external_logic85         void raise () {
86             throw *this;
87         }
88 #else
89     {
90         explicit
91         external_logic (const char *s = 0)
92             {}
93         void raise () {
94             std::abort ();
95         }
96 #endif
97     };
98 
99     struct bad_argument
100 #if ! defined (BOOST_NO_EXCEPTIONS) && ! defined (BOOST_UBLAS_NO_EXCEPTIONS)
101         // Inherit from standard exceptions as requested during review.
102         : public std::invalid_argument {
103         explicit
bad_argumentboost::numeric::ublas::bad_argument104         bad_argument (const char *s = "bad argument") :
105             std::invalid_argument (s) {}
raiseboost::numeric::ublas::bad_argument106         void raise () {
107             throw *this;
108         }
109 #else
110     {
111         explicit
112         bad_argument (const char *s = 0)
113             {}
114         void raise () {
115             throw *this;
116             std::abort ();
117         }
118 #endif
119     };
120 
121     struct bad_size
122 #if ! defined (BOOST_NO_EXCEPTIONS) && ! defined (BOOST_UBLAS_NO_EXCEPTIONS)
123         // Inherit from standard exceptions as requested during review.
124         : public std::domain_error {
125         explicit
bad_sizeboost::numeric::ublas::bad_size126         bad_size (const char *s = "bad size") :
127             std::domain_error (s) {}
raiseboost::numeric::ublas::bad_size128         void raise () {
129             throw *this;
130         }
131 #else
132     {
133         explicit
134         bad_size (const char *s = 0)
135             {}
136         void raise () {
137 #ifdef BOOST_NO_STDC_NAMESPACE
138             ::abort ();
139 #else
140             std::abort ();
141 #endif
142         }
143 #endif
144     };
145 
146     struct bad_index
147 #if ! defined (BOOST_NO_EXCEPTIONS) && ! defined (BOOST_UBLAS_NO_EXCEPTIONS)
148         // Inherit from standard exceptions as requested during review.
149         : public std::out_of_range {
150         explicit
bad_indexboost::numeric::ublas::bad_index151         bad_index (const char *s = "bad index") :
152             std::out_of_range (s) {}
raiseboost::numeric::ublas::bad_index153         void raise () {
154             throw *this;
155         }
156 #else
157     {
158         explicit
159         bad_index (const char *s = 0)
160             {}
161         void raise () {
162             std::abort ();
163         }
164 #endif
165     };
166 
167     struct singular
168 #if ! defined (BOOST_NO_EXCEPTIONS) && ! defined (BOOST_UBLAS_NO_EXCEPTIONS)
169         // Inherit from standard exceptions as requested during review.
170         : public std::runtime_error {
171         explicit
singularboost::numeric::ublas::singular172         singular (const char *s = "singular") :
173             std::runtime_error (s) {}
raiseboost::numeric::ublas::singular174         void raise () {
175             throw *this;
176         }
177 #else
178     {
179         explicit
180         singular (const char *s = 0)
181             {}
182         void raise () {
183             throw *this;
184             std::abort ();
185         }
186 #endif
187     };
188 
189     struct non_real
190 #if ! defined (BOOST_NO_EXCEPTIONS) && ! defined (BOOST_UBLAS_NO_EXCEPTIONS)
191         // Inherit from standard exceptions as requested during review.
192         : public std::domain_error {
193         explicit
non_realboost::numeric::ublas::non_real194         non_real (const char *s = "exception: non real") :
195             std::domain_error (s) {}
raiseboost::numeric::ublas::non_real196         void raise () {
197             throw *this;
198         }
199 #else
200      {
201         explicit
202         non_real (const char *s = 0)
203             {}
204         void raise () {
205             std::abort ();
206         }
207 #endif
208     };
209 
210 #if BOOST_UBLAS_CHECK_ENABLE
211 // FIXME for performance reasons we better use macros
212 //    template<class E>
213 //    BOOST_UBLAS_INLINE
214 //    void check (bool expression, const E &e) {
215 //        if (! expression)
216 //            e.raise ();
217 //    }
218 //    template<class E>
219 //    BOOST_UBLAS_INLINE
220 //    void check_ex (bool expression, const char *file, int line, const E &e) {
221 //        if (! expression)
222 //            e.raise ();
223 //    }
224 // Dan Muller reported problems with COMO in GUI applications
225 // So we need a new preprocessor symbol:
226 #ifndef BOOST_UBLAS_NO_STD_CERR
227 #define BOOST_UBLAS_CHECK(expression, e) \
228     if (! (expression)) { \
229         std::cerr << "Assertion failed in file " << __FILE__ << " at line " << __LINE__ << ":" << std::endl; \
230         std::cerr << #expression << std::endl; \
231         e.raise (); \
232     }
233 #define BOOST_UBLAS_CHECK_EX(expression, file, line, e) \
234     if (! (expression)) { \
235         std::cerr << "Assertion failed in file " << (file) << " at line " << (line) << ":" << std::endl; \
236         std::cerr << #expression << std::endl; \
237         e.raise (); \
238     }
239 #else
240 #define BOOST_UBLAS_CHECK(expression, e) \
241     if (! (expression)) { \
242         e.raise (); \
243     }
244 #define BOOST_UBLAS_CHECK_EX(expression, file, line, e) \
245     if (! (expression)) { \
246         e.raise (); \
247     }
248 #endif
249 #else
250 // FIXME for performance reasons we better use macros
251 //    template<class E>
252 //    BOOST_UBLAS_INLINE
253 //    void check (bool expression, const E &e) {}
254 //    template<class E>
255 //    BOOST_UBLAS_INLINE
256 //    void check_ex (bool expression, const char *file, int line, const E &e) {}
257 #define BOOST_UBLAS_CHECK(expression, e)
258 #define BOOST_UBLAS_CHECK_EX(expression, file, line, e)
259 #endif
260 
261 
262 #ifndef BOOST_UBLAS_USE_FAST_SAME
263 // FIXME for performance reasons we better use macros
264 //    template<class T>
265 //    BOOST_UBLAS_INLINE
266 //    const T &same_impl (const T &size1, const T &size2) {
267 //        BOOST_UBLAS_CHECK (size1 == size2, bad_argument ());
268 //        return (std::min) (size1, size2);
269 //    }
270 // #define BOOST_UBLAS_SAME(size1, size2) same_impl ((size1), (size2))
271     template<class T>
272     BOOST_UBLAS_INLINE
273     // Kresimir Fresl and Dan Muller reported problems with COMO.
274     // We better change the signature instead of libcomo ;-)
275     // const T &same_impl_ex (const T &size1, const T &size2, const char *file, int line) {
same_impl_ex(const T & size1,const T & size2,const char * file,int line)276     T same_impl_ex (const T &size1, const T &size2, const char *file, int line) {
277         BOOST_UBLAS_CHECK_EX (size1 == size2, file, line, bad_argument ());
278         return (std::min) (size1, size2);
279     }
280 #define BOOST_UBLAS_SAME(size1, size2) same_impl_ex ((size1), (size2), __FILE__, __LINE__)
281 #else
282 // FIXME for performance reasons we better use macros
283 //    template<class T>
284 //    BOOST_UBLAS_INLINE
285 //    const T &same_impl (const T &size1, const T &size2) {
286 //        return size1;
287 //    }
288 // #define BOOST_UBLAS_SAME(size1, size2) same_impl ((size1), (size2))
289 #define BOOST_UBLAS_SAME(size1, size2) (size1)
290 #endif
291 
292 }}}
293 
294 #endif
295