vigra - vigra/error.hxx Source File

[ 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) Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany | html generated using doxygen and Python vigra 1.9.0 (Tue Nov 6 2012)