Chaste Release::3.1
Exception.hpp
Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (c) 2005-2012, University of Oxford.
00004 All rights reserved.
00005 
00006 University of Oxford means the Chancellor, Masters and Scholars of the
00007 University of Oxford, having an administrative office at Wellington
00008 Square, Oxford OX1 2JD, UK.
00009 
00010 This file is part of Chaste.
00011 
00012 Redistribution and use in source and binary forms, with or without
00013 modification, are permitted provided that the following conditions are met:
00014  * Redistributions of source code must retain the above copyright notice,
00015    this list of conditions and the following disclaimer.
00016  * Redistributions in binary form must reproduce the above copyright notice,
00017    this list of conditions and the following disclaimer in the documentation
00018    and/or other materials provided with the distribution.
00019  * Neither the name of the University of Oxford nor the names of its
00020    contributors may be used to endorse or promote products derived from this
00021    software without specific prior written permission.
00022 
00023 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00024 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00025 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00026 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00027 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00028 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
00029 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00030 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00031 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
00032 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00033 
00034 */
00035 
00036 
00037 #ifndef _EXCEPTION_HPP_
00038 #define _EXCEPTION_HPP_
00039 
00045 #include <string>
00046 #include <sstream>
00047 #include <cfloat>  // For DBL_MAX
00048 #include <climits> // For UINT_MAX & INT_MAX, necessary in gcc-4.3
00049 #include <cstdlib> // For system() etc., necessary in gcc-4.3
00050 
00052 const unsigned UNSIGNED_UNSET = UINT_MAX;
00054 const int INT_UNSET = INT_MAX;
00056 const double DOUBLE_UNSET = DBL_MAX;
00057 
00063 class Exception
00064 {
00065 public:
00073     Exception(const std::string& rMessage, const std::string& rFilename, unsigned lineNumber);
00074 
00080     std::string GetMessage() const;
00081 
00087     std::string GetShortMessage() const;
00088 
00098     std::string CheckShortMessage(std::string expected) const;
00099 
00109     std::string CheckShortMessageContains(std::string expected) const;
00110 
00119     static void Terminate(const std::string& rMessage, const std::string& rFilename, unsigned lineNumber);
00120 
00121 protected:
00130     void SetMessage(const std::string& rMessage,
00131                     const std::string& rFilename, unsigned lineNumber);
00132 
00133 private:
00134     std::string mMessage; 
00135     std::string mShortMessage; 
00136 };
00137 
00143 #define EXCEPTION(message)                           \
00144     do {                                             \
00145         std::stringstream msg_stream;                \
00146         msg_stream << message;                       \
00147         throw Exception(msg_stream.str(), __FILE__, __LINE__); \
00148     } while (false)
00149 
00150 #include <boost/preprocessor/stringize.hpp>
00151 
00158 #define EXCEPT_IF_NOT(test) \
00159     if (!(test)) EXCEPTION("Assertion tripped: " BOOST_PP_STRINGIZE(test))
00160 
00161 
00168 #define TERMINATE(message)                           \
00169     do {                                             \
00170         std::stringstream msg_stream;                \
00171         msg_stream << message;                       \
00172         Exception::Terminate(msg_stream.str(), __FILE__, __LINE__); \
00173     } while (false)
00174 
00206 #define NEVER_REACHED  TERMINATE("Should have been impossible to reach this line of code"); exit(EXIT_FAILURE)
00207 
00213 #ifdef NDEBUG
00214 #define UNUSED_OPT(var) var=var
00215 #else
00216 #define UNUSED_OPT(var)
00217 #endif
00218 
00231 #define EXPECT0(cmd, arg) {      \
00232     std::string _arg(arg);       \
00233     int ret = cmd(_arg.c_str()); \
00234     if (ret != 0) {              \
00235         EXCEPTION("Error executing command: " #cmd "(" + _arg + ")"); \
00236     } }
00237 
00238 
00245 #define ABORT_IF_NON0_WITH_MSG(retcode, msg)     \
00246     if (retcode != 0) {                          \
00247         TERMINATE(msg);                          \
00248     }
00249 
00260 #define ABORT_IF_NON0(cmd, arg) { \
00261     std::string _arg(arg);        \
00262     int ret = cmd(_arg.c_str());  \
00263     ABORT_IF_NON0_WITH_MSG(ret, "Error executing command: " #cmd "(" + _arg + ")") \
00264     }
00265 
00272 #define ABORT_IF_THROWS(block)          \
00273     try {                               \
00274         block;                          \
00275     } catch (const Exception& e) {      \
00276         TERMINATE(e.GetMessage());      \
00277     } catch (const std::exception &e) { \
00278         TERMINATE(e.what());            \
00279     } catch (...) {                     \
00280         TERMINATE("Unexpected exception thrown."); \
00281     }
00282 
00289 #define EXPECT_NON0(cmd, arg) {   \
00290     std::string _arg = (arg);     \
00291     int ret = cmd(_arg.c_str());  \
00292     if (ret == 0) {               \
00293         EXCEPTION("Command: " #cmd "(" + _arg + ") succeeded and it shouldn't have"); \
00294     } }
00295 
00302 #define IGNORE_RET(cmd, arg) {   \
00303     std::string _arg = (arg);    \
00304     int ret = cmd(_arg.c_str()); \
00305     ret = ret;                   \
00306     }
00307 
00308 #endif // _EXCEPTION_HPP_