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

vigra/error.hxx

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