1 //
2 //  Copyright (c) 2000-2002
3 //  Joerg Walter, Mathias Koch
4 //
5 //  Distributed under the Boost Software License, Version 1.0. (See
6 //  accompanying file LICENSE_1_0.txt or copy at
7 //  http://www.boost.org/LICENSE_1_0.txt)
8 //
9 //  The authors gratefully acknowledge the support of
10 //  GeNeSys mbH & Co. KG in producing this work.
11 //
12 
13 #ifndef _BOOST_UBLAS_EXCEPTION_
14 #define _BOOST_UBLAS_EXCEPTION_
15 
16 #if ! defined (BOOST_NO_EXCEPTIONS) && ! defined (BOOST_UBLAS_NO_EXCEPTIONS)
17 #include <stdexcept>
18 #else
19 #include <cstdlib>
20 #endif
21 #ifndef BOOST_UBLAS_NO_STD_CERR
22 #include <iostream>
23 #endif
24 
25 #include <boost/numeric/ublas/detail/config.hpp>
26 
27 namespace boost { namespace numeric { namespace ublas {
28 
29     /** \brief Exception raised when a division by zero occurs
30      */
31     struct divide_by_zero
32 #if ! defined (BOOST_NO_EXCEPTIONS) && ! defined (BOOST_UBLAS_NO_EXCEPTIONS)
33         // Inherit from standard exceptions as requested during review.
34         : public std::runtime_error
35 	{
divide_by_zeroboost::numeric::ublas::divide_by_zero36         explicit divide_by_zero (const char *s = "divide by zero") :
37             std::runtime_error (s) {}
raiseboost::numeric::ublas::divide_by_zero38         void raise () {
39             throw *this;
40         }
41 #else
42     {
43         divide_by_zero ()
44             {}
45         explicit divide_by_zero (const char *)
46             {}
47         void raise () {
48             std::abort ();
49         }
50 #endif
51     };
52 
53     /** \brief Expception raised when some interal errors occurs like computations errors, zeros values where you should not have zeros, etc...
54      */
55     struct internal_logic
56 #if ! defined (BOOST_NO_EXCEPTIONS) && ! defined (BOOST_UBLAS_NO_EXCEPTIONS)
57         // Inherit from standard exceptions as requested during review.
58         : public std::logic_error {
internal_logicboost::numeric::ublas::internal_logic59         explicit 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         internal_logic ()
67             {}
68         explicit internal_logic (const char *)
69             {}
70         void raise () {
71             std::abort ();
72         }
73 #endif
74     };
75 
76     struct external_logic
77 #if ! defined (BOOST_NO_EXCEPTIONS) && ! defined (BOOST_UBLAS_NO_EXCEPTIONS)
78         // Inherit from standard exceptions as requested during review.
79         : public std::logic_error {
external_logicboost::numeric::ublas::external_logic80         explicit 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         external_logic ()
91             {}
92         explicit external_logic (const char *)
93             {}
94         void raise () {
95             std::abort ();
96         }
97 #endif
98     };
99 
100     struct bad_argument
101 #if ! defined (BOOST_NO_EXCEPTIONS) && ! defined (BOOST_UBLAS_NO_EXCEPTIONS)
102         // Inherit from standard exceptions as requested during review.
103         : public std::invalid_argument {
bad_argumentboost::numeric::ublas::bad_argument104         explicit 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         bad_argument ()
112             {}
113         explicit bad_argument (const char *)
114             {}
115         void raise () {
116             std::abort ();
117         }
118 #endif
119     };
120 
121     /**
122      */
123     struct bad_size
124 #if ! defined (BOOST_NO_EXCEPTIONS) && ! defined (BOOST_UBLAS_NO_EXCEPTIONS)
125         // Inherit from standard exceptions as requested during review.
126         : public std::domain_error {
bad_sizeboost::numeric::ublas::bad_size127         explicit bad_size (const char *s = "bad size") :
128             std::domain_error (s) {}
raiseboost::numeric::ublas::bad_size129         void raise () {
130             throw *this;
131         }
132 #else
133     {
134         bad_size ()
135             {}
136         explicit bad_size (const char *)
137             {}
138         void raise () {
139             std::abort ();
140         }
141 #endif
142     };
143 
144     struct bad_index
145 #if ! defined (BOOST_NO_EXCEPTIONS) && ! defined (BOOST_UBLAS_NO_EXCEPTIONS)
146         // Inherit from standard exceptions as requested during review.
147         : public std::out_of_range {
bad_indexboost::numeric::ublas::bad_index148         explicit bad_index (const char *s = "bad index") :
149             std::out_of_range (s) {}
raiseboost::numeric::ublas::bad_index150         void raise () {
151             throw *this;
152         }
153 #else
154     {
155         bad_index ()
156             {}
157         explicit bad_index (const char *)
158             {}
159         void raise () {
160             std::abort ();
161         }
162 #endif
163     };
164 
165     struct singular
166 #if ! defined (BOOST_NO_EXCEPTIONS) && ! defined (BOOST_UBLAS_NO_EXCEPTIONS)
167         // Inherit from standard exceptions as requested during review.
168         : public std::runtime_error {
singularboost::numeric::ublas::singular169         explicit singular (const char *s = "singular") :
170             std::runtime_error (s) {}
raiseboost::numeric::ublas::singular171         void raise () {
172             throw *this;
173         }
174 #else
175     {
176         singular ()
177             {}
178         explicit singular (const char *)
179             {}
180         void raise () {
181             std::abort ();
182         }
183 #endif
184     };
185 
186     struct non_real
187 #if ! defined (BOOST_NO_EXCEPTIONS) && ! defined (BOOST_UBLAS_NO_EXCEPTIONS)
188         // Inherit from standard exceptions as requested during review.
189         : public std::domain_error {
non_realboost::numeric::ublas::non_real190         explicit non_real (const char *s = "exception: non real") :
191             std::domain_error (s) {}
raiseboost::numeric::ublas::non_real192         void raise () {
193             throw *this;
194         }
195 #else
196      {
197         non_real ()
198             {}
199         explicit non_real (const char *)
200             {}
201         void raise () {
202             std::abort ();
203         }
204 #endif
205     };
206 
207 #if BOOST_UBLAS_CHECK_ENABLE
208 // Macros are equivilent to
209 //    template<class E>
210 //    BOOST_UBLAS_INLINE
211 //    void check (bool expression, const E &e) {
212 //        if (! expression)
213 //            e.raise ();
214 //    }
215 //    template<class E>
216 //    BOOST_UBLAS_INLINE
217 //    void check_ex (bool expression, const char *file, int line, const E &e) {
218 //        if (! expression)
219 //            e.raise ();
220 //    }
221 #ifndef BOOST_UBLAS_NO_STD_CERR
222 #define BOOST_UBLAS_CHECK_FALSE(e) \
223     std::cerr << "Check failed in file " << __FILE__ << " at line " << __LINE__ << ":" << std::endl; \
224     e.raise ();
225 #define BOOST_UBLAS_CHECK(expression, 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 #define BOOST_UBLAS_CHECK_EX(expression, file, line, e) \
232     if (! (expression)) { \
233         std::cerr << "Check failed in file " << (file) << " at line " << (line) << ":" << std::endl; \
234         std::cerr << #expression << std::endl; \
235         e.raise (); \
236     }
237 #else
238 #define BOOST_UBLAS_CHECK_FALSE(e) \
239     e.raise ();
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 // Macros are equivilent to
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_FALSE(e)
258 #define BOOST_UBLAS_CHECK(expression, e)
259 #define BOOST_UBLAS_CHECK_EX(expression, file, line, e)
260 #endif
261 
262 
263 #ifndef BOOST_UBLAS_USE_FAST_SAME
264 // Macro is equivilent to
265 //    template<class T>
266 //    BOOST_UBLAS_INLINE
267 //    const T &same_impl (const T &size1, const T &size2) {
268 //        BOOST_UBLAS_CHECK (size1 == size2, bad_argument ());
269 //        return (std::min) (size1, size2);
270 //    }
271 // #define BOOST_UBLAS_SAME(size1, size2) same_impl ((size1), (size2))
272      // need two types here because different containers can have
273      // different size_types (especially sparse types)
274     template<class T1, class T2>
275     BOOST_UBLAS_INLINE
276     // Kresimir Fresl and Dan Muller reported problems with COMO.
277     // We better change the signature instead of libcomo ;-)
278     // const T &same_impl_ex (const T &size1, const T &size2, const char *file, int line) {
same_impl_ex(const T1 & size1,const T2 & size2,const char * file,int line)279     T1 same_impl_ex (const T1 &size1, const T2 &size2, const char *file, int line) {
280         BOOST_UBLAS_CHECK_EX (size1 == size2, file, line, bad_argument ());
281         return (size1 < size2)?(size1):(size2);
282     }
283     template<class T>
284     BOOST_UBLAS_INLINE
same_impl_ex(const T & size1,const T & size2,const char * file,int line)285     T same_impl_ex (const T &size1, const T &size2, const char *file, int line) {
286         BOOST_UBLAS_CHECK_EX (size1 == size2, file, line, bad_argument ());
287         return (std::min) (size1, size2);
288     }
289 #define BOOST_UBLAS_SAME(size1, size2) same_impl_ex ((size1), (size2), __FILE__, __LINE__)
290 #else
291 // Macros are equivilent to
292 //    template<class T>
293 //    BOOST_UBLAS_INLINE
294 //    const T &same_impl (const T &size1, const T &size2) {
295 //        return size1;
296 //    }
297 // #define BOOST_UBLAS_SAME(size1, size2) same_impl ((size1), (size2))
298 #define BOOST_UBLAS_SAME(size1, size2) (size1)
299 #endif
300 
301 }}}
302 
303 #endif
304