1 /* 2 * Copyright © 2004 Ondra Kamenik 3 * Copyright © 2019 Dynare Team 4 * 5 * This file is part of Dynare. 6 * 7 * Dynare is free software: you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation, either version 3 of the License, or 10 * (at your option) any later version. 11 * 12 * Dynare is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with Dynare. If not, see <http://www.gnu.org/licenses/>. 19 */ 20 21 // Exception. 22 23 /* Within the code we often check some state of variables, typically 24 preconditions or postconditions. If the state is not as required, it 25 is worthless to continue, since this means some fatal error in 26 algorithms. In this case we raise an exception which can be caught at 27 some higher level. This header file defines a simple infrastructure 28 for this. */ 29 30 #ifndef TL_EXCEPTION_H 31 #define TL_EXCEPTION_H 32 33 #include <iostream> 34 #include <utility> 35 #include <string> 36 37 /* The basic idea of raising an exception if some condition fails is that the 38 conditions is checked only if required. We define global TL_DEBUG macro 39 which is integer and says, how many debug messages the programm has to emit. 40 We also define TL_DEBUG_EXCEPTION which says, for what values of TL_DEBUG we 41 will check for conditions of the exceptions. If the TL_DEBUG is equal or 42 higher than TL_DEBUG_EXCEPTION, the exception conditions are checked. 43 44 We define TL_RAISE, and TL_RAISE_IF macros which throw an instance of 45 TLException (only if TL_DEBUG >= TL_DEBUG_EXCEPTION for the latter). The 46 first is unconditional throw, the second is conditioned by a given 47 expression. Note that if TL_DEBUG < TL_DEBUG_EXCEPTION then the code is 48 compiled but evaluation of the condition is passed. If code is optimized, 49 the optimizer also passes evaluation of TL_DEBUG and TL_DEBUG_EXCEPTION 50 comparison (I hope). 51 52 We provide default values for TL_DEBUG and TL_DEBUG_EXCEPTION. */ 53 54 #ifndef TL_DEBUG_EXCEPTION 55 # define TL_DEBUG_EXCEPTION 1 56 #endif 57 58 #ifndef TL_DEBUG 59 # define TL_DEBUG 0 60 #endif 61 62 #define TL_RAISE(mes) \ 63 throw TLException(__FILE__, __LINE__, mes) 64 65 #define TL_RAISE_IF(expr, mes) \ 66 if (TL_DEBUG >= TL_DEBUG_EXCEPTION && (expr)) throw TLException(__FILE__, __LINE__, mes); 67 68 /* Primitive exception class containing file name, line number and message. */ 69 70 class TLException 71 { 72 const std::string fname; 73 int lnum; 74 public: 75 const std::string message; TLException(std::string fname_arg,int lnum_arg,std::string message_arg)76 TLException(std::string fname_arg, int lnum_arg, std::string message_arg) 77 : fname{std::move(fname_arg)}, 78 lnum{lnum_arg}, 79 message{std::move(message_arg)} 80 { 81 } 82 virtual ~TLException() = default; 83 virtual void print() const84 print() const 85 { 86 std::cout << "At " << fname << ':' << lnum << ':' << message << std::endl; 87 } 88 }; 89 90 #endif 91