exception.hpp

Go to the documentation of this file.
00001 /*****************************************************************************
00002     
00003     exception.hpp -- basic exceptions of library and specific macro for
00004         asserts.
00005 
00006     This file is a part of the Arageli library.
00007 
00008     Copyright (C) Nikolai Yu. Zolotykh, 1999--2006
00009     Copyright (C) Sergey S. Lyalin, 2005
00010     University of Nizhni Novgorod, Russia
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::abort();*/::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) /* nothing */
00286     #define ARAGELI_ASSERT_0(EXPR)  /* nothing */
00287     #define ARAGELI_DEBUG_EXEC_0(WHAT)  /* nothing */
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) /* nothing */
00305     #define ARAGELI_ASSERT_1(EXPR) /* nothing */
00306     #define ARAGELI_DEBUG_EXEC_1(WHAT)  /* nothing */
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) /* nothing */
00324     #define ARAGELI_ASSERT_2(EXPR) /* nothing */
00325     #define ARAGELI_DEBUG_EXEC_2(WHAT)  /* nothing */
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) /* nothing */
00343     #define ARAGELI_ASSERT_3(EXPR) /* nothing */
00344     #define ARAGELI_DEBUG_EXEC_3(WHAT)  /* nothing */
00345 
00346 #endif
00347 
00348 
00349 } // namespace Arageli
00350 
00351 
00352 #endif  //  #ifndef _ARAGELI_exception_hpp_

Generated on Thu Aug 31 17:38:05 2006 for Arageli by  doxygen 1.4.7