Moved alias code from tests/testdai.cpp to src/alldai.cpp
[libdai.git] / include / dai / exceptions.h
1 /* This file is part of libDAI - http://www.libdai.org/
2 *
3 * libDAI is licensed under the terms of the GNU General Public License version
4 * 2, or (at your option) any later version. libDAI is distributed without any
5 * warranty. See the file COPYING for more details.
6 *
7 * Copyright (C) 2006-2009 Joris Mooij [joris dot mooij at libdai dot org]
8 * Copyright (C) 2006-2007 Radboud University Nijmegen, The Netherlands
9 */
10
11
12 /// \file
13 /// \brief Defines the Exception class and macros for throwing exceptions and doing assertions
14
15
16 #ifndef __defined_libdai_exceptions_h
17 #define __defined_libdai_exceptions_h
18
19
20 #include <exception>
21 #include <stdexcept>
22 #include <string>
23 #include <iostream>
24
25
26 /// Used by DAI_THROW
27 #define DAI_QUOTE(x) #x
28
29 /// Used by DAI_THROW
30 #define DAI_TOSTRING(x) DAI_QUOTE(x)
31
32 /// Macro that simplifies throwing an exception with a useful default error message.
33 /** The error message consists of a description of the exception, the source
34 * code file and line number where the exception has been thrown.
35 * \param cod Corresponds to one of the enum values of dai::Exception::Code
36 *
37 * \par Example:
38 * \code
39 * DAI_THROW(NOT_IMPLEMENTED);
40 * \endcode
41 */
42 #define DAI_THROW(cod) throw dai::Exception(dai::Exception::cod, std::string(__FILE__ ", line " DAI_TOSTRING(__LINE__)))
43
44 /// Macro that simplifies throwing an exception with a user-defined error message.
45 /** \param cod Corresponds to one of the enum values of dai::Exception::Code
46 * \param msg Detailed error message that will be written to std::cerr.
47 *
48 * \par Example:
49 * \code
50 * DAI_THROWE(NOT_IMPLEMENTED,"Detailed error message");
51 * \endcode
52 */
53 #define DAI_THROWE(cod,msg) throw dai::Exception(dai::Exception::cod, std::string(__FILE__ ", line " DAI_TOSTRING(__LINE__)), msg)
54
55 /// Assertion mechanism, similar to the standard assert() macro. It is always active, even if NDEBUG is defined
56 #define DAI_ASSERT(condition) ((condition) ? ((void)0) : DAI_THROWE(ASSERTION_FAILED, std::string("Assertion \"" #condition "\" failed")))
57
58 // Assertion only if DAI_DEBUG is defined
59 #ifdef DAI_DEBUG
60 /// Assertion mechanism similar to DAI_ASSERT which is only active if DAI_DEBUG is defined
61 #define DAI_DEBASSERT(x) do {DAI_ASSERT(x);} while(0)
62 #else
63 #define DAI_DEBASSERT(x) do {} while(0)
64 #endif
65
66
67 namespace dai {
68
69
70 /// Error handling in libDAI is done by throwing an instance of the Exception class.
71 /** The Exception class inherits from std::runtime_error. It defines several types of exceptions
72 * and corresponding error messages. The recommended way to throw an instance of the Exception
73 * class is by using the #DAI_THROW or #DAI_THROWE macros.
74 */
75 class Exception : public std::runtime_error {
76 public:
77 /// Enumeration of exceptions used in libDAI
78 enum Code {NOT_IMPLEMENTED,
79 ASSERTION_FAILED,
80 IMPOSSIBLE_TYPECAST,
81 OBJECT_NOT_FOUND,
82 BELIEF_NOT_AVAILABLE,
83 UNKNOWN_ENUM_VALUE,
84 UNKNOWN_DAI_ALGORITHM,
85 UNKNOWN_PARAMETER_ESTIMATION_METHOD,
86 UNKNOWN_PROPERTY_TYPE,
87 UNKNOWN_PROPERTY,
88 MALFORMED_PROPERTY,
89 NOT_ALL_PROPERTIES_SPECIFIED,
90 INVALID_ALIAS,
91 CANNOT_READ_FILE,
92 CANNOT_WRITE_FILE,
93 INVALID_FACTORGRAPH_FILE,
94 INVALID_EVIDENCE_FILE,
95 INVALID_EMALG_FILE,
96 NOT_NORMALIZABLE,
97 MULTIPLE_UNDO,
98 FACTORGRAPH_NOT_CONNECTED,
99 INTERNAL_ERROR,
100 RUNTIME_ERROR,
101 NUM_ERRORS}; // NUM_ERRORS should be the last entry
102
103 /// Constructor
104 Exception( Code _code, const std::string& msg="", const std::string& detailedMsg="" ) : std::runtime_error(ErrorStrings[_code] + " [" + msg + "]"), errorcode(_code) {
105 if( !detailedMsg.empty() )
106 std::cerr << "ERROR: " << detailedMsg << std::endl;
107 }
108
109 /// Returns error code of this exception
110 Code code() const { return errorcode; }
111
112 /// Returns error message corresponding to an error code
113 const std::string &message( const Code c ) const { return ErrorStrings[c]; }
114
115
116 private:
117 /// Contains the error code of this exception
118 Code errorcode;
119
120 /// Error messages corresponding to the exceptions enumerated above
121 static std::string ErrorStrings[NUM_ERRORS];
122 };
123
124
125 }
126
127
128 #endif