00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00021 #ifndef _ARAGELI_exception_hpp_
00022 #define _ARAGELI_exception_hpp_
00023
00024 #include "config.hpp"
00025
00026 #include <cstddef>
00027 #include <cassert>
00028 #include <string>
00029 #include <iostream>
00030 #include <sstream>
00031 #include <list>
00032
00033
00034
00035
00036 namespace Arageli
00037 {
00038
00039
00041 class exception
00042 {
00043 public:
00044
00045 typedef std::list<std::string> descriptions_type;
00046
00047 exception () {}
00048
00049 exception (const std::string& description_a)
00050 : descriptions_m(1, description_a) {}
00051
00052 const descriptions_type& descriptions () const
00053 { return descriptions_m; }
00054
00055 descriptions_type& descriptions ()
00056 { return descriptions_m; }
00057
00058 virtual void add_description (const std::string& desc)
00059 { descriptions_m.push_back(desc); }
00060
00061 virtual void add_location
00062 (
00063 const std::string& src,
00064 std::size_t line,
00065 const std::string& desc = std::string()
00066 );
00067
00069 virtual std::string msg () const;
00070
00072 virtual void output (std::ostream& out) const { out << msg(); }
00073
00074 virtual ~exception () {}
00075
00076 private:
00077
00078 descriptions_type descriptions_m;
00079
00080 };
00081
00082
00083 inline std::ostream& operator<< (std::ostream& out, const exception& e)
00084 { e.output(out); return out; }
00085
00086
00087 #define ARAGELI_EXCEPT_LOC(e) e.add_location(__FILE__, __LINE__)
00088 #define ARAGELI_EXCEPT_LOC_DESC(e, d) e.add_location(__FILE__, __LINE__, d)
00089
00090 #define ARAGELI_EXCEPT_LOCCTRL_REGION_BEGIN \
00091 { try {
00092
00093 #define ARAGELI_EXCEPT_LOCCTRL_REGION_END \
00094 }catch(::Arageli::exception& e) \
00095 { ARAGELI_EXCEPT_LOC_DESC(e, "Exception gate."); throw; } }
00096
00097
00099
00101 class assert_failed : public virtual exception
00102 {
00103 public:
00104
00105 assert_failed
00106 (
00107 const char* expr_a,
00108 const char* source_a,
00109 std::size_t line_a
00110 ) throw()
00111 : expr_m(expr_a),
00112 source_m(source_a),
00113 line_m(line_a)
00114 {}
00115
00117 const char* expr () const throw() { return expr_m; }
00118
00120 const char* source () const throw() { return source_m; }
00121
00123 std::size_t line () const throw() { return line_m; }
00124
00126 virtual std::string msg () const
00127 {
00128 std::ostringstream buf;
00129 output(buf);
00130 return buf.str();
00131 }
00132
00134 virtual void output (std::ostream& out) const;
00135
00136 private:
00137
00138 const char* expr_m;
00139 const char* source_m;
00140 std::size_t line_m;
00141
00142 };
00143
00144
00146 class out_of_range : public virtual exception
00147 {
00148 public:
00149
00150 virtual std::string msg () const
00151 {
00152 return
00153 "Out of range at an index expression."
00154 "\nAdditional information:\n" +
00155 exception::msg();
00156 }
00157 };
00158
00159
00161 class invalid_argument : public virtual exception
00162 {
00163 public:
00164
00165 virtual std::string msg () const
00166 {
00167 return
00168 "Invalid argument for the operation"
00169 "\nAdditional information:\n" +
00170 exception::msg();
00171 }
00172 };
00173
00174
00176 class division_by_zero : public invalid_argument
00177 {
00178 public:
00179
00180 virtual std::string msg () const
00181 {
00182 return
00183 "Division by zero"
00184 "\nAdditional information:\n" +
00185 exception::msg();
00186 }
00187 };
00188
00189
00191 class matrix_is_singular : public invalid_argument
00192 {
00193 public:
00194
00195 virtual std::string msg () const
00196 {
00197 return "Matrix is singular"
00198 "\nAdditional information:\n" +
00199 exception::msg();
00200 }
00201 };
00202
00203
00205 class incorrect_string : public invalid_argument
00206 {
00207 std::string str_m;
00208
00209 public:
00210
00211 incorrect_string (const std::string& str_a) : str_m(str_a) {}
00212
00213 virtual std::string msg () const
00214 {
00215 std::string res = "Incorrect string";
00216 if(!str_m.empty())
00217 res += " \"" + str_m + "\"";
00218 return res + "\nAdditional information:\n" + exception::msg();
00219 }
00220
00221 const std::string& str () const { return str_m; }
00222
00223 };
00224
00225
00226 namespace ctrl
00227 {
00228
00229 class abort : public virtual exception
00230 {
00231 public:
00232
00233 virtual std::string msg () const
00234 {
00235 return std::string("Controller \"") +
00236 typeid(*this).name() +
00237 "\" breaks execution of the function."
00238 + "\nAdditional information:\n" + exception::msg();
00239 }
00240 };
00241
00242 }
00243
00244
00246 #ifdef ARAGELI_ASSERT_THROW_EXCEPTION
00247 #define ARAGELI_THROW_ASSERT_FAILED(EXPR) \
00248 { throw ::Arageli::assert_failed(#EXPR, __FILE__, __LINE__); }
00249 #else
00250 #ifdef NDEBUG
00251 #define ARAGELI_THROW_ASSERT_FAILED(EXPR) \
00252 { \
00253 ::std::cerr << '\n' << ::Arageli::assert_failed(#EXPR, __FILE__, __LINE__); \
00254 ::std::cin.get(); \
00255 }
00256 #else
00257 #define ARAGELI_THROW_ASSERT_FAILED(EXPR) \
00258 { assert(!#EXPR); }
00259 #endif
00260 #endif
00261
00262
00264 #define ARAGELI_ASSERT_ALWAYS_CUST(EXPR, EXCEPT_OBJ) \
00265 { if(!(EXPR))throw EXCEPT_OBJ; }
00266
00267
00269 #define ARAGELI_ASSERT_ALWAYS(EXPR) \
00270 { if(!(EXPR))ARAGELI_THROW_ASSERT_FAILED(EXPR); }
00271
00272
00273 #if ARAGELI_DEBUG_LEVEL > 0
00274
00275 #define ARAGELI_ASSERT_0_CUST(EXPR, EXCEPT_OBJ) \
00276 ARAGELI_ASSERT_ALWAYS_CUST(EXPR, EXCEPT_OBJ)
00277
00278 #define ARAGELI_ASSERT_0(EXPR) \
00279 ARAGELI_ASSERT_ALWAYS(EXPR)
00280
00281 #define ARAGELI_DEBUG_EXEC_0(WHAT) WHAT
00282
00283 #else
00284
00285 #define ARAGELI_ASSERT_0_CUST(EXPR, EXCEPT_OBJ)
00286 #define ARAGELI_ASSERT_0(EXPR)
00287 #define ARAGELI_DEBUG_EXEC_0(WHAT)
00288
00289 #endif
00290
00291
00292 #if ARAGELI_DEBUG_LEVEL > 1
00293
00294 #define ARAGELI_ASSERT_1_CUST(EXPR, EXCEPT_OBJ) \
00295 ARAGELI_ASSERT_ALWAYS_CUST(EXPR, EXCEPT_OBJ)
00296
00297 #define ARAGELI_ASSERT_1(EXPR) \
00298 ARAGELI_ASSERT_ALWAYS(EXPR)
00299
00300 #define ARAGELI_DEBUG_EXEC_1(WHAT) WHAT
00301
00302 #else
00303
00304 #define ARAGELI_ASSERT_1_CUST(EXPR, EXCEPT_OBJ)
00305 #define ARAGELI_ASSERT_1(EXPR)
00306 #define ARAGELI_DEBUG_EXEC_1(WHAT)
00307
00308 #endif
00309
00310
00311 #if ARAGELI_DEBUG_LEVEL > 2
00312
00313 #define ARAGELI_ASSERT_2_CUST(EXPR, EXCEPT_OBJ) \
00314 ARAGELI_ASSERT_ALWAYS_CUST(EXPR, EXCEPT_OBJ)
00315
00316 #define ARAGELI_ASSERT_2(EXPR) \
00317 ARAGELI_ASSERT_ALWAYS(EXPR)
00318
00319 #define ARAGELI_DEBUG_EXEC_2(WHAT) WHAT
00320
00321 #else
00322
00323 #define ARAGELI_ASSERT_2_CUST(EXPR, EXCEPT_OBJ)
00324 #define ARAGELI_ASSERT_2(EXPR)
00325 #define ARAGELI_DEBUG_EXEC_2(WHAT)
00326
00327 #endif
00328
00329
00330 #if ARAGELI_DEBUG_LEVEL > 3
00331
00332 #define ARAGELI_ASSERT_3_CUST(EXPR, EXCEPT_OBJ) \
00333 ARAGELI_ASSERT_ALWAYS_CUST(EXPR, EXCEPT_OBJ)
00334
00335 #define ARAGELI_ASSERT_3(EXPR) \
00336 ARAGELI_ASSERT_ALWAYS(EXPR)
00337
00338 #define ARAGELI_DEBUG_EXEC_3(WHAT) WHAT
00339
00340 #else
00341
00342 #define ARAGELI_ASSERT_3_CUST(EXPR, EXCEPT_OBJ)
00343 #define ARAGELI_ASSERT_3(EXPR)
00344 #define ARAGELI_DEBUG_EXEC_3(WHAT)
00345
00346 #endif
00347
00348
00349 }
00350
00351
00352 #endif // #ifndef _ARAGELI_exception_hpp_