[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]

vigra/error.hxx VIGRA

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)
Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany

html generated using doxygen and Python
vigra 1.9.0 (Tue Nov 6 2012)