[ 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 inline 00210 void throw_invariant_error(bool predicate, char const * message, char const * file, int line) 00211 { 00212 if(!predicate) 00213 throw vigra::InvariantViolation(message, file, line); 00214 } 00215 00216 inline 00217 void throw_invariant_error(bool predicate, std::string message, char const * file, int line) 00218 { 00219 if(!predicate) 00220 throw vigra::InvariantViolation(message.c_str(), file, line); 00221 } 00222 00223 inline 00224 void throw_precondition_error(bool predicate, char const * message, char const * file, int line) 00225 { 00226 if(!predicate) 00227 throw vigra::PreconditionViolation(message, file, line); 00228 } 00229 00230 inline 00231 void throw_precondition_error(bool predicate, std::string message, char const * file, int line) 00232 { 00233 if(!predicate) 00234 throw vigra::PreconditionViolation(message.c_str(), file, line); 00235 } 00236 00237 inline 00238 void throw_postcondition_error(bool predicate, char const * message, char const * file, int line) 00239 { 00240 if(!predicate) 00241 throw vigra::PostconditionViolation(message, file, line); 00242 } 00243 00244 inline 00245 void throw_postcondition_error(bool predicate, std::string message, char const * file, int line) 00246 { 00247 if(!predicate) 00248 throw vigra::PostconditionViolation(message.c_str(), file, line); 00249 } 00250 00251 inline 00252 void throw_runtime_error(char const * message, char const * file, int line) 00253 { 00254 std::ostringstream what; 00255 what << "\n" << message << "\n(" << file << ":" << line << ")\n"; 00256 throw std::runtime_error(what.str()); 00257 } 00258 00259 inline 00260 void throw_runtime_error(std::string message, char const * file, int line) 00261 { 00262 std::ostringstream what; 00263 what << "\n" << message << "\n(" << file << ":" << line << ")\n"; 00264 throw std::runtime_error(what.str()); 00265 } 00266 00267 #define vigra_precondition(PREDICATE, MESSAGE) vigra::throw_precondition_error((PREDICATE), MESSAGE, __FILE__, __LINE__) 00268 00269 #define vigra_assert(PREDICATE, MESSAGE) vigra_precondition(PREDICATE, MESSAGE) 00270 00271 #define vigra_postcondition(PREDICATE, MESSAGE) vigra::throw_postcondition_error((PREDICATE), MESSAGE, __FILE__, __LINE__) 00272 00273 #define vigra_invariant(PREDICATE, MESSAGE) vigra::throw_invariant_error((PREDICATE), MESSAGE, __FILE__, __LINE__) 00274 00275 #define vigra_fail(MESSAGE) vigra::throw_runtime_error(MESSAGE, __FILE__, __LINE__) 00276 00277 #else // NDEBUG 00278 00279 inline 00280 void throw_invariant_error(bool predicate, char const * message) 00281 { 00282 if(!predicate) 00283 throw vigra::InvariantViolation(message); 00284 } 00285 00286 inline 00287 void throw_precondition_error(bool predicate, char const * message) 00288 { 00289 if(!predicate) 00290 throw vigra::PreconditionViolation(message); 00291 } 00292 00293 inline 00294 void throw_postcondition_error(bool predicate, char const * message) 00295 { 00296 if(!predicate) 00297 throw vigra::PostconditionViolation(message); 00298 } 00299 00300 inline 00301 void throw_invariant_error(bool predicate, std::string message) 00302 { 00303 if(!predicate) 00304 throw vigra::InvariantViolation(message.c_str()); 00305 } 00306 00307 inline 00308 void throw_precondition_error(bool predicate, std::string message) 00309 { 00310 if(!predicate) 00311 throw vigra::PreconditionViolation(message.c_str()); 00312 } 00313 00314 inline 00315 void throw_postcondition_error(bool predicate, std::string message) 00316 { 00317 if(!predicate) 00318 throw vigra::PostconditionViolation(message.c_str()); 00319 } 00320 00321 #define vigra_precondition(PREDICATE, MESSAGE) vigra::throw_precondition_error((PREDICATE), MESSAGE) 00322 00323 #define vigra_assert(PREDICATE, MESSAGE) 00324 00325 #define vigra_postcondition(PREDICATE, MESSAGE) vigra::throw_postcondition_error((PREDICATE), MESSAGE) 00326 00327 #define vigra_invariant(PREDICATE, MESSAGE) vigra::throw_invariant_error((PREDICATE), MESSAGE) 00328 00329 #define vigra_fail(MESSAGE) throw std::runtime_error(MESSAGE) 00330 00331 #endif // NDEBUG 00332 00333 } // namespace vigra 00334 00335 #endif // VIGRA_ERROR_HXX
© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de) |
html generated using doxygen and Python
|