[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]
vigra/error.hxx | ![]() |
00001 /************************************************************************/ 00002 /* */ 00003 /* Copyright 1998-2002 by Ullrich Koethe */ 00004 /* */ 00005 /* This file is part of the VIGRA computer vision library. */ 00006 /* The VIGRA Website is */ 00007 /* http://hci.iwr.uni-heidelberg.de/vigra/ */ 00008 /* Please direct questions, bug reports, and contributions to */ 00009 /* ullrich.koethe@iwr.uni-heidelberg.de or */ 00010 /* vigra@informatik.uni-hamburg.de */ 00011 /* */ 00012 /* Permission is hereby granted, free of charge, to any person */ 00013 /* obtaining a copy of this software and associated documentation */ 00014 /* files (the "Software"), to deal in the Software without */ 00015 /* restriction, including without limitation the rights to use, */ 00016 /* copy, modify, merge, publish, distribute, sublicense, and/or */ 00017 /* sell copies of the Software, and to permit persons to whom the */ 00018 /* Software is furnished to do so, subject to the following */ 00019 /* conditions: */ 00020 /* */ 00021 /* The above copyright notice and this permission notice shall be */ 00022 /* included in all copies or substantial portions of the */ 00023 /* Software. */ 00024 /* */ 00025 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */ 00026 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */ 00027 /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */ 00028 /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */ 00029 /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */ 00030 /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */ 00031 /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */ 00032 /* OTHER DEALINGS IN THE SOFTWARE. */ 00033 /* */ 00034 /************************************************************************/ 00035 00036 00037 #ifndef VIGRA_ERROR_HXX 00038 #define VIGRA_ERROR_HXX 00039 00040 #include <stdexcept> 00041 #include <sstream> 00042 #include <string> 00043 #include "config.hxx" 00044 00045 /*! \page ErrorReporting Error Reporting 00046 Exceptions and assertions provided by VIGRA 00047 00048 <b>\#include</b> <vigra/error.hxx> 00049 00050 VIGRA defines the following exception classes: 00051 00052 \code 00053 namespace vigra { 00054 class ContractViolation : public std::exception; 00055 class PreconditionViolation : public ContractViolation; 00056 class PostconditionViolation : public ContractViolation; 00057 class InvariantViolation : public ContractViolation; 00058 } 00059 \endcode 00060 00061 The following associated macros throw the corresponding exception if 00062 their PREDICATE evaluates to '<TT>false</TT>': 00063 00064 \code 00065 vigra_precondition(PREDICATE, MESSAGE); 00066 vigra_postcondition(PREDICATE, MESSAGE); 00067 vigra_invariant(PREDICATE, MESSAGE); 00068 \endcode 00069 00070 The MESSAGE is passed to the exception and can be retrieved via 00071 the overloaded member function '<TT>exception.what()</TT>'. If the compiler 00072 flag '<TT>NDEBUG</TT>' is <em>not</em> defined, the file name and line number of 00073 the error are automatically included in the message. The macro 00074 00075 \code 00076 vigra_assert(PREDICATE, MESSAGE); 00077 \endcode 00078 00079 is identical to <tt>vigra_precondition()</tt> except that it is completely removed 00080 when '<TT>NDEBUG</TT>' is defined. This is useful for test that are only needed during 00081 debugging, such as array index bound checking. The following macro 00082 00083 \code 00084 vigra_fail(MESSAGE); 00085 \endcode 00086 00087 unconditionally throws a '<TT>std::runtime_error</TT>' constructed from the message 00088 (along with file name and line number, if NDEBUG is not set). 00089 00090 <b> Usage:</b> 00091 00092 Include-File: 00093 <vigra/error.hxx> 00094 <p> 00095 Namespace: vigra (except for the macros, of course) 00096 00097 \code 00098 int main(int argc, char ** argv) 00099 { 00100 try 00101 { 00102 const char* input_file_name = argv[1]; 00103 00104 // read input image 00105 vigra::ImageImportInfo info(input_file_name); 00106 00107 // fail if input image is not grayscale 00108 vigra_precondition(info.isGrayscale(), "Input image must be grayscale"); 00109 00110 ...// process image 00111 } 00112 catch (std::exception & e) 00113 { 00114 std::cerr << e.what() << std::endl; // print message 00115 return 1; 00116 } 00117 00118 return 0; 00119 } 00120 \endcode 00121 **/ 00122 00123 namespace vigra { 00124 00125 class ContractViolation : public StdException 00126 { 00127 public: 00128 ContractViolation() 00129 {} 00130 00131 ContractViolation(char const * prefix, char const * message, 00132 char const * file, int line) 00133 { 00134 (*this) << "\n" << prefix << "\n" << message << "\n(" 00135 << file << ":" << line << ")\n"; 00136 } 00137 00138 ContractViolation(char const * prefix, char const * message) 00139 { 00140 (*this) << "\n" << prefix << "\n" << message << "\n"; 00141 } 00142 00143 ~ContractViolation() throw() 00144 {} 00145 00146 template<class T> 00147 ContractViolation & operator<<(T const & data) 00148 { 00149 std::ostringstream what; 00150 what << data; 00151 what_ += what.str(); 00152 return *this; 00153 } 00154 00155 virtual const char * what() const throw() 00156 { 00157 try 00158 { 00159 return what_.c_str(); 00160 } 00161 catch(...) 00162 { 00163 return "vigra::ContractViolation: error message was lost, sorry."; 00164 } 00165 } 00166 00167 private: 00168 std::string what_; 00169 }; 00170 00171 class PreconditionViolation : public ContractViolation 00172 { 00173 public: 00174 PreconditionViolation(char const * message, const char * file, int line) 00175 : ContractViolation("Precondition violation!", message, file, line) 00176 {} 00177 00178 PreconditionViolation(char const * message) 00179 : ContractViolation("Precondition violation!", message) 00180 {} 00181 }; 00182 00183 class PostconditionViolation : public ContractViolation 00184 { 00185 public: 00186 PostconditionViolation(char const * message, const char * file, int line) 00187 : ContractViolation("Postcondition violation!", message, file, line) 00188 {} 00189 00190 PostconditionViolation(char const * message) 00191 : ContractViolation("Postcondition violation!", message) 00192 {} 00193 }; 00194 00195 class InvariantViolation : public ContractViolation 00196 { 00197 public: 00198 InvariantViolation(char const * message, const char * file, int line) 00199 : ContractViolation("Invariant violation!", message, file, line) 00200 {} 00201 00202 InvariantViolation(char const * message) 00203 : ContractViolation("Invariant violation!", message) 00204 {} 00205 }; 00206 00207 //#ifndef NDEBUG 00208 00209 #if 1 00210 00211 inline 00212 void throw_invariant_error(bool predicate, char const * message, char const * file, int line) 00213 { 00214 if(!predicate) 00215 throw vigra::InvariantViolation(message, file, line); 00216 } 00217 00218 inline 00219 void throw_invariant_error(bool predicate, std::string message, char const * file, int line) 00220 { 00221 if(!predicate) 00222 throw vigra::InvariantViolation(message.c_str(), file, line); 00223 } 00224 00225 inline 00226 void throw_precondition_error(bool predicate, char const * message, char const * file, int line) 00227 { 00228 if(!predicate) 00229 throw vigra::PreconditionViolation(message, file, line); 00230 } 00231 00232 inline 00233 void throw_precondition_error(bool predicate, std::string message, char const * file, int line) 00234 { 00235 if(!predicate) 00236 throw vigra::PreconditionViolation(message.c_str(), file, line); 00237 } 00238 00239 inline 00240 void throw_postcondition_error(bool predicate, char const * message, char const * file, int line) 00241 { 00242 if(!predicate) 00243 throw vigra::PostconditionViolation(message, file, line); 00244 } 00245 00246 inline 00247 void throw_postcondition_error(bool predicate, std::string message, char const * file, int line) 00248 { 00249 if(!predicate) 00250 throw vigra::PostconditionViolation(message.c_str(), file, line); 00251 } 00252 00253 inline 00254 void throw_runtime_error(char const * message, char const * file, int line) 00255 { 00256 std::ostringstream what; 00257 what << "\n" << message << "\n(" << file << ":" << line << ")\n"; 00258 throw std::runtime_error(what.str()); 00259 } 00260 00261 inline 00262 void throw_runtime_error(std::string message, char const * file, int line) 00263 { 00264 std::ostringstream what; 00265 what << "\n" << message << "\n(" << file << ":" << line << ")\n"; 00266 throw std::runtime_error(what.str()); 00267 } 00268 00269 #define vigra_precondition(PREDICATE, MESSAGE) vigra::throw_precondition_error((PREDICATE), MESSAGE, __FILE__, __LINE__) 00270 00271 #define vigra_assert(PREDICATE, MESSAGE) vigra_precondition(PREDICATE, MESSAGE) 00272 00273 #define vigra_postcondition(PREDICATE, MESSAGE) vigra::throw_postcondition_error((PREDICATE), MESSAGE, __FILE__, __LINE__) 00274 00275 #define vigra_invariant(PREDICATE, MESSAGE) vigra::throw_invariant_error((PREDICATE), MESSAGE, __FILE__, __LINE__) 00276 00277 #define vigra_fail(MESSAGE) vigra::throw_runtime_error(MESSAGE, __FILE__, __LINE__) 00278 00279 #else // NDEBUG 00280 00281 inline 00282 void throw_invariant_error(bool predicate, char const * message) 00283 { 00284 if(!predicate) 00285 throw vigra::InvariantViolation(message); 00286 } 00287 00288 inline 00289 void throw_precondition_error(bool predicate, char const * message) 00290 { 00291 if(!predicate) 00292 throw vigra::PreconditionViolation(message); 00293 } 00294 00295 inline 00296 void throw_postcondition_error(bool predicate, char const * message) 00297 { 00298 if(!predicate) 00299 throw vigra::PostconditionViolation(message); 00300 } 00301 00302 inline 00303 void throw_invariant_error(bool predicate, std::string message) 00304 { 00305 if(!predicate) 00306 throw vigra::InvariantViolation(message.c_str()); 00307 } 00308 00309 inline 00310 void throw_precondition_error(bool predicate, std::string message) 00311 { 00312 if(!predicate) 00313 throw vigra::PreconditionViolation(message.c_str()); 00314 } 00315 00316 inline 00317 void throw_postcondition_error(bool predicate, std::string message) 00318 { 00319 if(!predicate) 00320 throw vigra::PostconditionViolation(message.c_str()); 00321 } 00322 00323 #define vigra_precondition(PREDICATE, MESSAGE) vigra::throw_precondition_error((PREDICATE), MESSAGE) 00324 00325 #define vigra_assert(PREDICATE, MESSAGE) 00326 00327 #define vigra_postcondition(PREDICATE, MESSAGE) vigra::throw_postcondition_error((PREDICATE), MESSAGE) 00328 00329 #define vigra_invariant(PREDICATE, MESSAGE) vigra::throw_invariant_error((PREDICATE), MESSAGE) 00330 00331 #define vigra_fail(MESSAGE) throw std::runtime_error(MESSAGE) 00332 00333 #endif // NDEBUG 00334 00335 } // namespace vigra 00336 00337 #endif // VIGRA_ERROR_HXX
© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de) |
html generated using doxygen and Python
|